1/*
2 * AAC decoder wrapper
3 * Copyright (c) 2012 Martin Storsjo
4 *
5 * This file is part of FFmpeg.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <fdk-aac/aacdecoder_lib.h>
21
22#include "libavutil/channel_layout.h"
23#include "libavutil/common.h"
24#include "libavutil/opt.h"
25#include "avcodec.h"
26#include "internal.h"
27
28enum ConcealMethod {
29    CONCEAL_METHOD_SPECTRAL_MUTING      =  0,
30    CONCEAL_METHOD_NOISE_SUBSTITUTION   =  1,
31    CONCEAL_METHOD_ENERGY_INTERPOLATION =  2,
32    CONCEAL_METHOD_NB,
33};
34
35typedef struct FDKAACDecContext {
36    const AVClass *class;
37    HANDLE_AACDECODER handle;
38    int initialized;
39    enum ConcealMethod conceal_method;
40} FDKAACDecContext;
41
42#define OFFSET(x) offsetof(FDKAACDecContext, x)
43#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
44static const AVOption fdk_aac_dec_options[] = {
45    { "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" },
46    { "spectral", "Spectral muting",      0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING },      INT_MIN, INT_MAX, AD, "conceal" },
47    { "noise",    "Noise Substitution",   0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION },   INT_MIN, INT_MAX, AD, "conceal" },
48    { "energy",   "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
49    { NULL }
50};
51
52static const AVClass fdk_aac_dec_class = {
53    "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
54};
55
56static int get_stream_info(AVCodecContext *avctx)
57{
58    FDKAACDecContext *s   = avctx->priv_data;
59    CStreamInfo *info     = aacDecoder_GetStreamInfo(s->handle);
60    int channel_counts[9] = { 0 };
61    int i, ch_error       = 0;
62    uint64_t ch_layout    = 0;
63
64    if (!info) {
65        av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
66        return AVERROR_UNKNOWN;
67    }
68
69    if (info->sampleRate <= 0) {
70        av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
71        return AVERROR_UNKNOWN;
72    }
73    avctx->sample_rate = info->sampleRate;
74    avctx->frame_size  = info->frameSize;
75
76    for (i = 0; i < info->numChannels; i++) {
77        AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
78        if (ctype <= ACT_NONE || ctype > ACT_TOP) {
79            av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
80            break;
81        }
82        channel_counts[ctype]++;
83    }
84    av_log(avctx, AV_LOG_DEBUG,
85           "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
86           info->numChannels,
87           channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
88           channel_counts[ACT_BACK],  channel_counts[ACT_LFE],
89           channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
90           channel_counts[ACT_BACK_TOP]  + channel_counts[ACT_TOP]);
91
92    switch (channel_counts[ACT_FRONT]) {
93    case 4:
94        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |
95                     AV_CH_FRONT_RIGHT_OF_CENTER;
96        break;
97    case 3:
98        ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
99        break;
100    case 2:
101        ch_layout |= AV_CH_LAYOUT_STEREO;
102        break;
103    case 1:
104        ch_layout |= AV_CH_FRONT_CENTER;
105        break;
106    default:
107        av_log(avctx, AV_LOG_WARNING,
108               "unsupported number of front channels: %d\n",
109               channel_counts[ACT_FRONT]);
110        ch_error = 1;
111        break;
112    }
113    if (channel_counts[ACT_SIDE] > 0) {
114        if (channel_counts[ACT_SIDE] == 2) {
115            ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
116        } else {
117            av_log(avctx, AV_LOG_WARNING,
118                   "unsupported number of side channels: %d\n",
119                   channel_counts[ACT_SIDE]);
120            ch_error = 1;
121        }
122    }
123    if (channel_counts[ACT_BACK] > 0) {
124        switch (channel_counts[ACT_BACK]) {
125        case 3:
126            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
127            break;
128        case 2:
129            ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
130            break;
131        case 1:
132            ch_layout |= AV_CH_BACK_CENTER;
133            break;
134        default:
135            av_log(avctx, AV_LOG_WARNING,
136                   "unsupported number of back channels: %d\n",
137                   channel_counts[ACT_BACK]);
138            ch_error = 1;
139            break;
140        }
141    }
142    if (channel_counts[ACT_LFE] > 0) {
143        if (channel_counts[ACT_LFE] == 1) {
144            ch_layout |= AV_CH_LOW_FREQUENCY;
145        } else {
146            av_log(avctx, AV_LOG_WARNING,
147                   "unsupported number of LFE channels: %d\n",
148                   channel_counts[ACT_LFE]);
149            ch_error = 1;
150        }
151    }
152    if (!ch_error &&
153        av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {
154        av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
155        ch_error = 1;
156    }
157    if (ch_error)
158        avctx->channel_layout = 0;
159    else
160        avctx->channel_layout = ch_layout;
161
162    avctx->channels = info->numChannels;
163
164    return 0;
165}
166
167static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
168{
169    FDKAACDecContext *s = avctx->priv_data;
170
171    if (s->handle)
172        aacDecoder_Close(s->handle);
173
174    return 0;
175}
176
177static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
178{
179    FDKAACDecContext *s = avctx->priv_data;
180    AAC_DECODER_ERROR err;
181
182    s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
183    if (!s->handle) {
184        av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
185        return AVERROR_UNKNOWN;
186    }
187
188    if (avctx->extradata_size) {
189        if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata,
190                                        &avctx->extradata_size)) != AAC_DEC_OK) {
191            av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
192            return AVERROR_INVALIDDATA;
193        }
194    }
195
196    if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD,
197                                   s->conceal_method)) != AAC_DEC_OK) {
198        av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
199        return AVERROR_UNKNOWN;
200    }
201
202    avctx->sample_fmt = AV_SAMPLE_FMT_S16;
203
204    return 0;
205}
206
207static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
208                                int *got_frame_ptr, AVPacket *avpkt)
209{
210    FDKAACDecContext *s = avctx->priv_data;
211    AVFrame *frame = data;
212    int ret;
213    AAC_DECODER_ERROR err;
214    UINT valid = avpkt->size;
215    uint8_t *buf, *tmpptr = NULL;
216    int buf_size;
217
218    err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
219    if (err != AAC_DEC_OK) {
220        av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
221        return AVERROR_INVALIDDATA;
222    }
223
224    if (s->initialized) {
225        frame->nb_samples = avctx->frame_size;
226        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
227            return ret;
228        buf = frame->extended_data[0];
229        buf_size = avctx->channels * frame->nb_samples *
230                   av_get_bytes_per_sample(avctx->sample_fmt);
231    } else {
232        buf_size = 50 * 1024;
233        buf = tmpptr = av_malloc(buf_size);
234        if (!buf)
235            return AVERROR(ENOMEM);
236    }
237
238    err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) buf, buf_size, 0);
239    if (err == AAC_DEC_NOT_ENOUGH_BITS) {
240        ret = avpkt->size - valid;
241        goto end;
242    }
243    if (err != AAC_DEC_OK) {
244        av_log(avctx, AV_LOG_ERROR,
245               "aacDecoder_DecodeFrame() failed: %x\n", err);
246        ret = AVERROR_UNKNOWN;
247        goto end;
248    }
249
250    if (!s->initialized) {
251        if ((ret = get_stream_info(avctx)) < 0)
252            goto end;
253        s->initialized = 1;
254        frame->nb_samples = avctx->frame_size;
255    }
256
257    if (tmpptr) {
258        frame->nb_samples = avctx->frame_size;
259        if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
260            goto end;
261        memcpy(frame->extended_data[0], tmpptr,
262               avctx->channels * avctx->frame_size *
263               av_get_bytes_per_sample(avctx->sample_fmt));
264    }
265
266    *got_frame_ptr = 1;
267    ret = avpkt->size - valid;
268
269end:
270    av_free(tmpptr);
271    return ret;
272}
273
274static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
275{
276    FDKAACDecContext *s = avctx->priv_data;
277    AAC_DECODER_ERROR err;
278
279    if (!s->handle)
280        return;
281
282    if ((err = aacDecoder_SetParam(s->handle,
283                                   AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
284        av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
285}
286
287AVCodec ff_libfdk_aac_decoder = {
288    .name           = "libfdk_aac",
289    .long_name      = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
290    .type           = AVMEDIA_TYPE_AUDIO,
291    .id             = AV_CODEC_ID_AAC,
292    .priv_data_size = sizeof(FDKAACDecContext),
293    .init           = fdk_aac_decode_init,
294    .decode         = fdk_aac_decode_frame,
295    .close          = fdk_aac_decode_close,
296    .flush          = fdk_aac_decode_flush,
297    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_CHANNEL_CONF,
298    .priv_class     = &fdk_aac_dec_class,
299};
300