]> git.sesse.net Git - ffmpeg/blob - libavcodec/libaacplus.c
eamad: release the reference frame on video size changes
[ffmpeg] / libavcodec / libaacplus.c
1 /*
2  * Interface to libaacplus for aac+ (sbr+ps) encoding
3  * Copyright (c) 2010 tipok <piratfm@gmail.com>
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21
22 /**
23  * @file
24  * Interface to libaacplus for aac+ (sbr+ps) encoding.
25  */
26
27 #include "avcodec.h"
28 #include <aacplus.h>
29
30 typedef struct aacPlusAudioContext {
31     aacplusEncHandle aacplus_handle;
32 } aacPlusAudioContext;
33
34 static av_cold int aacPlus_encode_init(AVCodecContext *avctx)
35 {
36     aacPlusAudioContext *s = avctx->priv_data;
37     aacplusEncConfiguration *aacplus_cfg;
38     unsigned long samples_input, max_bytes_output;
39
40     /* number of channels */
41     if (avctx->channels < 1 || avctx->channels > 2) {
42         av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels);
43         return -1;
44     }
45
46     s->aacplus_handle = aacplusEncOpen(avctx->sample_rate,
47                                  avctx->channels,
48                                  &samples_input, &max_bytes_output);
49     if(!s->aacplus_handle) {
50             av_log(avctx, AV_LOG_ERROR, "can't open encoder\n");
51             return -1;
52     }
53
54     /* check aacplus version */
55     aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle);
56
57     /* put the options in the configuration struct */
58     if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) {
59             av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile);
60             aacplusEncClose(s->aacplus_handle);
61             return -1;
62     }
63
64     aacplus_cfg->bitRate = avctx->bit_rate;
65     aacplus_cfg->bandWidth = avctx->cutoff;
66     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
67         aacplus_cfg->outputFormat = 0; //raw aac
68     }
69     aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT;
70     if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) {
71         av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n");
72         return -1;
73     }
74
75     avctx->frame_size = samples_input / avctx->channels;
76
77     avctx->coded_frame= avcodec_alloc_frame();
78     avctx->coded_frame->key_frame= 1;
79
80     /* Set decoder specific info */
81     avctx->extradata_size = 0;
82     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
83
84         unsigned char *buffer = NULL;
85         unsigned long decoder_specific_info_size;
86
87         if (aacplusEncGetDecoderSpecificInfo(s->aacplus_handle, &buffer,
88                                            &decoder_specific_info_size) == 1) {
89             avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE);
90             avctx->extradata_size = decoder_specific_info_size;
91             memcpy(avctx->extradata, buffer, avctx->extradata_size);
92         }
93 #undef free
94         free(buffer);
95 #define free please_use_av_free
96     }
97     return 0;
98 }
99
100 static int aacPlus_encode_frame(AVCodecContext *avctx,
101                              unsigned char *frame, int buf_size, void *data)
102 {
103     aacPlusAudioContext *s = avctx->priv_data;
104     int bytes_written;
105
106     bytes_written = aacplusEncEncode(s->aacplus_handle,
107                                   data,
108                                   avctx->frame_size * avctx->channels,
109                                   frame,
110                                   buf_size);
111
112     return bytes_written;
113 }
114
115 static av_cold int aacPlus_encode_close(AVCodecContext *avctx)
116 {
117     aacPlusAudioContext *s = avctx->priv_data;
118
119     av_freep(&avctx->coded_frame);
120     av_freep(&avctx->extradata);
121
122     aacplusEncClose(s->aacplus_handle);
123     return 0;
124 }
125
126 AVCodec ff_libaacplus_encoder = {
127     "libaacplus",
128     AVMEDIA_TYPE_AUDIO,
129     CODEC_ID_AAC,
130     sizeof(aacPlusAudioContext),
131     aacPlus_encode_init,
132     aacPlus_encode_frame,
133     aacPlus_encode_close,
134     .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
135     .long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"),
136 };