FFmpeg
libfdk-aacenc.c
Go to the documentation of this file.
1 /*
2  * AAC encoder wrapper
3  * Copyright (c) 2012 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <fdk-aac/aacenc_lib.h>
21 
23 #include "libavutil/common.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 #include "avcodec.h"
28 #include "audio_frame_queue.h"
29 #include "codec_internal.h"
30 #include "encode.h"
31 #include "profiles.h"
32 
33 #ifdef AACENCODER_LIB_VL0
34 #define FDKENC_VER_AT_LEAST(vl0, vl1) \
35  ((AACENCODER_LIB_VL0 > vl0) || \
36  (AACENCODER_LIB_VL0 == vl0 && AACENCODER_LIB_VL1 >= vl1))
37 #else
38 #define FDKENC_VER_AT_LEAST(vl0, vl1) 0
39 #endif
40 
41 typedef struct AACContext {
42  const AVClass *class;
43  HANDLE_AACENCODER handle;
45  int eld_sbr;
46  int eld_v2;
47  int signaling;
48  int latm;
50  int vbr;
55  int prog_ref;
57  AACENC_MetaData metaDataSetup;
58  int delay;
60 
62 } AACContext;
63 
64 static const AVOption aac_enc_options[] = {
65  { "afterburner", "Afterburner (improved quality)", offsetof(AACContext, afterburner), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
66  { "eld_sbr", "Enable SBR for ELD (for SBR in other configurations, use the -profile parameter)", offsetof(AACContext, eld_sbr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
67 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
68  { "eld_v2", "Enable ELDv2 (LD-MPS extension for ELD stereo signals)", offsetof(AACContext, eld_v2), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
69 #endif
70  { "signaling", "SBR/PS signaling style", offsetof(AACContext, signaling), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 2, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, .unit = "signaling" },
71  { "default", "Choose signaling implicitly (explicit hierarchical by default, implicit if global header is disabled)", 0, AV_OPT_TYPE_CONST, { .i64 = -1 }, 0, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, .unit = "signaling" },
72  { "implicit", "Implicit backwards compatible signaling", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, .unit = "signaling" },
73  { "explicit_sbr", "Explicit SBR, implicit PS signaling", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, .unit = "signaling" },
74  { "explicit_hierarchical", "Explicit hierarchical signaling", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, .unit = "signaling" },
75  { "latm", "Output LATM/LOAS encapsulated data", offsetof(AACContext, latm), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
76  { "header_period", "StreamMuxConfig and PCE repetition period (in frames)", offsetof(AACContext, header_period), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 0xffff, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
77  { "vbr", "VBR mode (1-5)", offsetof(AACContext, vbr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 5, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
78  { "drc_profile", "The desired compression profile for AAC DRC", offsetof(AACContext, drc_profile), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 256, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
79  { "drc_target_ref", "Expected target reference level at decoder side in dB (for clipping prevention/limiter)", offsetof(AACContext, drc_target_ref), AV_OPT_TYPE_INT, { .i64 = 0.0 }, -31.75, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
80  { "comp_profile", "The desired compression profile for AAC DRC", offsetof(AACContext, comp_profile), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 256, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
81  { "comp_target_ref", "Expected target reference level at decoder side in dB (for clipping prevention/limiter)", offsetof(AACContext, comp_target_ref), AV_OPT_TYPE_INT, { .i64 = 0.0 }, -31.75, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
82  { "prog_ref", "The program reference level or dialog level in dB", offsetof(AACContext, prog_ref), AV_OPT_TYPE_INT, { .i64 = 0.0 }, -31.75, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
83  { "frame_length", "The desired frame length", offsetof(AACContext, frame_length), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1024, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
85  { NULL }
86 };
87 
88 static const AVClass aac_enc_class = {
89  .class_name = "libfdk_aac",
90  .item_name = av_default_item_name,
91  .option = aac_enc_options,
92  .version = LIBAVUTIL_VERSION_INT,
93 };
94 
95 static const char *aac_get_error(AACENC_ERROR err)
96 {
97  switch (err) {
98  case AACENC_OK:
99  return "No error";
100  case AACENC_INVALID_HANDLE:
101  return "Invalid handle";
102  case AACENC_MEMORY_ERROR:
103  return "Memory allocation error";
104  case AACENC_UNSUPPORTED_PARAMETER:
105  return "Unsupported parameter";
106  case AACENC_INVALID_CONFIG:
107  return "Invalid config";
108  case AACENC_INIT_ERROR:
109  return "Initialization error";
110  case AACENC_INIT_AAC_ERROR:
111  return "AAC library initialization error";
112  case AACENC_INIT_SBR_ERROR:
113  return "SBR library initialization error";
114  case AACENC_INIT_TP_ERROR:
115  return "Transport library initialization error";
116  case AACENC_INIT_META_ERROR:
117  return "Metadata library initialization error";
118  case AACENC_ENCODE_ERROR:
119  return "Encoding error";
120  case AACENC_ENCODE_EOF:
121  return "End of file";
122  default:
123  return "Unknown error";
124  }
125 }
126 
128 {
129  AACContext *s = avctx->priv_data;
130 
131  if (s->handle)
132  aacEncClose(&s->handle);
133  ff_af_queue_close(&s->afq);
134 
135  return 0;
136 }
137 
138 static void aac_encode_flush(AVCodecContext *avctx)
139 {
140  AACContext *s = avctx->priv_data;
141  AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
142  AACENC_InArgs in_args = { 0 };
143  AACENC_OutArgs out_args;
144  uint8_t dummy_in[1], dummy_out[1];
145  int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP };
146  int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) };
147  int in_buffer_sizes[] = { 0, sizeof(s->metaDataSetup) };
148  int out_buffer_identifier = OUT_BITSTREAM_DATA;
149  int out_buffer_size = sizeof(dummy_out), out_buffer_element_size = 1;
150  void* inBuffer[] = { dummy_in, &s->metaDataSetup };
151  void *out_ptr = dummy_out;
152  AACENC_ERROR err;
153 
154  ff_af_queue_remove(&s->afq, s->afq.frame_count, NULL);
155 
156  in_buf.bufs = (void **)inBuffer;
157  in_buf.numBufs = s->metadata_mode == 0 ? 1 : 2;
158  in_buf.bufferIdentifiers = in_buffer_identifiers;
159  in_buf.bufSizes = in_buffer_sizes;
160  in_buf.bufElSizes = in_buffer_element_sizes;
161 
162  out_buf.numBufs = 1;
163  out_buf.bufs = &out_ptr;
164  out_buf.bufferIdentifiers = &out_buffer_identifier;
165  out_buf.bufSizes = &out_buffer_size;
166  out_buf.bufElSizes = &out_buffer_element_size;
167 
168  err = aacEncEncode(s->handle, &in_buf, &out_buf, &in_args, &out_args);
169  if (err != AACENC_OK) {
170  av_log(avctx, AV_LOG_ERROR, "Unexpected error while flushing: %s\n",
171  aac_get_error(err));
172  }
173 }
174 
176 {
177  AACContext *s = avctx->priv_data;
178  int ret = AVERROR(EINVAL);
179  AACENC_InfoStruct info = { 0 };
180  AVCPBProperties *cpb_props;
181  CHANNEL_MODE mode;
182  AACENC_ERROR err;
183  int aot = AV_PROFILE_AAC_LOW + 1;
184  int sce = 0, cpe = 0;
185 
186  if ((err = aacEncOpen(&s->handle, 0, avctx->ch_layout.nb_channels)) != AACENC_OK) {
187  av_log(avctx, AV_LOG_ERROR, "Unable to open the encoder: %s\n",
188  aac_get_error(err));
189  goto error;
190  }
191 
192  if (avctx->profile != AV_PROFILE_UNKNOWN)
193  aot = avctx->profile + 1;
194 
195  if ((err = aacEncoder_SetParam(s->handle, AACENC_AOT, aot)) != AACENC_OK) {
196  av_log(avctx, AV_LOG_ERROR, "Unable to set the AOT %d: %s\n",
197  aot, aac_get_error(err));
198  goto error;
199  }
200 
201  if (aot == AV_PROFILE_AAC_ELD + 1 && s->eld_sbr) {
202  if ((err = aacEncoder_SetParam(s->handle, AACENC_SBR_MODE,
203  1)) != AACENC_OK) {
204  av_log(avctx, AV_LOG_ERROR, "Unable to enable SBR for ELD: %s\n",
205  aac_get_error(err));
206  goto error;
207  }
208  }
209 
210  if (s->frame_length >= 0) {
211  if ((err = aacEncoder_SetParam(s->handle, AACENC_GRANULE_LENGTH,
212  s->frame_length)) != AACENC_OK) {
213  av_log(avctx, AV_LOG_ERROR, "Unable to set granule length: %s\n",
214  aac_get_error(err));
215  goto error;
216  }
217  }
218 
219  if ((err = aacEncoder_SetParam(s->handle, AACENC_SAMPLERATE,
220  avctx->sample_rate)) != AACENC_OK) {
221  av_log(avctx, AV_LOG_ERROR, "Unable to set the sample rate %d: %s\n",
222  avctx->sample_rate, aac_get_error(err));
223  goto error;
224  }
225 
226  switch (avctx->ch_layout.nb_channels) {
227  case 1: mode = MODE_1; sce = 1; cpe = 0; break;
228  case 2:
229 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
230  // (profile + 1) to map from profile range to AOT range
231  if (aot == AV_PROFILE_AAC_ELD + 1 && s->eld_v2) {
232  if ((err = aacEncoder_SetParam(s->handle, AACENC_CHANNELMODE,
233  128)) != AACENC_OK) {
234  av_log(avctx, AV_LOG_ERROR, "Unable to enable ELDv2: %s\n",
235  aac_get_error(err));
236  goto error;
237  } else {
238  mode = MODE_212;
239  sce = 1;
240  cpe = 0;
241  }
242  } else
243 #endif
244  {
245  mode = MODE_2;
246  sce = 0;
247  cpe = 1;
248  }
249  break;
250  case 3: mode = MODE_1_2; sce = 1; cpe = 1; break;
251  case 4: mode = MODE_1_2_1; sce = 2; cpe = 1; break;
252  case 5: mode = MODE_1_2_2; sce = 1; cpe = 2; break;
253  case 6: mode = MODE_1_2_2_1; sce = 2; cpe = 2; break;
254 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
255  case 7: mode = MODE_6_1; sce = 3; cpe = 2; break;
256 #endif
257 /* The version macro is introduced the same time as the 7.1 support, so this
258  should suffice. */
259 #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
260  case 8:
261  sce = 2;
262  cpe = 3;
264  mode = MODE_7_1_REAR_SURROUND;
265 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
267  mode = MODE_7_1_TOP_FRONT;
268 #endif
269  } else {
270  // MODE_1_2_2_2_1 and MODE_7_1_FRONT_CENTER use the same channel layout
271  mode = MODE_7_1_FRONT_CENTER;
272  }
273  break;
274 #endif
275  default:
276  av_log(avctx, AV_LOG_ERROR,
277  "Unsupported number of channels %d\n", avctx->ch_layout.nb_channels);
278  goto error;
279  }
280 
281  if ((err = aacEncoder_SetParam(s->handle, AACENC_CHANNELMODE,
282  mode)) != AACENC_OK) {
283  av_log(avctx, AV_LOG_ERROR,
284  "Unable to set channel mode %d: %s\n", mode, aac_get_error(err));
285  goto error;
286  }
287 
288  if ((err = aacEncoder_SetParam(s->handle, AACENC_CHANNELORDER,
289  1)) != AACENC_OK) {
290  av_log(avctx, AV_LOG_ERROR,
291  "Unable to set wav channel order %d: %s\n",
292  mode, aac_get_error(err));
293  goto error;
294  }
295 
296  if (avctx->flags & AV_CODEC_FLAG_QSCALE || s->vbr) {
297  int mode = s->vbr ? s->vbr : avctx->global_quality;
298  if (mode < 1 || mode > 5) {
299  av_log(avctx, AV_LOG_WARNING,
300  "VBR quality %d out of range, should be 1-5\n", mode);
301  mode = av_clip(mode, 1, 5);
302  }
303  av_log(avctx, AV_LOG_WARNING,
304  "Note, the VBR setting is unsupported and only works with "
305  "some parameter combinations\n");
306  if ((err = aacEncoder_SetParam(s->handle, AACENC_BITRATEMODE,
307  mode)) != AACENC_OK) {
308  av_log(avctx, AV_LOG_ERROR, "Unable to set the VBR bitrate mode %d: %s\n",
309  mode, aac_get_error(err));
310  goto error;
311  }
312  } else {
313  if (avctx->bit_rate <= 0) {
314  if (avctx->profile == AV_PROFILE_AAC_HE_V2) {
315  sce = 1;
316  cpe = 0;
317  }
318  avctx->bit_rate = (96*sce + 128*cpe) * avctx->sample_rate / 44;
319  if (avctx->profile == AV_PROFILE_AAC_HE ||
320  avctx->profile == AV_PROFILE_AAC_HE_V2 ||
321  avctx->profile == AV_PROFILE_MPEG2_AAC_HE ||
322  s->eld_sbr)
323  avctx->bit_rate /= 2;
324  }
325  if ((err = aacEncoder_SetParam(s->handle, AACENC_BITRATE,
326  avctx->bit_rate)) != AACENC_OK) {
327  av_log(avctx, AV_LOG_ERROR, "Unable to set the bitrate %"PRId64": %s\n",
328  avctx->bit_rate, aac_get_error(err));
329  goto error;
330  }
331  }
332 
333  /* Choose bitstream format - if global header is requested, use
334  * raw access units, otherwise use ADTS. */
335  if ((err = aacEncoder_SetParam(s->handle, AACENC_TRANSMUX,
336  avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER ? TT_MP4_RAW :
337  s->latm ? TT_MP4_LOAS : TT_MP4_ADTS)) != AACENC_OK) {
338  av_log(avctx, AV_LOG_ERROR, "Unable to set the transmux format: %s\n",
339  aac_get_error(err));
340  goto error;
341  }
342 
343  if (s->latm && s->header_period) {
344  if ((err = aacEncoder_SetParam(s->handle, AACENC_HEADER_PERIOD,
345  s->header_period)) != AACENC_OK) {
346  av_log(avctx, AV_LOG_ERROR, "Unable to set header period: %s\n",
347  aac_get_error(err));
348  goto error;
349  }
350  }
351 
352  /* If no signaling mode is chosen, use explicit hierarchical signaling
353  * if using mp4 mode (raw access units, with global header) and
354  * implicit signaling if using ADTS. */
355  if (s->signaling < 0)
356  s->signaling = avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER ? 2 : 0;
357 
358  if ((err = aacEncoder_SetParam(s->handle, AACENC_SIGNALING_MODE,
359  s->signaling)) != AACENC_OK) {
360  av_log(avctx, AV_LOG_ERROR, "Unable to set signaling mode %d: %s\n",
361  s->signaling, aac_get_error(err));
362  goto error;
363  }
364 
365  if ((err = aacEncoder_SetParam(s->handle, AACENC_AFTERBURNER,
366  s->afterburner)) != AACENC_OK) {
367  av_log(avctx, AV_LOG_ERROR, "Unable to set afterburner to %d: %s\n",
368  s->afterburner, aac_get_error(err));
369  goto error;
370  }
371 
372  if (avctx->cutoff > 0) {
373  if (avctx->cutoff < (avctx->sample_rate + 255) >> 8 || avctx->cutoff > 20000) {
374  av_log(avctx, AV_LOG_ERROR, "cutoff valid range is %d-20000\n",
375  (avctx->sample_rate + 255) >> 8);
376  goto error;
377  }
378  if ((err = aacEncoder_SetParam(s->handle, AACENC_BANDWIDTH,
379  avctx->cutoff)) != AACENC_OK) {
380  av_log(avctx, AV_LOG_ERROR, "Unable to set the encoder bandwidth to %d: %s\n",
381  avctx->cutoff, aac_get_error(err));
382  goto error;
383  }
384  }
385 
386  s->metadata_mode = 0;
387  if (s->prog_ref) {
388  s->metadata_mode = 1;
389  s->metaDataSetup.prog_ref_level_present = 1;
390  s->metaDataSetup.prog_ref_level = s->prog_ref << 16;
391  }
392  if (s->drc_profile) {
393  s->metadata_mode = 1;
394  s->metaDataSetup.drc_profile = s->drc_profile;
395  s->metaDataSetup.drc_TargetRefLevel = s->drc_target_ref << 16;
396  if (s->comp_profile) {
397  /* Including the comp_profile means that we need to set the mode to ETSI */
398  s->metadata_mode = 2;
399  s->metaDataSetup.comp_profile = s->comp_profile;
400  s->metaDataSetup.comp_TargetRefLevel = s->comp_target_ref << 16;
401  }
402  }
403 
404  if ((err = aacEncoder_SetParam(s->handle, AACENC_METADATA_MODE, s->metadata_mode)) != AACENC_OK) {
405  av_log(avctx, AV_LOG_ERROR, "Unable to set metadata mode to %d: %s\n",
406  s->metadata_mode, aac_get_error(err));
407  goto error;
408  }
409 
410  if ((err = aacEncEncode(s->handle, NULL, NULL, NULL, NULL)) != AACENC_OK) {
411  av_log(avctx, AV_LOG_ERROR, "Unable to initialize the encoder: %s\n",
412  aac_get_error(err));
413  return AVERROR(EINVAL);
414  }
415 
416  if ((err = aacEncInfo(s->handle, &info)) != AACENC_OK) {
417  av_log(avctx, AV_LOG_ERROR, "Unable to get encoder info: %s\n",
418  aac_get_error(err));
419  goto error;
420  }
421 
422  avctx->frame_size = info.frameLength;
423  s->delay =
424 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
425  avctx->initial_padding = info.nDelay;
426 #else
427  avctx->initial_padding = info.encoderDelay;
428 #endif
429  ff_af_queue_init(avctx, &s->afq);
430 
431  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
432  avctx->extradata_size = info.confSize;
433  avctx->extradata = av_mallocz(avctx->extradata_size +
435  if (!avctx->extradata) {
436  ret = AVERROR(ENOMEM);
437  goto error;
438  }
439 
440  memcpy(avctx->extradata, info.confBuf, info.confSize);
441  }
442 
443  cpb_props = ff_encode_add_cpb_side_data(avctx);
444  if (!cpb_props)
445  return AVERROR(ENOMEM);
446  cpb_props->max_bitrate =
447  cpb_props->min_bitrate =
448  cpb_props->avg_bitrate = avctx->bit_rate;
449 
450  return 0;
451 error:
452  aac_encode_close(avctx);
453  return ret;
454 }
455 
456 static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
457  const AVFrame *frame, int *got_packet_ptr)
458 {
459  AACContext *s = avctx->priv_data;
460  AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
461  AACENC_InArgs in_args = { 0 };
462  AACENC_OutArgs out_args = { 0 };
463  void* inBuffer[] = { 0, &s->metaDataSetup };
464  int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP };
465  int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) };
466  int in_buffer_sizes[] = { 0, sizeof(s->metaDataSetup) };
467  int out_buffer_identifier = OUT_BITSTREAM_DATA;
468  int out_buffer_size, out_buffer_element_size;
469  void *out_ptr;
470  int ret;
471  uint8_t dummy_buf[1];
472  AACENC_ERROR err;
473 
474  /* handle end-of-stream small frame and flushing */
475  if (!frame) {
476  /* Must be a non-null pointer, even if it's a dummy. We could use
477  * the address of anything else on the stack as well. */
478  inBuffer[0] = dummy_buf;
479 
480  in_args.numInSamples = -1;
481  } else {
482  inBuffer[0] = frame->data[0];
483  in_buffer_sizes[0] = 2 * avctx->ch_layout.nb_channels * frame->nb_samples;
484 
485  in_args.numInSamples = avctx->ch_layout.nb_channels * frame->nb_samples;
486 
487  /* add current frame to the queue */
488  if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
489  return ret;
490  }
491 
492  if (s->metadata_mode == 0) {
493  in_buf.numBufs = 1;
494  } else {
495  in_buf.numBufs = 2;
496  }
497 
498  in_buf.bufs = (void**)inBuffer;
499  in_buf.bufferIdentifiers = in_buffer_identifiers;
500  in_buf.bufSizes = in_buffer_sizes;
501  in_buf.bufElSizes = in_buffer_element_sizes;
502 
503  /* The maximum packet size is 6144 bits aka 768 bytes per channel. */
504  ret = ff_alloc_packet(avctx, avpkt, FFMAX(8192, 768 * avctx->ch_layout.nb_channels));
505  if (ret < 0)
506  return ret;
507 
508  out_ptr = avpkt->data;
509  out_buffer_size = avpkt->size;
510  out_buffer_element_size = 1;
511  out_buf.numBufs = 1;
512  out_buf.bufs = &out_ptr;
513  out_buf.bufferIdentifiers = &out_buffer_identifier;
514  out_buf.bufSizes = &out_buffer_size;
515  out_buf.bufElSizes = &out_buffer_element_size;
516 
517  if ((err = aacEncEncode(s->handle, &in_buf, &out_buf, &in_args,
518  &out_args)) != AACENC_OK) {
519  if (!frame && err == AACENC_ENCODE_EOF)
520  return 0;
521  av_log(avctx, AV_LOG_ERROR, "Unable to encode frame: %s\n",
522  aac_get_error(err));
523  return AVERROR(EINVAL);
524  }
525 
526  if (!out_args.numOutBytes)
527  return 0;
528 
529  /* Get the next frame pts & duration */
530  ret = ff_af_queue_remove(&s->afq, avctx->frame_size, avpkt);
531  if (ret < 0)
532  return ret;
533 
534  avpkt->size = out_args.numOutBytes;
535  avpkt->flags |= AV_PKT_FLAG_KEY;
536  *got_packet_ptr = 1;
537  return 0;
538 }
539 
540 static const AVProfile profiles[] = {
541  { AV_PROFILE_AAC_LOW, "LC" },
542  { AV_PROFILE_AAC_HE, "HE-AAC" },
543  { AV_PROFILE_AAC_HE_V2, "HE-AACv2" },
544  { AV_PROFILE_AAC_LD, "LD" },
545  { AV_PROFILE_AAC_ELD, "ELD" },
546  { AV_PROFILE_UNKNOWN },
547 };
548 
550  { "b", "0" },
551  { NULL }
552 };
553 
554 static const AVChannelLayout aac_ch_layouts[16] = {
561 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
563 #endif
564 #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
567 #endif
568 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
570 #endif
571  { 0 },
572 };
573 
574 static const int aac_sample_rates[] = {
575  96000, 88200, 64000, 48000, 44100, 32000,
576  24000, 22050, 16000, 12000, 11025, 8000, 0
577 };
578 
580  .p.name = "libfdk_aac",
581  CODEC_LONG_NAME("Fraunhofer FDK AAC"),
582  .p.type = AVMEDIA_TYPE_AUDIO,
583  .p.id = AV_CODEC_ID_AAC,
584  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
587  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
588  .priv_data_size = sizeof(AACContext),
591  .flush = aac_encode_flush,
592  .close = aac_encode_close,
594  .p.priv_class = &aac_enc_class,
595  .defaults = aac_encode_defaults,
596  .p.profiles = profiles,
598  .p.wrapper_name = "libfdk",
600 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:32
AVCodecContext::frame_size
int frame_size
Number of samples per channel in an audio frame.
Definition: avcodec.h:1068
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
av_clip
#define av_clip
Definition: common.h:100
aac_ch_layouts
static const AVChannelLayout aac_ch_layouts[16]
Definition: libfdk-aacenc.c:554
AACContext::metadata_mode
int metadata_mode
Definition: libfdk-aacenc.c:56
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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. Frame references ownership and permissions
opt.h
aac_enc_class
static const AVClass aac_enc_class
Definition: libfdk-aacenc.c:88
ff_libfdk_aac_encoder
const FFCodec ff_libfdk_aac_encoder
Definition: libfdk-aacenc.c:579
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:395
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1040
AV_CODEC_FLAG_QSCALE
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:213
av_cold
#define av_cold
Definition: attributes.h:119
ff_af_queue_init
av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
Initialize AudioFrameQueue.
Definition: audio_frame_queue.c:29
aac_encode_frame
static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition: libfdk-aacenc.c:456
mode
Definition: swscale.c:71
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
aac_encode_init
static av_cold int aac_encode_init(AVCodecContext *avctx)
Definition: libfdk-aacenc.c:175
AVPacket::data
uint8_t * data
Definition: packet.h:603
AACContext::signaling
int signaling
Definition: libfdk-aacenc.c:47
AVOption
AVOption.
Definition: opt.h:428
encode.h
FF_CODEC_CAP_NOT_INIT_THREADSAFE
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
Definition: codec_internal.h:35
FFCodec
Definition: codec_internal.h:127
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:650
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:318
AVProfile
AVProfile.
Definition: codec.h:161
AACContext::frame_length
int frame_length
Definition: libfdk-aacenc.c:59
FFCodecDefault
Definition: codec_internal.h:97
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:1055
aac_get_error
static const char * aac_get_error(AACENC_ERROR err)
Definition: libfdk-aacenc.c:95
audio_frame_queue.h
AVCodecContext::initial_padding
int initial_padding
Audio only.
Definition: avcodec.h:1114
AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK
#define AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK
Definition: channel_layout.h:435
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
AV_CODEC_CAP_ENCODER_FLUSH
#define AV_CODEC_CAP_ENCODER_FLUSH
This encoder can be flushed using avcodec_flush_buffers().
Definition: codec.h:148
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:376
ff_af_queue_add
int ff_af_queue_add(AudioFrameQueue *afq, const AVFrame *f)
Add a frame to the queue.
Definition: audio_frame_queue.c:46
AV_CHANNEL_LAYOUT_SURROUND
#define AV_CHANNEL_LAYOUT_SURROUND
Definition: channel_layout.h:398
AV_OPT_FLAG_AUDIO_PARAM
#define AV_OPT_FLAG_AUDIO_PARAM
Definition: opt.h:356
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
AV_CHANNEL_LAYOUT_4POINT0
#define AV_CHANNEL_LAYOUT_4POINT0
Definition: channel_layout.h:400
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:527
AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_7POINT1
Definition: channel_layout.h:417
intreadwrite.h
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1235
AV_PROFILE_MPEG2_AAC_HE
#define AV_PROFILE_MPEG2_AAC_HE
Definition: defs.h:78
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
info
MIPS optimizations info
Definition: mips.txt:2
AV_CHANNEL_LAYOUT_5POINT0_BACK
#define AV_CHANNEL_LAYOUT_5POINT0_BACK
Definition: channel_layout.h:406
AACContext::prog_ref
int prog_ref
Definition: libfdk-aacenc.c:55
AACContext::eld_v2
int eld_v2
Definition: libfdk-aacenc.c:46
AudioFrameQueue
Definition: audio_frame_queue.h:32
AACContext::vbr
int vbr
Definition: libfdk-aacenc.c:50
AACContext::header_period
int header_period
Definition: libfdk-aacenc.c:49
AV_PROFILE_AAC_ELD
#define AV_PROFILE_AAC_ELD
Definition: defs.h:75
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
AVCPBProperties
This structure describes the bitrate properties of an encoded bitstream.
Definition: defs.h:282
AACContext::latm
int latm
Definition: libfdk-aacenc.c:48
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:349
AACContext::comp_target_ref
int comp_target_ref
Definition: libfdk-aacenc.c:54
if
if(ret)
Definition: filter_design.txt:179
ff_af_queue_close
av_cold void ff_af_queue_close(AudioFrameQueue *afq)
Close AudioFrameQueue.
Definition: audio_frame_queue.c:38
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK
#define AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK
Definition: channel_layout.h:419
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
NULL
#define NULL
Definition: coverity.c:32
AACContext::comp_profile
int comp_profile
Definition: libfdk-aacenc.c:53
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:493
AACContext::delay
int delay
Definition: libfdk-aacenc.c:58
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
profiles.h
AACContext::metaDataSetup
AACENC_MetaData metaDataSetup
Definition: libfdk-aacenc.c:57
aac_encode_close
static int aac_encode_close(AVCodecContext *avctx)
Definition: libfdk-aacenc.c:127
AACContext::afterburner
int afterburner
Definition: libfdk-aacenc.c:44
AV_OPT_FLAG_ENCODING_PARAM
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition: opt.h:351
aac_encode_defaults
static const FFCodecDefault aac_encode_defaults[]
Definition: libfdk-aacenc.c:549
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:454
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:608
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:49
AVPacket::size
int size
Definition: packet.h:604
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
codec_internal.h
AACContext::afq
AudioFrameQueue afq
Definition: libfdk-aacenc.c:61
AV_PROFILE_AAC_LD
#define AV_PROFILE_AAC_LD
Definition: defs.h:74
AVCPBProperties::min_bitrate
int64_t min_bitrate
Minimum bitrate of the stream, in bits per second.
Definition: defs.h:292
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:609
ff_af_queue_remove
int ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, AVPacket *pkt)
Remove frame(s) from the queue.
Definition: audio_frame_queue.c:87
CODEC_SAMPLEFMTS
#define CODEC_SAMPLEFMTS(...)
Definition: codec_internal.h:395
AVCPBProperties::avg_bitrate
int64_t avg_bitrate
Average bitrate of the stream, in bits per second.
Definition: defs.h:297
aac_encode_flush
static void aac_encode_flush(AVCodecContext *avctx)
Definition: libfdk-aacenc.c:138
av_channel_layout_compare
int av_channel_layout_compare(const AVChannelLayout *chl, const AVChannelLayout *chl1)
Check whether two channel layouts are semantically the same, i.e.
Definition: channel_layout.c:811
AV_CHANNEL_LAYOUT_6POINT1_BACK
#define AV_CHANNEL_LAYOUT_6POINT1_BACK
Definition: channel_layout.h:413
AACContext::eld_sbr
int eld_sbr
Definition: libfdk-aacenc.c:45
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:526
common.h
AVCodecContext::cutoff
int cutoff
Audio cutoff bandwidth (0 means "automatic")
Definition: avcodec.h:1082
AVCPBProperties::max_bitrate
int64_t max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition: defs.h:287
s
uint8_t s
Definition: llvidencdsp.c:39
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:58
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:176
avcodec.h
ret
ret
Definition: filter_design.txt:187
AACContext::drc_target_ref
int drc_target_ref
Definition: libfdk-aacenc.c:52
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:81
frame
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 For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AV_PROFILE_AAC_LOW
#define AV_PROFILE_AAC_LOW
Definition: defs.h:69
AVCodecContext
main external API structure.
Definition: avcodec.h:443
channel_layout.h
CODEC_SAMPLERATES_ARRAY
#define CODEC_SAMPLERATES_ARRAY(array)
Definition: codec_internal.h:393
AV_PROFILE_AAC_HE_V2
#define AV_PROFILE_AAC_HE_V2
Definition: defs.h:73
mode
mode
Definition: ebur128.h:83
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:258
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1636
profiles
static const AVProfile profiles[]
Definition: libfdk-aacenc.c:540
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: codec.h:73
mem.h
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
AV_PROFILE_AAC_HE
#define AV_PROFILE_AAC_HE
Definition: defs.h:72
FF_AAC_PROFILE_OPTS
#define FF_AAC_PROFILE_OPTS
Definition: profiles.h:29
AVPacket
This structure stores compressed data.
Definition: packet.h:580
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
aac_sample_rates
static const int aac_sample_rates[]
Definition: libfdk-aacenc.c:574
AACContext
Definition: libfdk-aacenc.c:41
AV_CHANNEL_LAYOUT_5POINT1_BACK
#define AV_CHANNEL_LAYOUT_5POINT1_BACK
Definition: channel_layout.h:407
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_encode_add_cpb_side_data
AVCPBProperties * ff_encode_add_cpb_side_data(AVCodecContext *avctx)
Add a CPB properties side data to an encoding context.
Definition: encode.c:941
AACContext::handle
HANDLE_AACENCODER handle
Definition: libfdk-aacenc.c:43
AV_CODEC_CAP_SMALL_LAST_FRAME
#define AV_CODEC_CAP_SMALL_LAST_FRAME
Codec can be fed a final frame with a smaller size.
Definition: codec.h:78
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:298
ff_alloc_packet
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition: encode.c:61
CODEC_CH_LAYOUTS_ARRAY
#define CODEC_CH_LAYOUTS_ARRAY(array)
Definition: codec_internal.h:390
aac_enc_options
static const AVOption aac_enc_options[]
Definition: libfdk-aacenc.c:64
AACContext::drc_profile
int drc_profile
Definition: libfdk-aacenc.c:51