1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * AAC decoder wrapper 3cabdff1aSopenharmony_ci * Copyright (c) 2012 Martin Storsjo 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 8cabdff1aSopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 9cabdff1aSopenharmony_ci * copyright notice and this permission notice appear in all copies. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12cabdff1aSopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13cabdff1aSopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14cabdff1aSopenharmony_ci * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15cabdff1aSopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16cabdff1aSopenharmony_ci * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17cabdff1aSopenharmony_ci * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18cabdff1aSopenharmony_ci */ 19cabdff1aSopenharmony_ci 20cabdff1aSopenharmony_ci#include <fdk-aac/aacdecoder_lib.h> 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 23cabdff1aSopenharmony_ci#include "libavutil/common.h" 24cabdff1aSopenharmony_ci#include "libavutil/opt.h" 25cabdff1aSopenharmony_ci#include "avcodec.h" 26cabdff1aSopenharmony_ci#include "codec_internal.h" 27cabdff1aSopenharmony_ci#include "internal.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#ifdef AACDECODER_LIB_VL0 30cabdff1aSopenharmony_ci#define FDKDEC_VER_AT_LEAST(vl0, vl1) \ 31cabdff1aSopenharmony_ci ((AACDECODER_LIB_VL0 > vl0) || \ 32cabdff1aSopenharmony_ci (AACDECODER_LIB_VL0 == vl0 && AACDECODER_LIB_VL1 >= vl1)) 33cabdff1aSopenharmony_ci#else 34cabdff1aSopenharmony_ci#define FDKDEC_VER_AT_LEAST(vl0, vl1) 0 35cabdff1aSopenharmony_ci#endif 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_ci#if !FDKDEC_VER_AT_LEAST(2, 5) // < 2.5.10 38cabdff1aSopenharmony_ci#define AAC_PCM_MAX_OUTPUT_CHANNELS AAC_PCM_OUTPUT_CHANNELS 39cabdff1aSopenharmony_ci#endif 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_cienum ConcealMethod { 42cabdff1aSopenharmony_ci CONCEAL_METHOD_SPECTRAL_MUTING = 0, 43cabdff1aSopenharmony_ci CONCEAL_METHOD_NOISE_SUBSTITUTION = 1, 44cabdff1aSopenharmony_ci CONCEAL_METHOD_ENERGY_INTERPOLATION = 2, 45cabdff1aSopenharmony_ci CONCEAL_METHOD_NB, 46cabdff1aSopenharmony_ci}; 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_citypedef struct FDKAACDecContext { 49cabdff1aSopenharmony_ci const AVClass *class; 50cabdff1aSopenharmony_ci HANDLE_AACDECODER handle; 51cabdff1aSopenharmony_ci uint8_t *decoder_buffer; 52cabdff1aSopenharmony_ci int decoder_buffer_size; 53cabdff1aSopenharmony_ci uint8_t *anc_buffer; 54cabdff1aSopenharmony_ci int conceal_method; 55cabdff1aSopenharmony_ci int drc_level; 56cabdff1aSopenharmony_ci int drc_boost; 57cabdff1aSopenharmony_ci int drc_heavy; 58cabdff1aSopenharmony_ci int drc_effect; 59cabdff1aSopenharmony_ci int drc_cut; 60cabdff1aSopenharmony_ci int album_mode; 61cabdff1aSopenharmony_ci int level_limit; 62cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 63cabdff1aSopenharmony_ci int output_delay_set; 64cabdff1aSopenharmony_ci int flush_samples; 65cabdff1aSopenharmony_ci int delay_samples; 66cabdff1aSopenharmony_ci#endif 67cabdff1aSopenharmony_ci AVChannelLayout downmix_layout; 68cabdff1aSopenharmony_ci} FDKAACDecContext; 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_ci#define DMX_ANC_BUFFSIZE 128 72cabdff1aSopenharmony_ci#define DECODER_MAX_CHANNELS 8 73cabdff1aSopenharmony_ci#define DECODER_BUFFSIZE 2048 * sizeof(INT_PCM) 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(FDKAACDecContext, x) 76cabdff1aSopenharmony_ci#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM 77cabdff1aSopenharmony_cistatic const AVOption fdk_aac_dec_options[] = { 78cabdff1aSopenharmony_ci { "conceal", "Error concealment method", OFFSET(conceal_method), AV_OPT_TYPE_INT, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, CONCEAL_METHOD_SPECTRAL_MUTING, CONCEAL_METHOD_NB - 1, AD, "conceal" }, 79cabdff1aSopenharmony_ci { "spectral", "Spectral muting", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING }, INT_MIN, INT_MAX, AD, "conceal" }, 80cabdff1aSopenharmony_ci { "noise", "Noise Substitution", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, INT_MIN, INT_MAX, AD, "conceal" }, 81cabdff1aSopenharmony_ci { "energy", "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" }, 82cabdff1aSopenharmony_ci { "drc_boost", "Dynamic Range Control: boost, where [0] is none and [127] is max boost", 83cabdff1aSopenharmony_ci OFFSET(drc_boost), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL }, 84cabdff1aSopenharmony_ci { "drc_cut", "Dynamic Range Control: attenuation factor, where [0] is none and [127] is max compression", 85cabdff1aSopenharmony_ci OFFSET(drc_cut), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL }, 86cabdff1aSopenharmony_ci { "drc_level", "Dynamic Range Control: reference level, quantized to 0.25dB steps where [0] is 0dB and [127] is -31.75dB, -1 for auto, and -2 for disabled", 87cabdff1aSopenharmony_ci OFFSET(drc_level), AV_OPT_TYPE_INT, { .i64 = -1}, -2, 127, AD, NULL }, 88cabdff1aSopenharmony_ci { "drc_heavy", "Dynamic Range Control: heavy compression, where [1] is on (RF mode) and [0] is off", 89cabdff1aSopenharmony_ci OFFSET(drc_heavy), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, AD, NULL }, 90cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 91cabdff1aSopenharmony_ci { "level_limit", "Signal level limiting", 92cabdff1aSopenharmony_ci OFFSET(level_limit), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, AD }, 93cabdff1aSopenharmony_ci#endif 94cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(3, 0) // 3.0.0 95cabdff1aSopenharmony_ci { "drc_effect","Dynamic Range Control: effect type, where e.g. [0] is none and [6] is general", 96cabdff1aSopenharmony_ci OFFSET(drc_effect), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 8, AD, NULL }, 97cabdff1aSopenharmony_ci#endif 98cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(3, 1) // 3.1.0 99cabdff1aSopenharmony_ci { "album_mode","Dynamic Range Control: album mode, where [0] is off and [1] is on", 100cabdff1aSopenharmony_ci OFFSET(album_mode), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, AD, NULL }, 101cabdff1aSopenharmony_ci#endif 102cabdff1aSopenharmony_ci { "downmix", "Request a specific channel layout from the decoder", OFFSET(downmix_layout), AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, .flags = AD }, 103cabdff1aSopenharmony_ci { NULL } 104cabdff1aSopenharmony_ci}; 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_cistatic const AVClass fdk_aac_dec_class = { 107cabdff1aSopenharmony_ci .class_name = "libfdk-aac decoder", 108cabdff1aSopenharmony_ci .item_name = av_default_item_name, 109cabdff1aSopenharmony_ci .option = fdk_aac_dec_options, 110cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 111cabdff1aSopenharmony_ci}; 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_cistatic int get_stream_info(AVCodecContext *avctx) 114cabdff1aSopenharmony_ci{ 115cabdff1aSopenharmony_ci FDKAACDecContext *s = avctx->priv_data; 116cabdff1aSopenharmony_ci CStreamInfo *info = aacDecoder_GetStreamInfo(s->handle); 117cabdff1aSopenharmony_ci int channel_counts[0x24] = { 0 }; 118cabdff1aSopenharmony_ci int i, ch_error = 0; 119cabdff1aSopenharmony_ci uint64_t ch_layout = 0; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci if (!info) { 122cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n"); 123cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 124cabdff1aSopenharmony_ci } 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_ci if (info->sampleRate <= 0) { 127cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n"); 128cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 129cabdff1aSopenharmony_ci } 130cabdff1aSopenharmony_ci avctx->sample_rate = info->sampleRate; 131cabdff1aSopenharmony_ci avctx->frame_size = info->frameSize; 132cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 133cabdff1aSopenharmony_ci if (!s->output_delay_set && info->outputDelay) { 134cabdff1aSopenharmony_ci // Set this only once. 135cabdff1aSopenharmony_ci s->flush_samples = info->outputDelay; 136cabdff1aSopenharmony_ci s->delay_samples = info->outputDelay; 137cabdff1aSopenharmony_ci s->output_delay_set = 1; 138cabdff1aSopenharmony_ci } 139cabdff1aSopenharmony_ci#endif 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci for (i = 0; i < info->numChannels; i++) { 142cabdff1aSopenharmony_ci AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i]; 143cabdff1aSopenharmony_ci if (ctype <= ACT_NONE || ctype >= FF_ARRAY_ELEMS(channel_counts)) { 144cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "unknown channel type\n"); 145cabdff1aSopenharmony_ci break; 146cabdff1aSopenharmony_ci } 147cabdff1aSopenharmony_ci channel_counts[ctype]++; 148cabdff1aSopenharmony_ci } 149cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_DEBUG, 150cabdff1aSopenharmony_ci "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n", 151cabdff1aSopenharmony_ci info->numChannels, 152cabdff1aSopenharmony_ci channel_counts[ACT_FRONT], channel_counts[ACT_SIDE], 153cabdff1aSopenharmony_ci channel_counts[ACT_BACK], channel_counts[ACT_LFE], 154cabdff1aSopenharmony_ci channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] + 155cabdff1aSopenharmony_ci channel_counts[ACT_BACK_TOP] + channel_counts[ACT_TOP]); 156cabdff1aSopenharmony_ci 157cabdff1aSopenharmony_ci switch (channel_counts[ACT_FRONT]) { 158cabdff1aSopenharmony_ci case 4: 159cabdff1aSopenharmony_ci ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER | 160cabdff1aSopenharmony_ci AV_CH_FRONT_RIGHT_OF_CENTER; 161cabdff1aSopenharmony_ci break; 162cabdff1aSopenharmony_ci case 3: 163cabdff1aSopenharmony_ci ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER; 164cabdff1aSopenharmony_ci break; 165cabdff1aSopenharmony_ci case 2: 166cabdff1aSopenharmony_ci ch_layout |= AV_CH_LAYOUT_STEREO; 167cabdff1aSopenharmony_ci break; 168cabdff1aSopenharmony_ci case 1: 169cabdff1aSopenharmony_ci ch_layout |= AV_CH_FRONT_CENTER; 170cabdff1aSopenharmony_ci break; 171cabdff1aSopenharmony_ci default: 172cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, 173cabdff1aSopenharmony_ci "unsupported number of front channels: %d\n", 174cabdff1aSopenharmony_ci channel_counts[ACT_FRONT]); 175cabdff1aSopenharmony_ci ch_error = 1; 176cabdff1aSopenharmony_ci break; 177cabdff1aSopenharmony_ci } 178cabdff1aSopenharmony_ci if (channel_counts[ACT_SIDE] > 0) { 179cabdff1aSopenharmony_ci if (channel_counts[ACT_SIDE] == 2) { 180cabdff1aSopenharmony_ci ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT; 181cabdff1aSopenharmony_ci } else { 182cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, 183cabdff1aSopenharmony_ci "unsupported number of side channels: %d\n", 184cabdff1aSopenharmony_ci channel_counts[ACT_SIDE]); 185cabdff1aSopenharmony_ci ch_error = 1; 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci } 188cabdff1aSopenharmony_ci if (channel_counts[ACT_BACK] > 0) { 189cabdff1aSopenharmony_ci switch (channel_counts[ACT_BACK]) { 190cabdff1aSopenharmony_ci case 3: 191cabdff1aSopenharmony_ci ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER; 192cabdff1aSopenharmony_ci break; 193cabdff1aSopenharmony_ci case 2: 194cabdff1aSopenharmony_ci ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT; 195cabdff1aSopenharmony_ci break; 196cabdff1aSopenharmony_ci case 1: 197cabdff1aSopenharmony_ci ch_layout |= AV_CH_BACK_CENTER; 198cabdff1aSopenharmony_ci break; 199cabdff1aSopenharmony_ci default: 200cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, 201cabdff1aSopenharmony_ci "unsupported number of back channels: %d\n", 202cabdff1aSopenharmony_ci channel_counts[ACT_BACK]); 203cabdff1aSopenharmony_ci ch_error = 1; 204cabdff1aSopenharmony_ci break; 205cabdff1aSopenharmony_ci } 206cabdff1aSopenharmony_ci } 207cabdff1aSopenharmony_ci if (channel_counts[ACT_LFE] > 0) { 208cabdff1aSopenharmony_ci if (channel_counts[ACT_LFE] == 1) { 209cabdff1aSopenharmony_ci ch_layout |= AV_CH_LOW_FREQUENCY; 210cabdff1aSopenharmony_ci } else { 211cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, 212cabdff1aSopenharmony_ci "unsupported number of LFE channels: %d\n", 213cabdff1aSopenharmony_ci channel_counts[ACT_LFE]); 214cabdff1aSopenharmony_ci ch_error = 1; 215cabdff1aSopenharmony_ci } 216cabdff1aSopenharmony_ci } 217cabdff1aSopenharmony_ci 218cabdff1aSopenharmony_ci av_channel_layout_uninit(&avctx->ch_layout); 219cabdff1aSopenharmony_ci av_channel_layout_from_mask(&avctx->ch_layout, ch_layout); 220cabdff1aSopenharmony_ci if (!ch_error && avctx->ch_layout.nb_channels != info->numChannels) { 221cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n"); 222cabdff1aSopenharmony_ci ch_error = 1; 223cabdff1aSopenharmony_ci } 224cabdff1aSopenharmony_ci if (ch_error) 225cabdff1aSopenharmony_ci avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; 226cabdff1aSopenharmony_ci 227cabdff1aSopenharmony_ci return 0; 228cabdff1aSopenharmony_ci} 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_cistatic av_cold int fdk_aac_decode_close(AVCodecContext *avctx) 231cabdff1aSopenharmony_ci{ 232cabdff1aSopenharmony_ci FDKAACDecContext *s = avctx->priv_data; 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci if (s->handle) 235cabdff1aSopenharmony_ci aacDecoder_Close(s->handle); 236cabdff1aSopenharmony_ci av_freep(&s->decoder_buffer); 237cabdff1aSopenharmony_ci av_freep(&s->anc_buffer); 238cabdff1aSopenharmony_ci 239cabdff1aSopenharmony_ci return 0; 240cabdff1aSopenharmony_ci} 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_cistatic av_cold int fdk_aac_decode_init(AVCodecContext *avctx) 243cabdff1aSopenharmony_ci{ 244cabdff1aSopenharmony_ci FDKAACDecContext *s = avctx->priv_data; 245cabdff1aSopenharmony_ci AAC_DECODER_ERROR err; 246cabdff1aSopenharmony_ci 247cabdff1aSopenharmony_ci s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1); 248cabdff1aSopenharmony_ci if (!s->handle) { 249cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n"); 250cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 251cabdff1aSopenharmony_ci } 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_ci if (avctx->extradata_size) { 254cabdff1aSopenharmony_ci if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata, 255cabdff1aSopenharmony_ci &avctx->extradata_size)) != AAC_DEC_OK) { 256cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n"); 257cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 258cabdff1aSopenharmony_ci } 259cabdff1aSopenharmony_ci } 260cabdff1aSopenharmony_ci 261cabdff1aSopenharmony_ci if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD, 262cabdff1aSopenharmony_ci s->conceal_method)) != AAC_DEC_OK) { 263cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n"); 264cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 265cabdff1aSopenharmony_ci } 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_ci#if FF_API_OLD_CHANNEL_LAYOUT 268cabdff1aSopenharmony_ciFF_DISABLE_DEPRECATION_WARNINGS 269cabdff1aSopenharmony_ci if (avctx->request_channel_layout) { 270cabdff1aSopenharmony_ci av_channel_layout_uninit(&s->downmix_layout); 271cabdff1aSopenharmony_ci av_channel_layout_from_mask(&s->downmix_layout, avctx->request_channel_layout); 272cabdff1aSopenharmony_ci } 273cabdff1aSopenharmony_ciFF_ENABLE_DEPRECATION_WARNINGS 274cabdff1aSopenharmony_ci#endif 275cabdff1aSopenharmony_ci if (s->downmix_layout.nb_channels > 0 && 276cabdff1aSopenharmony_ci s->downmix_layout.order != AV_CHANNEL_ORDER_NATIVE) { 277cabdff1aSopenharmony_ci int downmix_channels = -1; 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci switch (s->downmix_layout.u.mask) { 280cabdff1aSopenharmony_ci case AV_CH_LAYOUT_STEREO: 281cabdff1aSopenharmony_ci case AV_CH_LAYOUT_STEREO_DOWNMIX: 282cabdff1aSopenharmony_ci downmix_channels = 2; 283cabdff1aSopenharmony_ci break; 284cabdff1aSopenharmony_ci case AV_CH_LAYOUT_MONO: 285cabdff1aSopenharmony_ci downmix_channels = 1; 286cabdff1aSopenharmony_ci break; 287cabdff1aSopenharmony_ci default: 288cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Invalid downmix option\n"); 289cabdff1aSopenharmony_ci break; 290cabdff1aSopenharmony_ci } 291cabdff1aSopenharmony_ci 292cabdff1aSopenharmony_ci if (downmix_channels != -1) { 293cabdff1aSopenharmony_ci if (aacDecoder_SetParam(s->handle, AAC_PCM_MAX_OUTPUT_CHANNELS, 294cabdff1aSopenharmony_ci downmix_channels) != AAC_DEC_OK) { 295cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "Unable to set output channels in the decoder\n"); 296cabdff1aSopenharmony_ci } else { 297cabdff1aSopenharmony_ci s->anc_buffer = av_malloc(DMX_ANC_BUFFSIZE); 298cabdff1aSopenharmony_ci if (!s->anc_buffer) { 299cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to allocate ancillary buffer for the decoder\n"); 300cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 301cabdff1aSopenharmony_ci } 302cabdff1aSopenharmony_ci if (aacDecoder_AncDataInit(s->handle, s->anc_buffer, DMX_ANC_BUFFSIZE)) { 303cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to register downmix ancillary buffer in the decoder\n"); 304cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 305cabdff1aSopenharmony_ci } 306cabdff1aSopenharmony_ci } 307cabdff1aSopenharmony_ci } 308cabdff1aSopenharmony_ci } 309cabdff1aSopenharmony_ci 310cabdff1aSopenharmony_ci if (s->drc_boost != -1) { 311cabdff1aSopenharmony_ci if (aacDecoder_SetParam(s->handle, AAC_DRC_BOOST_FACTOR, s->drc_boost) != AAC_DEC_OK) { 312cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set DRC boost factor in the decoder\n"); 313cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 314cabdff1aSopenharmony_ci } 315cabdff1aSopenharmony_ci } 316cabdff1aSopenharmony_ci 317cabdff1aSopenharmony_ci if (s->drc_cut != -1) { 318cabdff1aSopenharmony_ci if (aacDecoder_SetParam(s->handle, AAC_DRC_ATTENUATION_FACTOR, s->drc_cut) != AAC_DEC_OK) { 319cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set DRC attenuation factor in the decoder\n"); 320cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 321cabdff1aSopenharmony_ci } 322cabdff1aSopenharmony_ci } 323cabdff1aSopenharmony_ci 324cabdff1aSopenharmony_ci if (s->drc_level != -1) { 325cabdff1aSopenharmony_ci // This option defaults to -1, i.e. not calling 326cabdff1aSopenharmony_ci // aacDecoder_SetParam(AAC_DRC_REFERENCE_LEVEL) at all, which defaults 327cabdff1aSopenharmony_ci // to the level from DRC metadata, if available. The user can set 328cabdff1aSopenharmony_ci // -drc_level -2, which calls aacDecoder_SetParam( 329cabdff1aSopenharmony_ci // AAC_DRC_REFERENCE_LEVEL) with a negative value, which then 330cabdff1aSopenharmony_ci // explicitly disables the feature. 331cabdff1aSopenharmony_ci if (aacDecoder_SetParam(s->handle, AAC_DRC_REFERENCE_LEVEL, s->drc_level) != AAC_DEC_OK) { 332cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set DRC reference level in the decoder\n"); 333cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 334cabdff1aSopenharmony_ci } 335cabdff1aSopenharmony_ci } 336cabdff1aSopenharmony_ci 337cabdff1aSopenharmony_ci if (s->drc_heavy != -1) { 338cabdff1aSopenharmony_ci if (aacDecoder_SetParam(s->handle, AAC_DRC_HEAVY_COMPRESSION, s->drc_heavy) != AAC_DEC_OK) { 339cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set DRC heavy compression in the decoder\n"); 340cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 341cabdff1aSopenharmony_ci } 342cabdff1aSopenharmony_ci } 343cabdff1aSopenharmony_ci 344cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 345cabdff1aSopenharmony_ci // Setting this parameter to -1 enables the auto behaviour in the library. 346cabdff1aSopenharmony_ci if (aacDecoder_SetParam(s->handle, AAC_PCM_LIMITER_ENABLE, s->level_limit) != AAC_DEC_OK) { 347cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set in signal level limiting in the decoder\n"); 348cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 349cabdff1aSopenharmony_ci } 350cabdff1aSopenharmony_ci#endif 351cabdff1aSopenharmony_ci 352cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(3, 0) // 3.0.0 353cabdff1aSopenharmony_ci if (s->drc_effect != -1) { 354cabdff1aSopenharmony_ci if (aacDecoder_SetParam(s->handle, AAC_UNIDRC_SET_EFFECT, s->drc_effect) != AAC_DEC_OK) { 355cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set DRC effect type in the decoder\n"); 356cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 357cabdff1aSopenharmony_ci } 358cabdff1aSopenharmony_ci } 359cabdff1aSopenharmony_ci#endif 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(3, 1) // 3.1.0 362cabdff1aSopenharmony_ci if (s->album_mode != -1) { 363cabdff1aSopenharmony_ci if (aacDecoder_SetParam(s->handle, AAC_UNIDRC_ALBUM_MODE, s->album_mode) != AAC_DEC_OK) { 364cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Unable to set album mode in the decoder\n"); 365cabdff1aSopenharmony_ci return AVERROR_UNKNOWN; 366cabdff1aSopenharmony_ci } 367cabdff1aSopenharmony_ci } 368cabdff1aSopenharmony_ci#endif 369cabdff1aSopenharmony_ci 370cabdff1aSopenharmony_ci avctx->sample_fmt = AV_SAMPLE_FMT_S16; 371cabdff1aSopenharmony_ci 372cabdff1aSopenharmony_ci s->decoder_buffer_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS; 373cabdff1aSopenharmony_ci s->decoder_buffer = av_malloc(s->decoder_buffer_size); 374cabdff1aSopenharmony_ci if (!s->decoder_buffer) 375cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 376cabdff1aSopenharmony_ci 377cabdff1aSopenharmony_ci return 0; 378cabdff1aSopenharmony_ci} 379cabdff1aSopenharmony_ci 380cabdff1aSopenharmony_cistatic int fdk_aac_decode_frame(AVCodecContext *avctx, AVFrame *frame, 381cabdff1aSopenharmony_ci int *got_frame_ptr, AVPacket *avpkt) 382cabdff1aSopenharmony_ci{ 383cabdff1aSopenharmony_ci FDKAACDecContext *s = avctx->priv_data; 384cabdff1aSopenharmony_ci int ret; 385cabdff1aSopenharmony_ci AAC_DECODER_ERROR err; 386cabdff1aSopenharmony_ci UINT valid = avpkt->size; 387cabdff1aSopenharmony_ci UINT flags = 0; 388cabdff1aSopenharmony_ci int input_offset = 0; 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_ci if (avpkt->size) { 391cabdff1aSopenharmony_ci err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid); 392cabdff1aSopenharmony_ci if (err != AAC_DEC_OK) { 393cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err); 394cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 395cabdff1aSopenharmony_ci } 396cabdff1aSopenharmony_ci } else { 397cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 398cabdff1aSopenharmony_ci /* Handle decoder draining */ 399cabdff1aSopenharmony_ci if (s->flush_samples > 0) { 400cabdff1aSopenharmony_ci flags |= AACDEC_FLUSH; 401cabdff1aSopenharmony_ci } else { 402cabdff1aSopenharmony_ci return AVERROR_EOF; 403cabdff1aSopenharmony_ci } 404cabdff1aSopenharmony_ci#else 405cabdff1aSopenharmony_ci return AVERROR_EOF; 406cabdff1aSopenharmony_ci#endif 407cabdff1aSopenharmony_ci } 408cabdff1aSopenharmony_ci 409cabdff1aSopenharmony_ci err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, 410cabdff1aSopenharmony_ci s->decoder_buffer_size / sizeof(INT_PCM), 411cabdff1aSopenharmony_ci flags); 412cabdff1aSopenharmony_ci if (err == AAC_DEC_NOT_ENOUGH_BITS) { 413cabdff1aSopenharmony_ci ret = avpkt->size - valid; 414cabdff1aSopenharmony_ci goto end; 415cabdff1aSopenharmony_ci } 416cabdff1aSopenharmony_ci if (err != AAC_DEC_OK) { 417cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 418cabdff1aSopenharmony_ci "aacDecoder_DecodeFrame() failed: %x\n", err); 419cabdff1aSopenharmony_ci ret = AVERROR_UNKNOWN; 420cabdff1aSopenharmony_ci goto end; 421cabdff1aSopenharmony_ci } 422cabdff1aSopenharmony_ci 423cabdff1aSopenharmony_ci if ((ret = get_stream_info(avctx)) < 0) 424cabdff1aSopenharmony_ci goto end; 425cabdff1aSopenharmony_ci frame->nb_samples = avctx->frame_size; 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 428cabdff1aSopenharmony_ci if (flags & AACDEC_FLUSH) { 429cabdff1aSopenharmony_ci // Only return the right amount of samples at the end; if calling the 430cabdff1aSopenharmony_ci // decoder with AACDEC_FLUSH, it will keep returning frames indefinitely. 431cabdff1aSopenharmony_ci frame->nb_samples = FFMIN(s->flush_samples, frame->nb_samples); 432cabdff1aSopenharmony_ci av_log(s, AV_LOG_DEBUG, "Returning %d/%d delayed samples.\n", 433cabdff1aSopenharmony_ci frame->nb_samples, s->flush_samples); 434cabdff1aSopenharmony_ci s->flush_samples -= frame->nb_samples; 435cabdff1aSopenharmony_ci } else { 436cabdff1aSopenharmony_ci // Trim off samples from the start to compensate for extra decoder 437cabdff1aSopenharmony_ci // delay. We could also just adjust the pts, but this avoids 438cabdff1aSopenharmony_ci // including the extra samples in the output altogether. 439cabdff1aSopenharmony_ci if (s->delay_samples) { 440cabdff1aSopenharmony_ci int drop_samples = FFMIN(s->delay_samples, frame->nb_samples); 441cabdff1aSopenharmony_ci av_log(s, AV_LOG_DEBUG, "Dropping %d/%d delayed samples.\n", 442cabdff1aSopenharmony_ci drop_samples, s->delay_samples); 443cabdff1aSopenharmony_ci s->delay_samples -= drop_samples; 444cabdff1aSopenharmony_ci frame->nb_samples -= drop_samples; 445cabdff1aSopenharmony_ci input_offset = drop_samples * avctx->ch_layout.nb_channels; 446cabdff1aSopenharmony_ci if (frame->nb_samples <= 0) 447cabdff1aSopenharmony_ci return 0; 448cabdff1aSopenharmony_ci } 449cabdff1aSopenharmony_ci } 450cabdff1aSopenharmony_ci#endif 451cabdff1aSopenharmony_ci 452cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) 453cabdff1aSopenharmony_ci goto end; 454cabdff1aSopenharmony_ci 455cabdff1aSopenharmony_ci memcpy(frame->extended_data[0], s->decoder_buffer + input_offset, 456cabdff1aSopenharmony_ci avctx->ch_layout.nb_channels * frame->nb_samples * 457cabdff1aSopenharmony_ci av_get_bytes_per_sample(avctx->sample_fmt)); 458cabdff1aSopenharmony_ci 459cabdff1aSopenharmony_ci *got_frame_ptr = 1; 460cabdff1aSopenharmony_ci ret = avpkt->size - valid; 461cabdff1aSopenharmony_ci 462cabdff1aSopenharmony_ciend: 463cabdff1aSopenharmony_ci return ret; 464cabdff1aSopenharmony_ci} 465cabdff1aSopenharmony_ci 466cabdff1aSopenharmony_cistatic av_cold void fdk_aac_decode_flush(AVCodecContext *avctx) 467cabdff1aSopenharmony_ci{ 468cabdff1aSopenharmony_ci FDKAACDecContext *s = avctx->priv_data; 469cabdff1aSopenharmony_ci AAC_DECODER_ERROR err; 470cabdff1aSopenharmony_ci 471cabdff1aSopenharmony_ci if (!s->handle) 472cabdff1aSopenharmony_ci return; 473cabdff1aSopenharmony_ci 474cabdff1aSopenharmony_ci if ((err = aacDecoder_SetParam(s->handle, 475cabdff1aSopenharmony_ci AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK) 476cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n"); 477cabdff1aSopenharmony_ci} 478cabdff1aSopenharmony_ci 479cabdff1aSopenharmony_ciconst FFCodec ff_libfdk_aac_decoder = { 480cabdff1aSopenharmony_ci .p.name = "libfdk_aac", 481cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"), 482cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 483cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_AAC, 484cabdff1aSopenharmony_ci .priv_data_size = sizeof(FDKAACDecContext), 485cabdff1aSopenharmony_ci .init = fdk_aac_decode_init, 486cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(fdk_aac_decode_frame), 487cabdff1aSopenharmony_ci .close = fdk_aac_decode_close, 488cabdff1aSopenharmony_ci .flush = fdk_aac_decode_flush, 489cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF 490cabdff1aSopenharmony_ci#if FDKDEC_VER_AT_LEAST(2, 5) // 2.5.10 491cabdff1aSopenharmony_ci | AV_CODEC_CAP_DELAY 492cabdff1aSopenharmony_ci#endif 493cabdff1aSopenharmony_ci , 494cabdff1aSopenharmony_ci .p.priv_class = &fdk_aac_dec_class, 495cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | 496cabdff1aSopenharmony_ci FF_CODEC_CAP_INIT_CLEANUP, 497cabdff1aSopenharmony_ci .p.wrapper_name = "libfdk", 498cabdff1aSopenharmony_ci}; 499