00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #include <faac.h>
00029
00030 typedef struct FaacAudioContext {
00031 faacEncHandle faac_handle;
00032 } FaacAudioContext;
00033
00034 static av_cold int Faac_encode_init(AVCodecContext *avctx)
00035 {
00036 FaacAudioContext *s = avctx->priv_data;
00037 faacEncConfigurationPtr faac_cfg;
00038 unsigned long samples_input, max_bytes_output;
00039
00040
00041 if (avctx->channels < 1 || avctx->channels > 6) {
00042 av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels);
00043 return -1;
00044 }
00045
00046 s->faac_handle = faacEncOpen(avctx->sample_rate,
00047 avctx->channels,
00048 &samples_input, &max_bytes_output);
00049
00050
00051 faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle);
00052 if (faac_cfg->version != FAAC_CFG_VERSION) {
00053 av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version);
00054 faacEncClose(s->faac_handle);
00055 return -1;
00056 }
00057
00058
00059 switch(avctx->profile) {
00060 case FF_PROFILE_AAC_MAIN:
00061 faac_cfg->aacObjectType = MAIN;
00062 break;
00063 case FF_PROFILE_UNKNOWN:
00064 case FF_PROFILE_AAC_LOW:
00065 faac_cfg->aacObjectType = LOW;
00066 break;
00067 case FF_PROFILE_AAC_SSR:
00068 faac_cfg->aacObjectType = SSR;
00069 break;
00070 case FF_PROFILE_AAC_LTP:
00071 faac_cfg->aacObjectType = LTP;
00072 break;
00073 default:
00074 av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n");
00075 faacEncClose(s->faac_handle);
00076 return -1;
00077 }
00078 faac_cfg->mpegVersion = MPEG4;
00079 faac_cfg->useTns = 0;
00080 faac_cfg->allowMidside = 1;
00081 faac_cfg->bitRate = avctx->bit_rate / avctx->channels;
00082 faac_cfg->bandWidth = avctx->cutoff;
00083 if(avctx->flags & CODEC_FLAG_QSCALE) {
00084 faac_cfg->bitRate = 0;
00085 faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA;
00086 }
00087 faac_cfg->outputFormat = 1;
00088 faac_cfg->inputFormat = FAAC_INPUT_16BIT;
00089
00090 avctx->frame_size = samples_input / avctx->channels;
00091
00092 avctx->coded_frame= avcodec_alloc_frame();
00093 avctx->coded_frame->key_frame= 1;
00094
00095
00096 avctx->extradata_size = 0;
00097 if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
00098
00099 unsigned char *buffer = NULL;
00100 unsigned long decoder_specific_info_size;
00101
00102 if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer,
00103 &decoder_specific_info_size)) {
00104 avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE);
00105 avctx->extradata_size = decoder_specific_info_size;
00106 memcpy(avctx->extradata, buffer, avctx->extradata_size);
00107 faac_cfg->outputFormat = 0;
00108 }
00109 #undef free
00110 free(buffer);
00111 #define free please_use_av_free
00112 }
00113
00114 if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) {
00115 av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n");
00116 return -1;
00117 }
00118
00119 return 0;
00120 }
00121
00122 static int Faac_encode_frame(AVCodecContext *avctx,
00123 unsigned char *frame, int buf_size, void *data)
00124 {
00125 FaacAudioContext *s = avctx->priv_data;
00126 int bytes_written;
00127
00128 bytes_written = faacEncEncode(s->faac_handle,
00129 data,
00130 avctx->frame_size * avctx->channels,
00131 frame,
00132 buf_size);
00133
00134 return bytes_written;
00135 }
00136
00137 static av_cold int Faac_encode_close(AVCodecContext *avctx)
00138 {
00139 FaacAudioContext *s = avctx->priv_data;
00140
00141 av_freep(&avctx->coded_frame);
00142 av_freep(&avctx->extradata);
00143
00144 faacEncClose(s->faac_handle);
00145 return 0;
00146 }
00147
00148 AVCodec libfaac_encoder = {
00149 "libfaac",
00150 CODEC_TYPE_AUDIO,
00151 CODEC_ID_AAC,
00152 sizeof(FaacAudioContext),
00153 Faac_encode_init,
00154 Faac_encode_frame,
00155 Faac_encode_close,
00156 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
00157 .long_name = NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Codec)"),
00158 };