X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Faacdec_template.c;h=0c899285ddad4f60f7faf893d48c2a979ce8efd0;hb=fbb283cfefb1865375718c4a56ce608d96a4a8ed;hp=c2d9802023aead5358b2ca9c8cf8edec394192cd;hpb=7386b4ff39506b7a34b3689cc4b05993ed9b4a4f;p=ffmpeg diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index c2d9802023a..0c899285dda 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -997,6 +997,7 @@ static int decode_audio_specific_config_gb(AACContext *ac, switch (m4ac->object_type) { case AOT_AAC_MAIN: case AOT_AAC_LC: + case AOT_AAC_SSR: case AOT_AAC_LTP: case AOT_ER_AAC_LC: case AOT_ER_AAC_LD: @@ -1967,6 +1968,33 @@ static void apply_prediction(AACContext *ac, SingleChannelElement *sce) reset_all_predictors(sce->predictor_state); } +static void decode_gain_control(SingleChannelElement * sce, GetBitContext * gb) +{ + // wd_num, wd_test, aloc_size + static const uint8_t gain_mode[4][3] = { + {1, 0, 5}, // ONLY_LONG_SEQUENCE = 0, + {2, 1, 2}, // LONG_START_SEQUENCE, + {8, 0, 2}, // EIGHT_SHORT_SEQUENCE, + {2, 1, 5}, // LONG_STOP_SEQUENCE + }; + + const int mode = sce->ics.window_sequence[0]; + uint8_t bd, wd, ad; + + // FIXME: Store the gain control data on |sce| and do something with it. + uint8_t max_band = get_bits(gb, 2); + for (bd = 0; bd < max_band; bd++) { + for (wd = 0; wd < gain_mode[mode][0]; wd++) { + uint8_t adjust_num = get_bits(gb, 3); + for (ad = 0; ad < adjust_num; ad++) { + skip_bits(gb, 4 + ((wd == 0 && gain_mode[mode][1]) + ? 4 + : gain_mode[mode][2])); + } + } + } +} + /** * Decode an individual_channel_stream payload; reference: table 4.44. * @@ -2034,9 +2062,11 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, goto fail; } if (!eld_syntax && get_bits1(gb)) { - avpriv_request_sample(ac->avctx, "SSR"); - ret = AVERROR_PATCHWELCOME; - goto fail; + decode_gain_control(sce, gb); + if (!ac->warned_gain_control) { + avpriv_report_missing_feature(ac->avctx, "Gain control"); + ac->warned_gain_control = 1; + } } // I see no textual basis in the spec for this occurring after SSR gain // control, but this is what both reference and real implmentations do @@ -3294,20 +3324,14 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, AV_PKT_DATA_JP_DUALMONO, &jp_dualmono_size); - if (new_extradata && 0) { - av_free(avctx->extradata); - avctx->extradata = av_mallocz(new_extradata_size + - AV_INPUT_BUFFER_PADDING_SIZE); - if (!avctx->extradata) - return AVERROR(ENOMEM); - avctx->extradata_size = new_extradata_size; - memcpy(avctx->extradata, new_extradata, new_extradata_size); - push_output_configuration(ac); - if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, - avctx->extradata, - avctx->extradata_size*8LL, 1) < 0) { - pop_output_configuration(ac); - return AVERROR_INVALIDDATA; + if (new_extradata) { + /* discard previous configuration */ + ac->oc[1].status = OC_NONE; + err = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, + new_extradata, + new_extradata_size * 8LL, 1); + if (err < 0) { + return err; } }