Subversion Repositories Kolibri OS

Rev

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

  1. /*
  2.  * Interface to libfaac for aac encoding
  3.  * Copyright (c) 2002 Gildas Bazin <gbazin@netcourrier.com>
  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. /**
  23.  * @file
  24.  * Interface to libfaac for aac encoding.
  25.  */
  26.  
  27. #include <faac.h>
  28.  
  29. #include "libavutil/channel_layout.h"
  30. #include "libavutil/common.h"
  31. #include "avcodec.h"
  32. #include "audio_frame_queue.h"
  33. #include "internal.h"
  34.  
  35.  
  36. /* libfaac has an encoder delay of 1024 samples */
  37. #define FAAC_DELAY_SAMPLES 1024
  38.  
  39. typedef struct FaacAudioContext {
  40.     faacEncHandle faac_handle;
  41.     AudioFrameQueue afq;
  42. } FaacAudioContext;
  43.  
  44. static av_cold int Faac_encode_close(AVCodecContext *avctx)
  45. {
  46.     FaacAudioContext *s = avctx->priv_data;
  47.  
  48.     av_freep(&avctx->extradata);
  49.     ff_af_queue_close(&s->afq);
  50.  
  51.     if (s->faac_handle)
  52.         faacEncClose(s->faac_handle);
  53.  
  54.     return 0;
  55. }
  56.  
  57. static const int channel_maps[][6] = {
  58.     { 2, 0, 1 },          //< C L R
  59.     { 2, 0, 1, 3 },       //< C L R Cs
  60.     { 2, 0, 1, 3, 4 },    //< C L R Ls Rs
  61.     { 2, 0, 1, 4, 5, 3 }, //< C L R Ls Rs LFE
  62. };
  63.  
  64. static av_cold int Faac_encode_init(AVCodecContext *avctx)
  65. {
  66.     FaacAudioContext *s = avctx->priv_data;
  67.     faacEncConfigurationPtr faac_cfg;
  68.     unsigned long samples_input, max_bytes_output;
  69.     int ret;
  70.  
  71.     /* number of channels */
  72.     if (avctx->channels < 1 || avctx->channels > 6) {
  73.         av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels);
  74.         ret = AVERROR(EINVAL);
  75.         goto error;
  76.     }
  77.  
  78.     s->faac_handle = faacEncOpen(avctx->sample_rate,
  79.                                  avctx->channels,
  80.                                  &samples_input, &max_bytes_output);
  81.     if (!s->faac_handle) {
  82.         av_log(avctx, AV_LOG_ERROR, "error in faacEncOpen()\n");
  83.         ret = AVERROR_UNKNOWN;
  84.         goto error;
  85.     }
  86.  
  87.     /* check faac version */
  88.     faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle);
  89.     if (faac_cfg->version != FAAC_CFG_VERSION) {
  90.         av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version);
  91.         ret = AVERROR(EINVAL);
  92.         goto error;
  93.     }
  94.  
  95.     /* put the options in the configuration struct */
  96.     switch(avctx->profile) {
  97.         case FF_PROFILE_AAC_MAIN:
  98.             faac_cfg->aacObjectType = MAIN;
  99.             break;
  100.         case FF_PROFILE_UNKNOWN:
  101.         case FF_PROFILE_AAC_LOW:
  102.             faac_cfg->aacObjectType = LOW;
  103.             break;
  104.         case FF_PROFILE_AAC_SSR:
  105.             faac_cfg->aacObjectType = SSR;
  106.             break;
  107.         case FF_PROFILE_AAC_LTP:
  108.             faac_cfg->aacObjectType = LTP;
  109.             break;
  110.         default:
  111.             av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n");
  112.             ret = AVERROR(EINVAL);
  113.             goto error;
  114.     }
  115.     faac_cfg->mpegVersion = MPEG4;
  116.     faac_cfg->useTns = 0;
  117.     faac_cfg->allowMidside = 1;
  118.     faac_cfg->bitRate = avctx->bit_rate / avctx->channels;
  119.     faac_cfg->bandWidth = avctx->cutoff;
  120.     if(avctx->flags & CODEC_FLAG_QSCALE) {
  121.         faac_cfg->bitRate = 0;
  122.         faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA;
  123.     }
  124.     faac_cfg->outputFormat = 1;
  125.     faac_cfg->inputFormat = FAAC_INPUT_16BIT;
  126.     if (avctx->channels > 2)
  127.         memcpy(faac_cfg->channel_map, channel_maps[avctx->channels-3],
  128.                avctx->channels * sizeof(int));
  129.  
  130.     avctx->frame_size = samples_input / avctx->channels;
  131.  
  132.     /* Set decoder specific info */
  133.     avctx->extradata_size = 0;
  134.     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
  135.  
  136.         unsigned char *buffer = NULL;
  137.         unsigned long decoder_specific_info_size;
  138.  
  139.         if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer,
  140.                                            &decoder_specific_info_size)) {
  141.             avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE);
  142.             if (!avctx->extradata) {
  143.                 ret = AVERROR(ENOMEM);
  144.                 goto error;
  145.             }
  146.             avctx->extradata_size = decoder_specific_info_size;
  147.             memcpy(avctx->extradata, buffer, avctx->extradata_size);
  148.             faac_cfg->outputFormat = 0;
  149.         }
  150.         free(buffer);
  151.     }
  152.  
  153.     if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) {
  154.         int i;
  155.         for (i = avctx->bit_rate/1000; i ; i--) {
  156.             faac_cfg->bitRate = 1000*i / avctx->channels;
  157.             if (faacEncSetConfiguration(s->faac_handle, faac_cfg))
  158.                 break;
  159.         }
  160.         if (!i) {
  161.             av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n");
  162.             ret = AVERROR(EINVAL);
  163.             goto error;
  164.         } else {
  165.             avctx->bit_rate = 1000*i;
  166.             av_log(avctx, AV_LOG_WARNING, "libfaac doesn't support the specified bitrate, using %dkbit/s instead\n", i);
  167.         }
  168.     }
  169.  
  170.     avctx->delay = FAAC_DELAY_SAMPLES;
  171.     ff_af_queue_init(avctx, &s->afq);
  172.  
  173.     return 0;
  174. error:
  175.     Faac_encode_close(avctx);
  176.     return ret;
  177. }
  178.  
  179. static int Faac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
  180.                              const AVFrame *frame, int *got_packet_ptr)
  181. {
  182.     FaacAudioContext *s = avctx->priv_data;
  183.     int bytes_written, ret;
  184.     int num_samples  = frame ? frame->nb_samples : 0;
  185.     void *samples    = frame ? frame->data[0]    : NULL;
  186.  
  187.     if ((ret = ff_alloc_packet2(avctx, avpkt, (7 + 768) * avctx->channels)) < 0)
  188.         return ret;
  189.  
  190.     bytes_written = faacEncEncode(s->faac_handle, samples,
  191.                                   num_samples * avctx->channels,
  192.                                   avpkt->data, avpkt->size);
  193.     if (bytes_written < 0) {
  194.         av_log(avctx, AV_LOG_ERROR, "faacEncEncode() error\n");
  195.         return bytes_written;
  196.     }
  197.  
  198.     /* add current frame to the queue */
  199.     if (frame) {
  200.         if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
  201.             return ret;
  202.     }
  203.  
  204.     if (!bytes_written)
  205.         return 0;
  206.  
  207.     /* Get the next frame pts/duration */
  208.     ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
  209.                        &avpkt->duration);
  210.  
  211.     avpkt->size = bytes_written;
  212.     *got_packet_ptr = 1;
  213.     return 0;
  214. }
  215.  
  216. static const AVProfile profiles[] = {
  217.     { FF_PROFILE_AAC_MAIN, "Main" },
  218.     { FF_PROFILE_AAC_LOW,  "LC"   },
  219.     { FF_PROFILE_AAC_SSR,  "SSR"  },
  220.     { FF_PROFILE_AAC_LTP,  "LTP"  },
  221.     { FF_PROFILE_UNKNOWN },
  222. };
  223.  
  224. static const uint64_t faac_channel_layouts[] = {
  225.     AV_CH_LAYOUT_MONO,
  226.     AV_CH_LAYOUT_STEREO,
  227.     AV_CH_LAYOUT_SURROUND,
  228.     AV_CH_LAYOUT_4POINT0,
  229.     AV_CH_LAYOUT_5POINT0_BACK,
  230.     AV_CH_LAYOUT_5POINT1_BACK,
  231.     0
  232. };
  233.  
  234. AVCodec ff_libfaac_encoder = {
  235.     .name           = "libfaac",
  236.     .long_name      = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Coding)"),
  237.     .type           = AVMEDIA_TYPE_AUDIO,
  238.     .id             = AV_CODEC_ID_AAC,
  239.     .priv_data_size = sizeof(FaacAudioContext),
  240.     .init           = Faac_encode_init,
  241.     .encode2        = Faac_encode_frame,
  242.     .close          = Faac_encode_close,
  243.     .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
  244.     .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
  245.                                                      AV_SAMPLE_FMT_NONE },
  246.     .profiles       = NULL_IF_CONFIG_SMALL(profiles),
  247.     .channel_layouts = faac_channel_layouts,
  248. };
  249.