]> git.sesse.net Git - ffmpeg/blob - libavcodec/libfdk-aacdec.c
x86/hevc_mc: remove an unnecessary pxor
[ffmpeg] / libavcodec / libfdk-aacdec.c
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
28 enum 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
35 typedef 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
44 static 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
52 static const AVClass fdk_aac_dec_class = {
53     "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
54 };
55
56 static 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
167 static 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
177 static 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
207 static 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
269 end:
270     av_free(tmpptr);
271     return ret;
272 }
273
274 static 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
287 AVCodec 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 };