3 * Copyright (c) 2010 Martin Storsjo
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <vo-aacenc/voAAC.h>
23 #include <vo-aacenc/cmnMemory.h>
26 #include "audio_frame_queue.h"
28 #include "mpeg4audio.h"
30 #define FRAME_SIZE 1024
31 #define ENC_DELAY 1600
33 typedef struct AACContext
{
34 VO_AUDIO_CODECAPI codec_api
;
36 VO_MEM_OPERATOR mem_operator
;
37 VO_CODEC_INIT_USERDATA user_data
;
45 static int aac_encode_close(AVCodecContext
*avctx
)
47 AACContext
*s
= avctx
->priv_data
;
49 s
->codec_api
.Uninit(s
->handle
);
50 av_freep(&avctx
->extradata
);
51 ff_af_queue_close(&s
->afq
);
52 av_freep(&s
->end_buffer
);
57 static av_cold
int aac_encode_init(AVCodecContext
*avctx
)
59 AACContext
*s
= avctx
->priv_data
;
60 AACENC_PARAM params
= { 0 };
63 avctx
->frame_size
= FRAME_SIZE
;
64 avctx
->initial_padding
= ENC_DELAY
;
66 ff_af_queue_init(avctx
, &s
->afq
);
68 s
->end_buffer
= av_mallocz(avctx
->frame_size
* avctx
->channels
* 2);
70 ret
= AVERROR(ENOMEM
);
74 voGetAACEncAPI(&s
->codec_api
);
76 s
->mem_operator
.Alloc
= cmnMemAlloc
;
77 s
->mem_operator
.Copy
= cmnMemCopy
;
78 s
->mem_operator
.Free
= cmnMemFree
;
79 s
->mem_operator
.Set
= cmnMemSet
;
80 s
->mem_operator
.Check
= cmnMemCheck
;
81 s
->user_data
.memflag
= VO_IMF_USERMEMOPERATOR
;
82 s
->user_data
.memData
= &s
->mem_operator
;
83 s
->codec_api
.Init(&s
->handle
, VO_AUDIO_CodingAAC
, &s
->user_data
);
85 params
.sampleRate
= avctx
->sample_rate
;
86 params
.bitRate
= avctx
->bit_rate
;
87 params
.nChannels
= avctx
->channels
;
88 params
.adtsUsed
= !(avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
);
89 if (s
->codec_api
.SetParam(s
->handle
, VO_PID_AAC_ENCPARAM
, ¶ms
)
91 av_log(avctx
, AV_LOG_ERROR
, "Unable to set encoding parameters\n");
92 ret
= AVERROR(EINVAL
);
96 for (index
= 0; index
< 16; index
++)
97 if (avctx
->sample_rate
== avpriv_mpeg4audio_sample_rates
[index
])
100 av_log(avctx
, AV_LOG_ERROR
, "Unsupported sample rate %d\n",
102 ret
= AVERROR(ENOSYS
);
105 if (avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
) {
106 avctx
->extradata_size
= 2;
107 avctx
->extradata
= av_mallocz(avctx
->extradata_size
+
108 FF_INPUT_BUFFER_PADDING_SIZE
);
109 if (!avctx
->extradata
) {
110 ret
= AVERROR(ENOMEM
);
114 avctx
->extradata
[0] = 0x02 << 3 | index
>> 1;
115 avctx
->extradata
[1] = (index
& 0x01) << 7 | avctx
->channels
<< 3;
119 aac_encode_close(avctx
);
123 static int aac_encode_frame(AVCodecContext
*avctx
, AVPacket
*avpkt
,
124 const AVFrame
*frame
, int *got_packet_ptr
)
126 AACContext
*s
= avctx
->priv_data
;
127 VO_CODECBUFFER input
= { 0 }, output
= { 0 };
128 VO_AUDIO_OUTPUTINFO output_info
= { { 0 } };
132 /* handle end-of-stream small frame and flushing */
134 if (s
->last_frame
<= 0)
136 if (s
->last_samples
> 0 && s
->last_samples
< ENC_DELAY
- FRAME_SIZE
) {
141 memset(s
->end_buffer
, 0, 2 * avctx
->channels
* avctx
->frame_size
);
142 samples
= s
->end_buffer
;
144 if (frame
->nb_samples
< avctx
->frame_size
) {
145 s
->last_samples
= frame
->nb_samples
;
146 memcpy(s
->end_buffer
, frame
->data
[0], 2 * avctx
->channels
* frame
->nb_samples
);
147 samples
= s
->end_buffer
;
149 samples
= (VO_PBYTE
)frame
->data
[0];
151 /* add current frame to the queue */
152 if ((ret
= ff_af_queue_add(&s
->afq
, frame
)) < 0)
156 if ((ret
= ff_alloc_packet2(avctx
, avpkt
, FFMAX(8192, 768 * avctx
->channels
))) < 0)
159 input
.Buffer
= samples
;
160 input
.Length
= 2 * avctx
->channels
* avctx
->frame_size
;
161 output
.Buffer
= avpkt
->data
;
162 output
.Length
= avpkt
->size
;
164 s
->codec_api
.SetInputData(s
->handle
, &input
);
165 if (s
->codec_api
.GetOutputData(s
->handle
, &output
, &output_info
)
167 av_log(avctx
, AV_LOG_ERROR
, "Unable to encode frame\n");
168 return AVERROR(EINVAL
);
171 /* Get the next frame pts/duration */
172 ff_af_queue_remove(&s
->afq
, avctx
->frame_size
, &avpkt
->pts
,
175 avpkt
->size
= output
.Length
;
180 /* duplicated from avpriv_mpeg4audio_sample_rates to avoid shared build
182 static const int mpeg4audio_sample_rates
[16] = {
183 96000, 88200, 64000, 48000, 44100, 32000,
184 24000, 22050, 16000, 12000, 11025, 8000, 7350
187 AVCodec ff_libvo_aacenc_encoder
= {
188 .name
= "libvo_aacenc",
189 .long_name
= NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"),
190 .type
= AVMEDIA_TYPE_AUDIO
,
191 .id
= AV_CODEC_ID_AAC
,
192 .priv_data_size
= sizeof(AACContext
),
193 .init
= aac_encode_init
,
194 .encode2
= aac_encode_frame
,
195 .close
= aac_encode_close
,
196 .supported_samplerates
= mpeg4audio_sample_rates
,
197 .capabilities
= CODEC_CAP_SMALL_LAST_FRAME
| CODEC_CAP_DELAY
,
198 .sample_fmts
= (const enum AVSampleFormat
[]){ AV_SAMPLE_FMT_S16
,
199 AV_SAMPLE_FMT_NONE
},