23 #include <AudioToolbox/AudioToolbox.h>
25 #define FF_BUFQUEUE_SIZE 256
64 return kAudioFormatMPEG4AAC;
66 return kAudioFormatMPEG4AAC_HE;
68 return kAudioFormatMPEG4AAC_HE_V2;
70 return kAudioFormatMPEG4AAC_LD;
72 return kAudioFormatMPEG4AAC_ELD;
75 return kAudioFormatAppleIMA4;
77 return kAudioFormatAppleLossless;
79 return kAudioFormatiLBC;
81 return kAudioFormatALaw;
83 return kAudioFormatULaw;
93 UInt32
size =
sizeof(unsigned);
94 AudioConverterPrimeInfo prime_info;
95 AudioStreamBasicDescription out_format;
98 kAudioConverterPropertyMaximumOutputPacketSize,
104 size =
sizeof(prime_info);
106 if (!AudioConverterGetProperty(at->
converter,
107 kAudioConverterPrimeInfo,
108 &
size, &prime_info)) {
112 size =
sizeof(out_format);
113 if (!AudioConverterGetProperty(at->
converter,
114 kAudioConverterCurrentOutputStreamDescription,
115 &
size, &out_format)) {
116 if (out_format.mFramesPerPacket)
117 avctx->
frame_size = out_format.mFramesPerPacket;
134 *
tag = bytestream2_get_byte(gb);
136 int c = bytestream2_get_byte(gb);
151 return avctx->
bit_rate <= 14000 ? 30 : 20;
176 return kAudioChannelLabel_LFE2;
185 layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
186 layout->mNumberChannelDescriptions = count;
187 for (
i = 0;
i < count;
i++) {
189 while (!(in_layout & (1 <<
c)) &&
c < 64)
194 layout->mChannelDescriptions[
i].mChannelLabel = label;
206 return kAudioChannelLayoutTag_Mono;
208 return kAudioChannelLayoutTag_Stereo;
210 return kAudioChannelLayoutTag_AAC_Quadraphonic;
212 return kAudioChannelLayoutTag_AAC_Octagonal;
214 return kAudioChannelLayoutTag_AAC_3_0;
216 return kAudioChannelLayoutTag_AAC_4_0;
218 return kAudioChannelLayoutTag_AAC_5_0;
220 return kAudioChannelLayoutTag_AAC_5_1;
222 return kAudioChannelLayoutTag_AAC_6_0;
224 return kAudioChannelLayoutTag_AAC_6_1;
226 return kAudioChannelLayoutTag_AAC_7_0;
228 return kAudioChannelLayoutTag_AAC_7_1;
230 return kAudioChannelLayoutTag_MPEG_7_1_C;
241 AudioStreamBasicDescription in_format = {
243 .mFormatID = kAudioFormatLinearPCM,
247 : kAudioFormatFlagIsSignedInteger)
248 | kAudioFormatFlagIsPacked,
250 .mFramesPerPacket = 1,
252 .mChannelsPerFrame = avctx->
channels,
255 AudioStreamBasicDescription out_format = {
258 .mChannelsPerFrame = in_format.mChannelsPerFrame,
260 UInt32 layout_size =
sizeof(AudioChannelLayout) +
261 sizeof(AudioChannelDescription) * avctx->
channels;
262 AudioChannelLayout *channel_layout =
av_malloc(layout_size);
269 out_format.mFramesPerPacket = 8000 *
mode / 1000;
270 out_format.mBytesPerPacket = (
mode == 20 ? 38 : 50);
290 if (AudioConverterSetProperty(at->
converter, kAudioConverterInputChannelLayout,
291 layout_size, channel_layout)) {
299 channel_layout->mChannelLayoutTag =
tag;
300 channel_layout->mNumberChannelDescriptions = 0;
303 if (AudioConverterSetProperty(at->
converter, kAudioConverterOutputChannelLayout,
304 layout_size, channel_layout)) {
313 kAudioConverterPropertyBitDepthHint,
317 #if !TARGET_OS_IPHONE
320 kAudioCodecBitRateControlMode_Variable :
321 kAudioCodecBitRateControlMode_Constant;
323 AudioConverterSetProperty(at->
converter, kAudioCodecPropertyBitRateControlMode,
326 if (at->
mode == kAudioCodecBitRateControlMode_Variable) {
328 if (q < 0 || q > 14) {
330 "VBR quality %d out of range, should be 0-14\n", q);
334 AudioConverterSetProperty(at->
converter, kAudioCodecPropertySoundQualityForVBR,
342 kAudioConverterApplicableEncodeBitRates,
345 UInt32 new_rate = rate;
352 kAudioConverterApplicableEncodeBitRates,
354 count =
size /
sizeof(AudioValueRange);
355 for (
i = 0;
i < count;
i++) {
356 AudioValueRange *range = &ranges[
i];
357 if (rate >= range->mMinimum && rate <= range->mMaximum) {
360 }
else if (rate > range->mMaximum) {
361 new_rate = range->mMaximum;
363 new_rate = range->mMinimum;
367 if (new_rate != rate) {
369 "Bitrate %u not allowed; changing to %u\n", rate, new_rate);
374 AudioConverterSetProperty(at->
converter, kAudioConverterEncodeBitRate,
375 sizeof(rate), &rate);
379 AudioConverterSetProperty(at->
converter, kAudioConverterCodecQuality,
382 if (!AudioConverterGetPropertyInfo(at->
converter, kAudioConverterCompressionMagicCookie,
399 kAudioConverterCompressionMagicCookie,
400 &extradata_size, extradata);
422 flags = bytestream2_get_byte(&gb);
438 #if !TARGET_OS_IPHONE && defined(__MAC_10_9)
439 if (at->
mode == kAudioCodecBitRateControlMode_Variable && avctx->
rc_max_rate) {
442 AudioConverterSetProperty(at->
converter, kAudioCodecPropertyPacketSizeLimitForVBR,
443 sizeof(max_size), &max_size);
457 AudioBufferList *
data,
458 AudioStreamPacketDescription **packets,
478 data->mNumberBuffers = 1;
480 data->mBuffers[0].mDataByteSize =
frame->nb_samples *
483 data->mBuffers[0].mData =
frame->data[0];
484 if (*nb_packets >
frame->nb_samples)
485 *nb_packets =
frame->nb_samples;
505 AudioBufferList out_buffers = {
514 AudioStreamPacketDescription out_pkt_desc = {0};
545 out_buffers.mBuffers[0].mData = avpkt->
data;
550 got_packet_ptr, &out_buffers,
555 if ((!
ret ||
ret == 1) && *got_packet_ptr) {
556 avpkt->
size = out_buffers.mBuffers[0].mDataByteSize;
558 out_pkt_desc.mVariableFramesInPacket :
562 }
else if (
ret &&
ret != 1) {
597 #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
599 #if !TARGET_OS_IPHONE
600 {
"aac_at_mode",
"ratecontrol mode", offsetof(
ATDecodeContext,
mode),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, kAudioCodecBitRateControlMode_Variable,
AE,
"mode"},
601 {
"auto",
"VBR if global quality is given; CBR otherwise", 0,
AV_OPT_TYPE_CONST, {.i64 = -1}, INT_MIN, INT_MAX,
AE,
"mode"},
602 {
"cbr",
"constant bitrate", 0,
AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Constant}, INT_MIN, INT_MAX,
AE,
"mode"},
603 {
"abr",
"long-term average bitrate", 0,
AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_LongTermAverage}, INT_MIN, INT_MAX,
AE,
"mode"},
604 {
"cvbr",
"constrained variable bitrate", 0,
AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_VariableConstrained}, INT_MIN, INT_MAX,
AE,
"mode"},
605 {
"vbr" ,
"variable bitrate", 0,
AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Variable}, INT_MIN, INT_MAX,
AE,
"mode"},
611 #define FFAT_ENC_CLASS(NAME) \
612 static const AVClass ffat_##NAME##_enc_class = { \
613 .class_name = "at_" #NAME "_enc", \
614 .item_name = av_default_item_name, \
616 .version = LIBAVUTIL_VERSION_INT, \
619 #define FFAT_ENC(NAME, ID, PROFILES, ...) \
620 FFAT_ENC_CLASS(NAME) \
621 const AVCodec ff_##NAME##_at_encoder = { \
622 .name = #NAME "_at", \
623 .long_name = NULL_IF_CONFIG_SMALL(#NAME " (AudioToolbox)"), \
624 .type = AVMEDIA_TYPE_AUDIO, \
626 .priv_data_size = sizeof(ATDecodeContext), \
627 .init = ffat_init_encoder, \
628 .close = ffat_close_encoder, \
629 .encode2 = ffat_encode, \
630 .flush = ffat_encode_flush, \
631 .priv_class = &ffat_##NAME##_enc_class, \
632 .capabilities = AV_CODEC_CAP_DELAY | \
633 AV_CODEC_CAP_ENCODER_FLUSH __VA_ARGS__, \
634 .sample_fmts = (const enum AVSampleFormat[]) { \
636 AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE \
638 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \
639 .profiles = PROFILES, \
640 .wrapper_name = "at", \