X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Faacdec.c;h=ef5daed5cae92e002ef1a5900d066cfa802a9ab1;hb=a72cad0a6c05aa74940101e937cb3dc602d7d67b;hp=d26cce994ca04f23d0ac7fbe42f8ca15974f0e5f;hpb=767848d7619ce43e00d1a13607a5cf2aa61d2d6e;p=ffmpeg diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index d26cce994ca..ef5daed5cae 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -186,7 +186,7 @@ static av_cold int che_configure(AACContext *ac, if (che_pos[type][id]) { if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) return AVERROR(ENOMEM); - ff_aac_sbr_ctx_init(&ac->che[type][id]->sbr); + ff_aac_sbr_ctx_init(ac, &ac->che[type][id]->sbr); if (type != TYPE_CCE) { ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret; if (type == TYPE_CPE || @@ -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; @@ -546,6 +562,7 @@ static void reset_predictor_group(PredictorState *ps, int group_num) static av_cold int aac_decode_init(AVCodecContext *avctx) { AACContext *ac = avctx->priv_data; + float output_scale_factor; ac->avctx = avctx; ac->m4ac.sample_rate = avctx->sample_rate; @@ -555,9 +572,40 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) 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; + ac->m4ac.sbr = -1; + ac->m4ac.ps = -1; + + 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) { + int ret = set_default_channel_config(avctx, new_che_pos, ac->m4ac.chan_config); + if (!ret) + output_configure(ac, ac->che_pos, new_che_pos, ac->m4ac.chan_config, OC_GLOBAL_HDR); + else if (avctx->error_recognition >= FF_ER_EXPLODE) + return AVERROR_INVALIDDATA; + } } - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + if (avctx->request_sample_fmt == AV_SAMPLE_FMT_FLT) { + avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + output_scale_factor = 1.0 / 32768.0; + } else { + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + output_scale_factor = 1.0; + } AAC_INIT_VLC_STATIC( 0, 304); AAC_INIT_VLC_STATIC( 1, 270); @@ -585,9 +633,9 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) ff_aac_scalefactor_code, sizeof(ff_aac_scalefactor_code[0]), sizeof(ff_aac_scalefactor_code[0]), 352); - ff_mdct_init(&ac->mdct, 11, 1, 1.0/1024.0); - ff_mdct_init(&ac->mdct_small, 8, 1, 1.0/128.0); - ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0); + ff_mdct_init(&ac->mdct, 11, 1, output_scale_factor/1024.0); + ff_mdct_init(&ac->mdct_small, 8, 1, output_scale_factor/128.0); + ff_mdct_init(&ac->mdct_ltp, 11, 0, -2.0/output_scale_factor); // window initialization ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024); ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128); @@ -813,7 +861,7 @@ static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb, else offset[1] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60; clipped_offset = av_clip(offset[1], -100, 155); - if (offset[2] != clipped_offset) { + if (offset[1] != clipped_offset) { av_log_ask_for_sample(ac->avctx, "Noise gain clipped " "(%d -> %d).\nIf you heard an audible " "artifact, there may be a bug in the decoder. ", @@ -1746,12 +1794,10 @@ static void windowing_and_mdct_ltp(AACContext *ac, float *out, } else { memset(in, 0, 448 * sizeof(float)); ac->dsp.vector_fmul(in + 448, in + 448, swindow_prev, 128); - memcpy(in + 576, in + 576, 448 * sizeof(float)); } if (ics->window_sequence[0] != LONG_START_SEQUENCE) { ac->dsp.vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024); } else { - memcpy(in + 1024, in + 1024, 448 * sizeof(float)); ac->dsp.vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128); memset(in + 1024 + 576, 0, 448 * sizeof(float)); } @@ -1820,9 +1866,9 @@ static void update_ltp(AACContext *ac, SingleChannelElement *sce) saved_ltp[i + 512] = ac->buf_mdct[1023 - i] * lwindow[511 - i]; } - memcpy(sce->ltp_state, &sce->ltp_state[1024], 1024 * sizeof(int16_t)); - ac->fmt_conv.float_to_int16(&(sce->ltp_state[1024]), sce->ret, 1024); - ac->fmt_conv.float_to_int16(&(sce->ltp_state[2048]), saved_ltp, 1024); + memcpy(sce->ltp_state, sce->ltp_state+1024, 1024 * sizeof(*sce->ltp_state)); + memcpy(sce->ltp_state+1024, sce->ret, 1024 * sizeof(*sce->ltp_state)); + memcpy(sce->ltp_state+2048, saved_ltp, 1024 * sizeof(*sce->ltp_state)); } /** @@ -2040,15 +2086,16 @@ 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) { ac->m4ac.sbr = -1; ac->m4ac.ps = -1; + ac->m4ac.sample_rate = hdr_info.sample_rate; + ac->m4ac.sampling_index = hdr_info.sampling_index; + ac->m4ac.object_type = hdr_info.object_type; } - ac->m4ac.sample_rate = hdr_info.sample_rate; - ac->m4ac.sampling_index = hdr_info.sampling_index; - ac->m4ac.object_type = hdr_info.object_type; if (!ac->avctx->sample_rate) ac->avctx->sample_rate = hdr_info.sample_rate; if (hdr_info.num_aac_frames == 1) { @@ -2069,7 +2116,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, ChannelElement *che = NULL, *che_prev = NULL; enum RawDataBlockType elem_type, elem_type_prev = TYPE_END; int err, elem_id, data_size_tmp; - int samples = 0, multiplier; + int samples = 0, multiplier, audio_found = 0; if (show_bits(gb, 12) == 0xfff) { if (parse_adts_frame_header(ac, gb) < 0) { @@ -2100,10 +2147,12 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, case TYPE_SCE: err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; break; case TYPE_CPE: err = decode_cpe(ac, gb, che); + audio_found = 1; break; case TYPE_CCE: @@ -2112,6 +2161,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, case TYPE_LFE: err = decode_ics(ac, &che->ch[0], gb, 0, 0); + audio_found = 1; break; case TYPE_DSE: @@ -2169,7 +2219,8 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, avctx->frame_size = samples; } - data_size_tmp = samples * avctx->channels * sizeof(int16_t); + data_size_tmp = samples * avctx->channels * + av_get_bytes_per_sample(avctx->sample_fmt); if (*data_size < data_size_tmp) { av_log(avctx, AV_LOG_ERROR, "Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n", @@ -2178,10 +2229,16 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, } *data_size = data_size_tmp; - if (samples) - ac->fmt_conv.float_to_int16_interleave(data, (const float **)ac->output_data, samples, avctx->channels); + if (samples) { + if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) + ac->fmt_conv.float_interleave(data, (const float **)ac->output_data, + samples, avctx->channels); + else + ac->fmt_conv.float_to_int16_interleave(data, (const float **)ac->output_data, + samples, avctx->channels); + } - if (ac->output_configured) + if (ac->output_configured && audio_found) ac->output_configured = OC_LOCKED; return 0; @@ -2450,6 +2507,7 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size, *out_size = 0; return avpkt->size; } else { + aac_decode_close(avctx); if ((err = aac_decode_init(avctx)) < 0) return err; latmctx->initialized = 1; @@ -2487,18 +2545,18 @@ av_cold static int latm_decode_init(AVCodecContext *avctx) AVCodec ff_aac_decoder = { - "aac", - AVMEDIA_TYPE_AUDIO, - CODEC_ID_AAC, - sizeof(AACContext), - aac_decode_init, - NULL, - aac_decode_close, - aac_decode_frame, + .name = "aac", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_AAC, + .priv_data_size = sizeof(AACContext), + .init = aac_decode_init, + .close = aac_decode_close, + .decode = aac_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("Advanced Audio Coding"), .sample_fmts = (const enum AVSampleFormat[]) { - AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .capabilities = CODEC_CAP_CHANNEL_CONF, .channel_layouts = aac_channel_layout, }; @@ -2517,7 +2575,8 @@ AVCodec ff_aac_latm_decoder = { .decode = latm_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Codec LATM syntax)"), .sample_fmts = (const enum AVSampleFormat[]) { - AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE + AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, + .capabilities = CODEC_CAP_CHANNEL_CONF, .channel_layouts = aac_channel_layout, };