You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
10KB

  1. /*
  2. * AAC decoder wrapper
  3. * Copyright (c) 2012 Martin Storsjo
  4. *
  5. * This file is part of Libav.
  6. *
  7. * Libav is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * Libav is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with Libav; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include <fdk-aac/aacdecoder_lib.h>
  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. enum ConcealMethod {
  28. CONCEAL_METHOD_DEFAULT = -1,
  29. CONCEAL_METHOD_SPECTRAL_MUTING = 0,
  30. CONCEAL_METHOD_NOISE_SUBSTITUTION = 1,
  31. CONCEAL_METHOD_ENERGY_INTERPOLATION = 2,
  32. CONCEAL_METHOD_NB,
  33. };
  34. typedef struct FDKAACDecContext {
  35. const AVClass *class;
  36. HANDLE_AACDECODER handle;
  37. int initialized;
  38. enum ConcealMethod conceal_method;
  39. } FDKAACDecContext;
  40. #define OFFSET(x) offsetof(FDKAACDecContext, x)
  41. #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
  42. static const AVOption fdk_aac_dec_options[] = {
  43. { "conceal", "Error concealment method", OFFSET(conceal_method), AV_OPT_TYPE_INT, { .i64 = CONCEAL_METHOD_DEFAULT }, CONCEAL_METHOD_DEFAULT, CONCEAL_METHOD_NB - 1, AD, "conceal" },
  44. { "default", "Default", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_DEFAULT }, INT_MIN, INT_MAX, AD, "conceal" },
  45. { "spectral", "Spectral muting", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING }, INT_MIN, INT_MAX, AD, "conceal" },
  46. { "noise", "Noise Substitution", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, INT_MIN, INT_MAX, AD, "conceal" },
  47. { "energy", "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
  48. { NULL }
  49. };
  50. static const AVClass fdk_aac_dec_class = {
  51. "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
  52. };
  53. static int get_stream_info(AVCodecContext *avctx)
  54. {
  55. FDKAACDecContext *s = avctx->priv_data;
  56. CStreamInfo *info = aacDecoder_GetStreamInfo(s->handle);
  57. int channel_counts[9] = { 0 };
  58. int i, ch_error = 0;
  59. uint64_t ch_layout = 0;
  60. if (!info) {
  61. av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
  62. return AVERROR_UNKNOWN;
  63. }
  64. if (info->sampleRate <= 0) {
  65. av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
  66. return AVERROR_UNKNOWN;
  67. }
  68. avctx->sample_rate = info->sampleRate;
  69. avctx->frame_size = info->frameSize;
  70. for (i = 0; i < info->numChannels; i++) {
  71. AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
  72. if (ctype <= ACT_NONE || ctype > ACT_TOP) {
  73. av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
  74. break;
  75. }
  76. channel_counts[ctype]++;
  77. }
  78. av_log(avctx, AV_LOG_DEBUG,
  79. "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
  80. info->numChannels,
  81. channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
  82. channel_counts[ACT_BACK], channel_counts[ACT_LFE],
  83. channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
  84. channel_counts[ACT_BACK_TOP] + channel_counts[ACT_TOP]);
  85. switch (channel_counts[ACT_FRONT]) {
  86. case 4:
  87. ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |
  88. AV_CH_FRONT_RIGHT_OF_CENTER;
  89. break;
  90. case 3:
  91. ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
  92. break;
  93. case 2:
  94. ch_layout |= AV_CH_LAYOUT_STEREO;
  95. break;
  96. case 1:
  97. ch_layout |= AV_CH_FRONT_CENTER;
  98. break;
  99. default:
  100. av_log(avctx, AV_LOG_WARNING,
  101. "unsupported number of front channels: %d\n",
  102. channel_counts[ACT_FRONT]);
  103. ch_error = 1;
  104. break;
  105. }
  106. if (channel_counts[ACT_SIDE] > 0) {
  107. if (channel_counts[ACT_SIDE] == 2) {
  108. ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
  109. } else {
  110. av_log(avctx, AV_LOG_WARNING,
  111. "unsupported number of side channels: %d\n",
  112. channel_counts[ACT_SIDE]);
  113. ch_error = 1;
  114. }
  115. }
  116. if (channel_counts[ACT_BACK] > 0) {
  117. switch (channel_counts[ACT_BACK]) {
  118. case 3:
  119. ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
  120. break;
  121. case 2:
  122. ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
  123. break;
  124. case 1:
  125. ch_layout |= AV_CH_BACK_CENTER;
  126. break;
  127. default:
  128. av_log(avctx, AV_LOG_WARNING,
  129. "unsupported number of back channels: %d\n",
  130. channel_counts[ACT_BACK]);
  131. ch_error = 1;
  132. break;
  133. }
  134. }
  135. if (channel_counts[ACT_LFE] > 0) {
  136. if (channel_counts[ACT_LFE] == 1) {
  137. ch_layout |= AV_CH_LOW_FREQUENCY;
  138. } else {
  139. av_log(avctx, AV_LOG_WARNING,
  140. "unsupported number of LFE channels: %d\n",
  141. channel_counts[ACT_LFE]);
  142. ch_error = 1;
  143. }
  144. }
  145. if (!ch_error &&
  146. av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {
  147. av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
  148. ch_error = 1;
  149. }
  150. if (ch_error)
  151. avctx->channel_layout = 0;
  152. else
  153. avctx->channel_layout = ch_layout;
  154. avctx->channels = info->numChannels;
  155. return 0;
  156. }
  157. static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
  158. {
  159. FDKAACDecContext *s = avctx->priv_data;
  160. if (s->handle)
  161. aacDecoder_Close(s->handle);
  162. return 0;
  163. }
  164. static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
  165. {
  166. FDKAACDecContext *s = avctx->priv_data;
  167. AAC_DECODER_ERROR err;
  168. s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
  169. if (!s->handle) {
  170. av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
  171. return AVERROR_UNKNOWN;
  172. }
  173. if (avctx->extradata_size) {
  174. if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata,
  175. &avctx->extradata_size)) != AAC_DEC_OK) {
  176. av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
  177. return AVERROR_INVALIDDATA;
  178. }
  179. }
  180. if (s->conceal_method != CONCEAL_METHOD_DEFAULT) {
  181. if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD,
  182. s->conceal_method)) != AAC_DEC_OK) {
  183. av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
  184. return AVERROR_UNKNOWN;
  185. }
  186. }
  187. avctx->sample_fmt = AV_SAMPLE_FMT_S16;
  188. return 0;
  189. }
  190. static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
  191. int *got_frame_ptr, AVPacket *avpkt)
  192. {
  193. FDKAACDecContext *s = avctx->priv_data;
  194. AVFrame *frame = data;
  195. int ret;
  196. AAC_DECODER_ERROR err;
  197. UINT valid = avpkt->size;
  198. uint8_t *buf, *tmpptr = NULL;
  199. int buf_size;
  200. err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
  201. if (err != AAC_DEC_OK) {
  202. av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
  203. return AVERROR_INVALIDDATA;
  204. }
  205. if (s->initialized) {
  206. frame->nb_samples = avctx->frame_size;
  207. if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
  208. av_log(avctx, AV_LOG_ERROR, "ff_get_buffer() failed\n");
  209. return ret;
  210. }
  211. buf = frame->extended_data[0];
  212. buf_size = avctx->channels * frame->nb_samples *
  213. av_get_bytes_per_sample(avctx->sample_fmt);
  214. } else {
  215. buf_size = 50 * 1024;
  216. buf = tmpptr = av_malloc(buf_size);
  217. if (!buf)
  218. return AVERROR(ENOMEM);
  219. }
  220. err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) buf, buf_size, 0);
  221. if (err == AAC_DEC_NOT_ENOUGH_BITS) {
  222. ret = avpkt->size - valid;
  223. goto end;
  224. }
  225. if (err != AAC_DEC_OK) {
  226. av_log(avctx, AV_LOG_ERROR,
  227. "aacDecoder_DecodeFrame() failed: %x\n", err);
  228. ret = AVERROR_UNKNOWN;
  229. goto end;
  230. }
  231. if (!s->initialized) {
  232. if ((ret = get_stream_info(avctx)) < 0)
  233. goto end;
  234. s->initialized = 1;
  235. frame->nb_samples = avctx->frame_size;
  236. }
  237. if (tmpptr) {
  238. frame->nb_samples = avctx->frame_size;
  239. if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
  240. av_log(avctx, AV_LOG_ERROR, "ff_get_buffer() failed\n");
  241. goto end;
  242. }
  243. memcpy(frame->extended_data[0], tmpptr,
  244. avctx->channels * avctx->frame_size *
  245. av_get_bytes_per_sample(avctx->sample_fmt));
  246. }
  247. *got_frame_ptr = 1;
  248. ret = avpkt->size - valid;
  249. end:
  250. av_free(tmpptr);
  251. return ret;
  252. }
  253. static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
  254. {
  255. FDKAACDecContext *s = avctx->priv_data;
  256. AAC_DECODER_ERROR err;
  257. if (!s->handle)
  258. return;
  259. if ((err = aacDecoder_SetParam(s->handle,
  260. AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
  261. av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
  262. }
  263. AVCodec ff_libfdk_aac_decoder = {
  264. .name = "libfdk_aac",
  265. .long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
  266. .type = AVMEDIA_TYPE_AUDIO,
  267. .id = AV_CODEC_ID_AAC,
  268. .priv_data_size = sizeof(FDKAACDecContext),
  269. .init = fdk_aac_decode_init,
  270. .decode = fdk_aac_decode_frame,
  271. .close = fdk_aac_decode_close,
  272. .flush = fdk_aac_decode_flush,
  273. .capabilities = CODEC_CAP_DR1,
  274. .priv_class = &fdk_aac_dec_class,
  275. };