diff options
Diffstat (limited to 'chromium/third_party/ffmpeg/libavcodec/aacdec.c')
-rw-r--r-- | chromium/third_party/ffmpeg/libavcodec/aacdec.c | 78 |
1 files changed, 55 insertions, 23 deletions
diff --git a/chromium/third_party/ffmpeg/libavcodec/aacdec.c b/chromium/third_party/ffmpeg/libavcodec/aacdec.c index 1fb91853d01..a8f76e73e11 100644 --- a/chromium/third_party/ffmpeg/libavcodec/aacdec.c +++ b/chromium/third_party/ffmpeg/libavcodec/aacdec.c @@ -196,6 +196,9 @@ static int frame_configure_elements(AVCodecContext *avctx) /* get output buffer */ av_frame_unref(ac->frame); + if (!avctx->channels) + return 1; + ac->frame->nb_samples = 2048; if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) return ret; @@ -534,6 +537,25 @@ static int set_default_channel_config(AVCodecContext *avctx, *tags = tags_per_config[channel_config]; memcpy(layout_map, aac_channel_layout_map[channel_config - 1], *tags * sizeof(*layout_map)); + + /* + * AAC specification has 7.1(wide) as a default layout for 8-channel streams. + * However, at least Nero AAC encoder encodes 7.1 streams using the default + * channel config 7, mapping the side channels of the original audio stream + * to the second AAC_CHANNEL_FRONT pair in the AAC stream. Similarly, e.g. FAAD + * decodes the second AAC_CHANNEL_FRONT pair as side channels, therefore decoding + * the incorrect streams as if they were correct (and as the encoder intended). + * + * As actual intended 7.1(wide) streams are very rare, default to assuming a + * 7.1 layout was intended. + */ + if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) { + av_log(avctx, AV_LOG_INFO, "Assuming an incorrectly encoded 7.1 channel layout" + " instead of a spec-compliant 7.1(wide) layout, use -strict %d to decode" + " according to the specification instead.\n", FF_COMPLIANCE_STRICT); + layout_map[2][2] = AAC_CHANNEL_SIDE; + } + return 0; } @@ -1114,7 +1136,6 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0 * 32768.0); // window initialization ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); - ff_kbd_window_init(ff_aac_kbd_long_512, 4.0, 512); ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); ff_init_ff_sine_windows(10); ff_init_ff_sine_windows( 9); @@ -1227,13 +1248,14 @@ static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics, if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) { ics->swb_offset = ff_swb_offset_512[ac->oc[1].m4ac.sampling_index]; ics->num_swb = ff_aac_num_swb_512[ac->oc[1].m4ac.sampling_index]; + ics->tns_max_bands = ff_tns_max_bands_512[ac->oc[1].m4ac.sampling_index]; if (!ics->num_swb || !ics->swb_offset) return AVERROR_BUG; } else { ics->swb_offset = ff_swb_offset_1024[ac->oc[1].m4ac.sampling_index]; ics->num_swb = ff_aac_num_swb_1024[ac->oc[1].m4ac.sampling_index]; + ics->tns_max_bands = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index]; } - ics->tns_max_bands = ff_tns_max_bands_1024[ac->oc[1].m4ac.sampling_index]; if (aot != AOT_ER_AAC_ELD) { ics->predictor_present = get_bits1(gb); ics->predictor_reset_group = 0; @@ -1404,12 +1426,12 @@ static int decode_pulses(Pulse *pulse, GetBitContext *gb, return -1; pulse->pos[0] = swb_offset[pulse_swb]; pulse->pos[0] += get_bits(gb, 5); - if (pulse->pos[0] > 1023) + if (pulse->pos[0] >= swb_offset[num_swb]) return -1; pulse->amp[0] = get_bits(gb, 4); for (i = 1; i < pulse->num_pulse; i++) { pulse->pos[i] = get_bits(gb, 5) + pulse->pos[i - 1]; - if (pulse->pos[i] > 1023) + if (pulse->pos[i] >= swb_offset[num_swb]) return -1; pulse->amp[i] = get_bits(gb, 4); } @@ -2509,14 +2531,20 @@ static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce) float *in = sce->coeffs; float *out = sce->ret; float *saved = sce->saved; - const float *lwindow_prev = ics->use_kb_window[1] ? ff_aac_kbd_long_512 : ff_sine_512; float *buf = ac->buf_mdct; // imdct ac->mdct.imdct_half(&ac->mdct_ld, buf, in); // window overlapping - ac->fdsp.vector_fmul_window(out, saved, buf, lwindow_prev, 256); + if (ics->use_kb_window[1]) { + // AAC LD uses a low overlap sine window instead of a KBD window + memcpy(out, saved, 192 * sizeof(float)); + ac->fdsp.vector_fmul_window(out + 192, saved + 192, buf, ff_sine_128, 64); + memcpy( out + 320, buf + 64, 192 * sizeof(float)); + } else { + ac->fdsp.vector_fmul_window(out, saved, buf, ff_sine_512, 256); + } // buffer update memcpy(saved, buf + 256, 256 * sizeof(float)); @@ -2603,7 +2631,7 @@ static void apply_dependent_coupling(AACContext *ac, const float gain = cce->coup.gain[index][idx]; for (group = 0; group < ics->group_len[g]; group++) { for (k = offsets[i]; k < offsets[i + 1]; k++) { - // XXX dsputil-ize + // FIXME: SIMDify dest[group * 128 + k] += gain * src[group * 128 + k]; } } @@ -2844,6 +2872,7 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data, spectral_to_sample(ac); ac->frame->nb_samples = samples; + ac->frame->sample_rate = avctx->sample_rate; *got_frame_ptr = 1; skip_bits_long(gb, get_bits_left(gb)); @@ -2978,22 +3007,6 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0; samples <<= multiplier; - /* for dual-mono audio (SCE + SCE) */ - is_dmono = ac->dmono_mode && sce_count == 2 && - ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT); - - if (samples) - ac->frame->nb_samples = samples; - else - av_frame_unref(ac->frame); - *got_frame_ptr = !!samples; - - if (is_dmono) { - if (ac->dmono_mode == 1) - ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0]; - else if (ac->dmono_mode == 2) - ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1]; - } if (ac->oc[1].status && audio_found) { avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier; @@ -3007,6 +3020,25 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if (side && side_size>=4) AV_WL32(side, 2*AV_RL32(side)); } + + *got_frame_ptr = !!samples; + if (samples) { + ac->frame->nb_samples = samples; + ac->frame->sample_rate = avctx->sample_rate; + } else + av_frame_unref(ac->frame); + *got_frame_ptr = !!samples; + + /* for dual-mono audio (SCE + SCE) */ + is_dmono = ac->dmono_mode && sce_count == 2 && + ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT); + if (is_dmono) { + if (ac->dmono_mode == 1) + ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0]; + else if (ac->dmono_mode == 2) + ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1]; + } + return 0; fail: pop_output_configuration(ac); |