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;
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  int64_t pts, duration;
145  uint8_t dummy_in[1], dummy_out[1];
146  int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP };
147  int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) };
148  int in_buffer_sizes[] = { 0, sizeof(s->metaDataSetup) };
149  int out_buffer_identifier = OUT_BITSTREAM_DATA;
150  int out_buffer_size = sizeof(dummy_out), out_buffer_element_size = 1;
151  void* inBuffer[] = { dummy_in, &s->metaDataSetup };
152  void *out_ptr = dummy_out;
153  AACENC_ERROR err;
154 
155  ff_af_queue_remove(&s->afq, s->afq.frame_count, &pts, &duration);
156 
157  in_buf.bufs = (void **)inBuffer;
158  in_buf.numBufs = s->metadata_mode == 0 ? 1 : 2;
159  in_buf.bufferIdentifiers = in_buffer_identifiers;
160  in_buf.bufSizes = in_buffer_sizes;
161  in_buf.bufElSizes = in_buffer_element_sizes;
162 
163  out_buf.numBufs = 1;
164  out_buf.bufs = &out_ptr;
165  out_buf.bufferIdentifiers = &out_buffer_identifier;
166  out_buf.bufSizes = &out_buffer_size;
167  out_buf.bufElSizes = &out_buffer_element_size;
168 
169  err = aacEncEncode(s->handle, &in_buf, &out_buf, &in_args, &out_args);
170  if (err != AACENC_OK) {
171  av_log(avctx, AV_LOG_ERROR, "Unexpected error while flushing: %s\n",
172  aac_get_error(err));
173  }
174 }
175 
177 {
178  AACContext *s = avctx->priv_data;
179  int ret = AVERROR(EINVAL);
180  AACENC_InfoStruct info = { 0 };
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 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
424  avctx->initial_padding = info.nDelay;
425 #else
426  avctx->initial_padding = info.encoderDelay;
427 #endif
428  ff_af_queue_init(avctx, &s->afq);
429 
430  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
431  avctx->extradata_size = info.confSize;
432  avctx->extradata = av_mallocz(avctx->extradata_size +
434  if (!avctx->extradata) {
435  ret = AVERROR(ENOMEM);
436  goto error;
437  }
438 
439  memcpy(avctx->extradata, info.confBuf, info.confSize);
440  }
441  return 0;
442 error:
443  aac_encode_close(avctx);
444  return ret;
445 }
446 
447 static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
448  const AVFrame *frame, int *got_packet_ptr)
449 {
450  AACContext *s = avctx->priv_data;
451  AACENC_BufDesc in_buf = { 0 }, out_buf = { 0 };
452  AACENC_InArgs in_args = { 0 };
453  AACENC_OutArgs out_args = { 0 };
454  void* inBuffer[] = { 0, &s->metaDataSetup };
455  int in_buffer_identifiers[] = { IN_AUDIO_DATA, IN_METADATA_SETUP };
456  int in_buffer_element_sizes[] = { 2, sizeof(AACENC_MetaData) };
457  int in_buffer_sizes[] = { 0, sizeof(s->metaDataSetup) };
458  int out_buffer_identifier = OUT_BITSTREAM_DATA;
459  int out_buffer_size, out_buffer_element_size;
460  void *out_ptr;
461  int ret, discard_padding;
462  uint8_t dummy_buf[1];
463  AACENC_ERROR err;
464 
465  /* handle end-of-stream small frame and flushing */
466  if (!frame) {
467  /* Must be a non-null pointer, even if it's a dummy. We could use
468  * the address of anything else on the stack as well. */
469  inBuffer[0] = dummy_buf;
470 
471  in_args.numInSamples = -1;
472  } else {
473  inBuffer[0] = frame->data[0];
474  in_buffer_sizes[0] = 2 * avctx->ch_layout.nb_channels * frame->nb_samples;
475 
476  in_args.numInSamples = avctx->ch_layout.nb_channels * frame->nb_samples;
477 
478  /* add current frame to the queue */
479  if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
480  return ret;
481  }
482 
483  if (s->metadata_mode == 0) {
484  in_buf.numBufs = 1;
485  } else {
486  in_buf.numBufs = 2;
487  }
488 
489  in_buf.bufs = (void**)inBuffer;
490  in_buf.bufferIdentifiers = in_buffer_identifiers;
491  in_buf.bufSizes = in_buffer_sizes;
492  in_buf.bufElSizes = in_buffer_element_sizes;
493 
494  /* The maximum packet size is 6144 bits aka 768 bytes per channel. */
495  ret = ff_alloc_packet(avctx, avpkt, FFMAX(8192, 768 * avctx->ch_layout.nb_channels));
496  if (ret < 0)
497  return ret;
498 
499  out_ptr = avpkt->data;
500  out_buffer_size = avpkt->size;
501  out_buffer_element_size = 1;
502  out_buf.numBufs = 1;
503  out_buf.bufs = &out_ptr;
504  out_buf.bufferIdentifiers = &out_buffer_identifier;
505  out_buf.bufSizes = &out_buffer_size;
506  out_buf.bufElSizes = &out_buffer_element_size;
507 
508  if ((err = aacEncEncode(s->handle, &in_buf, &out_buf, &in_args,
509  &out_args)) != AACENC_OK) {
510  if (!frame && err == AACENC_ENCODE_EOF)
511  return 0;
512  av_log(avctx, AV_LOG_ERROR, "Unable to encode frame: %s\n",
513  aac_get_error(err));
514  return AVERROR(EINVAL);
515  }
516 
517  if (!out_args.numOutBytes)
518  return 0;
519 
520  /* Get the next frame pts & duration */
521  ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
522  &avpkt->duration);
523 
524  discard_padding = avctx->frame_size - avpkt->duration;
525  // Check if subtraction resulted in an overflow
526  if ((discard_padding < avctx->frame_size) != (avpkt->duration > 0)) {
527  av_log(avctx, AV_LOG_ERROR, "discard padding overflow\n");
528  return AVERROR(EINVAL);
529  }
530  if ((!s->delay_sent && avctx->initial_padding > 0) || discard_padding > 0) {
531  uint8_t *side_data =
533  if (!side_data)
534  return AVERROR(ENOMEM);
535  if (!s->delay_sent) {
536  AV_WL32(side_data, avctx->initial_padding);
537  s->delay_sent = 1;
538  }
539  AV_WL32(side_data + 4, discard_padding);
540  }
541 
542  avpkt->size = out_args.numOutBytes;
543  *got_packet_ptr = 1;
544  return 0;
545 }
546 
547 static const AVProfile profiles[] = {
548  { AV_PROFILE_AAC_LOW, "LC" },
549  { AV_PROFILE_AAC_HE, "HE-AAC" },
550  { AV_PROFILE_AAC_HE_V2, "HE-AACv2" },
551  { AV_PROFILE_AAC_LD, "LD" },
552  { AV_PROFILE_AAC_ELD, "ELD" },
553  { AV_PROFILE_UNKNOWN },
554 };
555 
557  { "b", "0" },
558  { NULL }
559 };
560 
561 static const AVChannelLayout aac_ch_layouts[16] = {
568 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
570 #endif
571 #if FDKENC_VER_AT_LEAST(3, 4) // 3.4.12
574 #endif
575 #if FDKENC_VER_AT_LEAST(4, 0) // 4.0.0
577 #endif
578  { 0 },
579 };
580 
581 static const int aac_sample_rates[] = {
582  96000, 88200, 64000, 48000, 44100, 32000,
583  24000, 22050, 16000, 12000, 11025, 8000, 0
584 };
585 
587  .p.name = "libfdk_aac",
588  CODEC_LONG_NAME("Fraunhofer FDK AAC"),
589  .p.type = AVMEDIA_TYPE_AUDIO,
590  .p.id = AV_CODEC_ID_AAC,
591  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
594  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
595  .priv_data_size = sizeof(AACContext),
598  .flush = aac_encode_flush,
599  .close = aac_encode_close,
600  .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
602  .p.priv_class = &aac_enc_class,
603  .defaults = aac_encode_defaults,
604  .p.profiles = profiles,
605  .p.supported_samplerates = aac_sample_rates,
606  .p.wrapper_name = "libfdk",
607  .p.ch_layouts = aac_ch_layouts,
608 };
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:1077
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
av_clip
#define av_clip
Definition: common.h:99
aac_ch_layouts
static const AVChannelLayout aac_ch_layouts[16]
Definition: libfdk-aacenc.c:561
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:586
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:424
ff_af_queue_remove
void ff_af_queue_remove(AudioFrameQueue *afq, int nb_samples, int64_t *pts, int64_t *duration)
Remove frame(s) from the queue.
Definition: audio_frame_queue.c:75
AV_CHANNEL_LAYOUT_STEREO
#define AV_CHANNEL_LAYOUT_STEREO
Definition: channel_layout.h:379
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1050
ff_af_queue_close
void ff_af_queue_close(AudioFrameQueue *afq)
Close AudioFrameQueue.
Definition: audio_frame_queue.c:36
AV_CODEC_FLAG_QSCALE
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:224
ff_af_queue_init
av_cold void ff_af_queue_init(AVCodecContext *avctx, AudioFrameQueue *afq)
Initialize AudioFrameQueue.
Definition: audio_frame_queue.c:28
aac_encode_frame
static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition: libfdk-aacenc.c:447
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
aac_encode_init
static av_cold int aac_encode_init(AVCodecContext *avctx)
Definition: libfdk-aacenc.c:176
AVPacket::data
uint8_t * data
Definition: packet.h:524
AACContext::signaling
int signaling
Definition: libfdk-aacenc.c:47
AVOption
AVOption.
Definition: opt.h:346
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:34
FFCodec
Definition: codec_internal.h:127
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:542
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:313
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:338
AVProfile
AVProfile.
Definition: codec.h:179
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:1065
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:1122
AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK
#define AV_CHANNEL_LAYOUT_7POINT1_TOP_BACK
Definition: channel_layout.h:416
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:502
pts
static int64_t pts
Definition: transcode_aac.c:644
AV_CODEC_CAP_ENCODER_FLUSH
#define AV_CODEC_CAP_ENCODER_FLUSH
This encoder can be flushed using avcodec_flush_buffers().
Definition: codec.h:166
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:296
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:44
AV_CHANNEL_LAYOUT_SURROUND
#define AV_CHANNEL_LAYOUT_SURROUND
Definition: channel_layout.h:382
AV_OPT_FLAG_AUDIO_PARAM
#define AV_OPT_FLAG_AUDIO_PARAM
Definition: opt.h:274
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
duration
int64_t duration
Definition: movenc.c:65
AV_CHANNEL_LAYOUT_4POINT0
#define AV_CHANNEL_LAYOUT_4POINT0
Definition: channel_layout.h:384
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:524
AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_7POINT1
Definition: channel_layout.h:401
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1239
AV_PROFILE_MPEG2_AAC_HE
#define AV_PROFILE_MPEG2_AAC_HE
Definition: defs.h:77
frame_size
int frame_size
Definition: mxfenc.c:2423
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
info
MIPS optimizations info
Definition: mips.txt:2
AV_CHANNEL_LAYOUT_5POINT0_BACK
#define AV_CHANNEL_LAYOUT_5POINT0_BACK
Definition: channel_layout.h:390
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
AACContext::latm
int latm
Definition: libfdk-aacenc.c:48
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:272
AACContext::comp_target_ref
int comp_target_ref
Definition: libfdk-aacenc.c:54
if
if(ret)
Definition: filter_design.txt:179
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK
#define AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK
Definition: channel_layout.h:403
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:495
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
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:269
aac_encode_defaults
static const FFCodecDefault aac_encode_defaults[]
Definition: libfdk-aacenc.c:556
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:442
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:366
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:52
AVPacket::size
int size
Definition: packet.h:525
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:303
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
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
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:801
AV_CHANNEL_LAYOUT_6POINT1_BACK
#define AV_CHANNEL_LAYOUT_6POINT1_BACK
Definition: channel_layout.h:397
AACContext::eld_sbr
int eld_sbr
Definition: libfdk-aacenc.c:45
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:517
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:523
common.h
AVCodecContext::cutoff
int cutoff
Audio cutoff bandwidth (0 means "automatic")
Definition: avcodec.h:1090
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
AV_SAMPLE_FMT_S16
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition: samplefmt.h:58
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
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:71
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:264
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:445
channel_layout.h
AV_PROFILE_AAC_HE_V2
#define AV_PROFILE_AAC_HE_V2
Definition: defs.h:73
av_packet_new_side_data
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition: packet.c:231
mode
mode
Definition: ebur128.h:83
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1639
AV_PKT_DATA_SKIP_SAMPLES
@ AV_PKT_DATA_SKIP_SAMPLES
Recommmends skipping the specified number of samples.
Definition: packet.h:157
profiles
static const AVProfile profiles[]
Definition: libfdk-aacenc.c:547
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:76
mem.h
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:378
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:501
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
aac_sample_rates
static const int aac_sample_rates[]
Definition: libfdk-aacenc.c:581
AACContext
Definition: libfdk-aacenc.c:41
AV_CHANNEL_LAYOUT_5POINT1_BACK
#define AV_CHANNEL_LAYOUT_5POINT1_BACK
Definition: channel_layout.h:391
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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:81
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
AACContext::delay_sent
int delay_sent
Definition: libfdk-aacenc.c:58
ff_alloc_packet
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition: encode.c:62
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