2 * Interface to libaacplus for aac+ (sbr+ps) encoding
3 * Copyright (c) 2010 tipok <piratfm@gmail.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 libaacplus for aac+ (sbr+ps) encoding.
32 typedef struct aacPlusAudioContext
{
33 aacplusEncHandle aacplus_handle
;
34 unsigned long max_output_bytes
;
35 unsigned long samples_input
;
36 } aacPlusAudioContext
;
38 static av_cold
int aacPlus_encode_init(AVCodecContext
*avctx
)
40 aacPlusAudioContext
*s
= avctx
->priv_data
;
41 aacplusEncConfiguration
*aacplus_cfg
;
43 /* number of channels */
44 if (avctx
->channels
< 1 || avctx
->channels
> 2) {
45 av_log(avctx
, AV_LOG_ERROR
, "encoding %d channel(s) is not allowed\n", avctx
->channels
);
46 return AVERROR(EINVAL
);
49 if (avctx
->profile
!= FF_PROFILE_AAC_LOW
&& avctx
->profile
!= FF_PROFILE_UNKNOWN
) {
50 av_log(avctx
, AV_LOG_ERROR
, "invalid AAC profile: %d, only LC supported\n", avctx
->profile
);
51 return AVERROR(EINVAL
);
54 s
->aacplus_handle
= aacplusEncOpen(avctx
->sample_rate
, avctx
->channels
,
55 &s
->samples_input
, &s
->max_output_bytes
);
56 if (!s
->aacplus_handle
) {
57 av_log(avctx
, AV_LOG_ERROR
, "can't open encoder\n");
58 return AVERROR(EINVAL
);
61 /* check aacplus version */
62 aacplus_cfg
= aacplusEncGetCurrentConfiguration(s
->aacplus_handle
);
64 aacplus_cfg
->bitRate
= avctx
->bit_rate
;
65 aacplus_cfg
->bandWidth
= avctx
->cutoff
;
66 aacplus_cfg
->outputFormat
= !(avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
);
67 aacplus_cfg
->inputFormat
= avctx
->sample_fmt
== AV_SAMPLE_FMT_FLT
? AACPLUS_INPUT_FLOAT
: AACPLUS_INPUT_16BIT
;
68 if (!aacplusEncSetConfiguration(s
->aacplus_handle
, aacplus_cfg
)) {
69 av_log(avctx
, AV_LOG_ERROR
, "libaacplus doesn't support this output format!\n");
70 return AVERROR(EINVAL
);
73 avctx
->frame_size
= s
->samples_input
/ avctx
->channels
;
75 /* Set decoder specific info */
76 avctx
->extradata_size
= 0;
77 if (avctx
->flags
& CODEC_FLAG_GLOBAL_HEADER
) {
79 unsigned char *buffer
= NULL
;
80 unsigned long decoder_specific_info_size
;
82 if (aacplusEncGetDecoderSpecificInfo(s
->aacplus_handle
, &buffer
,
83 &decoder_specific_info_size
) == 1) {
84 avctx
->extradata
= av_malloc(decoder_specific_info_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
85 avctx
->extradata_size
= decoder_specific_info_size
;
86 memcpy(avctx
->extradata
, buffer
, avctx
->extradata_size
);
93 static int aacPlus_encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
94 const AVFrame
*frame
, int *got_packet
)
96 aacPlusAudioContext
*s
= avctx
->priv_data
;
97 int32_t *input_buffer
= (int32_t *)frame
->data
[0];
100 if ((ret
= ff_alloc_packet2(avctx
, pkt
, s
->max_output_bytes
)) < 0)
103 pkt
->size
= aacplusEncEncode(s
->aacplus_handle
, input_buffer
,
104 s
->samples_input
, pkt
->data
, pkt
->size
);
106 pkt
->pts
= frame
->pts
;
110 static av_cold
int aacPlus_encode_close(AVCodecContext
*avctx
)
112 aacPlusAudioContext
*s
= avctx
->priv_data
;
114 av_freep(&avctx
->extradata
);
115 aacplusEncClose(s
->aacplus_handle
);
120 static const AVProfile profiles
[] = {
121 { FF_PROFILE_AAC_LOW
, "LC" },
122 { FF_PROFILE_UNKNOWN
},
125 AVCodec ff_libaacplus_encoder
= {
126 .name
= "libaacplus",
127 .long_name
= NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"),
128 .type
= AVMEDIA_TYPE_AUDIO
,
129 .id
= AV_CODEC_ID_AAC
,
130 .priv_data_size
= sizeof(aacPlusAudioContext
),
131 .init
= aacPlus_encode_init
,
132 .encode2
= aacPlus_encode_frame
,
133 .close
= aacPlus_encode_close
,
134 .sample_fmts
= (const enum AVSampleFormat
[]){ AV_SAMPLE_FMT_S16
,
136 AV_SAMPLE_FMT_NONE
},
137 .profiles
= profiles
,
138 .channel_layouts
= (const uint64_t[]) { AV_CH_LAYOUT_MONO
,