X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Faacdec_template.c;h=721511c5e953a1e8d0fcd2d019ac255c75841a1b;hb=b429c86d84cfc964c84bc68ec56799802de2b25a;hp=6c6cdd84aff54910dbcb1e1f317b3913279ab77d;hpb=e0f84c303db71b4d57dff84e13f868f3f7cf7b5a;p=ffmpeg diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index 6c6cdd84aff..721511c5e95 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: @@ -1926,7 +1927,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024], if (cbt_m1 < NOISE_BT - 1) { for (group = 0; group < (int)g_len; group++, cfo+=128) { ac->vector_pow43(cfo, off_len); - ac->subband_scale(cfo, cfo, sf[idx], 34, off_len); + ac->subband_scale(cfo, cfo, sf[idx], 34, off_len, ac->avctx); } } } @@ -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 @@ -2128,7 +2158,7 @@ static void apply_intensity_stereo(AACContext *ac, coef0 + group * 128 + offsets[i], scale, 23, - offsets[i + 1] - offsets[i]); + offsets[i + 1] - offsets[i] ,ac->avctx); #else ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[i], coef0 + group * 128 + offsets[i], @@ -2561,7 +2591,7 @@ static void apply_ltp(AACContext *ac, SingleChannelElement *sce) for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++) if (ltp->used[sfb]) for (i = offsets[sfb]; i < offsets[sfb + 1]; i++) - sce->coeffs[i] += predFreq[i]; + sce->coeffs[i] += (UINTFLOAT)predFreq[i]; } } @@ -3092,6 +3122,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, int samples = 0, multiplier, audio_found = 0, pce_found = 0; int is_dmono, sce_count = 0; int payload_alignment; + uint8_t che_presence[4][MAX_ELEM_ID] = {{0}}; ac->frame = data; @@ -3129,6 +3160,17 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, } if (elem_type < TYPE_DSE) { + if (che_presence[elem_type][elem_id]) { + int error = che_presence[elem_type][elem_id] > 1; + av_log(ac->avctx, error ? AV_LOG_ERROR : AV_LOG_DEBUG, "channel element %d.%d duplicate\n", + elem_type, elem_id); + if (error) { + err = AVERROR_INVALIDDATA; + goto fail; + } + } + che_presence[elem_type][elem_id]++; + if (!(che=get_che(ac, elem_type, elem_id))) { av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n", elem_type, elem_id); @@ -3294,20 +3336,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; } }