• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
26 #include "libavfilter/bufferqueue.h"
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"
37 #include "libavutil/channel_layout.h"
38 #include "libavutil/opt.h"
39 #include "libavutil/log.h"
40 
41 typedef struct ATDecodeContext {
42     AVClass *av_class;
43     int mode;
44     int quality;
45 
46     AudioConverterRef converter;
47     struct FFBufQueue frame_queue;
48     struct FFBufQueue used_frame_queue;
49 
50     unsigned pkt_size;
51     AudioFrameQueue afq;
52     int eof;
53     int frame_size;
54 
55     AVFrame* encoding_frame;
56 } ATDecodeContext;
57 
ffat_get_format_id(enum AVCodecID codec,int profile)58 static UInt32 ffat_get_format_id(enum AVCodecID codec, int profile)
59 {
60     switch (codec) {
61     case AV_CODEC_ID_AAC:
62         switch (profile) {
63         case FF_PROFILE_AAC_LOW:
64         default:
65             return kAudioFormatMPEG4AAC;
66         case FF_PROFILE_AAC_HE:
67             return kAudioFormatMPEG4AAC_HE;
68         case FF_PROFILE_AAC_HE_V2:
69             return kAudioFormatMPEG4AAC_HE_V2;
70         case FF_PROFILE_AAC_LD:
71             return kAudioFormatMPEG4AAC_LD;
72         case FF_PROFILE_AAC_ELD:
73             return kAudioFormatMPEG4AAC_ELD;
74         }
75     case AV_CODEC_ID_ADPCM_IMA_QT:
76         return kAudioFormatAppleIMA4;
77     case AV_CODEC_ID_ALAC:
78         return kAudioFormatAppleLossless;
79     case AV_CODEC_ID_ILBC:
80         return kAudioFormatiLBC;
81     case AV_CODEC_ID_PCM_ALAW:
82         return kAudioFormatALaw;
83     case AV_CODEC_ID_PCM_MULAW:
84         return kAudioFormatULaw;
85     default:
86         av_assert0(!"Invalid codec ID!");
87         return 0;
88     }
89 }
90 
ffat_update_ctx(AVCodecContext * avctx)91 static void ffat_update_ctx(AVCodecContext *avctx)
92 {
93     ATDecodeContext *at = avctx->priv_data;
94     UInt32 size = sizeof(unsigned);
95     AudioConverterPrimeInfo prime_info;
96     AudioStreamBasicDescription out_format;
97 
98     AudioConverterGetProperty(at->converter,
99                               kAudioConverterPropertyMaximumOutputPacketSize,
100                               &size, &at->pkt_size);
101 
102     if (at->pkt_size <= 0)
103         at->pkt_size = 1024 * 50;
104 
105     size = sizeof(prime_info);
106 
107     if (!AudioConverterGetProperty(at->converter,
108                                    kAudioConverterPrimeInfo,
109                                    &size, &prime_info)) {
110         avctx->initial_padding = prime_info.leadingFrames;
111     }
112 
113     size = sizeof(out_format);
114     if (!AudioConverterGetProperty(at->converter,
115                                    kAudioConverterCurrentOutputStreamDescription,
116                                    &size, &out_format)) {
117         if (out_format.mFramesPerPacket)
118             avctx->frame_size = out_format.mFramesPerPacket;
119         if (out_format.mBytesPerPacket && avctx->codec_id == AV_CODEC_ID_ILBC)
120             avctx->block_align = out_format.mBytesPerPacket;
121     }
122 
123     at->frame_size = avctx->frame_size;
124     if (avctx->codec_id == AV_CODEC_ID_PCM_MULAW ||
125         avctx->codec_id == AV_CODEC_ID_PCM_ALAW) {
126         at->pkt_size *= 1024;
127         avctx->frame_size *= 1024;
128     }
129 }
130 
read_descr(GetByteContext * gb,int * tag)131 static int read_descr(GetByteContext *gb, int *tag)
132 {
133     int len = 0;
134     int count = 4;
135     *tag = bytestream2_get_byte(gb);
136     while (count--) {
137         int c = bytestream2_get_byte(gb);
138         len = (len << 7) | (c & 0x7f);
139         if (!(c & 0x80))
140             break;
141     }
142     return len;
143 }
144 
get_ilbc_mode(AVCodecContext * avctx)145 static int get_ilbc_mode(AVCodecContext *avctx)
146 {
147     if (avctx->block_align == 38)
148         return 20;
149     else if (avctx->block_align == 50)
150         return 30;
151     else if (avctx->bit_rate > 0)
152         return avctx->bit_rate <= 14000 ? 30 : 20;
153     else
154         return 30;
155 }
156 
get_channel_label(int channel)157 static av_cold int get_channel_label(int channel)
158 {
159     uint64_t map = 1 << channel;
160     if (map <= AV_CH_LOW_FREQUENCY)
161         return channel + 1;
162     else if (map <= AV_CH_BACK_RIGHT)
163         return channel + 29;
164     else if (map <= AV_CH_BACK_CENTER)
165         return channel - 1;
166     else if (map <= AV_CH_SIDE_RIGHT)
167         return channel - 4;
168     else if (map <= AV_CH_TOP_BACK_RIGHT)
169         return channel + 1;
170     else if (map <= AV_CH_STEREO_RIGHT)
171         return -1;
172     else if (map <= AV_CH_WIDE_RIGHT)
173         return channel + 4;
174     else if (map <= AV_CH_SURROUND_DIRECT_RIGHT)
175         return channel - 23;
176     else if (map == AV_CH_LOW_FREQUENCY_2)
177         return kAudioChannelLabel_LFE2;
178     else
179         return -1;
180 }
181 
remap_layout(AudioChannelLayout * layout,const AVChannelLayout * in_layout)182 static int remap_layout(AudioChannelLayout *layout, const AVChannelLayout *in_layout)
183 {
184     int i;
185     layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
186     layout->mNumberChannelDescriptions = in_layout->nb_channels;
187     for (i = 0; i < in_layout->nb_channels; i++) {
188         int c, label;
189 
190         c = av_channel_layout_channel_from_index(in_layout, i);
191         if (c < 0 || c >= 64)
192             return AVERROR(EINVAL);
193         label = get_channel_label(c);
194         layout->mChannelDescriptions[i].mChannelLabel = label;
195         if (label < 0)
196             return AVERROR(EINVAL);
197         c++;
198     }
199     return 0;
200 }
201 
get_aac_tag(const AVChannelLayout * in_layout)202 static int get_aac_tag(const AVChannelLayout *in_layout)
203 {
204     static const struct {
205         AVChannelLayout chl;
206         int tag;
207     } map[] = {
208         { AV_CHANNEL_LAYOUT_MONO,              kAudioChannelLayoutTag_Mono },
209         { AV_CHANNEL_LAYOUT_STEREO,            kAudioChannelLayoutTag_Stereo },
210         { AV_CHANNEL_LAYOUT_QUAD,              kAudioChannelLayoutTag_AAC_Quadraphonic },
211         { AV_CHANNEL_LAYOUT_OCTAGONAL,         kAudioChannelLayoutTag_AAC_Octagonal },
212         { AV_CHANNEL_LAYOUT_SURROUND,          kAudioChannelLayoutTag_AAC_3_0 },
213         { AV_CHANNEL_LAYOUT_4POINT0,           kAudioChannelLayoutTag_AAC_4_0 },
214         { AV_CHANNEL_LAYOUT_5POINT0,           kAudioChannelLayoutTag_AAC_5_0 },
215         { AV_CHANNEL_LAYOUT_5POINT1,           kAudioChannelLayoutTag_AAC_5_1 },
216         { AV_CHANNEL_LAYOUT_6POINT0,           kAudioChannelLayoutTag_AAC_6_0 },
217         { AV_CHANNEL_LAYOUT_6POINT1,           kAudioChannelLayoutTag_AAC_6_1 },
218         { AV_CHANNEL_LAYOUT_7POINT0,           kAudioChannelLayoutTag_AAC_7_0 },
219         { AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK, kAudioChannelLayoutTag_AAC_7_1 },
220         { AV_CHANNEL_LAYOUT_7POINT1,           kAudioChannelLayoutTag_MPEG_7_1_C },
221     };
222     int i;
223 
224     for (i = 0; i < FF_ARRAY_ELEMS(map); i++)
225         if (!av_channel_layout_compare(in_layout, &map[i].chl))
226             return map[i].tag;
227 
228     return 0;
229 }
230 
ffat_init_encoder(AVCodecContext * avctx)231 static av_cold int ffat_init_encoder(AVCodecContext *avctx)
232 {
233     ATDecodeContext *at = avctx->priv_data;
234     OSStatus status;
235 
236     AudioStreamBasicDescription in_format = {
237         .mSampleRate = avctx->sample_rate,
238         .mFormatID = kAudioFormatLinearPCM,
239         .mFormatFlags = ((avctx->sample_fmt == AV_SAMPLE_FMT_FLT ||
240                           avctx->sample_fmt == AV_SAMPLE_FMT_DBL) ? kAudioFormatFlagIsFloat
241                         : avctx->sample_fmt == AV_SAMPLE_FMT_U8 ? 0
242                         : kAudioFormatFlagIsSignedInteger)
243                         | kAudioFormatFlagIsPacked,
244         .mBytesPerPacket = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->ch_layout.nb_channels,
245         .mFramesPerPacket = 1,
246         .mBytesPerFrame = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->ch_layout.nb_channels,
247         .mChannelsPerFrame = avctx->ch_layout.nb_channels,
248         .mBitsPerChannel = av_get_bytes_per_sample(avctx->sample_fmt) * 8,
249     };
250     AudioStreamBasicDescription out_format = {
251         .mSampleRate = avctx->sample_rate,
252         .mFormatID = ffat_get_format_id(avctx->codec_id, avctx->profile),
253         .mChannelsPerFrame = in_format.mChannelsPerFrame,
254     };
255     UInt32 layout_size = sizeof(AudioChannelLayout) +
256                          sizeof(AudioChannelDescription) * avctx->ch_layout.nb_channels;
257     AudioChannelLayout *channel_layout = av_malloc(layout_size);
258 
259     if (!channel_layout)
260         return AVERROR(ENOMEM);
261 
262     if (avctx->codec_id == AV_CODEC_ID_ILBC) {
263         int mode = get_ilbc_mode(avctx);
264         out_format.mFramesPerPacket  = 8000 * mode / 1000;
265         out_format.mBytesPerPacket   = (mode == 20 ? 38 : 50);
266     }
267 
268     status = AudioConverterNew(&in_format, &out_format, &at->converter);
269 
270     if (status != 0) {
271         av_log(avctx, AV_LOG_ERROR, "AudioToolbox init error: %i\n", (int)status);
272         av_free(channel_layout);
273         return AVERROR_UNKNOWN;
274     }
275 
276     if (avctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
277         av_channel_layout_default(&avctx->ch_layout, avctx->ch_layout.nb_channels);
278 
279     if ((status = remap_layout(channel_layout, &avctx->ch_layout)) < 0) {
280         av_log(avctx, AV_LOG_ERROR, "Invalid channel layout\n");
281         av_free(channel_layout);
282         return status;
283     }
284 
285     if (AudioConverterSetProperty(at->converter, kAudioConverterInputChannelLayout,
286                                   layout_size, channel_layout)) {
287         av_log(avctx, AV_LOG_ERROR, "Unsupported input channel layout\n");
288         av_free(channel_layout);
289         return AVERROR(EINVAL);
290     }
291     if (avctx->codec_id == AV_CODEC_ID_AAC) {
292         int tag = get_aac_tag(&avctx->ch_layout);
293         if (tag) {
294             channel_layout->mChannelLayoutTag = tag;
295             channel_layout->mNumberChannelDescriptions = 0;
296         }
297     }
298     if (AudioConverterSetProperty(at->converter, kAudioConverterOutputChannelLayout,
299                                   layout_size, channel_layout)) {
300         av_log(avctx, AV_LOG_ERROR, "Unsupported output channel layout\n");
301         av_free(channel_layout);
302         return AVERROR(EINVAL);
303     }
304     av_free(channel_layout);
305 
306     if (avctx->bits_per_raw_sample)
307         AudioConverterSetProperty(at->converter,
308                                   kAudioConverterPropertyBitDepthHint,
309                                   sizeof(avctx->bits_per_raw_sample),
310                                   &avctx->bits_per_raw_sample);
311 
312 #if !TARGET_OS_IPHONE
313     if (at->mode == -1)
314         at->mode = (avctx->flags & AV_CODEC_FLAG_QSCALE) ?
315                    kAudioCodecBitRateControlMode_Variable :
316                    kAudioCodecBitRateControlMode_Constant;
317 
318     AudioConverterSetProperty(at->converter, kAudioCodecPropertyBitRateControlMode,
319                               sizeof(at->mode), &at->mode);
320 
321     if (at->mode == kAudioCodecBitRateControlMode_Variable) {
322         int q = avctx->global_quality / FF_QP2LAMBDA;
323         if (q < 0 || q > 14) {
324             av_log(avctx, AV_LOG_WARNING,
325                    "VBR quality %d out of range, should be 0-14\n", q);
326             q = av_clip(q, 0, 14);
327         }
328         q = 127 - q * 9;
329         AudioConverterSetProperty(at->converter, kAudioCodecPropertySoundQualityForVBR,
330                                   sizeof(q), &q);
331     } else
332 #endif
333     if (avctx->bit_rate > 0) {
334         UInt32 rate = avctx->bit_rate;
335         UInt32 size;
336         status = AudioConverterGetPropertyInfo(at->converter,
337                                                kAudioConverterApplicableEncodeBitRates,
338                                                &size, NULL);
339         if (!status && size) {
340             UInt32 new_rate = rate;
341             int count;
342             int i;
343             AudioValueRange *ranges = av_malloc(size);
344             if (!ranges)
345                 return AVERROR(ENOMEM);
346             AudioConverterGetProperty(at->converter,
347                                       kAudioConverterApplicableEncodeBitRates,
348                                       &size, ranges);
349             count = size / sizeof(AudioValueRange);
350             for (i = 0; i < count; i++) {
351                 AudioValueRange *range = &ranges[i];
352                 if (rate >= range->mMinimum && rate <= range->mMaximum) {
353                     new_rate = rate;
354                     break;
355                 } else if (rate > range->mMaximum) {
356                     new_rate = range->mMaximum;
357                 } else {
358                     new_rate = range->mMinimum;
359                     break;
360                 }
361             }
362             if (new_rate != rate) {
363                 av_log(avctx, AV_LOG_WARNING,
364                        "Bitrate %u not allowed; changing to %u\n", rate, new_rate);
365                 rate = new_rate;
366             }
367             av_free(ranges);
368         }
369         AudioConverterSetProperty(at->converter, kAudioConverterEncodeBitRate,
370                                   sizeof(rate), &rate);
371     }
372 
373     at->quality = 96 - at->quality * 32;
374     AudioConverterSetProperty(at->converter, kAudioConverterCodecQuality,
375                               sizeof(at->quality), &at->quality);
376 
377     if (!AudioConverterGetPropertyInfo(at->converter, kAudioConverterCompressionMagicCookie,
378                                        &avctx->extradata_size, NULL) &&
379         avctx->extradata_size) {
380         int extradata_size = avctx->extradata_size;
381         uint8_t *extradata;
382         if (!(avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE)))
383             return AVERROR(ENOMEM);
384         if (avctx->codec_id == AV_CODEC_ID_ALAC) {
385             avctx->extradata_size = 0x24;
386             AV_WB32(avctx->extradata,     0x24);
387             AV_WB32(avctx->extradata + 4, MKBETAG('a','l','a','c'));
388             extradata = avctx->extradata + 12;
389             avctx->extradata_size = 0x24;
390         } else {
391             extradata = avctx->extradata;
392         }
393         status = AudioConverterGetProperty(at->converter,
394                                            kAudioConverterCompressionMagicCookie,
395                                            &extradata_size, extradata);
396         if (status != 0) {
397             av_log(avctx, AV_LOG_ERROR, "AudioToolbox cookie error: %i\n", (int)status);
398             return AVERROR_UNKNOWN;
399         } else if (avctx->codec_id == AV_CODEC_ID_AAC) {
400             GetByteContext gb;
401             int tag, len;
402             bytestream2_init(&gb, extradata, extradata_size);
403             do {
404                 len = read_descr(&gb, &tag);
405                 if (tag == MP4DecConfigDescrTag) {
406                     bytestream2_skip(&gb, 13);
407                     len = read_descr(&gb, &tag);
408                     if (tag == MP4DecSpecificDescrTag) {
409                         len = FFMIN(gb.buffer_end - gb.buffer, len);
410                         memmove(extradata, gb.buffer, len);
411                         avctx->extradata_size = len;
412                         break;
413                     }
414                 } else if (tag == MP4ESDescrTag) {
415                     int flags;
416                     bytestream2_skip(&gb, 2);
417                     flags = bytestream2_get_byte(&gb);
418                     if (flags & 0x80) //streamDependenceFlag
419                         bytestream2_skip(&gb, 2);
420                     if (flags & 0x40) //URL_Flag
421                         bytestream2_skip(&gb, bytestream2_get_byte(&gb));
422                     if (flags & 0x20) //OCRstreamFlag
423                         bytestream2_skip(&gb, 2);
424                 }
425             } while (bytestream2_get_bytes_left(&gb));
426         } else if (avctx->codec_id != AV_CODEC_ID_ALAC) {
427             avctx->extradata_size = extradata_size;
428         }
429     }
430 
431     ffat_update_ctx(avctx);
432 
433 #if !TARGET_OS_IPHONE && defined(__MAC_10_9)
434     if (at->mode == kAudioCodecBitRateControlMode_Variable && avctx->rc_max_rate) {
435         UInt32 max_size = avctx->rc_max_rate * avctx->frame_size / avctx->sample_rate;
436         if (max_size)
437             AudioConverterSetProperty(at->converter, kAudioCodecPropertyPacketSizeLimitForVBR,
438                                       sizeof(max_size), &max_size);
439     }
440 #endif
441 
442     ff_af_queue_init(avctx, &at->afq);
443 
444     at->encoding_frame = av_frame_alloc();
445     if (!at->encoding_frame)
446         return AVERROR(ENOMEM);
447 
448     return 0;
449 }
450 
ffat_encode_callback(AudioConverterRef converter,UInt32 * nb_packets,AudioBufferList * data,AudioStreamPacketDescription ** packets,void * inctx)451 static OSStatus ffat_encode_callback(AudioConverterRef converter, UInt32 *nb_packets,
452                                      AudioBufferList *data,
453                                      AudioStreamPacketDescription **packets,
454                                      void *inctx)
455 {
456     AVCodecContext *avctx = inctx;
457     ATDecodeContext *at = avctx->priv_data;
458     AVFrame *frame;
459     int ret;
460 
461     if (!at->frame_queue.available) {
462         if (at->eof) {
463             *nb_packets = 0;
464             return 0;
465         } else {
466             *nb_packets = 0;
467             return 1;
468         }
469     }
470 
471     frame = ff_bufqueue_get(&at->frame_queue);
472 
473     data->mNumberBuffers              = 1;
474     data->mBuffers[0].mNumberChannels = avctx->ch_layout.nb_channels;
475     data->mBuffers[0].mDataByteSize   = frame->nb_samples *
476                                         av_get_bytes_per_sample(avctx->sample_fmt) *
477                                         avctx->ch_layout.nb_channels;
478     data->mBuffers[0].mData           = frame->data[0];
479     if (*nb_packets > frame->nb_samples)
480         *nb_packets = frame->nb_samples;
481 
482     av_frame_unref(at->encoding_frame);
483     ret = av_frame_ref(at->encoding_frame, frame);
484     if (ret < 0) {
485         *nb_packets = 0;
486         return ret;
487     }
488 
489     ff_bufqueue_add(avctx, &at->used_frame_queue, frame);
490 
491     return 0;
492 }
493 
ffat_encode(AVCodecContext * avctx,AVPacket * avpkt,const AVFrame * frame,int * got_packet_ptr)494 static int ffat_encode(AVCodecContext *avctx, AVPacket *avpkt,
495                        const AVFrame *frame, int *got_packet_ptr)
496 {
497     ATDecodeContext *at = avctx->priv_data;
498     OSStatus ret;
499 
500     AudioBufferList out_buffers = {
501         .mNumberBuffers = 1,
502         .mBuffers = {
503             {
504                 .mNumberChannels = avctx->ch_layout.nb_channels,
505                 .mDataByteSize = at->pkt_size,
506             }
507         }
508     };
509     AudioStreamPacketDescription out_pkt_desc = {0};
510 
511     if (frame) {
512         AVFrame *in_frame;
513 
514         if (ff_bufqueue_is_full(&at->frame_queue)) {
515             /*
516              * The frame queue is significantly larger than needed in practice,
517              * but no clear way to determine the minimum number of samples to
518              * get output from AudioConverterFillComplexBuffer().
519              */
520             av_log(avctx, AV_LOG_ERROR, "Bug: frame queue is too small.\n");
521             return AVERROR_BUG;
522         }
523 
524         if ((ret = ff_af_queue_add(&at->afq, frame)) < 0)
525             return ret;
526 
527         in_frame = av_frame_clone(frame);
528         if (!in_frame)
529             return AVERROR(ENOMEM);
530 
531         ff_bufqueue_add(avctx, &at->frame_queue, in_frame);
532     } else {
533         at->eof = 1;
534     }
535 
536     if ((ret = ff_alloc_packet(avctx, avpkt, at->pkt_size)) < 0)
537         return ret;
538 
539 
540     out_buffers.mBuffers[0].mData = avpkt->data;
541 
542     *got_packet_ptr = avctx->frame_size / at->frame_size;
543 
544     ret = AudioConverterFillComplexBuffer(at->converter, ffat_encode_callback, avctx,
545                                           got_packet_ptr, &out_buffers,
546                                           (avctx->frame_size > at->frame_size) ? NULL : &out_pkt_desc);
547 
548     ff_bufqueue_discard_all(&at->used_frame_queue);
549 
550     if ((!ret || ret == 1) && *got_packet_ptr) {
551         avpkt->size = out_buffers.mBuffers[0].mDataByteSize;
552         ff_af_queue_remove(&at->afq, out_pkt_desc.mVariableFramesInPacket ?
553                                      out_pkt_desc.mVariableFramesInPacket :
554                                      avctx->frame_size,
555                            &avpkt->pts,
556                            &avpkt->duration);
557     } else if (ret && ret != 1) {
558         av_log(avctx, AV_LOG_ERROR, "Encode error: %i\n", ret);
559         return AVERROR_EXTERNAL;
560     }
561 
562     return 0;
563 }
564 
ffat_encode_flush(AVCodecContext * avctx)565 static av_cold void ffat_encode_flush(AVCodecContext *avctx)
566 {
567     ATDecodeContext *at = avctx->priv_data;
568     AudioConverterReset(at->converter);
569     ff_bufqueue_discard_all(&at->frame_queue);
570     ff_bufqueue_discard_all(&at->used_frame_queue);
571 }
572 
ffat_close_encoder(AVCodecContext * avctx)573 static av_cold int ffat_close_encoder(AVCodecContext *avctx)
574 {
575     ATDecodeContext *at = avctx->priv_data;
576     AudioConverterDispose(at->converter);
577     ff_bufqueue_discard_all(&at->frame_queue);
578     ff_bufqueue_discard_all(&at->used_frame_queue);
579     ff_af_queue_close(&at->afq);
580     av_frame_free(&at->encoding_frame);
581     return 0;
582 }
583 
584 static const AVProfile aac_profiles[] = {
585     { FF_PROFILE_AAC_LOW,   "LC"       },
586     { FF_PROFILE_AAC_HE,    "HE-AAC"   },
587     { FF_PROFILE_AAC_HE_V2, "HE-AACv2" },
588     { FF_PROFILE_AAC_LD,    "LD"       },
589     { FF_PROFILE_AAC_ELD,   "ELD"      },
590     { FF_PROFILE_UNKNOWN },
591 };
592 
593 #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
594 static const AVOption options[] = {
595 #if !TARGET_OS_IPHONE
596     {"aac_at_mode", "ratecontrol mode", offsetof(ATDecodeContext, mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, kAudioCodecBitRateControlMode_Variable, AE, "mode"},
597         {"auto", "VBR if global quality is given; CBR otherwise", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, INT_MIN, INT_MAX, AE, "mode"},
598         {"cbr",  "constant bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Constant}, INT_MIN, INT_MAX, AE, "mode"},
599         {"abr",  "long-term average bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_LongTermAverage}, INT_MIN, INT_MAX, AE, "mode"},
600         {"cvbr", "constrained variable bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_VariableConstrained}, INT_MIN, INT_MAX, AE, "mode"},
601         {"vbr" , "variable bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Variable}, INT_MIN, INT_MAX, AE, "mode"},
602 #endif
603     {"aac_at_quality", "quality vs speed control", offsetof(ATDecodeContext, quality), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 2, AE},
604     { NULL },
605 };
606 
607 #define FFAT_ENC_CLASS(NAME) \
608     static const AVClass ffat_##NAME##_enc_class = { \
609         .class_name = "at_" #NAME "_enc", \
610         .item_name  = av_default_item_name, \
611         .option     = options, \
612         .version    = LIBAVUTIL_VERSION_INT, \
613     };
614 
615 #define FFAT_ENC(NAME, ID, PROFILES, CAPS, CHANNEL_LAYOUTS, CH_LAYOUTS) \
616     FFAT_ENC_CLASS(NAME) \
617     const FFCodec ff_##NAME##_at_encoder = { \
618         .p.name         = #NAME "_at", \
619         .p.long_name    = NULL_IF_CONFIG_SMALL(#NAME " (AudioToolbox)"), \
620         .p.type         = AVMEDIA_TYPE_AUDIO, \
621         .p.id           = ID, \
622         .priv_data_size = sizeof(ATDecodeContext), \
623         .init           = ffat_init_encoder, \
624         .close          = ffat_close_encoder, \
625         FF_CODEC_ENCODE_CB(ffat_encode), \
626         .flush          = ffat_encode_flush, \
627         .p.priv_class   = &ffat_##NAME##_enc_class, \
628         .p.capabilities = AV_CODEC_CAP_DELAY | \
629                           AV_CODEC_CAP_ENCODER_FLUSH CAPS, \
630         .p.channel_layouts = CHANNEL_LAYOUTS, \
631         .p.ch_layouts   = CH_LAYOUTS, \
632         .p.sample_fmts  = (const enum AVSampleFormat[]) { \
633             AV_SAMPLE_FMT_S16, \
634             AV_SAMPLE_FMT_U8,  AV_SAMPLE_FMT_NONE \
635         }, \
636         .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE, \
637         .p.profiles     = PROFILES, \
638         .p.wrapper_name = "at", \
639     };
640 
641 static const AVChannelLayout aac_at_ch_layouts[] = {
642     AV_CHANNEL_LAYOUT_MONO,
643     AV_CHANNEL_LAYOUT_STEREO,
644     AV_CHANNEL_LAYOUT_SURROUND,
645     AV_CHANNEL_LAYOUT_4POINT0,
646     AV_CHANNEL_LAYOUT_5POINT0,
647     AV_CHANNEL_LAYOUT_5POINT1,
648     AV_CHANNEL_LAYOUT_6POINT0,
649     AV_CHANNEL_LAYOUT_6POINT1,
650     AV_CHANNEL_LAYOUT_7POINT0,
651     AV_CHANNEL_LAYOUT_7POINT1_WIDE_BACK,
652     AV_CHANNEL_LAYOUT_QUAD,
653     AV_CHANNEL_LAYOUT_OCTAGONAL,
654     { 0 },
655 };
656 
657 #if FF_API_OLD_CHANNEL_LAYOUT
658 static const uint64_t aac_at_channel_layouts[] = {
659     AV_CH_LAYOUT_MONO,
660     AV_CH_LAYOUT_STEREO,
661     AV_CH_LAYOUT_SURROUND,
662     AV_CH_LAYOUT_4POINT0,
663     AV_CH_LAYOUT_5POINT0,
664     AV_CH_LAYOUT_5POINT1,
665     AV_CH_LAYOUT_6POINT0,
666     AV_CH_LAYOUT_6POINT1,
667     AV_CH_LAYOUT_7POINT0,
668     AV_CH_LAYOUT_7POINT1_WIDE_BACK,
669     AV_CH_LAYOUT_QUAD,
670     AV_CH_LAYOUT_OCTAGONAL,
671     0,
672 };
673 #endif
674 
675 FFAT_ENC(aac,          AV_CODEC_ID_AAC,          aac_profiles, , aac_at_channel_layouts, aac_at_ch_layouts)
676 //FFAT_ENC(adpcm_ima_qt, AV_CODEC_ID_ADPCM_IMA_QT, NULL)
677 FFAT_ENC(alac,         AV_CODEC_ID_ALAC,         NULL, | AV_CODEC_CAP_VARIABLE_FRAME_SIZE, NULL, NULL)
678 FFAT_ENC(ilbc,         AV_CODEC_ID_ILBC,         NULL, , NULL, NULL)
679 FFAT_ENC(pcm_alaw,     AV_CODEC_ID_PCM_ALAW,     NULL, , NULL, NULL)
680 FFAT_ENC(pcm_mulaw,    AV_CODEC_ID_PCM_MULAW,    NULL, , NULL, NULL)
681