]> git.sesse.net Git - ffmpeg/blob - libavcodec/audiotoolboxdec.c
lavc: add AudioToolbox decoders
[ffmpeg] / libavcodec / audiotoolboxdec.c
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
23 #include <AudioToolbox/AudioToolbox.h>
24
25 #include "config.h"
26 #include "avcodec.h"
27 #include "bytestream.h"
28 #include "internal.h"
29 #include "libavutil/avassert.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/log.h"
32
33 typedef struct ATDecodeContext {
34     AVClass *av_class;
35
36     AudioConverterRef converter;
37     AudioStreamPacketDescription pkt_desc;
38     AVPacket in_pkt;
39     AVPacket new_in_pkt;
40
41     unsigned pkt_size;
42     int64_t last_pts;
43     int eof;
44 } ATDecodeContext;
45
46 static UInt32 ffat_get_format_id(enum AVCodecID codec, int profile)
47 {
48     switch (codec) {
49     case AV_CODEC_ID_AAC:
50         return kAudioFormatMPEG4AAC;
51     case AV_CODEC_ID_AC3:
52         return kAudioFormatAC3;
53     case AV_CODEC_ID_ADPCM_IMA_QT:
54         return kAudioFormatAppleIMA4;
55     case AV_CODEC_ID_ALAC:
56         return kAudioFormatAppleLossless;
57     case AV_CODEC_ID_AMR_NB:
58         return kAudioFormatAMR;
59     case AV_CODEC_ID_GSM_MS:
60         return kAudioFormatMicrosoftGSM;
61     case AV_CODEC_ID_ILBC:
62         return kAudioFormatiLBC;
63     case AV_CODEC_ID_MP1:
64         return kAudioFormatMPEGLayer1;
65     case AV_CODEC_ID_MP2:
66         return kAudioFormatMPEGLayer2;
67     case AV_CODEC_ID_MP3:
68         return kAudioFormatMPEGLayer3;
69     case AV_CODEC_ID_PCM_ALAW:
70         return kAudioFormatALaw;
71     case AV_CODEC_ID_PCM_MULAW:
72         return kAudioFormatULaw;
73     case AV_CODEC_ID_QDMC:
74         return kAudioFormatQDesign;
75     case AV_CODEC_ID_QDM2:
76         return kAudioFormatQDesign2;
77     default:
78         av_assert0(!"Invalid codec ID!");
79         return 0;
80     }
81 }
82
83 static void ffat_update_ctx(AVCodecContext *avctx)
84 {
85     ATDecodeContext *at = avctx->priv_data;
86     AudioStreamBasicDescription in_format;
87     UInt32 size = sizeof(in_format);
88     if (!AudioConverterGetProperty(at->converter,
89                                    kAudioConverterCurrentInputStreamDescription,
90                                    &size, &in_format)) {
91         avctx->channels = in_format.mChannelsPerFrame;
92         at->pkt_size = in_format.mFramesPerPacket;
93     }
94
95     if (!at->pkt_size)
96         at->pkt_size = 2048;
97 }
98
99 static void put_descr(PutByteContext *pb, int tag, unsigned int size)
100 {
101     int i = 3;
102     bytestream2_put_byte(pb, tag);
103     for (; i > 0; i--)
104         bytestream2_put_byte(pb, (size >> (7 * i)) | 0x80);
105     bytestream2_put_byte(pb, size & 0x7F);
106 }
107
108 static av_cold int ffat_init_decoder(AVCodecContext *avctx)
109 {
110     ATDecodeContext *at = avctx->priv_data;
111     OSStatus status;
112
113     enum AVSampleFormat sample_fmt = (avctx->bits_per_raw_sample == 32) ?
114                                      AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16;
115
116     AudioStreamBasicDescription in_format = {
117         .mSampleRate = avctx->sample_rate ? avctx->sample_rate : 44100,
118         .mFormatID = ffat_get_format_id(avctx->codec_id, avctx->profile),
119         .mBytesPerPacket = avctx->block_align,
120         .mChannelsPerFrame = avctx->channels ? avctx->channels : 1,
121     };
122     AudioStreamBasicDescription out_format = {
123         .mSampleRate = in_format.mSampleRate,
124         .mFormatID = kAudioFormatLinearPCM,
125         .mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked,
126         .mFramesPerPacket = 1,
127         .mChannelsPerFrame = in_format.mChannelsPerFrame,
128         .mBitsPerChannel = av_get_bytes_per_sample(sample_fmt) * 8,
129     };
130
131     avctx->sample_fmt = sample_fmt;
132
133     if (avctx->codec_id == AV_CODEC_ID_ADPCM_IMA_QT)
134         in_format.mFramesPerPacket = 64;
135
136     status = AudioConverterNew(&in_format, &out_format, &at->converter);
137
138     if (status != 0) {
139         av_log(avctx, AV_LOG_ERROR, "AudioToolbox init error: %i\n", (int)status);
140         return AVERROR_UNKNOWN;
141     }
142
143     if (avctx->extradata_size) {
144         char *extradata = avctx->extradata;
145         int extradata_size = avctx->extradata_size;
146         if (avctx->codec_id == AV_CODEC_ID_AAC) {
147             PutByteContext pb;
148             extradata_size = 5 + 3 + 5+13 + 5+avctx->extradata_size;
149             if (!(extradata = av_malloc(extradata_size)))
150                 return AVERROR(ENOMEM);
151
152             bytestream2_init_writer(&pb, extradata, extradata_size);
153
154             // ES descriptor
155             put_descr(&pb, 0x03, 3 + 5+13 + 5+avctx->extradata_size);
156             bytestream2_put_be16(&pb, 0);
157             bytestream2_put_byte(&pb, 0x00); // flags (= no flags)
158
159             // DecoderConfig descriptor
160             put_descr(&pb, 0x04, 13 + 5+avctx->extradata_size);
161
162             // Object type indication
163             bytestream2_put_byte(&pb, 0x40);
164
165             bytestream2_put_byte(&pb, 0x15); // flags (= Audiostream)
166
167             bytestream2_put_be24(&pb, 0); // Buffersize DB
168
169             bytestream2_put_be32(&pb, 0); // maxbitrate
170             bytestream2_put_be32(&pb, 0); // avgbitrate
171
172             // DecoderSpecific info descriptor
173             put_descr(&pb, 0x05, avctx->extradata_size);
174             bytestream2_put_buffer(&pb, avctx->extradata, avctx->extradata_size);
175         }
176
177         status = AudioConverterSetProperty(at->converter,
178                                            kAudioConverterDecompressionMagicCookie,
179                                            extradata_size, extradata);
180         if (status != 0)
181             av_log(avctx, AV_LOG_WARNING, "AudioToolbox cookie error: %i\n", (int)status);
182     }
183
184     ffat_update_ctx(avctx);
185
186     at->last_pts = AV_NOPTS_VALUE;
187
188     return 0;
189 }
190
191 static OSStatus ffat_decode_callback(AudioConverterRef converter, UInt32 *nb_packets,
192                                      AudioBufferList *data,
193                                      AudioStreamPacketDescription **packets,
194                                      void *inctx)
195 {
196     AVCodecContext *avctx = inctx;
197     ATDecodeContext *at = avctx->priv_data;
198
199     if (at->eof) {
200         *nb_packets = 0;
201         if (packets) {
202             *packets = &at->pkt_desc;
203             at->pkt_desc.mDataByteSize = 0;
204         }
205         return 0;
206     }
207
208     av_packet_move_ref(&at->in_pkt, &at->new_in_pkt);
209     at->new_in_pkt.data = 0;
210     at->new_in_pkt.size = 0;
211
212     if (!at->in_pkt.data) {
213         *nb_packets = 0;
214         return 1;
215     }
216
217     data->mNumberBuffers              = 1;
218     data->mBuffers[0].mNumberChannels = 0;
219     data->mBuffers[0].mDataByteSize   = at->in_pkt.size;
220     data->mBuffers[0].mData           = at->in_pkt.data;
221     *nb_packets = 1;
222
223     if (packets) {
224         *packets = &at->pkt_desc;
225         at->pkt_desc.mDataByteSize = at->in_pkt.size;
226     }
227
228     return 0;
229 }
230
231 static int ffat_decode(AVCodecContext *avctx, void *data,
232                        int *got_frame_ptr, AVPacket *avpkt)
233 {
234     ATDecodeContext *at = avctx->priv_data;
235     AVFrame *frame = data;
236     OSStatus ret;
237
238     AudioBufferList out_buffers = {
239         .mNumberBuffers = 1,
240         .mBuffers = {
241             {
242                 .mNumberChannels = avctx->channels,
243                 .mDataByteSize = av_get_bytes_per_sample(avctx->sample_fmt) * at->pkt_size * avctx->channels,
244             }
245         }
246     };
247
248     av_packet_unref(&at->new_in_pkt);
249
250     if (avpkt->size) {
251         if ((ret = av_packet_ref(&at->new_in_pkt, avpkt)) < 0)
252             return ret;
253     } else {
254         at->eof = 1;
255     }
256
257     frame->sample_rate = avctx->sample_rate;
258
259     frame->nb_samples = at->pkt_size;
260     ff_get_buffer(avctx, frame, 0);
261
262     out_buffers.mBuffers[0].mData = frame->data[0];
263
264     ret = AudioConverterFillComplexBuffer(at->converter, ffat_decode_callback, avctx,
265                                           &frame->nb_samples, &out_buffers, NULL);
266     if ((!ret || ret == 1) && frame->nb_samples) {
267         *got_frame_ptr = 1;
268         if (at->last_pts != AV_NOPTS_VALUE) {
269             frame->pts = at->last_pts;
270             at->last_pts = avpkt->pts;
271         }
272     } else if (ret && ret != 1) {
273         av_log(avctx, AV_LOG_WARNING, "Decode error: %i\n", ret);
274     } else {
275         at->last_pts = avpkt->pts;
276     }
277
278     return avpkt->size;
279 }
280
281 static av_cold void ffat_decode_flush(AVCodecContext *avctx)
282 {
283     ATDecodeContext *at = avctx->priv_data;
284     AudioConverterReset(at->converter);
285     av_packet_unref(&at->new_in_pkt);
286     av_packet_unref(&at->in_pkt);
287 }
288
289 static av_cold int ffat_close_decoder(AVCodecContext *avctx)
290 {
291     ATDecodeContext *at = avctx->priv_data;
292     AudioConverterDispose(at->converter);
293     av_packet_unref(&at->new_in_pkt);
294     av_packet_unref(&at->in_pkt);
295     return 0;
296 }
297
298 #define FFAT_DEC_CLASS(NAME) \
299     static const AVClass ffat_##NAME##_dec_class = { \
300         .class_name = "at_" #NAME "_dec", \
301         .version    = LIBAVUTIL_VERSION_INT, \
302     };
303
304 #define FFAT_DEC(NAME, ID) \
305     FFAT_DEC_CLASS(NAME) \
306     AVCodec ff_##NAME##_at_decoder = { \
307         .name           = #NAME "_at", \
308         .long_name      = NULL_IF_CONFIG_SMALL(#NAME " (AudioToolbox)"), \
309         .type           = AVMEDIA_TYPE_AUDIO, \
310         .id             = ID, \
311         .priv_data_size = sizeof(ATDecodeContext), \
312         .init           = ffat_init_decoder, \
313         .close          = ffat_close_decoder, \
314         .decode         = ffat_decode, \
315         .flush          = ffat_decode_flush, \
316         .priv_class     = &ffat_##NAME##_dec_class, \
317         .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, \
318         .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE, \
319     };
320
321 FFAT_DEC(aac,          AV_CODEC_ID_AAC)
322 FFAT_DEC(ac3,          AV_CODEC_ID_AC3)
323 FFAT_DEC(adpcm_ima_qt, AV_CODEC_ID_ADPCM_IMA_QT)
324 FFAT_DEC(alac,         AV_CODEC_ID_ALAC)
325 FFAT_DEC(amr_nb,       AV_CODEC_ID_AMR_NB)
326 FFAT_DEC(gsm_ms,       AV_CODEC_ID_GSM_MS)
327 FFAT_DEC(ilbc,         AV_CODEC_ID_ILBC)
328 FFAT_DEC(mp1,          AV_CODEC_ID_MP1)
329 FFAT_DEC(mp2,          AV_CODEC_ID_MP2)
330 FFAT_DEC(mp3,          AV_CODEC_ID_MP3)
331 FFAT_DEC(pcm_alaw,     AV_CODEC_ID_PCM_ALAW)
332 FFAT_DEC(pcm_mulaw,    AV_CODEC_ID_PCM_MULAW)
333 FFAT_DEC(qdmc,         AV_CODEC_ID_QDMC)
334 FFAT_DEC(qdm2,         AV_CODEC_ID_QDM2)