You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

618 lines
22KB

  1. /*
  2. * Audio Toolbox system codecs
  3. *
  4. * copyright (c) 2016 Rodger Combs
  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. #include <AudioToolbox/AudioToolbox.h>
  23. #include "config.h"
  24. #include "audio_frame_queue.h"
  25. #include "avcodec.h"
  26. #include "bytestream.h"
  27. #include "internal.h"
  28. #include "libavformat/isom.h"
  29. #include "libavutil/avassert.h"
  30. #include "libavutil/opt.h"
  31. #include "libavutil/log.h"
  32. typedef struct ATDecodeContext {
  33. AVClass *av_class;
  34. int mode;
  35. int quality;
  36. AudioConverterRef converter;
  37. AVFrame in_frame;
  38. AVFrame new_in_frame;
  39. unsigned pkt_size;
  40. AudioFrameQueue afq;
  41. int eof;
  42. int frame_size;
  43. } ATDecodeContext;
  44. static UInt32 ffat_get_format_id(enum AVCodecID codec, int profile)
  45. {
  46. switch (codec) {
  47. case AV_CODEC_ID_AAC:
  48. switch (profile) {
  49. case FF_PROFILE_AAC_LOW:
  50. default:
  51. return kAudioFormatMPEG4AAC;
  52. case FF_PROFILE_AAC_HE:
  53. return kAudioFormatMPEG4AAC_HE;
  54. case FF_PROFILE_AAC_HE_V2:
  55. return kAudioFormatMPEG4AAC_HE_V2;
  56. case FF_PROFILE_AAC_LD:
  57. return kAudioFormatMPEG4AAC_LD;
  58. case FF_PROFILE_AAC_ELD:
  59. return kAudioFormatMPEG4AAC_ELD;
  60. }
  61. case AV_CODEC_ID_ADPCM_IMA_QT:
  62. return kAudioFormatAppleIMA4;
  63. case AV_CODEC_ID_ALAC:
  64. return kAudioFormatAppleLossless;
  65. case AV_CODEC_ID_ILBC:
  66. return kAudioFormatiLBC;
  67. case AV_CODEC_ID_PCM_ALAW:
  68. return kAudioFormatALaw;
  69. case AV_CODEC_ID_PCM_MULAW:
  70. return kAudioFormatULaw;
  71. default:
  72. av_assert0(!"Invalid codec ID!");
  73. return 0;
  74. }
  75. }
  76. static void ffat_update_ctx(AVCodecContext *avctx)
  77. {
  78. ATDecodeContext *at = avctx->priv_data;
  79. UInt32 size = sizeof(unsigned);
  80. AudioConverterPrimeInfo prime_info;
  81. AudioStreamBasicDescription out_format;
  82. AudioConverterGetProperty(at->converter,
  83. kAudioConverterPropertyMaximumOutputPacketSize,
  84. &size, &at->pkt_size);
  85. if (at->pkt_size <= 0)
  86. at->pkt_size = 1024 * 50;
  87. size = sizeof(prime_info);
  88. if (!AudioConverterGetProperty(at->converter,
  89. kAudioConverterPrimeInfo,
  90. &size, &prime_info)) {
  91. avctx->initial_padding = prime_info.leadingFrames;
  92. }
  93. size = sizeof(out_format);
  94. if (!AudioConverterGetProperty(at->converter,
  95. kAudioConverterCurrentOutputStreamDescription,
  96. &size, &out_format)) {
  97. if (out_format.mFramesPerPacket)
  98. avctx->frame_size = out_format.mFramesPerPacket;
  99. if (out_format.mBytesPerPacket && avctx->codec_id == AV_CODEC_ID_ILBC)
  100. avctx->block_align = out_format.mBytesPerPacket;
  101. }
  102. at->frame_size = avctx->frame_size;
  103. if (avctx->codec_id == AV_CODEC_ID_PCM_MULAW ||
  104. avctx->codec_id == AV_CODEC_ID_PCM_ALAW) {
  105. at->pkt_size *= 1024;
  106. avctx->frame_size *= 1024;
  107. }
  108. }
  109. static int read_descr(GetByteContext *gb, int *tag)
  110. {
  111. int len = 0;
  112. int count = 4;
  113. *tag = bytestream2_get_byte(gb);
  114. while (count--) {
  115. int c = bytestream2_get_byte(gb);
  116. len = (len << 7) | (c & 0x7f);
  117. if (!(c & 0x80))
  118. break;
  119. }
  120. return len;
  121. }
  122. static int get_ilbc_mode(AVCodecContext *avctx)
  123. {
  124. if (avctx->block_align == 38)
  125. return 20;
  126. else if (avctx->block_align == 50)
  127. return 30;
  128. else if (avctx->bit_rate > 0)
  129. return avctx->bit_rate <= 14000 ? 30 : 20;
  130. else
  131. return 30;
  132. }
  133. static av_cold int get_channel_label(int channel)
  134. {
  135. uint64_t map = 1 << channel;
  136. if (map <= AV_CH_LOW_FREQUENCY)
  137. return channel + 1;
  138. else if (map <= AV_CH_BACK_RIGHT)
  139. return channel + 29;
  140. else if (map <= AV_CH_BACK_CENTER)
  141. return channel - 1;
  142. else if (map <= AV_CH_SIDE_RIGHT)
  143. return channel - 4;
  144. else if (map <= AV_CH_TOP_BACK_RIGHT)
  145. return channel + 1;
  146. else if (map <= AV_CH_STEREO_RIGHT)
  147. return -1;
  148. else if (map <= AV_CH_WIDE_RIGHT)
  149. return channel + 4;
  150. else if (map <= AV_CH_SURROUND_DIRECT_RIGHT)
  151. return channel - 23;
  152. else if (map == AV_CH_LOW_FREQUENCY_2)
  153. return kAudioChannelLabel_LFE2;
  154. else
  155. return -1;
  156. }
  157. static int remap_layout(AudioChannelLayout *layout, uint64_t in_layout, int count)
  158. {
  159. int i;
  160. int c = 0;
  161. layout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
  162. layout->mNumberChannelDescriptions = count;
  163. for (i = 0; i < count; i++) {
  164. int label;
  165. while (!(in_layout & (1 << c)) && c < 64)
  166. c++;
  167. if (c == 64)
  168. return AVERROR(EINVAL); // This should never happen
  169. label = get_channel_label(c);
  170. layout->mChannelDescriptions[i].mChannelLabel = label;
  171. if (label < 0)
  172. return AVERROR(EINVAL);
  173. c++;
  174. }
  175. return 0;
  176. }
  177. static int get_aac_tag(uint64_t in_layout)
  178. {
  179. switch (in_layout) {
  180. case AV_CH_LAYOUT_MONO:
  181. return kAudioChannelLayoutTag_Mono;
  182. case AV_CH_LAYOUT_STEREO:
  183. return kAudioChannelLayoutTag_Stereo;
  184. case AV_CH_LAYOUT_QUAD:
  185. return kAudioChannelLayoutTag_AAC_Quadraphonic;
  186. case AV_CH_LAYOUT_OCTAGONAL:
  187. return kAudioChannelLayoutTag_AAC_Octagonal;
  188. case AV_CH_LAYOUT_SURROUND:
  189. return kAudioChannelLayoutTag_AAC_3_0;
  190. case AV_CH_LAYOUT_4POINT0:
  191. return kAudioChannelLayoutTag_AAC_4_0;
  192. case AV_CH_LAYOUT_5POINT0:
  193. return kAudioChannelLayoutTag_AAC_5_0;
  194. case AV_CH_LAYOUT_5POINT1:
  195. return kAudioChannelLayoutTag_AAC_5_1;
  196. case AV_CH_LAYOUT_6POINT0:
  197. return kAudioChannelLayoutTag_AAC_6_0;
  198. case AV_CH_LAYOUT_6POINT1:
  199. return kAudioChannelLayoutTag_AAC_6_1;
  200. case AV_CH_LAYOUT_7POINT0:
  201. return kAudioChannelLayoutTag_AAC_7_0;
  202. case AV_CH_LAYOUT_7POINT1_WIDE_BACK:
  203. return kAudioChannelLayoutTag_AAC_7_1;
  204. case AV_CH_LAYOUT_7POINT1:
  205. return kAudioChannelLayoutTag_MPEG_7_1_C;
  206. default:
  207. return 0;
  208. }
  209. }
  210. static av_cold int ffat_init_encoder(AVCodecContext *avctx)
  211. {
  212. ATDecodeContext *at = avctx->priv_data;
  213. OSStatus status;
  214. AudioStreamBasicDescription in_format = {
  215. .mSampleRate = avctx->sample_rate,
  216. .mFormatID = kAudioFormatLinearPCM,
  217. .mFormatFlags = ((avctx->sample_fmt == AV_SAMPLE_FMT_FLT ||
  218. avctx->sample_fmt == AV_SAMPLE_FMT_DBL) ? kAudioFormatFlagIsFloat
  219. : avctx->sample_fmt == AV_SAMPLE_FMT_U8 ? 0
  220. : kAudioFormatFlagIsSignedInteger)
  221. | kAudioFormatFlagIsPacked,
  222. .mBytesPerPacket = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->channels,
  223. .mFramesPerPacket = 1,
  224. .mBytesPerFrame = av_get_bytes_per_sample(avctx->sample_fmt) * avctx->channels,
  225. .mChannelsPerFrame = avctx->channels,
  226. .mBitsPerChannel = av_get_bytes_per_sample(avctx->sample_fmt) * 8,
  227. };
  228. AudioStreamBasicDescription out_format = {
  229. .mSampleRate = avctx->sample_rate,
  230. .mFormatID = ffat_get_format_id(avctx->codec_id, avctx->profile),
  231. .mChannelsPerFrame = in_format.mChannelsPerFrame,
  232. };
  233. UInt32 layout_size = sizeof(AudioChannelLayout) +
  234. sizeof(AudioChannelDescription) * avctx->channels;
  235. AudioChannelLayout *channel_layout = av_malloc(layout_size);
  236. if (!channel_layout)
  237. return AVERROR(ENOMEM);
  238. if (avctx->codec_id == AV_CODEC_ID_ILBC) {
  239. int mode = get_ilbc_mode(avctx);
  240. out_format.mFramesPerPacket = 8000 * mode / 1000;
  241. out_format.mBytesPerPacket = (mode == 20 ? 38 : 50);
  242. }
  243. status = AudioConverterNew(&in_format, &out_format, &at->converter);
  244. if (status != 0) {
  245. av_log(avctx, AV_LOG_ERROR, "AudioToolbox init error: %i\n", (int)status);
  246. av_free(channel_layout);
  247. return AVERROR_UNKNOWN;
  248. }
  249. if (!avctx->channel_layout)
  250. avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
  251. if ((status = remap_layout(channel_layout, avctx->channel_layout, avctx->channels)) < 0) {
  252. av_log(avctx, AV_LOG_ERROR, "Invalid channel layout\n");
  253. av_free(channel_layout);
  254. return status;
  255. }
  256. if (AudioConverterSetProperty(at->converter, kAudioConverterInputChannelLayout,
  257. layout_size, channel_layout)) {
  258. av_log(avctx, AV_LOG_ERROR, "Unsupported input channel layout\n");
  259. av_free(channel_layout);
  260. return AVERROR(EINVAL);
  261. }
  262. if (avctx->codec_id == AV_CODEC_ID_AAC) {
  263. int tag = get_aac_tag(avctx->channel_layout);
  264. if (tag) {
  265. channel_layout->mChannelLayoutTag = tag;
  266. channel_layout->mNumberChannelDescriptions = 0;
  267. }
  268. }
  269. if (AudioConverterSetProperty(at->converter, kAudioConverterOutputChannelLayout,
  270. layout_size, channel_layout)) {
  271. av_log(avctx, AV_LOG_ERROR, "Unsupported output channel layout\n");
  272. av_free(channel_layout);
  273. return AVERROR(EINVAL);
  274. }
  275. av_free(channel_layout);
  276. if (avctx->bits_per_raw_sample)
  277. AudioConverterSetProperty(at->converter,
  278. kAudioConverterPropertyBitDepthHint,
  279. sizeof(avctx->bits_per_raw_sample),
  280. &avctx->bits_per_raw_sample);
  281. if (at->mode == -1)
  282. at->mode = (avctx->flags & AV_CODEC_FLAG_QSCALE) ?
  283. kAudioCodecBitRateControlMode_Variable :
  284. kAudioCodecBitRateControlMode_Constant;
  285. AudioConverterSetProperty(at->converter, kAudioCodecPropertyBitRateControlMode,
  286. sizeof(at->mode), &at->mode);
  287. if (at->mode == kAudioCodecBitRateControlMode_Variable) {
  288. int q = avctx->global_quality / FF_QP2LAMBDA;
  289. if (q < 0 || q > 14) {
  290. av_log(avctx, AV_LOG_WARNING,
  291. "VBR quality %d out of range, should be 0-14\n", q);
  292. q = av_clip(q, 0, 14);
  293. }
  294. q = 127 - q * 9;
  295. AudioConverterSetProperty(at->converter, kAudioCodecPropertySoundQualityForVBR,
  296. sizeof(q), &q);
  297. } else if (avctx->bit_rate > 0) {
  298. UInt32 rate = avctx->bit_rate;
  299. UInt32 size;
  300. status = AudioConverterGetPropertyInfo(at->converter,
  301. kAudioConverterApplicableEncodeBitRates,
  302. &size, NULL);
  303. if (!status && size) {
  304. UInt32 new_rate = rate;
  305. int count;
  306. int i;
  307. AudioValueRange *ranges = av_malloc(size);
  308. if (!ranges)
  309. return AVERROR(ENOMEM);
  310. AudioConverterGetProperty(at->converter,
  311. kAudioConverterApplicableEncodeBitRates,
  312. &size, ranges);
  313. count = size / sizeof(AudioValueRange);
  314. for (i = 0; i < count; i++) {
  315. AudioValueRange *range = &ranges[i];
  316. if (rate >= range->mMinimum && rate <= range->mMaximum) {
  317. new_rate = rate;
  318. break;
  319. } else if (rate > range->mMaximum) {
  320. new_rate = range->mMaximum;
  321. } else {
  322. new_rate = range->mMinimum;
  323. break;
  324. }
  325. }
  326. if (new_rate != rate) {
  327. av_log(avctx, AV_LOG_WARNING,
  328. "Bitrate %u not allowed; changing to %u\n", rate, new_rate);
  329. rate = new_rate;
  330. }
  331. av_free(ranges);
  332. }
  333. AudioConverterSetProperty(at->converter, kAudioConverterEncodeBitRate,
  334. sizeof(rate), &rate);
  335. }
  336. at->quality = 96 - at->quality * 32;
  337. AudioConverterSetProperty(at->converter, kAudioConverterCodecQuality,
  338. sizeof(at->quality), &at->quality);
  339. if (!AudioConverterGetPropertyInfo(at->converter, kAudioConverterCompressionMagicCookie,
  340. &avctx->extradata_size, NULL) &&
  341. avctx->extradata_size) {
  342. int extradata_size = avctx->extradata_size;
  343. uint8_t *extradata;
  344. if (!(avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE)))
  345. return AVERROR(ENOMEM);
  346. if (avctx->codec_id == AV_CODEC_ID_ALAC) {
  347. avctx->extradata_size = 0x24;
  348. AV_WB32(avctx->extradata, 0x24);
  349. AV_WB32(avctx->extradata + 4, MKBETAG('a','l','a','c'));
  350. extradata = avctx->extradata + 12;
  351. avctx->extradata_size = 0x24;
  352. } else {
  353. extradata = avctx->extradata;
  354. }
  355. status = AudioConverterGetProperty(at->converter,
  356. kAudioConverterCompressionMagicCookie,
  357. &extradata_size, extradata);
  358. if (status != 0) {
  359. av_log(avctx, AV_LOG_ERROR, "AudioToolbox cookie error: %i\n", (int)status);
  360. return AVERROR_UNKNOWN;
  361. } else if (avctx->codec_id == AV_CODEC_ID_AAC) {
  362. GetByteContext gb;
  363. int tag, len;
  364. bytestream2_init(&gb, extradata, extradata_size);
  365. do {
  366. len = read_descr(&gb, &tag);
  367. if (tag == MP4DecConfigDescrTag) {
  368. bytestream2_skip(&gb, 13);
  369. len = read_descr(&gb, &tag);
  370. if (tag == MP4DecSpecificDescrTag) {
  371. len = FFMIN(gb.buffer_end - gb.buffer, len);
  372. memmove(extradata, gb.buffer, len);
  373. avctx->extradata_size = len;
  374. break;
  375. }
  376. } else if (tag == MP4ESDescrTag) {
  377. int flags;
  378. bytestream2_skip(&gb, 2);
  379. flags = bytestream2_get_byte(&gb);
  380. if (flags & 0x80) //streamDependenceFlag
  381. bytestream2_skip(&gb, 2);
  382. if (flags & 0x40) //URL_Flag
  383. bytestream2_skip(&gb, bytestream2_get_byte(&gb));
  384. if (flags & 0x20) //OCRstreamFlag
  385. bytestream2_skip(&gb, 2);
  386. }
  387. } while (bytestream2_get_bytes_left(&gb));
  388. } else if (avctx->codec_id != AV_CODEC_ID_ALAC) {
  389. avctx->extradata_size = extradata_size;
  390. }
  391. }
  392. ffat_update_ctx(avctx);
  393. #if !TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
  394. if (at->mode == kAudioCodecBitRateControlMode_Variable && avctx->rc_max_rate) {
  395. UInt32 max_size = avctx->rc_max_rate * avctx->frame_size / avctx->sample_rate;
  396. if (max_size)
  397. AudioConverterSetProperty(at->converter, kAudioCodecPropertyPacketSizeLimitForVBR,
  398. sizeof(max_size), &max_size);
  399. }
  400. #endif
  401. ff_af_queue_init(avctx, &at->afq);
  402. return 0;
  403. }
  404. static OSStatus ffat_encode_callback(AudioConverterRef converter, UInt32 *nb_packets,
  405. AudioBufferList *data,
  406. AudioStreamPacketDescription **packets,
  407. void *inctx)
  408. {
  409. AVCodecContext *avctx = inctx;
  410. ATDecodeContext *at = avctx->priv_data;
  411. if (at->eof) {
  412. *nb_packets = 0;
  413. return 0;
  414. }
  415. av_frame_unref(&at->in_frame);
  416. av_frame_move_ref(&at->in_frame, &at->new_in_frame);
  417. if (!at->in_frame.data[0]) {
  418. *nb_packets = 0;
  419. return 1;
  420. }
  421. data->mNumberBuffers = 1;
  422. data->mBuffers[0].mNumberChannels = avctx->channels;
  423. data->mBuffers[0].mDataByteSize = at->in_frame.nb_samples *
  424. av_get_bytes_per_sample(avctx->sample_fmt) *
  425. avctx->channels;
  426. data->mBuffers[0].mData = at->in_frame.data[0];
  427. if (*nb_packets > at->in_frame.nb_samples)
  428. *nb_packets = at->in_frame.nb_samples;
  429. return 0;
  430. }
  431. static int ffat_encode(AVCodecContext *avctx, AVPacket *avpkt,
  432. const AVFrame *frame, int *got_packet_ptr)
  433. {
  434. ATDecodeContext *at = avctx->priv_data;
  435. OSStatus ret;
  436. AudioBufferList out_buffers = {
  437. .mNumberBuffers = 1,
  438. .mBuffers = {
  439. {
  440. .mNumberChannels = avctx->channels,
  441. .mDataByteSize = at->pkt_size,
  442. }
  443. }
  444. };
  445. AudioStreamPacketDescription out_pkt_desc = {0};
  446. if ((ret = ff_alloc_packet2(avctx, avpkt, at->pkt_size, 0)) < 0)
  447. return ret;
  448. av_frame_unref(&at->new_in_frame);
  449. if (frame) {
  450. if ((ret = ff_af_queue_add(&at->afq, frame)) < 0)
  451. return ret;
  452. if ((ret = av_frame_ref(&at->new_in_frame, frame)) < 0)
  453. return ret;
  454. } else {
  455. at->eof = 1;
  456. }
  457. out_buffers.mBuffers[0].mData = avpkt->data;
  458. *got_packet_ptr = avctx->frame_size / at->frame_size;
  459. ret = AudioConverterFillComplexBuffer(at->converter, ffat_encode_callback, avctx,
  460. got_packet_ptr, &out_buffers,
  461. (avctx->frame_size > at->frame_size) ? NULL : &out_pkt_desc);
  462. if ((!ret || ret == 1) && *got_packet_ptr) {
  463. avpkt->size = out_buffers.mBuffers[0].mDataByteSize;
  464. ff_af_queue_remove(&at->afq, out_pkt_desc.mVariableFramesInPacket ?
  465. out_pkt_desc.mVariableFramesInPacket :
  466. avctx->frame_size,
  467. &avpkt->pts,
  468. &avpkt->duration);
  469. } else if (ret && ret != 1) {
  470. av_log(avctx, AV_LOG_WARNING, "Encode error: %i\n", ret);
  471. }
  472. return 0;
  473. }
  474. static av_cold void ffat_encode_flush(AVCodecContext *avctx)
  475. {
  476. ATDecodeContext *at = avctx->priv_data;
  477. AudioConverterReset(at->converter);
  478. av_frame_unref(&at->new_in_frame);
  479. av_frame_unref(&at->in_frame);
  480. }
  481. static av_cold int ffat_close_encoder(AVCodecContext *avctx)
  482. {
  483. ATDecodeContext *at = avctx->priv_data;
  484. AudioConverterDispose(at->converter);
  485. av_frame_unref(&at->new_in_frame);
  486. av_frame_unref(&at->in_frame);
  487. ff_af_queue_close(&at->afq);
  488. return 0;
  489. }
  490. static const AVProfile aac_profiles[] = {
  491. { FF_PROFILE_AAC_LOW, "LC" },
  492. { FF_PROFILE_AAC_HE, "HE-AAC" },
  493. { FF_PROFILE_AAC_HE_V2, "HE-AACv2" },
  494. { FF_PROFILE_AAC_LD, "LD" },
  495. { FF_PROFILE_AAC_ELD, "ELD" },
  496. { FF_PROFILE_UNKNOWN },
  497. };
  498. #define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
  499. static const AVOption options[] = {
  500. {"aac_at_mode", "ratecontrol mode", offsetof(ATDecodeContext, mode), AV_OPT_TYPE_INT, {.i64 = -1}, -1, kAudioCodecBitRateControlMode_Variable, AE, "mode"},
  501. {"auto", "VBR if global quality is given; CBR otherwise", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, INT_MIN, INT_MAX, AE, "mode"},
  502. {"cbr", "constant bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Constant}, INT_MIN, INT_MAX, AE, "mode"},
  503. {"abr", "long-term average bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_LongTermAverage}, INT_MIN, INT_MAX, AE, "mode"},
  504. {"cvbr", "constrained variable bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_VariableConstrained}, INT_MIN, INT_MAX, AE, "mode"},
  505. {"vbr" , "variable bitrate", 0, AV_OPT_TYPE_CONST, {.i64 = kAudioCodecBitRateControlMode_Variable}, INT_MIN, INT_MAX, AE, "mode"},
  506. {"aac_at_quality", "quality vs speed control", offsetof(ATDecodeContext, quality), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 2, AE},
  507. { NULL },
  508. };
  509. #define FFAT_ENC_CLASS(NAME) \
  510. static const AVClass ffat_##NAME##_enc_class = { \
  511. .class_name = "at_" #NAME "_enc", \
  512. .item_name = av_default_item_name, \
  513. .option = options, \
  514. .version = LIBAVUTIL_VERSION_INT, \
  515. };
  516. #define FFAT_ENC(NAME, ID, PROFILES, ...) \
  517. FFAT_ENC_CLASS(NAME) \
  518. AVCodec ff_##NAME##_at_encoder = { \
  519. .name = #NAME "_at", \
  520. .long_name = NULL_IF_CONFIG_SMALL(#NAME " (AudioToolbox)"), \
  521. .type = AVMEDIA_TYPE_AUDIO, \
  522. .id = ID, \
  523. .priv_data_size = sizeof(ATDecodeContext), \
  524. .init = ffat_init_encoder, \
  525. .close = ffat_close_encoder, \
  526. .encode2 = ffat_encode, \
  527. .flush = ffat_encode_flush, \
  528. .priv_class = &ffat_##NAME##_enc_class, \
  529. .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY __VA_ARGS__, \
  530. .sample_fmts = (const enum AVSampleFormat[]) { \
  531. AV_SAMPLE_FMT_S16, \
  532. AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_NONE \
  533. }, \
  534. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, \
  535. .profiles = PROFILES, \
  536. };
  537. static const uint64_t aac_at_channel_layouts[] = {
  538. AV_CH_LAYOUT_MONO,
  539. AV_CH_LAYOUT_STEREO,
  540. AV_CH_LAYOUT_SURROUND,
  541. AV_CH_LAYOUT_4POINT0,
  542. AV_CH_LAYOUT_5POINT0,
  543. AV_CH_LAYOUT_5POINT1,
  544. AV_CH_LAYOUT_6POINT0,
  545. AV_CH_LAYOUT_6POINT1,
  546. AV_CH_LAYOUT_7POINT0,
  547. AV_CH_LAYOUT_7POINT1_WIDE_BACK,
  548. AV_CH_LAYOUT_QUAD,
  549. AV_CH_LAYOUT_OCTAGONAL,
  550. 0,
  551. };
  552. FFAT_ENC(aac, AV_CODEC_ID_AAC, aac_profiles, , .channel_layouts = aac_at_channel_layouts)
  553. //FFAT_ENC(adpcm_ima_qt, AV_CODEC_ID_ADPCM_IMA_QT, NULL)
  554. FFAT_ENC(alac, AV_CODEC_ID_ALAC, NULL, | AV_CODEC_CAP_VARIABLE_FRAME_SIZE | AV_CODEC_CAP_LOSSLESS)
  555. FFAT_ENC(ilbc, AV_CODEC_ID_ILBC, NULL)
  556. FFAT_ENC(pcm_alaw, AV_CODEC_ID_PCM_ALAW, NULL)
  557. FFAT_ENC(pcm_mulaw, AV_CODEC_ID_PCM_MULAW, NULL)