00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include <aacplus.h>
00028
00029 #include "avcodec.h"
00030 #include "internal.h"
00031
00032 typedef struct aacPlusAudioContext {
00033 aacplusEncHandle aacplus_handle;
00034 unsigned long max_output_bytes;
00035 unsigned long samples_input;
00036 } aacPlusAudioContext;
00037
00038 static av_cold int aacPlus_encode_init(AVCodecContext *avctx)
00039 {
00040 aacPlusAudioContext *s = avctx->priv_data;
00041 aacplusEncConfiguration *aacplus_cfg;
00042
00043
00044 if (avctx->channels < 1 || avctx->channels > 2) {
00045 av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels);
00046 return -1;
00047 }
00048
00049 s->aacplus_handle = aacplusEncOpen(avctx->sample_rate, avctx->channels,
00050 &s->samples_input, &s->max_output_bytes);
00051 if(!s->aacplus_handle) {
00052 av_log(avctx, AV_LOG_ERROR, "can't open encoder\n");
00053 return -1;
00054 }
00055
00056
00057 aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle);
00058
00059
00060 if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) {
00061 av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile);
00062 aacplusEncClose(s->aacplus_handle);
00063 return -1;
00064 }
00065
00066 aacplus_cfg->bitRate = avctx->bit_rate;
00067 aacplus_cfg->bandWidth = avctx->cutoff;
00068 aacplus_cfg->outputFormat = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER);
00069 aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT;
00070 if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) {
00071 av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n");
00072 return -1;
00073 }
00074
00075 avctx->frame_size = s->samples_input / avctx->channels;
00076
00077 #if FF_API_OLD_ENCODE_AUDIO
00078 avctx->coded_frame= avcodec_alloc_frame();
00079 avctx->coded_frame->key_frame= 1;
00080 #endif
00081
00082
00083 avctx->extradata_size = 0;
00084 if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
00085
00086 unsigned char *buffer = NULL;
00087 unsigned long decoder_specific_info_size;
00088
00089 if (aacplusEncGetDecoderSpecificInfo(s->aacplus_handle, &buffer,
00090 &decoder_specific_info_size) == 1) {
00091 avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE);
00092 avctx->extradata_size = decoder_specific_info_size;
00093 memcpy(avctx->extradata, buffer, avctx->extradata_size);
00094 }
00095 #undef free
00096 free(buffer);
00097 #define free please_use_av_free
00098 }
00099 return 0;
00100 }
00101
00102 static int aacPlus_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
00103 const AVFrame *frame, int *got_packet)
00104 {
00105 aacPlusAudioContext *s = avctx->priv_data;
00106 int32_t *input_buffer = (int32_t *)frame->data[0];
00107 int ret;
00108
00109 if ((ret = ff_alloc_packet2(avctx, pkt, s->max_output_bytes)))
00110 return ret;
00111
00112 pkt->size = aacplusEncEncode(s->aacplus_handle, input_buffer,
00113 s->samples_input, pkt->data, pkt->size);
00114 *got_packet = 1;
00115 pkt->pts = frame->pts;
00116 return 0;
00117 }
00118
00119 static av_cold int aacPlus_encode_close(AVCodecContext *avctx)
00120 {
00121 aacPlusAudioContext *s = avctx->priv_data;
00122
00123 #if FF_API_OLD_ENCODE_AUDIO
00124 av_freep(&avctx->coded_frame);
00125 #endif
00126 av_freep(&avctx->extradata);
00127
00128 aacplusEncClose(s->aacplus_handle);
00129 return 0;
00130 }
00131
00132 AVCodec ff_libaacplus_encoder = {
00133 .name = "libaacplus",
00134 .type = AVMEDIA_TYPE_AUDIO,
00135 .id = AV_CODEC_ID_AAC,
00136 .priv_data_size = sizeof(aacPlusAudioContext),
00137 .init = aacPlus_encode_init,
00138 .encode2 = aacPlus_encode_frame,
00139 .close = aacPlus_encode_close,
00140 .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
00141 AV_SAMPLE_FMT_NONE },
00142 .long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"),
00143 };