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

Reimar Döffinger Reimar.Doeffinger at gmx.de
Wed Aug 26 21:39:44 CEST 2009


On Wed, Aug 26, 2009 at 08:51:30PM +0200, Nico Sabbi wrote:
> Il giorno mer, 26/08/2009 alle 20.22 +0200, Reimar Döffinger ha scritto:
> > On Wed, Aug 26, 2009 at 08:17:34PM +0200, Nico Sabbi wrote:
> > > Il giorno mer, 26/08/2009 alle 19.42 +0200, Reimar Döffinger ha scritto:
> > > > 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.
> > > 
> > > fine for me, but what happens with unsupported audio formats? Or with
> > > aac?
> > 
> > They are treated the same as currently, i.e. no parsing is done (simply
> > because we don't know a lavc codec ID for it, which disables the
> > AVParser code).
> > I extended the code locally to also cover mp3/mp2 audio.
> > No idea what the situation with AAC is, are there any files that need
> > a parser to work with FFmpeg's faac? With my samples missing SBR support
> > is the only issue.
> 
> better not adding a parser for AAC: LATM wouldn't work. All the other
> samples I have play flawlessly (but mencoder would benefit from a
> parserm, anyway).

Sure, IMO AAC is not up for consideration anyway as long as it lacks SBR
and LATM I'd say (except for mencoder of course, but that is not that
high priority either).
Attached is an updated version that works a bit better (MP2/MP3 support,
and no more A-V sync with one of my DVDs).
-------------- 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,79 @@
            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;
+            case 0x55:
+            case 0x5500736d:
+            case MKTAG('.', 'm', 'p', '3'):
+            case MKTAG('M', 'P', 'E', ' '):
+            case MKTAG('L', 'A', 'M', 'E'):
+                codec_id = CODEC_ID_MP3;
+                break;
+            case 0x50:
+            case MKTAG('.', 'm', 'p', '2'):
+            case MKTAG('.', 'm', 'p', '1'):
+                codec_id = CODEC_ID_MP2;
+                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);
+            dp2->pos = dp->pos;
+            dp2->pts = dp->pts;
+            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