FFmpeg
audiotoolboxenc.c
Go to the documentation of this file.
1 /*
2  * Audio Toolbox system codecs
3  *
4  * copyright (c) 2016 rcombs
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include <AudioToolbox/AudioToolbox.h>
24 
25 #define FF_BUFQUEUE_SIZE 256
27 
28 #include "config.h"
29 #include "audio_frame_queue.h"
30 #include "avcodec.h"
31 #include "bytestream.h"
32 #include "codec_internal.h"
33 #include "encode.h"
34 #include "internal.h"
35 #include "libavformat/isom.h"
36 #include "libavutil/avassert.h"
38 #include "libavutil/mem.h"
39 #include "libavutil/opt.h"
40 #include "libavutil/log.h"
41 
42 typedef struct ATDecodeContext {
44  int mode;
45  int quality;
46 
47  AudioConverterRef converter;
50 
51  unsigned pkt_size;
53  int eof;
55 
58 
59 static UInt32 ffat_get_format_id(enum AVCodecID codec, int profile)
60 {
61  switch (codec) {
62  case AV_CODEC_ID_AAC:
63  switch (profile) {
64  case AV_PROFILE_AAC_LOW:
65  default:
66  return kAudioFormatMPEG4AAC;
67  case AV_PROFILE_AAC_HE:
68  return kAudioFormatMPEG4AAC_HE;
70  return kAudioFormatMPEG4AAC_HE_V2;
71  case AV_PROFILE_AAC_LD:
72  return kAudioFormatMPEG4AAC_LD;
73 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
74  case AV_PROFILE_AAC_ELD:
75  return kAudioFormatMPEG4AAC_ELD;
76 #endif
77  }
79  return kAudioFormatAppleIMA4;
80  case AV_CODEC_ID_ALAC:
81  return kAudioFormatAppleLossless;
82 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
83  case AV_CODEC_ID_ILBC:
84  return kAudioFormatiLBC;
85 #endif
87  return kAudioFormatALaw;
89  return kAudioFormatULaw;
90  default:
91  av_assert0(!"Invalid codec ID!");
92  return 0;
93  }
94 }
95 
96 static int ffat_update_ctx(AVCodecContext *avctx)
97 {
98  ATDecodeContext *at = avctx->priv_data;
99  UInt32 size = sizeof(unsigned);
100  AudioConverterPrimeInfo prime_info;
101  AudioStreamBasicDescription out_format;
102 
103  AudioConverterGetProperty(at->converter,
104  kAudioConverterPropertyMaximumOutputPacketSize,
105  &size, &at->pkt_size);
106 
107  if (at->pkt_size <= 0)
108  at->pkt_size = 1024 * 50;
109 
110  size = sizeof(prime_info);
111 
112  if (!AudioConverterGetProperty(at->converter,
113  kAudioConverterPrimeInfo,
114  &size, &prime_info)) {
115  avctx->initial_padding = prime_info.leadingFrames;
116  }
117 
118  size = sizeof(out_format);
119  if (!AudioConverterGetProperty(at->converter,
120  kAudioConverterCurrentOutputStreamDescription,
121  &size, &out_format)) {
122  if (out_format.mFramesPerPacket) {
123  avctx->frame_size = out_format.mFramesPerPacket;
124  } else {
125  /* The doc on mFramesPerPacket says:
126  * For formats with a variable number of frames per packet, such as
127  * Ogg Vorbis, set this field to 0.
128  * Looks like it means for decoding. There is no known case that
129  * mFramesPerPacket is zero for encoding. Use a default value for safety.
130  */
131  avctx->frame_size = 1024;
132  av_log(avctx, AV_LOG_WARNING, "Missing mFramesPerPacket\n");
133  }
134  if (out_format.mBytesPerPacket && avctx->codec_id == AV_CODEC_ID_ILBC)
135  avctx->block_align = out_format.mBytesPerPacket;
136  } else {
137  av_log(avctx, AV_LOG_ERROR, "Get OutputStreamDescription failed\n");
138  return AVERROR_EXTERNAL;
139  }
140 
141  at->frame_size = avctx->frame_size;
142  if (avctx->codec_id == AV_CODEC_ID_PCM_MULAW ||
143  avctx->codec_id == AV_CODEC_ID_PCM_ALAW) {
144  at->pkt_size *= 1024;
145  avctx->frame_size *= 1024;
146  }
147 
148  return 0;
149 }
150 
151 static int read_descr(GetByteContext *gb, int *tag)
152 {
153  int len = 0;
154  int count = 4;
155  *tag = bytestream2_get_byte(gb);
156  while (count--) {
157  int c = bytestream2_get_byte(gb);
158  len = (len << 7) | (c & 0x7f);
159  if (!(c & 0x80))
160  break;
161  }
162  return len;
163 }
164 
165 static int get_ilbc_mode(AVCodecContext *avctx)
166 {
167  if (avctx->block_align == 38)
168  return 20;
169  else if (avctx->block_align == 50)
170  return 30;
171  else if (avctx->bit_rate > 0)
172  return avctx->bit_rate <= 14000 ? 30 : 20;
173  else
174  return 30;
175 }
176 
178 {
179  uint64_t map = 1 << channel;
180  if (map <= AV_CH_LOW_FREQUENCY)
181  return channel + 1;
182  else if (map <= AV_CH_BACK_RIGHT)
183  return channel + 29;
184  else if (map <= AV_CH_BACK_CENTER)
185  return channel - 1;
186  else if (map <= AV_CH_SIDE_RIGHT)
187  return channel - 4;
188  else if (map <= AV_CH_TOP_BACK_RIGHT)
189  return channel + 1;
190  else if (map <= AV_CH_STEREO_RIGHT)
191  return -1;
192  else if (map <= AV_CH_WIDE_RIGHT)
193  return channel + 4;
194  else if (map <= AV_CH_SURROUND_DIRECT_RIGHT)
195  return channel - 23;
196  else if (map == AV_CH_LOW_FREQUENCY_2)
197  return kAudioChannelLabel_LFE2;
198  else
199  return -1;
200 }
201 
202 static int remap_layout(AudioChannelLayout *layout, const AVChannelLayout *in_layout)
203 {
204  int i;
205  layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
206  layout->mNumberChannelDescriptions = in_layout->nb_channels;
207  for (i = 0; i < in_layout->nb_channels; i++) {
208  int c, label;
209 
211  if (c < 0 || c >= 64)
212  return AVERROR(EINVAL);
213  label = get_channel_label(c);
214  layout->mChannelDescriptions[i].mChannelLabel = label;
215  if (label < 0)
216  return AVERROR(EINVAL);
217  c++;
218  }
219  return 0;
220 }
221 
222 static int get_aac_tag(const AVChannelLayout *in_layout)
223 {
224  static const struct {
225  AVChannelLayout chl;
226  int tag;
227  } map[] = {
228  { AV_CHANNEL_LAYOUT_MONO, kAudioChannelLayoutTag_Mono },
229  { AV_CHANNEL_LAYOUT_STEREO, kAudioChannelLayoutTag_Stereo },
230  { AV_CHANNEL_LAYOUT_QUAD, kAudioChannelLayoutTag_AAC_Quadraphonic },
231  { AV_CHANNEL_LAYOUT_OCTAGONAL, kAudioChannelLayoutTag_AAC_Octagonal },
232  { AV_CHANNEL_LAYOUT_SURROUND, kAudioChannelLayoutTag_AAC_3_0 },
233  { AV_CHANNEL_LAYOUT_4POINT0, kAudioChannelLayoutTag_AAC_4_0 },
234  { AV_CHANNEL_LAYOUT_5POINT0, kAudioChannelLayoutTag_AAC_5_0 },
235  { AV_CHANNEL_LAYOUT_5POINT1, kAudioChannelLayoutTag_AAC_5_1 },
236  { AV_CHANNEL_LAYOUT_6POINT0, kAudioChannelLayoutTag_AAC_6_0 },
237  { AV_CHANNEL_LAYOUT_6POINT1, kAudioChannelLayoutTag_AAC_6_1 },
238  { AV_CHANNEL_LAYOUT_7POINT0, kAudioChannelLayoutTag_AAC_7_0 },
239  { AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK, kAudioChannelLayoutTag_AAC_7_1 },
240  { AV_CHANNEL_LAYOUT_7POINT1, kAudioChannelLayoutTag_MPEG_7_1_C },
241  };
242  int i;
243 
244  for (i = 0; i < FF_ARRAY_ELEMS(map); i++)
245  if (!av_channel_layout_compare(in_layout, &map[i].chl))
246  return map[i].tag;
247 
248  return 0;
249 }
250 
252 {
253  ATDecodeContext *at = avctx->priv_data;
254  OSStatus status;
255  int ret;
256 
257  AudioStreamBasicDescription in_format = {
258  .mSampleRate = avctx->sample_rate,
259  .mFormatID = kAudioFormatLinearPCM,
260  .mFormatFlags = ((avctx->sample_fmt == AV_SAMPLE_FMT_FLT ||
261  avctx->sample_fmt == AV_SAMPLE_FMT_DBL) ? kAudioFormatFlagIsFloat
262  : avctx->sample_fmt == AV_SAMPLE_FMT_U8 ? 0
263  : kAudioFormatFlagIsSignedInteger)
264  | kAudioFormatFlagIsPacked,
265  .mBytesPerPacket = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->ch_layout.nb_channels,
266  .mFramesPerPacket = 1,
267  .mBytesPerFrame = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->ch_layout.nb_channels,
268  .mChannelsPerFrame = avctx->ch_layout.nb_channels,
269  .mBitsPerChannel = av_get_bytes_per_sample(avctx->sample_fmt) * 8,
270  };
271  AudioStreamBasicDescription out_format = {
272  .mSampleRate = avctx->sample_rate,
273  .mFormatID = ffat_get_format_id(avctx->codec_id, avctx->profile),
274  .mChannelsPerFrame = in_format.mChannelsPerFrame,
275  };
276  UInt32 layout_size = sizeof(AudioChannelLayout) +
277  sizeof(AudioChannelDescription) * avctx->ch_layout.nb_channels;
278  AudioChannelLayout *channel_layout = av_malloc(layout_size);
279 
280  if (!channel_layout)
281  return AVERROR(ENOMEM);
282 
283  if (avctx->codec_id == AV_CODEC_ID_ILBC) {
284  int mode = get_ilbc_mode(avctx);
285  out_format.mFramesPerPacket = 8000 * mode / 1000;
286  out_format.mBytesPerPacket = (mode == 20 ? 38 : 50);
287  }
288 
289  status = AudioConverterNew(&in_format, &out_format, &at->converter);
290 
291  if (status != 0) {
292  av_log(avctx, AV_LOG_ERROR, "AudioToolbox init error: %i\n", (int)status);
293  av_free(channel_layout);
294  return AVERROR_UNKNOWN;
295  }
296 
299 
300  if ((status = remap_layout(channel_layout, &avctx->ch_layout)) < 0) {
301  av_log(avctx, AV_LOG_ERROR, "Invalid channel layout\n");
302  av_free(channel_layout);
303  return status;
304  }
305 
306  if (AudioConverterSetProperty(at->converter, kAudioConverterInputChannelLayout,
307  layout_size, channel_layout)) {
308  av_log(avctx, AV_LOG_ERROR, "Unsupported input channel layout\n");
309  av_free(channel_layout);
310  return AVERROR(EINVAL);
311  }
312  if (avctx->codec_id == AV_CODEC_ID_AAC) {
313  int tag = get_aac_tag(&avctx->ch_layout);
314  if (tag) {
315  channel_layout->mChannelLayoutTag = tag;
316  channel_layout->mNumberChannelDescriptions = 0;
317  }
318  }
319  if (AudioConverterSetProperty(at->converter, kAudioConverterOutputChannelLayout,
320  layout_size, channel_layout)) {
321  av_log(avctx, AV_LOG_ERROR, "Unsupported output channel layout\n");
322  av_free(channel_layout);
323  return AVERROR(EINVAL);
324  }
325  av_free(channel_layout);
326 
327  if (avctx->bits_per_raw_sample)
328  AudioConverterSetProperty(at->converter,
329  kAudioConverterPropertyBitDepthHint,
330  sizeof(avctx->bits_per_raw_sample),
331  &avctx->bits_per_raw_sample);
332 
333 #if !TARGET_OS_IPHONE
334  if (at->mode == -1)
335  at->mode = (avctx->flags & AV_CODEC_FLAG_QSCALE) ?
336  kAudioCodecBitRateControlMode_Variable :
337  kAudioCodecBitRateControlMode_Constant;
338 
339  AudioConverterSetProperty(at->converter, kAudioCodecPropertyBitRateControlMode,
340  sizeof(at->mode), &at->mode);
341 
342  if (at->mode == kAudioCodecBitRateControlMode_Variable) {
343  int q = avctx->global_quality / FF_QP2LAMBDA;
344  if (q < 0 || q > 14) {
345  av_log(avctx, AV_LOG_WARNING,
346  "VBR quality %d out of range, should be 0-14\n", q);
347  q = av_clip(q, 0, 14);
348  }
349  q = 127 - q * 9;
350  AudioConverterSetProperty(at->converter, kAudioCodecPropertySoundQualityForVBR,
351  sizeof(q), &q);
352  } else
353 #endif
354  if (avctx->bit_rate > 0) {
355  UInt32 rate = avctx->bit_rate;
356  UInt32 size;
357  status = AudioConverterGetPropertyInfo(at->converter,
358  kAudioConverterApplicableEncodeBitRates,
359  &size, NULL);
360  if (!status && size) {
361  UInt32 new_rate = rate;
362  int count;
363  int i;
364  AudioValueRange *ranges = av_malloc(size);
365  if (!ranges)
366  return AVERROR(ENOMEM);
367  AudioConverterGetProperty(at->converter,
368  kAudioConverterApplicableEncodeBitRates,
369  &size, ranges);
370  count = size / sizeof(AudioValueRange);
371  for (i = 0; i < count; i++) {
372  AudioValueRange *range = &ranges[i];
373  if (rate >= range->mMinimum && rate <= range->mMaximum) {
374  new_rate = rate;
375  break;
376  } else if (rate > range->mMaximum) {
377  new_rate = range->mMaximum;
378  } else {
379  new_rate = range->mMinimum;
380  break;
381  }
382  }
383  if (new_rate != rate) {
384  av_log(avctx, AV_LOG_WARNING,
385  "Bitrate %u not allowed; changing to %u\n", rate, new_rate);
386  rate = new_rate;
387  }
388  av_free(ranges);
389  }
390  AudioConverterSetProperty(at->converter, kAudioConverterEncodeBitRate,
391  sizeof(rate), &rate);
392  }
393 
394  at->quality = 96 - at->quality * 32;
395  AudioConverterSetProperty(at->converter, kAudioConverterCodecQuality,
396  sizeof(at->quality), &at->quality);
397 
398  if (!AudioConverterGetPropertyInfo(at->converter, kAudioConverterCompressionMagicCookie,
399  &avctx->extradata_size, NULL) &&
400  avctx->extradata_size) {
401  int extradata_size = avctx->extradata_size;
402  uint8_t *extradata;
404  return AVERROR(ENOMEM);
405  if (avctx->codec_id == AV_CODEC_ID_ALAC) {
406  avctx->extradata_size = 0x24;
407  AV_WB32(avctx->extradata, 0x24);
408  AV_WB32(avctx->extradata + 4, MKBETAG('a','l','a','c'));
409  extradata = avctx->extradata + 12;
410  avctx->extradata_size = 0x24;
411  } else {
412  extradata = avctx->extradata;
413  }
414  status = AudioConverterGetProperty(at->converter,
415  kAudioConverterCompressionMagicCookie,
416  &extradata_size, extradata);
417  if (status != 0) {
418  av_log(avctx, AV_LOG_ERROR, "AudioToolbox cookie error: %i\n", (int)status);
419  return AVERROR_UNKNOWN;
420  } else if (avctx->codec_id == AV_CODEC_ID_AAC) {
421  GetByteContext gb;
422  int tag, len;
423  bytestream2_init(&gb, extradata, extradata_size);
424  do {
425  len = read_descr(&gb, &tag);
426  if (tag == MP4DecConfigDescrTag) {
427  bytestream2_skip(&gb, 13);
428  len = read_descr(&gb, &tag);
429  if (tag == MP4DecSpecificDescrTag) {
430  len = FFMIN(gb.buffer_end - gb.buffer, len);
431  memmove(extradata, gb.buffer, len);
432  avctx->extradata_size = len;
433  break;
434  }
435  } else if (tag == MP4ESDescrTag) {
436  int flags;
437  bytestream2_skip(&gb, 2);
438  flags = bytestream2_get_byte(&gb);
439  if (flags & 0x80) //streamDependenceFlag
440  bytestream2_skip(&gb, 2);
441  if (flags & 0x40) //URL_Flag
442  bytestream2_skip(&gb, bytestream2_get_byte(&gb));
443  if (flags & 0x20) //OCRstreamFlag
444  bytestream2_skip(&gb, 2);
445  }
446  } while (bytestream2_get_bytes_left(&gb));
447  } else if (avctx->codec_id != AV_CODEC_ID_ALAC) {
448  avctx->extradata_size = extradata_size;
449  }
450  }
451 
452  ret = ffat_update_ctx(avctx);
453  if (ret < 0)
454  return ret;
455 
456 #if !TARGET_OS_IPHONE && defined(__MAC_10_9)
457  if (at->mode == kAudioCodecBitRateControlMode_Variable && avctx->rc_max_rate) {
458  UInt32 max_size = avctx->rc_max_rate * avctx->frame_size / avctx->sample_rate;
459  if (max_size)
460  AudioConverterSetProperty(at->converter, kAudioCodecPropertyPacketSizeLimitForVBR,
461  sizeof(max_size), &max_size);
462  }
463 #endif
464 
465  ff_af_queue_init(avctx, &at->afq);
466 
468  if (!at->encoding_frame)
469  return AVERROR(ENOMEM);
470 
471  return 0;
472 }
473 
474 static OSStatus ffat_encode_callback(AudioConverterRef converter, UInt32 *nb_packets,
475  AudioBufferList *data,
476  AudioStreamPacketDescription **packets,
477  void *inctx)
478 {
479  AVCodecContext *avctx = inctx;
480  ATDecodeContext *at = avctx->priv_data;
481  AVFrame *frame;
482  int ret;
483 
484  if (!at->frame_queue.available) {
485  if (at->eof) {
486  *nb_packets = 0;
487  return 0;
488  } else {
489  *nb_packets = 0;
490  return 1;
491  }
492  }
493 
495 
496  data->mNumberBuffers = 1;
497  data->mBuffers[0].mNumberChannels = avctx->ch_layout.nb_channels;
498  data->mBuffers[0].mDataByteSize = frame->nb_samples *
500  avctx->ch_layout.nb_channels;
501  data->mBuffers[0].mData = frame->data[0];
502  if (*nb_packets > frame->nb_samples)
503  *nb_packets = frame->nb_samples;
504 
506  if (ret < 0) {
507  *nb_packets = 0;
508  return ret;
509  }
510 
511  ff_bufqueue_add(avctx, &at->used_frame_queue, frame);
512 
513  return 0;
514 }
515 
516 static int ffat_encode(AVCodecContext *avctx, AVPacket *avpkt,
517  const AVFrame *frame, int *got_packet_ptr)
518 {
519  ATDecodeContext *at = avctx->priv_data;
520  OSStatus ret;
521 
522  AudioBufferList out_buffers = {
523  .mNumberBuffers = 1,
524  .mBuffers = {
525  {
526  .mNumberChannels = avctx->ch_layout.nb_channels,
527  .mDataByteSize = at->pkt_size,
528  }
529  }
530  };
531  AudioStreamPacketDescription out_pkt_desc = {0};
532 
533  if (frame) {
534  AVFrame *in_frame;
535 
536  if (ff_bufqueue_is_full(&at->frame_queue)) {
537  /*
538  * The frame queue is significantly larger than needed in practice,
539  * but no clear way to determine the minimum number of samples to
540  * get output from AudioConverterFillComplexBuffer().
541  */
542  av_log(avctx, AV_LOG_ERROR, "Bug: frame queue is too small.\n");
543  return AVERROR_BUG;
544  }
545 
546  if ((ret = ff_af_queue_add(&at->afq, frame)) < 0)
547  return ret;
548 
549  in_frame = av_frame_clone(frame);
550  if (!in_frame)
551  return AVERROR(ENOMEM);
552 
553  ff_bufqueue_add(avctx, &at->frame_queue, in_frame);
554  } else {
555  at->eof = 1;
556  }
557 
558  if ((ret = ff_alloc_packet(avctx, avpkt, at->pkt_size)) < 0)
559  return ret;
560 
561 
562  out_buffers.mBuffers[0].mData = avpkt->data;
563 
564  *got_packet_ptr = avctx->frame_size / at->frame_size;
565 
566  ret = AudioConverterFillComplexBuffer(at->converter, ffat_encode_callback, avctx,
567  got_packet_ptr, &out_buffers,
568  (avctx->frame_size > at->frame_size) ? NULL : &out_pkt_desc);
569 
571 
572  if ((!ret || ret == 1) && *got_packet_ptr) {
573  avpkt->size = out_buffers.mBuffers[0].mDataByteSize;
574  ff_af_queue_remove(&at->afq, out_pkt_desc.mVariableFramesInPacket ?
575  out_pkt_desc.mVariableFramesInPacket :
576  avctx->frame_size,
577  &avpkt->pts,
578  &avpkt->duration);
579  avpkt->flags |= AV_PKT_FLAG_KEY;
580  } else if (ret && ret != 1) {
581  av_log(avctx, AV_LOG_ERROR, "Encode error: %i\n", ret);
582  return AVERROR_EXTERNAL;
583  }
584 
585  return 0;
586 }
587 
589 {
590  ATDecodeContext *at = avctx->priv_data;
591  AudioConverterReset(at->converter);
594 }
595 
597 {
598  ATDecodeContext *at = avctx->priv_data;
599  AudioConverterDispose(at->converter);
602  ff_af_queue_close(&at->afq);
604  return 0;
605 }
606 
607 static const AVProfile aac_profiles[] = {
608  { AV_PROFILE_AAC_LOW, "LC" },
609  { AV_PROFILE_AAC_HE, "HE-AAC" },
610  { AV_PROFILE_AAC_HE_V2, "HE-AACv2" },
611  { AV_PROFILE_AAC_LD, "LD" },
612  { AV_PROFILE_AAC_ELD, "ELD" },
613  { AV_PROFILE_UNKNOWN },
614 };
615 
616 #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
617 static const AVOption options[] = {
618 #if !TARGET_OS_IPHONE
619  {"aac_at_mode", "ratecontrol mode", offsetof(ATDecodeContext, mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, kAudioCodecBitRateControlMode_Variable, AE, .unit = "mode"},
620  {"auto", "VBR if global quality is given; CBR otherwise", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, INT_MIN, INT_MAX, AE, .unit = "mode"},
621  {"cbr", "constant bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Constant}, INT_MIN, INT_MAX, AE, .unit = "mode"},
622  {"abr", "long-term average bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_LongTermAverage}, INT_MIN, INT_MAX, AE, .unit = "mode"},
623  {"cvbr", "constrained variable bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_VariableConstrained}, INT_MIN, INT_MAX, AE, .unit = "mode"},
624  {"vbr" , "variable bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Variable}, INT_MIN, INT_MAX, AE, .unit = "mode"},
625 #endif
626  {"aac_at_quality", "quality vs speed control", offsetof(ATDecodeContext, quality), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 2, AE},
627  { NULL },
628 };
629 
630 #define FFAT_ENC_CLASS(NAME) \
631  static const AVClass ffat_##NAME##_enc_class = { \
632  .class_name = "at_" #NAME "_enc", \
633  .item_name = av_default_item_name, \
634  .option = options, \
635  .version = LIBAVUTIL_VERSION_INT, \
636  };
637 
638 #define FFAT_ENC(NAME, ID, PROFILES, CAPS, CHANNEL_LAYOUTS, CH_LAYOUTS) \
639  FFAT_ENC_CLASS(NAME) \
640  const FFCodec ff_##NAME##_at_encoder = { \
641  .p.name = #NAME "_at", \
642  CODEC_LONG_NAME(#NAME " (AudioToolbox)"), \
643  .p.type = AVMEDIA_TYPE_AUDIO, \
644  .p.id = ID, \
645  .priv_data_size = sizeof(ATDecodeContext), \
646  .init = ffat_init_encoder, \
647  .close = ffat_close_encoder, \
648  FF_CODEC_ENCODE_CB(ffat_encode), \
649  .flush = ffat_encode_flush, \
650  .p.priv_class = &ffat_##NAME##_enc_class, \
651  .p.capabilities = AV_CODEC_CAP_DELAY | \
652  AV_CODEC_CAP_ENCODER_FLUSH CAPS, \
653  .p.ch_layouts = CH_LAYOUTS, \
654  .p.sample_fmts = (const enum AVSampleFormat[]) { \
655  AV_SAMPLE_FMT_S16, \
656  AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE \
657  }, \
658  .p.profiles = PROFILES, \
659  .p.wrapper_name = "at", \
660  };
661 
675  { 0 },
676 };
677 
678 FFAT_ENC(aac, AV_CODEC_ID_AAC, aac_profiles, , aac_at_channel_layouts, aac_at_ch_layouts)
679 //FFAT_ENC(adpcm_ima_qt, AV_CODEC_ID_ADPCM_IMA_QT, NULL)
read_descr
static int read_descr(GetByteContext *gb, int *tag)
Definition: audiotoolboxenc.c:151
AVCodecContext::frame_size
int frame_size
Number of samples per channel in an audio frame.
Definition: avcodec.h:1083
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
AV_CODEC_ID_ADPCM_IMA_QT
@ AV_CODEC_ID_ADPCM_IMA_QT
Definition: codec_id.h:373
MP4DecConfigDescrTag
#define MP4DecConfigDescrTag
Definition: isom.h:383
FFAT_ENC
#define FFAT_ENC(NAME, ID, PROFILES, CAPS, CHANNEL_LAYOUTS, CH_LAYOUTS)
Definition: audiotoolboxenc.c:638
av_clip
#define av_clip
Definition: common.h:100
AV_CHANNEL_LAYOUT_OCTAGONAL
#define AV_CHANNEL_LAYOUT_OCTAGONAL
Definition: channel_layout.h:419
get_channel_label
static av_cold int get_channel_label(int channel)
Definition: audiotoolboxenc.c:177
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
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:393
AVCodecContext::sample_rate
int sample_rate
samples per second
Definition: avcodec.h:1056
GetByteContext
Definition: bytestream.h:33
AV_CH_LOW_FREQUENCY_2
#define AV_CH_LOW_FREQUENCY_2
Definition: channel_layout.h:199
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
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:162
mode
Definition: swscale.c:52
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
av_channel_layout_channel_from_index
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
Definition: channel_layout.c:671
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:539
AVOption
AVOption.
Definition: opt.h:429
encode.h
data
const char data[16]
Definition: mxf.c:149
AV_CODEC_ID_ALAC
@ AV_CODEC_ID_ALAC
Definition: codec_id.h:462
ffat_init_encoder
static av_cold int ffat_init_encoder(AVCodecContext *avctx)
Definition: audiotoolboxenc.c:251
get_ilbc_mode
static int get_ilbc_mode(AVCodecContext *avctx)
Definition: audiotoolboxenc.c:165
aac_profiles
static const AVProfile aac_profiles[]
Definition: audiotoolboxenc.c:607
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:557
AVChannelLayout::order
enum AVChannelOrder order
Channel order used in this layout.
Definition: channel_layout.h:322
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
ffat_get_format_id
static UInt32 ffat_get_format_id(enum AVCodecID codec, int profile)
Definition: audiotoolboxenc.c:59
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:327
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:594
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
ff_bufqueue_get
static AVFrame * ff_bufqueue_get(struct FFBufQueue *queue)
Get the first buffer from the queue and remove it.
Definition: bufferqueue.h:98
AV_CH_SURROUND_DIRECT_RIGHT
#define AV_CH_SURROUND_DIRECT_RIGHT
Definition: channel_layout.h:198
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AV_CH_WIDE_RIGHT
#define AV_CH_WIDE_RIGHT
Definition: channel_layout.h:196
AVProfile
AVProfile.
Definition: codec.h:179
bytestream2_skip
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
ATDecodeContext::used_frame_queue
struct FFBufQueue used_frame_queue
Definition: audiotoolboxenc.c:49
ATDecodeContext::frame_size
int frame_size
Definition: audiotoolboxenc.c:54
ffat_close_encoder
static av_cold int ffat_close_encoder(AVCodecContext *avctx)
Definition: audiotoolboxenc.c:596
ATDecodeContext::eof
int eof
Definition: audiotoolboxdec.c:57
MP4DecSpecificDescrTag
#define MP4DecSpecificDescrTag
Definition: isom.h:384
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition: avcodec.h:1071
AE
#define AE
Definition: audiotoolboxenc.c:616
remap_layout
static int remap_layout(AudioChannelLayout *layout, const AVChannelLayout *in_layout)
Definition: audiotoolboxenc.c:202
audio_frame_queue.h
AVCodecContext::initial_padding
int initial_padding
Audio only.
Definition: avcodec.h:1128
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:508
ffat_encode_callback
static OSStatus ffat_encode_callback(AudioConverterRef converter, UInt32 *nb_packets, AudioBufferList *data, AudioStreamPacketDescription **packets, void *inctx)
Definition: audiotoolboxenc.c:474
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
ATDecodeContext::mode
int mode
Definition: audiotoolboxenc.c:44
ffat_update_ctx
static int ffat_update_ctx(AVCodecContext *avctx)
Definition: audiotoolboxenc.c:96
AV_CHANNEL_LAYOUT_SURROUND
#define AV_CHANNEL_LAYOUT_SURROUND
Definition: channel_layout.h:396
ff_bufqueue_is_full
static int ff_bufqueue_is_full(struct FFBufQueue *queue)
Test if a buffer queue is full.
Definition: bufferqueue.h:60
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:150
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
AV_CH_LOW_FREQUENCY
#define AV_CH_LOW_FREQUENCY
Definition: channel_layout.h:178
AV_CHANNEL_LAYOUT_4POINT0
#define AV_CHANNEL_LAYOUT_4POINT0
Definition: channel_layout.h:398
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:530
AV_CHANNEL_LAYOUT_7POINT1
#define AV_CHANNEL_LAYOUT_7POINT1
Definition: channel_layout.h:415
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1249
AV_CHANNEL_ORDER_UNSPEC
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
Definition: channel_layout.h:119
GetByteContext::buffer
const uint8_t * buffer
Definition: bytestream.h:34
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AudioFrameQueue
Definition: audio_frame_queue.h:32
AVCodecContext::bits_per_raw_sample
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1585
ATDecodeContext::encoding_frame
AVFrame * encoding_frame
Definition: audiotoolboxenc.c:56
AV_PROFILE_AAC_ELD
#define AV_PROFILE_AAC_ELD
Definition: defs.h:75
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:609
AV_CODEC_ID_PCM_MULAW
@ AV_CODEC_ID_PCM_MULAW
Definition: codec_id.h:340
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1302
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:461
AV_CH_STEREO_RIGHT
#define AV_CH_STEREO_RIGHT
Definition: channel_layout.h:194
AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK
#define AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK
Definition: channel_layout.h:417
MP4ESDescrTag
#define MP4ESDescrTag
Definition: isom.h:382
AV_CODEC_ID_PCM_ALAW
@ AV_CODEC_ID_PCM_ALAW
Definition: codec_id.h:341
ATDecodeContext::quality
int quality
Definition: audiotoolboxenc.c:45
get_aac_tag
static int get_aac_tag(const AVChannelLayout *in_layout)
Definition: audiotoolboxenc.c:222
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
NULL
#define NULL
Definition: coverity.c:32
isom.h
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:501
ff_bufqueue_discard_all
static void ff_bufqueue_discard_all(struct FFBufQueue *queue)
Unref and remove all buffers from the queue.
Definition: bufferqueue.h:111
options
Definition: swscale.c:42
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
bytestream2_get_bytes_left
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
AV_CODEC_ID_AAC
@ AV_CODEC_ID_AAC
Definition: codec_id.h:448
bufferqueue.h
AVPacket::size
int size
Definition: packet.h:540
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:317
codec_internal.h
AV_PROFILE_AAC_LD
#define AV_PROFILE_AAC_LD
Definition: defs.h:74
AVCodecContext::sample_fmt
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1063
size
int size
Definition: twinvq_data.h:10344
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
range
enum AVColorRange range
Definition: mediacodec_wrapper.c:2594
AV_CHANNEL_LAYOUT_6POINT0
#define AV_CHANNEL_LAYOUT_6POINT0
Definition: channel_layout.h:406
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
ff_bufqueue_add
static void ff_bufqueue_add(void *log, struct FFBufQueue *queue, AVFrame *buf)
Add a buffer to the queue.
Definition: bufferqueue.h:71
AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_BACK_RIGHT
Definition: channel_layout.h:192
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:545
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:807
av_channel_layout_default
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
Definition: channel_layout.c:837
layout
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 layout
Definition: filter_design.txt:18
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:532
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:108
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:529
FFBufQueue
Structure holding the queue.
Definition: bufferqueue.h:49
AV_CHANNEL_LAYOUT_QUAD
#define AV_CHANNEL_LAYOUT_QUAD
Definition: channel_layout.h:401
AV_SAMPLE_FMT_U8
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition: samplefmt.h:57
FFBufQueue::available
unsigned short available
number of available buffers
Definition: bufferqueue.h:52
AV_CH_BACK_CENTER
#define AV_CH_BACK_CENTER
Definition: channel_layout.h:183
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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
AV_CH_SIDE_RIGHT
#define AV_CH_SIDE_RIGHT
Definition: channel_layout.h:185
len
int len
Definition: vorbis_enc_data.h:426
profile
int profile
Definition: mxfenc.c:2233
GetByteContext::buffer_end
const uint8_t * buffer_end
Definition: bytestream.h:34
avcodec.h
tag
uint32_t tag
Definition: movenc.c:1879
ret
ret
Definition: filter_design.txt:187
AVCodecContext::block_align
int block_align
number of bytes per packet if constant and known or 0 Used by some WAV based audio codecs.
Definition: avcodec.h:1089
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
ffat_encode_flush
static av_cold void ffat_encode_flush(AVCodecContext *avctx)
Definition: audiotoolboxenc.c:588
AV_CHANNEL_LAYOUT_7POINT0
#define AV_CHANNEL_LAYOUT_7POINT0
Definition: channel_layout.h:413
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
av_frame_replace
int av_frame_replace(AVFrame *dst, const AVFrame *src)
Ensure the destination frame refers to the same data described by the source frame,...
Definition: frame.c:499
ATDecodeContext::converter
AudioConverterRef converter
Definition: audiotoolboxdec.c:46
AVCodecContext
main external API structure.
Definition: avcodec.h:451
status
ov_status_e status
Definition: dnn_backend_openvino.c:100
channel_layout.h
AV_PROFILE_AAC_HE_V2
#define AV_PROFILE_AAC_HE_V2
Definition: defs.h:73
ffat_encode
static int ffat_encode(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition: audiotoolboxenc.c:516
ATDecodeContext
Definition: audiotoolboxdec.c:43
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1650
mem.h
map
const VDPAUPixFmtMap * map
Definition: hwcontext_vdpau.c:71
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:392
AV_PROFILE_AAC_HE
#define AV_PROFILE_AAC_HE
Definition: defs.h:72
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVPacket
This structure stores compressed data.
Definition: packet.h:516
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
aac_at_ch_layouts
static const AVChannelLayout aac_at_ch_layouts[]
Definition: audiotoolboxenc.c:662
ATDecodeContext::pkt_size
unsigned pkt_size
Definition: audiotoolboxenc.c:51
AV_CODEC_ID_ILBC
@ AV_CODEC_ID_ILBC
Definition: codec_id.h:505
bytestream.h
ATDecodeContext::av_class
AVClass * av_class
Definition: audiotoolboxdec.c:44
bytestream2_init
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
ATDecodeContext::afq
AudioFrameQueue afq
Definition: audiotoolboxenc.c:52
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AV_CHANNEL_LAYOUT_6POINT1
#define AV_CHANNEL_LAYOUT_6POINT1
Definition: channel_layout.h:410
AV_CH_BACK_RIGHT
#define AV_CH_BACK_RIGHT
Definition: channel_layout.h:180
AV_CHANNEL_LAYOUT_5POINT0
#define AV_CHANNEL_LAYOUT_5POINT0
Definition: channel_layout.h:402
AV_SAMPLE_FMT_DBL
@ AV_SAMPLE_FMT_DBL
double
Definition: samplefmt.h:61
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:227
AV_CHANNEL_LAYOUT_5POINT1
#define AV_CHANNEL_LAYOUT_5POINT1
Definition: channel_layout.h:403
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
ff_alloc_packet
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition: encode.c:62
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:60
channel
channel
Definition: ebur128.h:39
ATDecodeContext::frame_queue
struct FFBufQueue frame_queue
Definition: audiotoolboxenc.c:48