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 <aacplus.h>
00029
00030 typedef struct aacPlusAudioContext {
00031 aacplusEncHandle aacplus_handle;
00032 } aacPlusAudioContext;
00033
00034 static av_cold int aacPlus_encode_init(AVCodecContext *avctx)
00035 {
00036 aacPlusAudioContext *s = avctx->priv_data;
00037 aacplusEncConfiguration *aacplus_cfg;
00038 unsigned long samples_input, max_bytes_output;
00039
00040
00041 if (avctx->channels < 1 || avctx->channels > 2) {
00042 av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels);
00043 return -1;
00044 }
00045
00046 s->aacplus_handle = aacplusEncOpen(avctx->sample_rate,
00047 avctx->channels,
00048 &samples_input, &max_bytes_output);
00049 if(!s->aacplus_handle) {
00050 av_log(avctx, AV_LOG_ERROR, "can't open encoder\n");
00051 return -1;
00052 }
00053
00054
00055 aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle);
00056
00057
00058 if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) {
00059 av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile);
00060 aacplusEncClose(s->aacplus_handle);
00061 return -1;
00062 }
00063
00064 aacplus_cfg->bitRate = avctx->bit_rate;
00065 aacplus_cfg->bandWidth = avctx->cutoff;
00066 aacplus_cfg->outputFormat = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER);
00067 aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT;
00068 if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) {
00069 av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n");
00070 return -1;
00071 }
00072
00073 avctx->frame_size = samples_input / avctx->channels;
00074
00075 avctx->coded_frame= avcodec_alloc_frame();
00076 avctx->coded_frame->key_frame= 1;
00077
00078
00079 avctx->extradata_size = 0;
00080 if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
00081
00082 unsigned char *buffer = NULL;
00083 unsigned long decoder_specific_info_size;
00084
00085 if (aacplusEncGetDecoderSpecificInfo(s->aacplus_handle, &buffer,
00086 &decoder_specific_info_size) == 1) {
00087 avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE);
00088 avctx->extradata_size = decoder_specific_info_size;
00089 memcpy(avctx->extradata, buffer, avctx->extradata_size);
00090 }
00091 #undef free
00092 free(buffer);
00093 #define free please_use_av_free
00094 }
00095 return 0;
00096 }
00097
00098 static int aacPlus_encode_frame(AVCodecContext *avctx,
00099 unsigned char *frame, int buf_size, void *data)
00100 {
00101 aacPlusAudioContext *s = avctx->priv_data;
00102 int bytes_written;
00103
00104 bytes_written = aacplusEncEncode(s->aacplus_handle,
00105 data,
00106 avctx->frame_size * avctx->channels,
00107 frame,
00108 buf_size);
00109
00110 return bytes_written;
00111 }
00112
00113 static av_cold int aacPlus_encode_close(AVCodecContext *avctx)
00114 {
00115 aacPlusAudioContext *s = avctx->priv_data;
00116
00117 av_freep(&avctx->coded_frame);
00118 av_freep(&avctx->extradata);
00119
00120 aacplusEncClose(s->aacplus_handle);
00121 return 0;
00122 }
00123
00124 AVCodec ff_libaacplus_encoder = {
00125 "libaacplus",
00126 AVMEDIA_TYPE_AUDIO,
00127 CODEC_ID_AAC,
00128 sizeof(aacPlusAudioContext),
00129 aacPlus_encode_init,
00130 aacPlus_encode_frame,
00131 aacPlus_encode_close,
00132 .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
00133 .long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"),
00134 };