3 * Copyright (c) 2012 Martin Storsjo
5 * This file is part of FFmpeg.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <fdk-aac/aacdecoder_lib.h>
34 #include "libavutil/channel_layout.h"
35 #include "libavutil/common.h"
36 #include "libavutil/opt.h"
41 CONCEAL_METHOD_DEFAULT = -1,
42 CONCEAL_METHOD_SPECTRAL_MUTING = 0,
43 CONCEAL_METHOD_NOISE_SUBSTITUTION = 1,
44 CONCEAL_METHOD_ENERGY_INTERPOLATION = 2,
48 typedef struct FDKAACDecContext {
50 HANDLE_AACDECODER handle;
52 enum ConcealMethod conceal_method;
55 #define OFFSET(x) offsetof(FDKAACDecContext, x)
56 #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
57 static const AVOption fdk_aac_dec_options[] = {
58 { "conceal", "Error concealment method", OFFSET(conceal_method), AV_OPT_TYPE_INT, { .i64 = CONCEAL_METHOD_DEFAULT }, CONCEAL_METHOD_DEFAULT, CONCEAL_METHOD_NB - 1, AD, "conceal" },
59 { "default", "Default", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_DEFAULT }, INT_MIN, INT_MAX, AD, "conceal" },
60 { "spectral", "Spectral muting", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING }, INT_MIN, INT_MAX, AD, "conceal" },
61 { "noise", "Noise Substitution", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, INT_MIN, INT_MAX, AD, "conceal" },
62 { "energy", "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
66 static const AVClass fdk_aac_dec_class = {
67 "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
70 static int get_stream_info(AVCodecContext *avctx)
72 FDKAACDecContext *s = avctx->priv_data;
73 CStreamInfo *info = aacDecoder_GetStreamInfo(s->handle);
74 int channel_counts[9] = { 0 };
76 uint64_t ch_layout = 0;
79 av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
80 return AVERROR_UNKNOWN;
83 if (info->sampleRate <= 0) {
84 av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
85 return AVERROR_UNKNOWN;
87 avctx->sample_rate = info->sampleRate;
88 avctx->frame_size = info->frameSize;
90 for (i = 0; i < info->numChannels; i++) {
91 AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
92 if (ctype <= ACT_NONE || ctype > ACT_TOP) {
93 av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
96 channel_counts[ctype]++;
98 av_log(avctx, AV_LOG_DEBUG,
99 "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
101 channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
102 channel_counts[ACT_BACK], channel_counts[ACT_LFE],
103 channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
104 channel_counts[ACT_BACK_TOP] + channel_counts[ACT_TOP]);
106 switch (channel_counts[ACT_FRONT]) {
108 ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |
109 AV_CH_FRONT_RIGHT_OF_CENTER;
112 ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
115 ch_layout |= AV_CH_LAYOUT_STEREO;
118 ch_layout |= AV_CH_FRONT_CENTER;
121 av_log(avctx, AV_LOG_WARNING,
122 "unsupported number of front channels: %d\n",
123 channel_counts[ACT_FRONT]);
127 if (channel_counts[ACT_SIDE] > 0) {
128 if (channel_counts[ACT_SIDE] == 2) {
129 ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
131 av_log(avctx, AV_LOG_WARNING,
132 "unsupported number of side channels: %d\n",
133 channel_counts[ACT_SIDE]);
137 if (channel_counts[ACT_BACK] > 0) {
138 switch (channel_counts[ACT_BACK]) {
140 ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
143 ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
146 ch_layout |= AV_CH_BACK_CENTER;
149 av_log(avctx, AV_LOG_WARNING,
150 "unsupported number of back channels: %d\n",
151 channel_counts[ACT_BACK]);
156 if (channel_counts[ACT_LFE] > 0) {
157 if (channel_counts[ACT_LFE] == 1) {
158 ch_layout |= AV_CH_LOW_FREQUENCY;
160 av_log(avctx, AV_LOG_WARNING,
161 "unsupported number of LFE channels: %d\n",
162 channel_counts[ACT_LFE]);
167 av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {
168 av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
172 avctx->channel_layout = 0;
174 avctx->channel_layout = ch_layout;
176 avctx->channels = info->numChannels;
181 static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
183 FDKAACDecContext *s = avctx->priv_data;
186 aacDecoder_Close(s->handle);
191 static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
193 FDKAACDecContext *s = avctx->priv_data;
194 AAC_DECODER_ERROR err;
196 s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
198 av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
199 return AVERROR_UNKNOWN;
202 if (avctx->extradata_size) {
203 if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata,
204 &avctx->extradata_size)) != AAC_DEC_OK) {
205 av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
206 return AVERROR_INVALIDDATA;
210 if (s->conceal_method != CONCEAL_METHOD_DEFAULT) {
211 if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD,
212 s->conceal_method)) != AAC_DEC_OK) {
213 av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
214 return AVERROR_UNKNOWN;
218 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
223 static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
224 int *got_frame_ptr, AVPacket *avpkt)
226 FDKAACDecContext *s = avctx->priv_data;
227 AVFrame *frame = data;
229 AAC_DECODER_ERROR err;
230 UINT valid = avpkt->size;
231 uint8_t *buf, *tmpptr = NULL;
234 err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
235 if (err != AAC_DEC_OK) {
236 av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
237 return AVERROR_INVALIDDATA;
240 if (s->initialized) {
241 frame->nb_samples = avctx->frame_size;
242 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
244 buf = frame->extended_data[0];
245 buf_size = avctx->channels * frame->nb_samples *
246 av_get_bytes_per_sample(avctx->sample_fmt);
248 buf_size = 50 * 1024;
249 buf = tmpptr = av_malloc(buf_size);
251 return AVERROR(ENOMEM);
254 err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) buf, buf_size, 0);
255 if (err == AAC_DEC_NOT_ENOUGH_BITS) {
256 ret = avpkt->size - valid;
259 if (err != AAC_DEC_OK) {
260 av_log(avctx, AV_LOG_ERROR,
261 "aacDecoder_DecodeFrame() failed: %x\n", err);
262 ret = AVERROR_UNKNOWN;
266 if (!s->initialized) {
267 if ((ret = get_stream_info(avctx)) < 0)
270 frame->nb_samples = avctx->frame_size;
274 frame->nb_samples = avctx->frame_size;
275 if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
277 memcpy(frame->extended_data[0], tmpptr,
278 avctx->channels * avctx->frame_size *
279 av_get_bytes_per_sample(avctx->sample_fmt));
283 ret = avpkt->size - valid;
290 static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
292 FDKAACDecContext *s = avctx->priv_data;
293 AAC_DECODER_ERROR err;
298 if ((err = aacDecoder_SetParam(s->handle,
299 AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
300 av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
303 AVCodec ff_libfdk_aac_decoder = {
304 .name = "libfdk_aac",
305 .long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
306 .type = AVMEDIA_TYPE_AUDIO,
307 .id = AV_CODEC_ID_AAC,
308 .priv_data_size = sizeof(FDKAACDecContext),
309 .init = fdk_aac_decode_init,
310 .decode = fdk_aac_decode_frame,
311 .close = fdk_aac_decode_close,
312 .flush = fdk_aac_decode_flush,
313 .capabilities = CODEC_CAP_DR1,
314 .priv_class = &fdk_aac_dec_class,