Subversion Repositories Kolibri OS

Rev

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.  * 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. /* The version macro is introduced the same time as the setting enum was
  29.  * changed, so this check should suffice. */
  30. #ifndef AACDECODER_LIB_VL0
  31. #define AAC_PCM_MAX_OUTPUT_CHANNELS AAC_PCM_OUTPUT_CHANNELS
  32. #endif
  33.  
  34. enum ConcealMethod {
  35.     CONCEAL_METHOD_SPECTRAL_MUTING      =  0,
  36.     CONCEAL_METHOD_NOISE_SUBSTITUTION   =  1,
  37.     CONCEAL_METHOD_ENERGY_INTERPOLATION =  2,
  38.     CONCEAL_METHOD_NB,
  39. };
  40.  
  41. typedef struct FDKAACDecContext {
  42.     const AVClass *class;
  43.     HANDLE_AACDECODER handle;
  44.     uint8_t *decoder_buffer;
  45.     int decoder_buffer_size;
  46.     uint8_t *anc_buffer;
  47.     int conceal_method;
  48.     int drc_level;
  49.     int drc_boost;
  50.     int drc_heavy;
  51.     int drc_cut;
  52.     int level_limit;
  53. } FDKAACDecContext;
  54.  
  55.  
  56. #define DMX_ANC_BUFFSIZE       128
  57. #define DECODER_MAX_CHANNELS     8
  58. #define DECODER_BUFFSIZE      2048 * sizeof(INT_PCM)
  59.  
  60. #define OFFSET(x) offsetof(FDKAACDecContext, x)
  61. #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
  62. static const AVOption fdk_aac_dec_options[] = {
  63.     { "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" },
  64.     { "spectral", "Spectral muting",      0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING },      INT_MIN, INT_MAX, AD, "conceal" },
  65.     { "noise",    "Noise Substitution",   0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION },   INT_MIN, INT_MAX, AD, "conceal" },
  66.     { "energy",   "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
  67.     { "drc_boost", "Dynamic Range Control: boost, where [0] is none and [127] is max boost",
  68.                      OFFSET(drc_boost),      AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, 127, AD, NULL    },
  69.     { "drc_cut",   "Dynamic Range Control: attenuation factor, where [0] is none and [127] is max compression",
  70.                      OFFSET(drc_cut),        AV_OPT_TYPE_INT,   { .i64 = -1 }, -1, 127, AD, NULL    },
  71.     { "drc_level", "Dynamic Range Control: reference level, quantized to 0.25dB steps where [0] is 0dB and [127] is -31.75dB",
  72.                      OFFSET(drc_level),      AV_OPT_TYPE_INT,   { .i64 = -1},  -1, 127, AD, NULL    },
  73.     { "drc_heavy", "Dynamic Range Control: heavy compression, where [1] is on (RF mode) and [0] is off",
  74.                      OFFSET(drc_heavy),      AV_OPT_TYPE_INT,   { .i64 = -1},  -1, 1,   AD, NULL    },
  75. #ifdef AACDECODER_LIB_VL0
  76.     { "level_limit", "Signal level limiting", OFFSET(level_limit), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 1, AD },
  77. #endif
  78.     { NULL }
  79. };
  80.  
  81. static const AVClass fdk_aac_dec_class = {
  82.     "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
  83. };
  84.  
  85. static int get_stream_info(AVCodecContext *avctx)
  86. {
  87.     FDKAACDecContext *s   = avctx->priv_data;
  88.     CStreamInfo *info     = aacDecoder_GetStreamInfo(s->handle);
  89.     int channel_counts[0x24] = { 0 };
  90.     int i, ch_error       = 0;
  91.     uint64_t ch_layout    = 0;
  92.  
  93.     if (!info) {
  94.         av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
  95.         return AVERROR_UNKNOWN;
  96.     }
  97.  
  98.     if (info->sampleRate <= 0) {
  99.         av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
  100.         return AVERROR_UNKNOWN;
  101.     }
  102.     avctx->sample_rate = info->sampleRate;
  103.     avctx->frame_size  = info->frameSize;
  104.  
  105.     for (i = 0; i < info->numChannels; i++) {
  106.         AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
  107.         if (ctype <= ACT_NONE || ctype >= FF_ARRAY_ELEMS(channel_counts)) {
  108.             av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
  109.             break;
  110.         }
  111.         channel_counts[ctype]++;
  112.     }
  113.     av_log(avctx, AV_LOG_DEBUG,
  114.            "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
  115.            info->numChannels,
  116.            channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
  117.            channel_counts[ACT_BACK],  channel_counts[ACT_LFE],
  118.            channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
  119.            channel_counts[ACT_BACK_TOP]  + channel_counts[ACT_TOP]);
  120.  
  121.     switch (channel_counts[ACT_FRONT]) {
  122.     case 4:
  123.         ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |
  124.                      AV_CH_FRONT_RIGHT_OF_CENTER;
  125.         break;
  126.     case 3:
  127.         ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
  128.         break;
  129.     case 2:
  130.         ch_layout |= AV_CH_LAYOUT_STEREO;
  131.         break;
  132.     case 1:
  133.         ch_layout |= AV_CH_FRONT_CENTER;
  134.         break;
  135.     default:
  136.         av_log(avctx, AV_LOG_WARNING,
  137.                "unsupported number of front channels: %d\n",
  138.                channel_counts[ACT_FRONT]);
  139.         ch_error = 1;
  140.         break;
  141.     }
  142.     if (channel_counts[ACT_SIDE] > 0) {
  143.         if (channel_counts[ACT_SIDE] == 2) {
  144.             ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
  145.         } else {
  146.             av_log(avctx, AV_LOG_WARNING,
  147.                    "unsupported number of side channels: %d\n",
  148.                    channel_counts[ACT_SIDE]);
  149.             ch_error = 1;
  150.         }
  151.     }
  152.     if (channel_counts[ACT_BACK] > 0) {
  153.         switch (channel_counts[ACT_BACK]) {
  154.         case 3:
  155.             ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
  156.             break;
  157.         case 2:
  158.             ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
  159.             break;
  160.         case 1:
  161.             ch_layout |= AV_CH_BACK_CENTER;
  162.             break;
  163.         default:
  164.             av_log(avctx, AV_LOG_WARNING,
  165.                    "unsupported number of back channels: %d\n",
  166.                    channel_counts[ACT_BACK]);
  167.             ch_error = 1;
  168.             break;
  169.         }
  170.     }
  171.     if (channel_counts[ACT_LFE] > 0) {
  172.         if (channel_counts[ACT_LFE] == 1) {
  173.             ch_layout |= AV_CH_LOW_FREQUENCY;
  174.         } else {
  175.             av_log(avctx, AV_LOG_WARNING,
  176.                    "unsupported number of LFE channels: %d\n",
  177.                    channel_counts[ACT_LFE]);
  178.             ch_error = 1;
  179.         }
  180.     }
  181.     if (!ch_error &&
  182.         av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {
  183.         av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
  184.         ch_error = 1;
  185.     }
  186.     if (ch_error)
  187.         avctx->channel_layout = 0;
  188.     else
  189.         avctx->channel_layout = ch_layout;
  190.  
  191.     avctx->channels = info->numChannels;
  192.  
  193.     return 0;
  194. }
  195.  
  196. static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
  197. {
  198.     FDKAACDecContext *s = avctx->priv_data;
  199.  
  200.     if (s->handle)
  201.         aacDecoder_Close(s->handle);
  202.     av_freep(&s->decoder_buffer);
  203.     av_freep(&s->anc_buffer);
  204.  
  205.     return 0;
  206. }
  207.  
  208. static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
  209. {
  210.     FDKAACDecContext *s = avctx->priv_data;
  211.     AAC_DECODER_ERROR err;
  212.  
  213.     s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
  214.     if (!s->handle) {
  215.         av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
  216.         return AVERROR_UNKNOWN;
  217.     }
  218.  
  219.     if (avctx->extradata_size) {
  220.         if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata,
  221.                                         &avctx->extradata_size)) != AAC_DEC_OK) {
  222.             av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
  223.             return AVERROR_INVALIDDATA;
  224.         }
  225.     }
  226.  
  227.     if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD,
  228.                                    s->conceal_method)) != AAC_DEC_OK) {
  229.         av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
  230.         return AVERROR_UNKNOWN;
  231.     }
  232.  
  233.     if (avctx->request_channel_layout > 0 &&
  234.         avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) {
  235.         int downmix_channels = -1;
  236.  
  237.         switch (avctx->request_channel_layout) {
  238.         case AV_CH_LAYOUT_STEREO:
  239.         case AV_CH_LAYOUT_STEREO_DOWNMIX:
  240.             downmix_channels = 2;
  241.             break;
  242.         case AV_CH_LAYOUT_MONO:
  243.             downmix_channels = 1;
  244.             break;
  245.         default:
  246.             av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n");
  247.             break;
  248.         }
  249.  
  250.         if (downmix_channels != -1) {
  251.             if (aacDecoder_SetParam(s->handle, AAC_PCM_MAX_OUTPUT_CHANNELS,
  252.                                     downmix_channels) != AAC_DEC_OK) {
  253.                av_log(avctx, AV_LOG_WARNING, "Unable to set output channels in the decoder\n");
  254.             } else {
  255.                s->anc_buffer = av_malloc(DMX_ANC_BUFFSIZE);
  256.                if (!s->anc_buffer) {
  257.                    av_log(avctx, AV_LOG_ERROR, "Unable to allocate ancillary buffer for the decoder\n");
  258.                    return AVERROR(ENOMEM);
  259.                }
  260.                if (aacDecoder_AncDataInit(s->handle, s->anc_buffer, DMX_ANC_BUFFSIZE)) {
  261.                    av_log(avctx, AV_LOG_ERROR, "Unable to register downmix ancillary buffer in the decoder\n");
  262.                    return AVERROR_UNKNOWN;
  263.                }
  264.             }
  265.         }
  266.     }
  267.  
  268.     if (s->drc_boost != -1) {
  269.         if (aacDecoder_SetParam(s->handle, AAC_DRC_BOOST_FACTOR, s->drc_boost) != AAC_DEC_OK) {
  270.             av_log(avctx, AV_LOG_ERROR, "Unable to set DRC boost factor in the decoder\n");
  271.             return AVERROR_UNKNOWN;
  272.         }
  273.     }
  274.  
  275.     if (s->drc_cut != -1) {
  276.         if (aacDecoder_SetParam(s->handle, AAC_DRC_ATTENUATION_FACTOR, s->drc_cut) != AAC_DEC_OK) {
  277.             av_log(avctx, AV_LOG_ERROR, "Unable to set DRC attenuation factor in the decoder\n");
  278.             return AVERROR_UNKNOWN;
  279.         }
  280.     }
  281.  
  282.     if (s->drc_level != -1) {
  283.         if (aacDecoder_SetParam(s->handle, AAC_DRC_REFERENCE_LEVEL, s->drc_level) != AAC_DEC_OK) {
  284.             av_log(avctx, AV_LOG_ERROR, "Unable to set DRC reference level in the decoder\n");
  285.             return AVERROR_UNKNOWN;
  286.         }
  287.     }
  288.  
  289.     if (s->drc_heavy != -1) {
  290.         if (aacDecoder_SetParam(s->handle, AAC_DRC_HEAVY_COMPRESSION, s->drc_heavy) != AAC_DEC_OK) {
  291.             av_log(avctx, AV_LOG_ERROR, "Unable to set DRC heavy compression in the decoder\n");
  292.             return AVERROR_UNKNOWN;
  293.         }
  294.     }
  295.  
  296. #ifdef AACDECODER_LIB_VL0
  297.     if (aacDecoder_SetParam(s->handle, AAC_PCM_LIMITER_ENABLE, s->level_limit) != AAC_DEC_OK) {
  298.         av_log(avctx, AV_LOG_ERROR, "Unable to set in signal level limiting in the decoder\n");
  299.         return AVERROR_UNKNOWN;
  300.     }
  301. #endif
  302.  
  303.     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
  304.  
  305.     s->decoder_buffer_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS;
  306.     s->decoder_buffer = av_malloc(s->decoder_buffer_size);
  307.     if (!s->decoder_buffer)
  308.         return AVERROR(ENOMEM);
  309.  
  310.     return 0;
  311. }
  312.  
  313. static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
  314.                                 int *got_frame_ptr, AVPacket *avpkt)
  315. {
  316.     FDKAACDecContext *s = avctx->priv_data;
  317.     AVFrame *frame = data;
  318.     int ret;
  319.     AAC_DECODER_ERROR err;
  320.     UINT valid = avpkt->size;
  321.  
  322.     err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
  323.     if (err != AAC_DEC_OK) {
  324.         av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
  325.         return AVERROR_INVALIDDATA;
  326.     }
  327.  
  328.     err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, s->decoder_buffer_size, 0);
  329.     if (err == AAC_DEC_NOT_ENOUGH_BITS) {
  330.         ret = avpkt->size - valid;
  331.         goto end;
  332.     }
  333.     if (err != AAC_DEC_OK) {
  334.         av_log(avctx, AV_LOG_ERROR,
  335.                "aacDecoder_DecodeFrame() failed: %x\n", err);
  336.         ret = AVERROR_UNKNOWN;
  337.         goto end;
  338.     }
  339.  
  340.     if ((ret = get_stream_info(avctx)) < 0)
  341.         goto end;
  342.     frame->nb_samples = avctx->frame_size;
  343.  
  344.     if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
  345.         goto end;
  346.  
  347.     memcpy(frame->extended_data[0], s->decoder_buffer,
  348.            avctx->channels * avctx->frame_size *
  349.            av_get_bytes_per_sample(avctx->sample_fmt));
  350.  
  351.     *got_frame_ptr = 1;
  352.     ret = avpkt->size - valid;
  353.  
  354. end:
  355.     return ret;
  356. }
  357.  
  358. static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
  359. {
  360.     FDKAACDecContext *s = avctx->priv_data;
  361.     AAC_DECODER_ERROR err;
  362.  
  363.     if (!s->handle)
  364.         return;
  365.  
  366.     if ((err = aacDecoder_SetParam(s->handle,
  367.                                    AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
  368.         av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
  369. }
  370.  
  371. AVCodec ff_libfdk_aac_decoder = {
  372.     .name           = "libfdk_aac",
  373.     .long_name      = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
  374.     .type           = AVMEDIA_TYPE_AUDIO,
  375.     .id             = AV_CODEC_ID_AAC,
  376.     .priv_data_size = sizeof(FDKAACDecContext),
  377.     .init           = fdk_aac_decode_init,
  378.     .decode         = fdk_aac_decode_frame,
  379.     .close          = fdk_aac_decode_close,
  380.     .flush          = fdk_aac_decode_flush,
  381.     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
  382.     .priv_class     = &fdk_aac_dec_class,
  383.     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
  384.                       FF_CODEC_CAP_INIT_CLEANUP,
  385. };
  386.