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 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 return -1;
00043
00044 s->faac_handle = faacEncOpen(avctx->sample_rate,
00045 avctx->channels,
00046 &samples_input, &max_bytes_output);
00047
00048
00049 faac_cfg = faacEncGetCurrentConfiguration(s->faac_handle);
00050 if (faac_cfg->version != FAAC_CFG_VERSION) {
00051 av_log(avctx, AV_LOG_ERROR, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION, faac_cfg->version);
00052 faacEncClose(s->faac_handle);
00053 return -1;
00054 }
00055
00056
00057 switch(avctx->profile) {
00058 case FF_PROFILE_AAC_MAIN:
00059 faac_cfg->aacObjectType = MAIN;
00060 break;
00061 case FF_PROFILE_UNKNOWN:
00062 case FF_PROFILE_AAC_LOW:
00063 faac_cfg->aacObjectType = LOW;
00064 break;
00065 case FF_PROFILE_AAC_SSR:
00066 faac_cfg->aacObjectType = SSR;
00067 break;
00068 case FF_PROFILE_AAC_LTP:
00069 faac_cfg->aacObjectType = LTP;
00070 break;
00071 default:
00072 av_log(avctx, AV_LOG_ERROR, "invalid AAC profile\n");
00073 faacEncClose(s->faac_handle);
00074 return -1;
00075 }
00076 faac_cfg->mpegVersion = MPEG4;
00077 faac_cfg->useTns = 0;
00078 faac_cfg->allowMidside = 1;
00079 faac_cfg->bitRate = avctx->bit_rate / avctx->channels;
00080 faac_cfg->bandWidth = avctx->cutoff;
00081 if(avctx->flags & CODEC_FLAG_QSCALE) {
00082 faac_cfg->bitRate = 0;
00083 faac_cfg->quantqual = avctx->global_quality / FF_QP2LAMBDA;
00084 }
00085 faac_cfg->outputFormat = 1;
00086 faac_cfg->inputFormat = FAAC_INPUT_16BIT;
00087
00088 avctx->frame_size = samples_input / avctx->channels;
00089
00090 avctx->coded_frame= avcodec_alloc_frame();
00091 avctx->coded_frame->key_frame= 1;
00092
00093
00094 avctx->extradata_size = 0;
00095 if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
00096
00097 unsigned char *buffer = NULL;
00098 unsigned long decoder_specific_info_size;
00099
00100 if (!faacEncGetDecoderSpecificInfo(s->faac_handle, &buffer,
00101 &decoder_specific_info_size)) {
00102 avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE);
00103 avctx->extradata_size = decoder_specific_info_size;
00104 memcpy(avctx->extradata, buffer, avctx->extradata_size);
00105 faac_cfg->outputFormat = 0;
00106 }
00107 #undef free
00108 free(buffer);
00109 #define free please_use_av_free
00110 }
00111
00112 if (!faacEncSetConfiguration(s->faac_handle, faac_cfg)) {
00113 av_log(avctx, AV_LOG_ERROR, "libfaac doesn't support this output format!\n");
00114 return -1;
00115 }
00116
00117 return 0;
00118 }
00119
00120 static int Faac_encode_frame(AVCodecContext *avctx,
00121 unsigned char *frame, int buf_size, void *data)
00122 {
00123 FaacAudioContext *s = avctx->priv_data;
00124 int bytes_written;
00125
00126 bytes_written = faacEncEncode(s->faac_handle,
00127 data,
00128 avctx->frame_size * avctx->channels,
00129 frame,
00130 buf_size);
00131
00132 return bytes_written;
00133 }
00134
00135 static int Faac_encode_close(AVCodecContext *avctx)
00136 {
00137 FaacAudioContext *s = avctx->priv_data;
00138
00139 av_freep(&avctx->coded_frame);
00140 av_freep(&avctx->extradata);
00141
00142 faacEncClose(s->faac_handle);
00143 return 0;
00144 }
00145
00146 AVCodec libfaac_encoder = {
00147 "libfaac",
00148 CODEC_TYPE_AUDIO,
00149 CODEC_ID_AAC,
00150 sizeof(FaacAudioContext),
00151 Faac_encode_init,
00152 Faac_encode_frame,
00153 Faac_encode_close
00154 };