On Tue, Jun 28, 2011 at 1:20 AM, Alex Converse <[email protected]> wrote:
> On Tue, Jun 28, 2011 at 1:16 AM, Benjamin Larsson <[email protected]> 
> wrote:
>>
>> On 06/28/2011 09:23 AM, Alex Converse wrote:
>>> On Tue, May 24, 2011 at 6:28 AM, Benjamin Larsson <[email protected]> 
>>> wrote:
>>>>
>>>>> Based on the output with and without this patch it is clear that you
>>>>> have broken implicit SBR+Implicit PS.
>>>>>
>>>>> Regards,
>>>>> Alex
>>>>
>>>> Now file nr 2 sounded fine.
>>>>
>>>
>>> I'm sorry this took so long. I think I had mistakenly written this off
>>> as the previous attempt.
>>>
>>> I've gone ahead and fixed some issues related to invalid channel
>>> configs in the no-extradata path... and fixed bfi.
>>>
>>> Regards,
>>> Alex
>>>
>>
>> Looks good.
>>
>
> Actually this still has a minor problem. When trial decoding probing
> an ADTS file with chan_config 0, it sets avctx->channels to the
> correct number of channels. Then when doing the real decoding it sets
> chan_config to avctx->channels which causes the decoder to ignore the
> PCE config.
>
> The fix for this should be simple.
>

For real this time:
From f32cb6ff9bba4f59a152571109d001fb7283f5e3 Mon Sep 17 00:00:00 2001
From: Benjamin Larsson <[email protected]>
Date: Mon, 27 Jun 2011 23:39:12 -0700
Subject: [PATCH] Add support for aac streams in mp4/mov without extradata.

---
 libavcodec/aacdec.c |   42 ++++++++++++++++++++++++++++++++++++++++++
 libavformat/utils.c |   25 +++++++++++--------------
 2 files changed, 53 insertions(+), 14 deletions(-)

diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index 26ce204..f26a4b7 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -530,6 +530,22 @@ static void reset_all_predictors(PredictorState *ps)
         reset_predict_state(&ps[i]);
 }
 
+static int sample_rate_idx (int rate)
+{
+         if (92017 <= rate) return 0;
+    else if (75132 <= rate) return 1;
+    else if (55426 <= rate) return 2;
+    else if (46009 <= rate) return 3;
+    else if (37566 <= rate) return 4;
+    else if (27713 <= rate) return 5;
+    else if (23004 <= rate) return 6;
+    else if (18783 <= rate) return 7;
+    else if (13856 <= rate) return 8;
+    else if (11502 <= rate) return 9;
+    else if (9391  <= rate) return 10;
+    else                    return 11;
+}
+
 static void reset_predictor_group(PredictorState *ps, int group_num)
 {
     int i;
@@ -552,10 +568,33 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
     ac->m4ac.sample_rate = avctx->sample_rate;
 
     if (avctx->extradata_size > 0) {
+        avctx->channels    = 0;
+        avctx->frame_size  = 0;
+        avctx->sample_rate = 0;
         if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac,
                                          avctx->extradata,
                                          avctx->extradata_size) < 0)
             return -1;
+    } else {
+        int sr, i;
+        enum ChannelPosition new_che_pos[4][MAX_ELEM_ID];
+
+        sr = sample_rate_idx(avctx->sample_rate);
+        ac->m4ac.sampling_index = sr;
+        ac->m4ac.channels = avctx->channels;
+
+        for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++)
+            if (ff_mpeg4audio_channels[i] == avctx->channels)
+                break;
+        if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) {
+            i = 0;
+        }
+        ac->m4ac.chan_config = i;
+
+        if (ac->m4ac.chan_config) {
+            set_default_channel_config(avctx, new_che_pos, ac->m4ac.chan_config);
+            output_configure(ac, ac->che_pos, new_che_pos, ac->m4ac.chan_config, OC_GLOBAL_HDR);
+        }
     }
 
     if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) {
@@ -2047,6 +2086,7 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
             if (output_configure(ac, ac->che_pos, new_che_pos, hdr_info.chan_config, OC_TRIAL_FRAME))
                 return -7;
         } else if (ac->output_configured != OC_LOCKED) {
+            ac->m4ac.chan_config = 0;
             ac->output_configured = OC_NONE;
         }
         if (ac->output_configured != OC_LOCKED) {
@@ -2514,6 +2554,7 @@ AVCodec ff_aac_decoder = {
     .sample_fmts = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
     },
+    .capabilities = CODEC_CAP_CHANNEL_CONF,
     .channel_layouts = aac_channel_layout,
 };
 
@@ -2534,5 +2575,6 @@ AVCodec ff_aac_latm_decoder = {
     .sample_fmts = (const enum AVSampleFormat[]) {
         AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE
     },
+    .capabilities = CODEC_CAP_CHANNEL_CONF,
     .channel_layouts = aac_channel_layout,
 };
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 7370c60..5ce8994 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2207,11 +2207,7 @@ int av_find_stream_info(AVFormatContext *ic)
     for(i=0;i<ic->nb_streams;i++) {
         AVCodec *codec;
         st = ic->streams[i];
-        if (st->codec->codec_id == CODEC_ID_AAC) {
-            st->codec->sample_rate = 0;
-            st->codec->frame_size = 0;
-            st->codec->channels = 0;
-        }
+
         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
             st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
 /*            if(!st->time_base.num)
@@ -2229,13 +2225,6 @@ int av_find_stream_info(AVFormatContext *ic)
         assert(!st->codec->codec);
         codec = avcodec_find_decoder(st->codec->codec_id);
 
-        /* Force decoding of at least one frame of codec data
-         * this makes sure the codec initializes the channel configuration
-         * and does not trust the values from the container.
-         */
-        if (codec && codec->capabilities & CODEC_CAP_CHANNEL_CONF)
-            st->codec->channels = 0;
-
         /* Ensure that subtitle_header is properly set. */
         if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
             && codec && !st->codec->codec)
@@ -2377,8 +2366,16 @@ int av_find_stream_info(AVFormatContext *ic)
         /* if still no information, we try to open the codec and to
            decompress the frame. We try to avoid that in most cases as
            it takes longer and uses more memory. For MPEG-4, we need to
-           decompress for QuickTime. */
-        if (!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st))
+           decompress for QuickTime.
+
+           If CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
+           least one frame of codec data, this makes sure the codec initializes
+           the channel configuration and does not only trust the values from the container.
+        */
+        if (!has_codec_parameters(st->codec) ||
+            !has_decode_delay_been_guessed(st) ||
+            (st->codec->codec && 
+             st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))
             try_decode_frame(st, pkt);
 
         st->codec_info_nb_frames++;
-- 
1.7.3.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to