Libav 0.7.1
|
00001 /* 00002 * AAC encoder wrapper 00003 * Copyright (c) 2010 Martin Storsjo 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include <vo-aacenc/voAAC.h> 00023 #include <vo-aacenc/cmnMemory.h> 00024 00025 #include "avcodec.h" 00026 #include "mpeg4audio.h" 00027 00028 typedef struct AACContext { 00029 VO_AUDIO_CODECAPI codec_api; 00030 VO_HANDLE handle; 00031 VO_MEM_OPERATOR mem_operator; 00032 VO_CODEC_INIT_USERDATA user_data; 00033 } AACContext; 00034 00035 static av_cold int aac_encode_init(AVCodecContext *avctx) 00036 { 00037 AACContext *s = avctx->priv_data; 00038 AACENC_PARAM params = { 0 }; 00039 int index; 00040 00041 avctx->coded_frame = avcodec_alloc_frame(); 00042 avctx->frame_size = 1024; 00043 00044 voGetAACEncAPI(&s->codec_api); 00045 00046 s->mem_operator.Alloc = cmnMemAlloc; 00047 s->mem_operator.Copy = cmnMemCopy; 00048 s->mem_operator.Free = cmnMemFree; 00049 s->mem_operator.Set = cmnMemSet; 00050 s->mem_operator.Check = cmnMemCheck; 00051 s->user_data.memflag = VO_IMF_USERMEMOPERATOR; 00052 s->user_data.memData = &s->mem_operator; 00053 s->codec_api.Init(&s->handle, VO_AUDIO_CodingAAC, &s->user_data); 00054 00055 params.sampleRate = avctx->sample_rate; 00056 params.bitRate = avctx->bit_rate; 00057 params.nChannels = avctx->channels; 00058 params.adtsUsed = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER); 00059 if (s->codec_api.SetParam(s->handle, VO_PID_AAC_ENCPARAM, ¶ms) 00060 != VO_ERR_NONE) { 00061 av_log(avctx, AV_LOG_ERROR, "Unable to set encoding parameters\n"); 00062 return AVERROR(EINVAL); 00063 } 00064 00065 for (index = 0; index < 16; index++) 00066 if (avctx->sample_rate == ff_mpeg4audio_sample_rates[index]) 00067 break; 00068 if (index == 16) { 00069 av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n", 00070 avctx->sample_rate); 00071 return AVERROR(ENOSYS); 00072 } 00073 if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { 00074 avctx->extradata_size = 2; 00075 avctx->extradata = av_mallocz(avctx->extradata_size + 00076 FF_INPUT_BUFFER_PADDING_SIZE); 00077 if (!avctx->extradata) 00078 return AVERROR(ENOMEM); 00079 00080 avctx->extradata[0] = 0x02 << 3 | index >> 1; 00081 avctx->extradata[1] = (index & 0x01) << 7 | avctx->channels << 3; 00082 } 00083 return 0; 00084 } 00085 00086 static int aac_encode_close(AVCodecContext *avctx) 00087 { 00088 AACContext *s = avctx->priv_data; 00089 00090 s->codec_api.Uninit(s->handle); 00091 av_freep(&avctx->coded_frame); 00092 00093 return 0; 00094 } 00095 00096 static int aac_encode_frame(AVCodecContext *avctx, 00097 unsigned char *frame/*out*/, 00098 int buf_size, void *data/*in*/) 00099 { 00100 AACContext *s = avctx->priv_data; 00101 VO_CODECBUFFER input = { 0 }, output = { 0 }; 00102 VO_AUDIO_OUTPUTINFO output_info = { { 0 } }; 00103 00104 input.Buffer = data; 00105 input.Length = 2 * avctx->channels * avctx->frame_size; 00106 output.Buffer = frame; 00107 output.Length = buf_size; 00108 00109 s->codec_api.SetInputData(s->handle, &input); 00110 if (s->codec_api.GetOutputData(s->handle, &output, &output_info) 00111 != VO_ERR_NONE) { 00112 av_log(avctx, AV_LOG_ERROR, "Unable to encode frame\n"); 00113 return AVERROR(EINVAL); 00114 } 00115 return output.Length; 00116 } 00117 00118 AVCodec ff_libvo_aacenc_encoder = { 00119 "libvo_aacenc", 00120 AVMEDIA_TYPE_AUDIO, 00121 CODEC_ID_AAC, 00122 sizeof(AACContext), 00123 aac_encode_init, 00124 aac_encode_frame, 00125 aac_encode_close, 00126 NULL, 00127 .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, 00128 .long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AAC"), 00129 }; 00130