00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <vo-aacenc/voAAC.h>
00023 #include <vo-aacenc/cmnMemory.h>
00024
00025 #include "avcodec.h"
00026 #include "audio_frame_queue.h"
00027 #include "internal.h"
00028 #include "mpeg4audio.h"
00029
00030 #define FRAME_SIZE 1024
00031 #define ENC_DELAY 1600
00032
00033 typedef struct AACContext {
00034 VO_AUDIO_CODECAPI codec_api;
00035 VO_HANDLE handle;
00036 VO_MEM_OPERATOR mem_operator;
00037 VO_CODEC_INIT_USERDATA user_data;
00038 VO_PBYTE end_buffer;
00039 AudioFrameQueue afq;
00040 int last_frame;
00041 int last_samples;
00042 } AACContext;
00043
00044
00045 static int aac_encode_close(AVCodecContext *avctx)
00046 {
00047 AACContext *s = avctx->priv_data;
00048
00049 s->codec_api.Uninit(s->handle);
00050 #if FF_API_OLD_ENCODE_AUDIO
00051 av_freep(&avctx->coded_frame);
00052 #endif
00053 av_freep(&avctx->extradata);
00054 ff_af_queue_close(&s->afq);
00055 av_freep(&s->end_buffer);
00056
00057 return 0;
00058 }
00059
00060 static av_cold int aac_encode_init(AVCodecContext *avctx)
00061 {
00062 AACContext *s = avctx->priv_data;
00063 AACENC_PARAM params = { 0 };
00064 int index, ret;
00065
00066 #if FF_API_OLD_ENCODE_AUDIO
00067 avctx->coded_frame = avcodec_alloc_frame();
00068 if (!avctx->coded_frame)
00069 return AVERROR(ENOMEM);
00070 #endif
00071 avctx->frame_size = FRAME_SIZE;
00072 avctx->delay = ENC_DELAY;
00073 s->last_frame = 2;
00074 ff_af_queue_init(avctx, &s->afq);
00075
00076 s->end_buffer = av_mallocz(avctx->frame_size * avctx->channels * 2);
00077 if (!s->end_buffer) {
00078 ret = AVERROR(ENOMEM);
00079 goto error;
00080 }
00081
00082 voGetAACEncAPI(&s->codec_api);
00083
00084 s->mem_operator.Alloc = cmnMemAlloc;
00085 s->mem_operator.Copy = cmnMemCopy;
00086 s->mem_operator.Free = cmnMemFree;
00087 s->mem_operator.Set = cmnMemSet;
00088 s->mem_operator.Check = cmnMemCheck;
00089 s->user_data.memflag = VO_IMF_USERMEMOPERATOR;
00090 s->user_data.memData = &s->mem_operator;
00091 s->codec_api.Init(&s->handle, VO_AUDIO_CodingAAC, &s->user_data);
00092
00093 params.sampleRate = avctx->sample_rate;
00094 params.bitRate = avctx->bit_rate;
00095 params.nChannels = avctx->channels;
00096 params.adtsUsed = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER);
00097 if (s->codec_api.SetParam(s->handle, VO_PID_AAC_ENCPARAM, ¶ms)
00098 != VO_ERR_NONE) {
00099 av_log(avctx, AV_LOG_ERROR, "Unable to set encoding parameters\n");
00100 ret = AVERROR(EINVAL);
00101 goto error;
00102 }
00103
00104 for (index = 0; index < 16; index++)
00105 if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[index])
00106 break;
00107 if (index == 16) {
00108 av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n",
00109 avctx->sample_rate);
00110 ret = AVERROR(ENOSYS);
00111 goto error;
00112 }
00113 if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
00114 avctx->extradata_size = 2;
00115 avctx->extradata = av_mallocz(avctx->extradata_size +
00116 FF_INPUT_BUFFER_PADDING_SIZE);
00117 if (!avctx->extradata) {
00118 ret = AVERROR(ENOMEM);
00119 goto error;
00120 }
00121
00122 avctx->extradata[0] = 0x02 << 3 | index >> 1;
00123 avctx->extradata[1] = (index & 0x01) << 7 | avctx->channels << 3;
00124 }
00125 return 0;
00126 error:
00127 aac_encode_close(avctx);
00128 return ret;
00129 }
00130
00131 static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
00132 const AVFrame *frame, int *got_packet_ptr)
00133 {
00134 AACContext *s = avctx->priv_data;
00135 VO_CODECBUFFER input = { 0 }, output = { 0 };
00136 VO_AUDIO_OUTPUTINFO output_info = { { 0 } };
00137 VO_PBYTE samples;
00138 int ret;
00139
00140
00141 if (!frame) {
00142 if (s->last_frame <= 0)
00143 return 0;
00144 if (s->last_samples > 0 && s->last_samples < ENC_DELAY - FRAME_SIZE) {
00145 s->last_samples = 0;
00146 s->last_frame--;
00147 }
00148 s->last_frame--;
00149 memset(s->end_buffer, 0, 2 * avctx->channels * avctx->frame_size);
00150 samples = s->end_buffer;
00151 } else {
00152 if (frame->nb_samples < avctx->frame_size) {
00153 s->last_samples = frame->nb_samples;
00154 memcpy(s->end_buffer, frame->data[0], 2 * avctx->channels * frame->nb_samples);
00155 samples = s->end_buffer;
00156 } else {
00157 samples = (VO_PBYTE)frame->data[0];
00158 }
00159
00160 if ((ret = ff_af_queue_add(&s->afq, frame) < 0))
00161 return ret;
00162 }
00163
00164 if ((ret = ff_alloc_packet2(avctx, avpkt, FFMAX(8192, 768 * avctx->channels))))
00165 return ret;
00166
00167 input.Buffer = samples;
00168 input.Length = 2 * avctx->channels * avctx->frame_size;
00169 output.Buffer = avpkt->data;
00170 output.Length = avpkt->size;
00171
00172 s->codec_api.SetInputData(s->handle, &input);
00173 if (s->codec_api.GetOutputData(s->handle, &output, &output_info)
00174 != VO_ERR_NONE) {
00175 av_log(avctx, AV_LOG_ERROR, "Unable to encode frame\n");
00176 return AVERROR(EINVAL);
00177 }
00178
00179
00180 ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
00181 &avpkt->duration);
00182
00183 avpkt->size = output.Length;
00184 *got_packet_ptr = 1;
00185 return 0;
00186 }
00187
00188 AVCodec ff_libvo_aacenc_encoder = {
00189 .name = "libvo_aacenc",
00190 .type = AVMEDIA_TYPE_AUDIO,
00191 .id = AV_CODEC_ID_AAC,
00192 .priv_data_size = sizeof(AACContext),
00193 .init = aac_encode_init,
00194 .encode2 = aac_encode_frame,
00195 .close = aac_encode_close,
00196 .supported_samplerates = avpriv_mpeg4audio_sample_rates,
00197 .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
00198 .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
00199 AV_SAMPLE_FMT_NONE },
00200 .long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"),
00201 };