23 #include <AudioToolbox/AudioToolbox.h>
25 #define FF_BUFQUEUE_SIZE 256
62 return kAudioFormatMPEG4AAC;
64 return kAudioFormatMPEG4AAC_HE;
66 return kAudioFormatMPEG4AAC_HE_V2;
68 return kAudioFormatMPEG4AAC_LD;
70 return kAudioFormatMPEG4AAC_ELD;
73 return kAudioFormatAppleIMA4;
75 return kAudioFormatAppleLossless;
77 return kAudioFormatiLBC;
79 return kAudioFormatALaw;
81 return kAudioFormatULaw;
91 UInt32
size =
sizeof(unsigned);
92 AudioConverterPrimeInfo prime_info;
93 AudioStreamBasicDescription out_format;
96 kAudioConverterPropertyMaximumOutputPacketSize,
102 size =
sizeof(prime_info);
104 if (!AudioConverterGetProperty(at->
converter,
105 kAudioConverterPrimeInfo,
106 &
size, &prime_info)) {
110 size =
sizeof(out_format);
111 if (!AudioConverterGetProperty(at->
converter,
112 kAudioConverterCurrentOutputStreamDescription,
113 &
size, &out_format)) {
114 if (out_format.mFramesPerPacket)
115 avctx->
frame_size = out_format.mFramesPerPacket;
132 *
tag = bytestream2_get_byte(gb);
134 int c = bytestream2_get_byte(gb);
149 return avctx->
bit_rate <= 14000 ? 30 : 20;
174 return kAudioChannelLabel_LFE2;
183 layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
184 layout->mNumberChannelDescriptions = count;
185 for (
i = 0;
i < count;
i++) {
187 while (!(in_layout & (1 <<
c)) &&
c < 64)
192 layout->mChannelDescriptions[
i].mChannelLabel = label;
204 return kAudioChannelLayoutTag_Mono;
206 return kAudioChannelLayoutTag_Stereo;
208 return kAudioChannelLayoutTag_AAC_Quadraphonic;
210 return kAudioChannelLayoutTag_AAC_Octagonal;
212 return kAudioChannelLayoutTag_AAC_3_0;
214 return kAudioChannelLayoutTag_AAC_4_0;
216 return kAudioChannelLayoutTag_AAC_5_0;
218 return kAudioChannelLayoutTag_AAC_5_1;
220 return kAudioChannelLayoutTag_AAC_6_0;
222 return kAudioChannelLayoutTag_AAC_6_1;
224 return kAudioChannelLayoutTag_AAC_7_0;
226 return kAudioChannelLayoutTag_AAC_7_1;
228 return kAudioChannelLayoutTag_MPEG_7_1_C;
239 AudioStreamBasicDescription in_format = {
241 .mFormatID = kAudioFormatLinearPCM,
245 : kAudioFormatFlagIsSignedInteger)
246 | kAudioFormatFlagIsPacked,
248 .mFramesPerPacket = 1,
250 .mChannelsPerFrame = avctx->
channels,
253 AudioStreamBasicDescription out_format = {
256 .mChannelsPerFrame = in_format.mChannelsPerFrame,
258 UInt32 layout_size =
sizeof(AudioChannelLayout) +
259 sizeof(AudioChannelDescription) * avctx->
channels;
260 AudioChannelLayout *channel_layout =
av_malloc(layout_size);
267 out_format.mFramesPerPacket = 8000 *
mode / 1000;
268 out_format.mBytesPerPacket = (
mode == 20 ? 38 : 50);
288 if (AudioConverterSetProperty(at->
converter, kAudioConverterInputChannelLayout,
289 layout_size, channel_layout)) {
297 channel_layout->mChannelLayoutTag =
tag;
298 channel_layout->mNumberChannelDescriptions = 0;
301 if (AudioConverterSetProperty(at->
converter, kAudioConverterOutputChannelLayout,
302 layout_size, channel_layout)) {
311 kAudioConverterPropertyBitDepthHint,
315 #if !TARGET_OS_IPHONE
318 kAudioCodecBitRateControlMode_Variable :
319 kAudioCodecBitRateControlMode_Constant;
321 AudioConverterSetProperty(at->
converter, kAudioCodecPropertyBitRateControlMode,
324 if (at->
mode == kAudioCodecBitRateControlMode_Variable) {
326 if (q < 0 || q > 14) {
328 "VBR quality %d out of range, should be 0-14\n", q);
332 AudioConverterSetProperty(at->
converter, kAudioCodecPropertySoundQualityForVBR,
340 kAudioConverterApplicableEncodeBitRates,
343 UInt32 new_rate = rate;
350 kAudioConverterApplicableEncodeBitRates,
352 count =
size /
sizeof(AudioValueRange);
353 for (
i = 0;
i < count;
i++) {
354 AudioValueRange *range = &ranges[
i];
355 if (rate >= range->mMinimum && rate <= range->mMaximum) {
358 }
else if (rate > range->mMaximum) {
359 new_rate = range->mMaximum;
361 new_rate = range->mMinimum;
365 if (new_rate != rate) {
367 "Bitrate %u not allowed; changing to %u\n", rate, new_rate);
372 AudioConverterSetProperty(at->
converter, kAudioConverterEncodeBitRate,
373 sizeof(rate), &rate);
377 AudioConverterSetProperty(at->
converter, kAudioConverterCodecQuality,
380 if (!AudioConverterGetPropertyInfo(at->
converter, kAudioConverterCompressionMagicCookie,
397 kAudioConverterCompressionMagicCookie,
398 &extradata_size, extradata);
420 flags = bytestream2_get_byte(&gb);
436 #if !TARGET_OS_IPHONE && defined(__MAC_10_9)
437 if (at->
mode == kAudioCodecBitRateControlMode_Variable && avctx->
rc_max_rate) {
440 AudioConverterSetProperty(at->
converter, kAudioCodecPropertyPacketSizeLimitForVBR,
441 sizeof(max_size), &max_size);
455 AudioBufferList *
data,
456 AudioStreamPacketDescription **packets,
476 data->mNumberBuffers = 1;
478 data->mBuffers[0].mDataByteSize =
frame->nb_samples *
481 data->mBuffers[0].mData =
frame->data[0];
482 if (*nb_packets >
frame->nb_samples)
483 *nb_packets =
frame->nb_samples;
503 AudioBufferList out_buffers = {
512 AudioStreamPacketDescription out_pkt_desc = {0};
543 out_buffers.mBuffers[0].mData = avpkt->
data;
548 got_packet_ptr, &out_buffers,
553 if ((!
ret ||
ret == 1) && *got_packet_ptr) {
554 avpkt->
size = out_buffers.mBuffers[0].mDataByteSize;
556 out_pkt_desc.mVariableFramesInPacket :
560 }
else if (
ret &&
ret != 1) {
595 #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
597 #if !TARGET_OS_IPHONE
598 {
"aac_at_mode",
"ratecontrol mode", offsetof(
ATDecodeContext,
mode),
AV_OPT_TYPE_INT, {.i64 = -1}, -1, kAudioCodecBitRateControlMode_Variable,
AE,
"mode"},
599 {
"auto",
"VBR if global quality is given; CBR otherwise", 0,
AV_OPT_TYPE_CONST, {.i64 = -1}, INT_MIN, INT_MAX,
AE,
"mode"},
600 {
"cbr",
"constant bitrate", 0,
AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Constant}, INT_MIN, INT_MAX,
AE,
"mode"},
601 {
"abr",
"long-term average bitrate", 0,
AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_LongTermAverage}, INT_MIN, INT_MAX,
AE,
"mode"},
602 {
"cvbr",
"constrained variable bitrate", 0,
AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_VariableConstrained}, INT_MIN, INT_MAX,
AE,
"mode"},
603 {
"vbr" ,
"variable bitrate", 0,
AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Variable}, INT_MIN, INT_MAX,
AE,
"mode"},
609 #define FFAT_ENC_CLASS(NAME) \
610 static const AVClass ffat_##NAME##_enc_class = { \
611 .class_name = "at_" #NAME "_enc", \
612 .item_name = av_default_item_name, \
614 .version = LIBAVUTIL_VERSION_INT, \
617 #define FFAT_ENC(NAME, ID, PROFILES, ...) \
618 FFAT_ENC_CLASS(NAME) \
619 AVCodec ff_##NAME##_at_encoder = { \
620 .name = #NAME "_at", \
621 .long_name = NULL_IF_CONFIG_SMALL(#NAME " (AudioToolbox)"), \
622 .type = AVMEDIA_TYPE_AUDIO, \
624 .priv_data_size = sizeof(ATDecodeContext), \
625 .init = ffat_init_encoder, \
626 .close = ffat_close_encoder, \
627 .encode2 = ffat_encode, \
628 .flush = ffat_encode_flush, \
629 .priv_class = &ffat_##NAME##_enc_class, \
630 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | \
631 AV_CODEC_CAP_ENCODER_FLUSH __VA_ARGS__, \
632 .sample_fmts = (const enum AVSampleFormat[]) { \
634 AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE \
636 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \
637 .profiles = PROFILES, \
638 .wrapper_name = "at", \