3 * Copyright (c) 2010 Martin Storsjo
5 * This file is part of Libav.
7 * Libav 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 * Libav 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 Libav; 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 #if FF_API_OLD_ENCODE_AUDIO
51 av_freep(&avctx
->coded_frame
);
53 av_freep(&avctx
->extradata
);
54 ff_af_queue_close(&s
->afq
);
55 av_freep(&s
->end_buffer
);
60 static av_cold
int aac_encode_init(AVCodecContext
*avctx
)
62 AACContext
*s
= avctx
->priv_data
;
63 AACENC_PARAM params
= { 0 };
66 #if FF_API_OLD_ENCODE_AUDIO
67 avctx
->coded_frame
= avcodec_alloc_frame();
68 if (!avctx
->coded_frame
)
69 return AVERROR(ENOMEM
);
71 avctx
->frame_size
= FRAME_SIZE
;
72 avctx
->delay
= ENC_DELAY
;
74 ff_af_queue_init(avctx
, &s
->afq
);
76 s
->end_buffer
= av_mallocz(avctx
->frame_size
* avctx
->channels
* 2);
78 ret
= AVERROR(ENOMEM
);
82 voGetAACEncAPI(&s
->codec_api
);
84 s
->mem_operator
.Alloc
= cmnMemAlloc
;
85 s
->mem_operator
.Copy
= cmnMemCopy
;
86 s
->mem_operator
.Free
= cmnMemFree
;
87 s
->mem_operator
.Set
= cmnMemSet
;
88 s
->mem_operator
.Check
= cmnMemCheck
;
89 s
->user_data
.memflag
= VO_IMF_USERMEMOPERATOR
;
90 s
->user_data
.memData
= &s
->mem_operator
;
91 s
->codec_api
.Init(&s
->handle
, VO_AUDIO_CodingAAC
, &s
->user_data
);
93 params
.sampleRate
= avctx
->sample_rate
;
94 params
.bitRate
= avctx
->bit_rate
;
95 params
.nChannels
= avctx
->channels
;
96 params
.adtsUsed
= !(avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
);
97 if (s
->codec_api
.SetParam(s
->handle
, VO_PID_AAC_ENCPARAM
, ¶ms
)
99 av_log(avctx
, AV_LOG_ERROR
, "Unable to set encoding parameters\n");
100 ret
= AVERROR(EINVAL
);
104 for (index
= 0; index
< 16; index
++)
105 if (avctx
->sample_rate
== avpriv_mpeg4audio_sample_rates
[index
])
108 av_log(avctx
, AV_LOG_ERROR
, "Unsupported sample rate %d\n",
110 ret
= AVERROR(ENOSYS
);
113 if (avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
) {
114 avctx
->extradata_size
= 2;
115 avctx
->extradata
= av_mallocz(avctx
->extradata_size
+
116 FF_INPUT_BUFFER_PADDING_SIZE
);
117 if (!avctx
->extradata
) {
118 ret
= AVERROR(ENOMEM
);
122 avctx
->extradata
[0] = 0x02 << 3 | index
>> 1;
123 avctx
->extradata
[1] = (index
& 0x01) << 7 | avctx
->channels
<< 3;
127 aac_encode_close(avctx
);
131 static int aac_encode_frame(AVCodecContext
*avctx
, AVPacket
*avpkt
,
132 const AVFrame
*frame
, int *got_packet_ptr
)
134 AACContext
*s
= avctx
->priv_data
;
135 VO_CODECBUFFER input
= { 0 }, output
= { 0 };
136 VO_AUDIO_OUTPUTINFO output_info
= { { 0 } };
140 /* handle end-of-stream small frame and flushing */
142 if (s
->last_frame
<= 0)
144 if (s
->last_samples
> 0 && s
->last_samples
< ENC_DELAY
- FRAME_SIZE
) {
149 memset(s
->end_buffer
, 0, 2 * avctx
->channels
* avctx
->frame_size
);
150 samples
= s
->end_buffer
;
152 if (frame
->nb_samples
< avctx
->frame_size
) {
153 s
->last_samples
= frame
->nb_samples
;
154 memcpy(s
->end_buffer
, frame
->data
[0], 2 * avctx
->channels
* frame
->nb_samples
);
155 samples
= s
->end_buffer
;
157 samples
= (VO_PBYTE
)frame
->data
[0];
159 /* add current frame to the queue */
160 if ((ret
= ff_af_queue_add(&s
->afq
, frame
)) < 0)
164 if ((ret
= ff_alloc_packet(avpkt
, FFMAX(8192, 768 * avctx
->channels
)))) {
165 av_log(avctx
, AV_LOG_ERROR
, "Error getting output packet\n");
169 input
.Buffer
= samples
;
170 input
.Length
= 2 * avctx
->channels
* avctx
->frame_size
;
171 output
.Buffer
= avpkt
->data
;
172 output
.Length
= avpkt
->size
;
174 s
->codec_api
.SetInputData(s
->handle
, &input
);
175 if (s
->codec_api
.GetOutputData(s
->handle
, &output
, &output_info
)
177 av_log(avctx
, AV_LOG_ERROR
, "Unable to encode frame\n");
178 return AVERROR(EINVAL
);
181 /* Get the next frame pts/duration */
182 ff_af_queue_remove(&s
->afq
, avctx
->frame_size
, &avpkt
->pts
,
185 avpkt
->size
= output
.Length
;
190 AVCodec ff_libvo_aacenc_encoder
= {
191 .name
= "libvo_aacenc",
192 .type
= AVMEDIA_TYPE_AUDIO
,
193 .id
= AV_CODEC_ID_AAC
,
194 .priv_data_size
= sizeof(AACContext
),
195 .init
= aac_encode_init
,
196 .encode2
= aac_encode_frame
,
197 .close
= aac_encode_close
,
198 .capabilities
= CODEC_CAP_SMALL_LAST_FRAME
| CODEC_CAP_DELAY
,
199 .sample_fmts
= (const enum AVSampleFormat
[]){ AV_SAMPLE_FMT_S16
,
200 AV_SAMPLE_FMT_NONE
},
201 .long_name
= NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"),