libvo-aacenc.c
Go to the documentation of this file.
1 /*
2  * AAC encoder wrapper
3  * Copyright (c) 2010 Martin Storsjo
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 #include <vo-aacenc/voAAC.h>
23 #include <vo-aacenc/cmnMemory.h>
24 
25 #include "avcodec.h"
26 #include "audio_frame_queue.h"
27 #include "internal.h"
28 #include "mpeg4audio.h"
29 
30 #define FRAME_SIZE 1024
31 #define ENC_DELAY 1600
32 
33 typedef struct AACContext {
34  VO_AUDIO_CODECAPI codec_api;
35  VO_HANDLE handle;
36  VO_MEM_OPERATOR mem_operator;
37  VO_CODEC_INIT_USERDATA user_data;
38  VO_PBYTE end_buffer;
42 } AACContext;
43 
44 
46 {
47  AACContext *s = avctx->priv_data;
48 
49  s->codec_api.Uninit(s->handle);
50  av_freep(&avctx->extradata);
52  av_freep(&s->end_buffer);
53 
54  return 0;
55 }
56 
58 {
59  AACContext *s = avctx->priv_data;
60  AACENC_PARAM params = { 0 };
61  int index, ret;
62 
63  avctx->frame_size = FRAME_SIZE;
64  avctx->delay = ENC_DELAY;
65  s->last_frame = 2;
66  ff_af_queue_init(avctx, &s->afq);
67 
68  s->end_buffer = av_mallocz(avctx->frame_size * avctx->channels * 2);
69  if (!s->end_buffer) {
70  ret = AVERROR(ENOMEM);
71  goto error;
72  }
73 
74  voGetAACEncAPI(&s->codec_api);
75 
76  s->mem_operator.Alloc = cmnMemAlloc;
77  s->mem_operator.Copy = cmnMemCopy;
78  s->mem_operator.Free = cmnMemFree;
79  s->mem_operator.Set = cmnMemSet;
80  s->mem_operator.Check = cmnMemCheck;
81  s->user_data.memflag = VO_IMF_USERMEMOPERATOR;
82  s->user_data.memData = &s->mem_operator;
83  s->codec_api.Init(&s->handle, VO_AUDIO_CodingAAC, &s->user_data);
84 
85  params.sampleRate = avctx->sample_rate;
86  params.bitRate = avctx->bit_rate;
87  params.nChannels = avctx->channels;
88  params.adtsUsed = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER);
89  if (s->codec_api.SetParam(s->handle, VO_PID_AAC_ENCPARAM, &params)
90  != VO_ERR_NONE) {
91  av_log(avctx, AV_LOG_ERROR, "Unable to set encoding parameters\n");
92  ret = AVERROR(EINVAL);
93  goto error;
94  }
95 
96  for (index = 0; index < 16; index++)
97  if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[index])
98  break;
99  if (index == 16) {
100  av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n",
101  avctx->sample_rate);
102  ret = AVERROR(ENOSYS);
103  goto error;
104  }
105  if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
106  avctx->extradata_size = 2;
107  avctx->extradata = av_mallocz(avctx->extradata_size +
109  if (!avctx->extradata) {
110  ret = AVERROR(ENOMEM);
111  goto error;
112  }
113 
114  avctx->extradata[0] = 0x02 << 3 | index >> 1;
115  avctx->extradata[1] = (index & 0x01) << 7 | avctx->channels << 3;
116  }
117  return 0;
118 error:
119  aac_encode_close(avctx);
120  return ret;
121 }
122 
124  const AVFrame *frame, int *got_packet_ptr)
125 {
126  AACContext *s = avctx->priv_data;
127  VO_CODECBUFFER input = { 0 }, output = { 0 };
128  VO_AUDIO_OUTPUTINFO output_info = { { 0 } };
129  VO_PBYTE samples;
130  int ret;
131 
132  /* handle end-of-stream small frame and flushing */
133  if (!frame) {
134  if (s->last_frame <= 0)
135  return 0;
136  if (s->last_samples > 0 && s->last_samples < ENC_DELAY - FRAME_SIZE) {
137  s->last_samples = 0;
138  s->last_frame--;
139  }
140  s->last_frame--;
141  memset(s->end_buffer, 0, 2 * avctx->channels * avctx->frame_size);
142  samples = s->end_buffer;
143  } else {
144  if (frame->nb_samples < avctx->frame_size) {
145  s->last_samples = frame->nb_samples;
146  memcpy(s->end_buffer, frame->data[0], 2 * avctx->channels * frame->nb_samples);
147  samples = s->end_buffer;
148  } else {
149  samples = (VO_PBYTE)frame->data[0];
150  }
151  /* add current frame to the queue */
152  if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
153  return ret;
154  }
155 
156  if ((ret = ff_alloc_packet2(avctx, avpkt, FFMAX(8192, 768 * avctx->channels))) < 0)
157  return ret;
158 
159  input.Buffer = samples;
160  input.Length = 2 * avctx->channels * avctx->frame_size;
161  output.Buffer = avpkt->data;
162  output.Length = avpkt->size;
163 
164  s->codec_api.SetInputData(s->handle, &input);
165  if (s->codec_api.GetOutputData(s->handle, &output, &output_info)
166  != VO_ERR_NONE) {
167  av_log(avctx, AV_LOG_ERROR, "Unable to encode frame\n");
168  return AVERROR(EINVAL);
169  }
170 
171  /* Get the next frame pts/duration */
172  ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
173  &avpkt->duration);
174 
175  avpkt->size = output.Length;
176  *got_packet_ptr = 1;
177  return 0;
178 }
179 
180 /* duplicated from avpriv_mpeg4audio_sample_rates to avoid shared build
181  * failures */
182 static const int mpeg4audio_sample_rates[16] = {
183  96000, 88200, 64000, 48000, 44100, 32000,
184  24000, 22050, 16000, 12000, 11025, 8000, 7350
185 };
186 
188  .name = "libvo_aacenc",
189  .type = AVMEDIA_TYPE_AUDIO,
190  .id = AV_CODEC_ID_AAC,
191  .priv_data_size = sizeof(AACContext),
193  .encode2 = aac_encode_frame,
197  .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
199  .long_name = NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"),
200 };
#define ENC_DELAY
Definition: libvo-aacenc.c:31
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
const char * s
Definition: avisynth_c.h:668
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
HANDLE_AACENCODER handle
Definition: libfdk-aacenc.c:33
AVCodecContext * avctx
Definition: aac.h:264
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
signed 16 bits
Definition: samplefmt.h:52
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
AVCodec ff_libvo_aacenc_encoder
Definition: libvo-aacenc.c:187
supported_samplerates
#define av_cold
Definition: attributes.h:78
AudioFrameQueue afq
Definition: libfdk-aacenc.c:41
#define CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
uint8_t * data
static av_cold int aac_encode_init(AVCodecContext *avctx)
Definition: libvo-aacenc.c:57
VO_PBYTE end_buffer
Definition: libvo-aacenc.c:38
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
VO_MEM_OPERATOR mem_operator
Definition: libvo-aacenc.c:36
#define CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
#define CODEC_CAP_SMALL_LAST_FRAME
Codec can be fed a final frame with a smaller size.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
int flags
CODEC_FLAG_*.
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame This method is called when a frame is wanted on an output For an input
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
Add a frame to the queue.
#define FFMAX(a, b)
Definition: common.h:56
external API header
struct AACContext AACContext
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
int bit_rate
the average bitrate
ret
Definition: avfilter.c:821
VO_CODEC_INIT_USERDATA user_data
Definition: libvo-aacenc.c:37
int last_frame
Definition: libvo-aacenc.c:40
#define FRAME_SIZE
Definition: libvo-aacenc.c:30
int last_samples
Definition: libvo-aacenc.c:41
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int size)
Check AVPacket size and/or allocate data.
int frame_size
Number of samples per channel in an audio frame.
int sample_rate
samples per second
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
int index
Definition: gxfenc.c:89
main AAC context
Definition: aac.h:262
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
const int avpriv_mpeg4audio_sample_rates[16]
Definition: mpeg4audio.c:57
static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition: libvo-aacenc.c:123
AVFrame * frame
Definition: aac.h:265
const char const char * params
Definition: avisynth_c.h:675
static int aac_encode_close(AVCodecContext *avctx)
Definition: libvo-aacenc.c:45
static const int mpeg4audio_sample_rates[16]
Definition: libvo-aacenc.c:182
common internal api header.
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
these buffered frames must be flushed immediately if a new input produces new output(Example:frame rate-doubling filter:filter_frame must(1) flush the second copy of the previous frame, if it is still there,(2) push the first copy of the incoming frame,(3) keep the second copy for later.) If the input frame is not enough to produce output
void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
Initialize AudioFrameQueue.
void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts, int *duration)
Remove frame(s) from the queue.
int channels
number of audio channels
void ff_af_queue_close(AudioFrameQueue *afq)
Close AudioFrameQueue.
VO_AUDIO_CODECAPI codec_api
Definition: libvo-aacenc.c:34
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:700
Filter the word “frame” indicates either a video frame or a group of audio samples
This structure stores compressed data.
int delay
Codec delay.
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:127
VO_HANDLE handle
Definition: libvo-aacenc.c:35
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...