Browse code

Make AAC in Ogg (ogm) work.

This needs the extradata to be extracted.
The approach used is the one MPlayer uses, though it is
unclear whether the 4 bytes extradata that are skipped
should be skipped always or only for AAC.
The AAC parser must be disabled, too, otherwise playback
still does not work.
Fixes trac issue #547.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>

Reimar Döffinger authored on 2012/02/07 06:04:46
Showing 1 changed files
... ...
@@ -23,6 +23,7 @@
23 23
 **/
24 24
 
25 25
 #include <stdlib.h>
26
+#include "libavutil/avassert.h"
26 27
 #include "libavutil/intreadwrite.h"
27 28
 #include "libavcodec/get_bits.h"
28 29
 #include "libavcodec/bytestream.h"
... ...
@@ -40,6 +41,7 @@ ogm_header(AVFormatContext *s, int idx)
40 40
     const uint8_t *p = os->buf + os->pstart;
41 41
     uint64_t time_unit;
42 42
     uint64_t spu;
43
+    uint32_t size;
43 44
 
44 45
     if(!(*p & 1))
45 46
         return 0;
... ...
@@ -67,11 +69,13 @@ ogm_header(AVFormatContext *s, int idx)
67 67
             acid[4] = 0;
68 68
             cid = strtol(acid, NULL, 16);
69 69
             st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid);
70
-            st->need_parsing = AVSTREAM_PARSE_FULL;
70
+            // our parser completely breaks AAC in Ogg
71
+            if (st->codec->codec_id != CODEC_ID_AAC)
72
+                st->need_parsing = AVSTREAM_PARSE_FULL;
71 73
         }
72 74
 
73
-        p += 4;                     /* useless size field */
74
-
75
+        size        = bytestream_get_le32(&p);
76
+        size        = FFMIN(size, os->psize);
75 77
         time_unit   = bytestream_get_le64(&p);
76 78
         spu         = bytestream_get_le64(&p);
77 79
         p += 4;                     /* default_len */
... ...
@@ -89,6 +93,17 @@ ogm_header(AVFormatContext *s, int idx)
89 89
             st->codec->bit_rate = bytestream_get_le32(&p) * 8;
90 90
             st->codec->sample_rate = spu * 10000000 / time_unit;
91 91
             avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
92
+            if (size >= 56 && st->codec->codec_id == CODEC_ID_AAC) {
93
+                p += 4;
94
+                size -= 4;
95
+            }
96
+            if (size > 52) {
97
+                av_assert0(FF_INPUT_BUFFER_PADDING_SIZE <= 52);
98
+                size -= 52;
99
+                st->codec->extradata_size = size;
100
+                st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
101
+                bytestream_get_buffer(&p, st->codec->extradata, size);
102
+            }
92 103
         }
93 104
     } else if (*p == 3) {
94 105
         if (os->psize > 8)