[MPlayer-dev-eng] [PATCH] AVParser for audio support

Reimar Döffinger Reimar.Doeffinger at gmx.de
Wed Aug 26 19:42:31 CEST 2009


Hello,
probably quite some room for improvements, though I think it is a good
step forward even if it is still a bit ugly.
It allows to use ffdca and ffac3 with the native AVI and MPEG demuxers.
-------------- next part --------------
Index: libmpdemux/demux_ts.c
===================================================================
--- libmpdemux/demux_ts.c	(revision 29551)
+++ libmpdemux/demux_ts.c	(working copy)
@@ -305,6 +305,7 @@
 		if(sh)
 		{
 			const char *lang = pid_lang_from_pmt(priv, es->pid);
+			sh->needs_parsing = 1;
 			sh->format = IS_AUDIO(es->type) ? es->type : es->subtype;
 			sh->ds = demuxer->audio;
 
Index: libmpdemux/demux_mpg.c
===================================================================
--- libmpdemux/demux_mpg.c	(revision 29551)
+++ libmpdemux/demux_mpg.c	(working copy)
@@ -270,6 +270,7 @@
     sh_audio_t* sh_a;
     new_sh_audio(demux,aid);
     sh_a = (sh_audio_t*)demux->a_streams[aid];
+    sh_a->needs_parsing = 1;
     switch(aid & 0xE0){  // 1110 0000 b  (high 3 bit: type  low 5: id)
       case 0x00: sh_a->format=0x50;break; // mpeg
       case 0xA0: sh_a->format=0x10001;break;  // dvd pcm
Index: libmpdemux/stheader.h
===================================================================
--- libmpdemux/stheader.h	(revision 29551)
+++ libmpdemux/stheader.h	(working copy)
@@ -32,6 +32,10 @@
   unsigned int format;
   int initialized;
   float stream_delay; // number of seconds stream should be delayed (according to dwStart or similar)
+  // things needed for parsing
+  int needs_parsing;
+  struct AVCodecContext *avctx;
+  struct AVCodecParserContext *parser;
   // output format:
   int sample_format;
   int samplerate;
Index: libmpdemux/demuxer.c
===================================================================
--- libmpdemux/demuxer.c	(revision 29551)
+++ libmpdemux/demuxer.c	(working copy)
@@ -330,6 +330,10 @@
     free(sh->wf);
     free(sh->codecdata);
     free(sh->lang);
+#ifdef CONFIG_LIBAVCODEC
+    av_parser_close(sh->parser);
+    av_freep(&sh->avctx);
+#endif
     free(sh);
 }
 
@@ -409,7 +413,7 @@
 }
 
 
-void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
+static void ds_add_packet_internal(demux_stream_t *ds, demux_packet_t *dp)
 {
     // append packet to DS stream:
     ++ds->packs;
@@ -429,6 +433,65 @@
            ds->demuxer->video->packs);
 }
 
+void ds_add_packet(demux_stream_t *ds, demux_packet_t *dp)
+{
+#ifdef CONFIG_LIBAVCODEC
+    AVCodecParserContext *parser = NULL;
+    AVCodecContext *avctx = NULL;
+    if (ds == ds->demuxer->audio) {
+        sh_audio_t *sh = ds->sh;
+        if (!sh->parser && sh->needs_parsing) {
+            enum CodecID codec_id = CODEC_ID_NONE;
+            extern int avcodec_initialized;
+            if (!avcodec_initialized) {
+                avcodec_init();
+                avcodec_register_all();
+                avcodec_initialized = 1;
+            }
+            switch (sh->format) {
+            case 0x2000:
+	    case 0x332D6361:
+	    case 0x332D4341:
+            case MKTAG('d', 'n', 'e', 't'):
+            case MKTAG('s', 'a', 'c', '3'):
+                codec_id = CODEC_ID_AC3;
+                break;
+            case MKTAG('E', 'A', 'C', '3'):
+                codec_id = CODEC_ID_EAC3;
+                break;
+            case 0x2001:
+            case 0x86:
+                codec_id = CODEC_ID_DTS;
+                break;
+            }
+            if (codec_id != CODEC_ID_NONE) {
+                sh->avctx = avcodec_alloc_context();
+                sh->parser = av_parser_init(codec_id);
+            }
+        }
+        parser = sh->parser;
+        avctx = sh->avctx;
+    }
+    if (parser) {
+        int len = dp->len;
+        int pos = 0;
+        while (len > 0) {
+            demux_packet_t *dp2;
+            uint8_t *parsed_start = dp->buffer + pos;
+            int parsed_len = len;
+            int consumed = av_parser_parse2(parser, avctx, &parsed_start, &parsed_len,
+                                            dp->buffer + pos, len, dp->pts, dp->pts, dp->pos);
+            pos += consumed;
+            len -= consumed;
+            dp2 = new_demux_packet(parsed_len);
+            memcpy(dp2->buffer, parsed_start, parsed_len);
+            ds_add_packet_internal(ds, dp2);
+        }
+    } else
+#endif
+    ds_add_packet_internal(ds, dp);
+}
+
 void ds_read_packet(demux_stream_t *ds, stream_t *stream, int len,
                     double pts, off_t pos, int flags)
 {
Index: libmpdemux/demux_avi.c
===================================================================
--- libmpdemux/demux_avi.c	(revision 29551)
+++ libmpdemux/demux_avi.c	(working copy)
@@ -60,6 +60,7 @@
         sh_audio_t* sh;
 	avi_priv_t *priv=demux->priv;
         sh=demux->audio->sh=demux->a_streams[stream_id];
+        sh->needs_parsing = 1;
         mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected AVI audio ID = %d\n",demux->audio->id);
 	if(sh->wf){
 	  priv->audio_block_size=sh->wf->nBlockAlign;


More information about the MPlayer-dev-eng mailing list