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
23 * @file libavcodec/libfaac.c
24 * Interface to libfaac for aac encoding.
30 typedef struct FaacAudioContext
{
31 faacEncHandle faac_handle
;
34 static av_cold
int Faac_encode_init(AVCodecContext
*avctx
)
36 FaacAudioContext
*s
= avctx
->priv_data
;
37 faacEncConfigurationPtr faac_cfg
;
38 unsigned long samples_input
, max_bytes_output
;
40 /* number of channels */
41 if (avctx
->channels
< 1 || avctx
->channels
> 6) {
42 av_log(avctx
, AV_LOG_ERROR
, "encoding %d channel(s) is not allowed\n", avctx
->channels
);
46 s
->faac_handle
= faacEncOpen(avctx
->sample_rate
,
48 &samples_input
, &max_bytes_output
);
50 /* check faac version */
51 faac_cfg
= faacEncGetCurrentConfiguration(s
->faac_handle
);
52 if (faac_cfg
->version
!= FAAC_CFG_VERSION
) {
53 av_log(avctx
, AV_LOG_ERROR
, "wrong libfaac version (compiled for: %d, using %d)\n", FAAC_CFG_VERSION
, faac_cfg
->version
);
54 faacEncClose(s
->faac_handle
);
58 /* put the options in the configuration struct */
59 switch(avctx
->profile
) {
60 case FF_PROFILE_AAC_MAIN
:
61 faac_cfg
->aacObjectType
= MAIN
;
63 case FF_PROFILE_UNKNOWN
:
64 case FF_PROFILE_AAC_LOW
:
65 faac_cfg
->aacObjectType
= LOW
;
67 case FF_PROFILE_AAC_SSR
:
68 faac_cfg
->aacObjectType
= SSR
;
70 case FF_PROFILE_AAC_LTP
:
71 faac_cfg
->aacObjectType
= LTP
;
74 av_log(avctx
, AV_LOG_ERROR
, "invalid AAC profile\n");
75 faacEncClose(s
->faac_handle
);
78 faac_cfg
->mpegVersion
= MPEG4
;
80 faac_cfg
->allowMidside
= 1;
81 faac_cfg
->bitRate
= avctx
->bit_rate
/ avctx
->channels
;
82 faac_cfg
->bandWidth
= avctx
->cutoff
;
83 if(avctx
->flags
& CODEC_FLAG_QSCALE
) {
84 faac_cfg
->bitRate
= 0;
85 faac_cfg
->quantqual
= avctx
->global_quality
/ FF_QP2LAMBDA
;
87 faac_cfg
->outputFormat
= 1;
88 faac_cfg
->inputFormat
= FAAC_INPUT_16BIT
;
90 avctx
->frame_size
= samples_input
/ avctx
->channels
;
92 avctx
->coded_frame
= avcodec_alloc_frame();
93 avctx
->coded_frame
->key_frame
= 1;
95 /* Set decoder specific info */
96 avctx
->extradata_size
= 0;
97 if (avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
) {
99 unsigned char *buffer
= NULL
;
100 unsigned long decoder_specific_info_size
;
102 if (!faacEncGetDecoderSpecificInfo(s
->faac_handle
, &buffer
,
103 &decoder_specific_info_size
)) {
104 avctx
->extradata
= av_malloc(decoder_specific_info_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
105 avctx
->extradata_size
= decoder_specific_info_size
;
106 memcpy(avctx
->extradata
, buffer
, avctx
->extradata_size
);
107 faac_cfg
->outputFormat
= 0;
111 #define free please_use_av_free
114 if (!faacEncSetConfiguration(s
->faac_handle
, faac_cfg
)) {
115 av_log(avctx
, AV_LOG_ERROR
, "libfaac doesn't support this output format!\n");
122 static int Faac_encode_frame(AVCodecContext
*avctx
,
123 unsigned char *frame
, int buf_size
, void *data
)
125 FaacAudioContext
*s
= avctx
->priv_data
;
128 bytes_written
= faacEncEncode(s
->faac_handle
,
130 avctx
->frame_size
* avctx
->channels
,
134 return bytes_written
;
137 static av_cold
int Faac_encode_close(AVCodecContext
*avctx
)
139 FaacAudioContext
*s
= avctx
->priv_data
;
141 av_freep(&avctx
->coded_frame
);
142 av_freep(&avctx
->extradata
);
144 faacEncClose(s
->faac_handle
);
148 AVCodec libfaac_encoder
= {
152 sizeof(FaacAudioContext
),
156 .sample_fmts
= (const enum SampleFormat
[]){SAMPLE_FMT_S16
,SAMPLE_FMT_NONE
},
157 .long_name
= NULL_IF_CONFIG_SMALL("libfaac AAC (Advanced Audio Codec)"),