changeset 1468:3f467725b70f libavformat

add support for AAC in matroska
author aurel
date Wed, 08 Nov 2006 20:13:30 +0000
parents 24c082e20a6a
children 5789e36270ce
files matroska.c
diffstat 1 files changed, 55 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/matroska.c	Wed Nov 08 20:09:56 2006 +0000
+++ b/matroska.c	Wed Nov 08 20:13:30 2006 +0000
@@ -223,7 +223,7 @@
     {"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 @@
     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 @@
 
         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 @@
                 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 @@
 
             }
 
+            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",