Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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