2 * Interface to libfaac for aac encoding
3 * Copyright (c) 2002 Gildas Bazin <gbazin@netcourrier.com>
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
24 * Interface to libfaac for aac encoding.
29 #include "libavutil/channel_layout.h"
30 #include "libavutil/common.h"
32 #include "audio_frame_queue.h"
36 /* libfaac has an encoder delay of 1024 samples */
37 #define FAAC_DELAY_SAMPLES 1024
39 typedef struct FaacAudioContext
{
40 faacEncHandle faac_handle
;
44 static av_cold
int Faac_encode_close(AVCodecContext
*avctx
)
46 FaacAudioContext
*s
= avctx
->priv_data
;
48 av_freep(&avctx
->extradata
);
49 ff_af_queue_close(&s
->afq
);
52 faacEncClose(s
->faac_handle
);
57 static const int channel_maps
[][6] = {
58 { 2, 0, 1 }, //< C L R
59 { 2, 0, 1, 3 }, //< C L R Cs
60 { 2, 0, 1, 3, 4 }, //< C L R Ls Rs
61 { 2, 0, 1, 4, 5, 3 }, //< C L R Ls Rs LFE
64 static av_cold
int Faac_encode_init(AVCodecContext
*avctx
)
66 FaacAudioContext
*s
= avctx
->priv_data
;
67 faacEncConfigurationPtr faac_cfg
;
68 unsigned long samples_input
, max_bytes_output
;
71 /* number of channels */
72 if (avctx
->channels
< 1 || avctx
->channels
> 6) {
73 av_log(avctx
, AV_LOG_ERROR
, "encoding %d channel(s) is not allowed\n", avctx
->channels
);
74 ret
= AVERROR(EINVAL
);
78 s
->faac_handle
= faacEncOpen(avctx
->sample_rate
,
80 &samples_input
, &max_bytes_output
);
81 if (!s
->faac_handle
) {
82 av_log(avctx
, AV_LOG_ERROR
, "error in faacEncOpen()\n");
83 ret
= AVERROR_UNKNOWN
;
87 /* check faac version */
88 faac_cfg
= faacEncGetCurrentConfiguration(s
->faac_handle
);
89 if (faac_cfg
->version
!= FAAC_CFG_VERSION
) {
90 av_log(avctx
, AV_LOG_ERROR
, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION
, faac_cfg
->version
);
91 ret
= AVERROR(EINVAL
);
95 /* put the options in the configuration struct */
96 switch(avctx
->profile
) {
97 case FF_PROFILE_AAC_MAIN
:
98 faac_cfg
->aacObjectType
= MAIN
;
100 case FF_PROFILE_UNKNOWN
:
101 case FF_PROFILE_AAC_LOW
:
102 faac_cfg
->aacObjectType
= LOW
;
104 case FF_PROFILE_AAC_SSR
:
105 faac_cfg
->aacObjectType
= SSR
;
107 case FF_PROFILE_AAC_LTP
:
108 faac_cfg
->aacObjectType
= LTP
;
111 av_log(avctx
, AV_LOG_ERROR
, "invalid AAC profile\n");
112 ret
= AVERROR(EINVAL
);
115 faac_cfg
->mpegVersion
= MPEG4
;
116 faac_cfg
->useTns
= 0;
117 faac_cfg
->allowMidside
= 1;
118 faac_cfg
->bitRate
= avctx
->bit_rate
/ avctx
->channels
;
119 faac_cfg
->bandWidth
= avctx
->cutoff
;
120 if(avctx
->flags
& CODEC_FLAG_QSCALE
) {
121 faac_cfg
->bitRate
= 0;
122 faac_cfg
->quantqual
= avctx
->global_quality
/ FF_QP2LAMBDA
;
124 faac_cfg
->outputFormat
= 1;
125 faac_cfg
->inputFormat
= FAAC_INPUT_16BIT
;
126 if (avctx
->channels
> 2)
127 memcpy(faac_cfg
->channel_map
, channel_maps
[avctx
->channels
-3],
128 avctx
->channels
* sizeof(int));
130 avctx
->frame_size
= samples_input
/ avctx
->channels
;
132 /* Set decoder specific info */
133 avctx
->extradata_size
= 0;
134 if (avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
) {
136 unsigned char *buffer
= NULL
;
137 unsigned long decoder_specific_info_size
;
139 if (!faacEncGetDecoderSpecificInfo(s
->faac_handle
, &buffer
,
140 &decoder_specific_info_size
)) {
141 avctx
->extradata
= av_malloc(decoder_specific_info_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
142 if (!avctx
->extradata
) {
143 ret
= AVERROR(ENOMEM
);
146 avctx
->extradata_size
= decoder_specific_info_size
;
147 memcpy(avctx
->extradata
, buffer
, avctx
->extradata_size
);
148 faac_cfg
->outputFormat
= 0;
153 if (!faacEncSetConfiguration(s
->faac_handle
, faac_cfg
)) {
155 for (i
= avctx
->bit_rate
/1000; i
; i
--) {
156 faac_cfg
->bitRate
= 1000*i
/ avctx
->channels
;
157 if (faacEncSetConfiguration(s
->faac_handle
, faac_cfg
))
161 av_log(avctx
, AV_LOG_ERROR
, "libfaac doesn't support this output format!\n");
162 ret
= AVERROR(EINVAL
);
165 avctx
->bit_rate
= 1000*i
;
166 av_log(avctx
, AV_LOG_WARNING
, "libfaac doesn't support the specified bitrate, using %dkbit/s instead\n", i
);
170 avctx
->initial_padding
= FAAC_DELAY_SAMPLES
;
171 ff_af_queue_init(avctx
, &s
->afq
);
175 Faac_encode_close(avctx
);
179 static int Faac_encode_frame(AVCodecContext
*avctx
, AVPacket
*avpkt
,
180 const AVFrame
*frame
, int *got_packet_ptr
)
182 FaacAudioContext
*s
= avctx
->priv_data
;
183 int bytes_written
, ret
;
184 int num_samples
= frame
? frame
->nb_samples
: 0;
185 void *samples
= frame
? frame
->data
[0] : NULL
;
187 if ((ret
= ff_alloc_packet2(avctx
, avpkt
, (7 + 768) * avctx
->channels
)) < 0)
190 bytes_written
= faacEncEncode(s
->faac_handle
, samples
,
191 num_samples
* avctx
->channels
,
192 avpkt
->data
, avpkt
->size
);
193 if (bytes_written
< 0) {
194 av_log(avctx
, AV_LOG_ERROR
, "faacEncEncode() error\n");
195 return bytes_written
;
198 /* add current frame to the queue */
200 if ((ret
= ff_af_queue_add(&s
->afq
, frame
)) < 0)
207 /* Get the next frame pts/duration */
208 ff_af_queue_remove(&s
->afq
, avctx
->frame_size
, &avpkt
->pts
,
211 avpkt
->size
= bytes_written
;
216 static const AVProfile profiles
[] = {
217 { FF_PROFILE_AAC_MAIN
, "Main" },
218 { FF_PROFILE_AAC_LOW
, "LC" },
219 { FF_PROFILE_AAC_SSR
, "SSR" },
220 { FF_PROFILE_AAC_LTP
, "LTP" },
221 { FF_PROFILE_UNKNOWN
},
224 static const uint64_t faac_channel_layouts
[] = {
227 AV_CH_LAYOUT_SURROUND
,
228 AV_CH_LAYOUT_4POINT0
,
229 AV_CH_LAYOUT_5POINT0_BACK
,
230 AV_CH_LAYOUT_5POINT1_BACK
,
234 AVCodec ff_libfaac_encoder
= {
236 .long_name
= NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Coding)"),
237 .type
= AVMEDIA_TYPE_AUDIO
,
238 .id
= AV_CODEC_ID_AAC
,
239 .priv_data_size
= sizeof(FaacAudioContext
),
240 .init
= Faac_encode_init
,
241 .encode2
= Faac_encode_frame
,
242 .close
= Faac_encode_close
,
243 .capabilities
= CODEC_CAP_SMALL_LAST_FRAME
| CODEC_CAP_DELAY
,
244 .sample_fmts
= (const enum AVSampleFormat
[]){ AV_SAMPLE_FMT_S16
,
245 AV_SAMPLE_FMT_NONE
},
246 .profiles
= NULL_IF_CONFIG_SMALL(profiles
),
247 .channel_layouts
= faac_channel_layouts
,