add support for AAC in matroska
authorAurelien Jacobs <aurel@gnuage.org>
Wed, 8 Nov 2006 20:13:30 +0000 (20:13 +0000)
committerAurelien Jacobs <aurel@gnuage.org>
Wed, 8 Nov 2006 20:13:30 +0000 (20:13 +0000)
Originally committed as revision 6947 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/matroska.c

index 4917388a1c8bade6aad8483b90936561c51a77fa..b7982752b3e5fa2a968986639de0dcf7e9b12b4c 100644 (file)
@@ -223,7 +223,7 @@ static CodecTags codec_tags[]={
     {"A_DTS"            , CODEC_ID_DTS},
     {"A_VORBIS"         , CODEC_ID_VORBIS},
     {"A_AAC/MPEG2/"     , CODEC_ID_AAC},
-    {"A_AAC/MPEG4/"     , CODEC_ID_AAC},
+    {"A_AAC/MPEG4/"     , CODEC_ID_MPEG4AAC},
     {"A_WAVPACK4"       , CODEC_ID_WAVPACK},
     {NULL               , CODEC_ID_NONE}
 /* TODO: AC3-9/10 (?), Real, Musepack, Quicktime */
@@ -2022,6 +2022,37 @@ matroska_parse_seekhead (MatroskaDemuxContext *matroska)
     return res;
 }
 
+#define ARRAY_SIZE(x)  (sizeof(x)/sizeof(*x))
+
+static int
+matroska_aac_profile (char *codec_id)
+{
+    static const char *aac_profiles[] = {
+        "MAIN", "LC", "SSR"
+    };
+    int profile;
+
+    for (profile=0; profile<ARRAY_SIZE(aac_profiles); profile++)
+        if (strstr(codec_id, aac_profiles[profile]))
+            break;
+    return profile + 1;
+}
+
+static int
+matroska_aac_sri (int samplerate)
+{
+    static const int aac_sample_rates[] = {
+        96000, 88200, 64000, 48000, 44100, 32000,
+        24000, 22050, 16000, 12000, 11025,  8000,
+    };
+    int sri;
+
+    for (sri=0; sri<ARRAY_SIZE(aac_sample_rates); sri++)
+        if (aac_sample_rates[sri] == samplerate)
+            break;
+    return sri;
+}
+
 static int
 matroska_read_header (AVFormatContext    *s,
                       AVFormatParameters *ap)
@@ -2164,7 +2195,7 @@ matroska_read_header (AVFormatContext    *s,
 
         for (i = 0; i < matroska->num_tracks; i++) {
             enum CodecID codec_id = CODEC_ID_NONE;
-            void *extradata = NULL;
+            uint8_t *extradata = NULL;
             int extradata_size = 0;
             track = matroska->tracks[i];
 
@@ -2175,7 +2206,8 @@ matroska_read_header (AVFormatContext    *s,
                 continue;
 
             for(j=0; codec_tags[j].str; j++){
-                if(!strcmp(codec_tags[j].str, track->codec_id)){
+                if(!strncmp(codec_tags[j].str, track->codec_id,
+                            strlen(codec_tags[j].str))){
                     codec_id= codec_tags[j].id;
                     break;
                 }
@@ -2214,6 +2246,26 @@ matroska_read_header (AVFormatContext    *s,
 
             }
 
+            if (codec_id==CODEC_ID_AAC || codec_id==CODEC_ID_MPEG4AAC) {
+                MatroskaAudioTrack *audiotrack = (MatroskaAudioTrack *) track;
+                int profile = matroska_aac_profile(track->codec_id);
+                int sri = matroska_aac_sri(audiotrack->internal_samplerate);
+                extradata = av_malloc(5);
+                if (extradata == NULL)
+                    return AVERROR_NOMEM;
+                extradata[0] = (profile << 3) | ((sri&0x0E) >> 1);
+                extradata[1] = ((sri&0x01) << 7) | (audiotrack->channels<<3);
+                if (strstr(track->codec_id, "SBR")) {
+                    sri = matroska_aac_sri(audiotrack->samplerate);
+                    extradata[2] = 0x56;
+                    extradata[3] = 0xE5;
+                    extradata[4] = 0x80 | (sri<<3);
+                    extradata_size = 5;
+                } else {
+                    extradata_size = 2;
+                }
+            }
+
             if (codec_id == CODEC_ID_NONE) {
                 av_log(matroska->ctx, AV_LOG_INFO,
                        "Unknown/unsupported CodecID %s.\n",