~ubuntu-branches/debian/sid/ffmpeg/sid

« back to all changes in this revision

Viewing changes to libavcodec/videotoolbox.c

  • Committer: Package Import Robot
  • Author(s): Andreas Cadhalpun, Fabian Greffrath, Andreas Cadhalpun
  • Date: 2015-09-22 15:15:20 UTC
  • mfrom: (0.1.29)
  • Revision ID: package-import@ubuntu.com-20150922151520-hhmd3in9ykigjvs9
Tags: 7:2.8-1
[ Fabian Greffrath ]
* Pass the --dbg-package=ffmpeg-dbg parameter only to dh_strip.
* Add alternative Depends: libavcodec-ffmpeg-extra56 to libavcodec-dev and
  ffmpeg-dbg to allow for building and debugging with this library installed.

[ Andreas Cadhalpun ]
* Import new major upstream release 2.8.
* Remove the transitional lib*-ffmpeg-dev packages.
* Drop old Breaks on kodi-bin.
* Drop workaround for sparc, which is no Debian architecture anymore.
* Re-enable x265 on alpha, as it's available again.
* Disable unavailable frei0r, opencv and x264 on mips64el.
* Disable libopenjpeg (#787275) and libschroedinger (#787957) decoders.
  (Closes: #786670)
* Disable libdc1394 on sparc64, because it links against the broken due to
  #790560 libudev1.
* Enable libsnappy support.
* Add new symbols.
* Update debian/copyright.
* Update debian/tests/encdec_list.txt.
* Add hls-only-seek-if-there-is-an-offset.patch. (Closes: #798189)
* Add 'Breaks: libavutil-ffmpeg54 (>= 8:0)' to the libraries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Videotoolbox hardware acceleration
 
3
 *
 
4
 * copyright (c) 2012 Sebastien Zwickert
 
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 "config.h"
 
24
#if CONFIG_VIDEOTOOLBOX
 
25
#  include "videotoolbox.h"
 
26
#else
 
27
#  include "vda.h"
 
28
#endif
 
29
#include "vda_vt_internal.h"
 
30
#include "libavutil/avutil.h"
 
31
#include "bytestream.h"
 
32
#include "h264.h"
 
33
#include "mpegvideo.h"
 
34
 
 
35
#ifndef kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder
 
36
#  define kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder CFSTR("EnableHardwareAcceleratedVideoDecoder")
 
37
#endif
 
38
 
 
39
#define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING  12
 
40
 
 
41
static void videotoolbox_buffer_release(void *opaque, uint8_t *data)
 
42
{
 
43
    CVPixelBufferRef cv_buffer = (CVImageBufferRef)data;
 
44
    CVPixelBufferRelease(cv_buffer);
 
45
}
 
46
 
 
47
static int videotoolbox_buffer_copy(VTContext *vtctx,
 
48
                                    const uint8_t *buffer,
 
49
                                    uint32_t size)
 
50
{
 
51
    void *tmp;
 
52
 
 
53
    tmp = av_fast_realloc(vtctx->bitstream,
 
54
                         &vtctx->allocated_size,
 
55
                         size);
 
56
 
 
57
    if (!tmp)
 
58
        return AVERROR(ENOMEM);
 
59
 
 
60
    vtctx->bitstream = tmp;
 
61
    memcpy(vtctx->bitstream, buffer, size);
 
62
    vtctx->bitstream_size = size;
 
63
 
 
64
    return 0;
 
65
}
 
66
 
 
67
int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
 
68
{
 
69
    frame->width  = avctx->width;
 
70
    frame->height = avctx->height;
 
71
    frame->format = avctx->pix_fmt;
 
72
    frame->buf[0] = av_buffer_alloc(1);
 
73
 
 
74
    if (!frame->buf[0])
 
75
        return AVERROR(ENOMEM);
 
76
 
 
77
    return 0;
 
78
}
 
79
 
 
80
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
 
81
{
 
82
    CFDataRef data = NULL;
 
83
 
 
84
    /* Each VCL NAL in the bitstream sent to the decoder
 
85
     * is preceded by a 4 bytes length header.
 
86
     * Change the avcC atom header if needed, to signal headers of 4 bytes. */
 
87
    if (avctx->extradata_size >= 4 && (avctx->extradata[4] & 0x03) != 0x03) {
 
88
        uint8_t *rw_extradata = av_memdup(avctx->extradata, avctx->extradata_size);
 
89
 
 
90
        if (!rw_extradata)
 
91
            return NULL;
 
92
 
 
93
        rw_extradata[4] |= 0x03;
 
94
 
 
95
        data = CFDataCreate(kCFAllocatorDefault, rw_extradata, avctx->extradata_size);
 
96
 
 
97
        av_freep(&rw_extradata);
 
98
    } else {
 
99
        data = CFDataCreate(kCFAllocatorDefault, avctx->extradata, avctx->extradata_size);
 
100
    }
 
101
 
 
102
    return data;
 
103
}
 
104
 
 
105
int ff_videotoolbox_buffer_create(VTContext *vtctx, AVFrame *frame)
 
106
{
 
107
    av_buffer_unref(&frame->buf[0]);
 
108
 
 
109
    frame->buf[0] = av_buffer_create((uint8_t*)vtctx->frame,
 
110
                                     sizeof(vtctx->frame),
 
111
                                     videotoolbox_buffer_release,
 
112
                                     NULL,
 
113
                                     AV_BUFFER_FLAG_READONLY);
 
114
    if (!frame->buf[0]) {
 
115
        return AVERROR(ENOMEM);
 
116
    }
 
117
 
 
118
    frame->data[3] = (uint8_t*)vtctx->frame;
 
119
    vtctx->frame = NULL;
 
120
 
 
121
    return 0;
 
122
}
 
123
 
 
124
int ff_videotoolbox_h264_start_frame(AVCodecContext *avctx,
 
125
                                     const uint8_t *buffer,
 
126
                                     uint32_t size)
 
127
{
 
128
    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
 
129
    H264Context *h  = avctx->priv_data;
 
130
 
 
131
    vtctx->bitstream_size = 0;
 
132
 
 
133
    if (h->is_avc == 1) {
 
134
        return videotoolbox_buffer_copy(vtctx, buffer, size);
 
135
    }
 
136
 
 
137
    return 0;
 
138
}
 
139
 
 
140
int ff_videotoolbox_h264_decode_slice(AVCodecContext *avctx,
 
141
                                      const uint8_t *buffer,
 
142
                                      uint32_t size)
 
143
{
 
144
    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
 
145
    H264Context *h  = avctx->priv_data;
 
146
    void *tmp;
 
147
 
 
148
    if (h->is_avc == 1)
 
149
        return 0;
 
150
 
 
151
    tmp = av_fast_realloc(vtctx->bitstream,
 
152
                          &vtctx->allocated_size,
 
153
                          vtctx->bitstream_size+size+4);
 
154
    if (!tmp)
 
155
        return AVERROR(ENOMEM);
 
156
 
 
157
    vtctx->bitstream = tmp;
 
158
 
 
159
    AV_WB32(vtctx->bitstream + vtctx->bitstream_size, size);
 
160
    memcpy(vtctx->bitstream + vtctx->bitstream_size + 4, buffer, size);
 
161
 
 
162
    vtctx->bitstream_size += size + 4;
 
163
 
 
164
    return 0;
 
165
}
 
166
 
 
167
int ff_videotoolbox_uninit(AVCodecContext *avctx)
 
168
{
 
169
    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
 
170
    if (vtctx) {
 
171
        av_freep(&vtctx->bitstream);
 
172
        if (vtctx->frame)
 
173
            CVPixelBufferRelease(vtctx->frame);
 
174
    }
 
175
 
 
176
    return 0;
 
177
}
 
178
 
 
179
#if CONFIG_VIDEOTOOLBOX
 
180
static void videotoolbox_write_mp4_descr_length(PutByteContext *pb, int length)
 
181
{
 
182
    int i;
 
183
    uint8_t b;
 
184
 
 
185
    for (i = 3; i >= 0; i--) {
 
186
        b = (length >> (i * 7)) & 0x7F;
 
187
        if (i != 0)
 
188
            b |= 0x80;
 
189
 
 
190
        bytestream2_put_byteu(pb, b);
 
191
    }
 
192
}
 
193
 
 
194
static CFDataRef videotoolbox_esds_extradata_create(AVCodecContext *avctx)
 
195
{
 
196
    CFDataRef data;
 
197
    uint8_t *rw_extradata;
 
198
    PutByteContext pb;
 
199
    int full_size = 3 + 5 + 13 + 5 + avctx->extradata_size + 3;
 
200
    // ES_DescrTag data + DecoderConfigDescrTag + data + DecSpecificInfoTag + size + SLConfigDescriptor
 
201
    int config_size = 13 + 5 + avctx->extradata_size;
 
202
    int s;
 
203
 
 
204
    if (!(rw_extradata = av_mallocz(full_size + VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING)))
 
205
        return NULL;
 
206
 
 
207
    bytestream2_init_writer(&pb, rw_extradata, full_size + VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING);
 
208
    bytestream2_put_byteu(&pb, 0);        // version
 
209
    bytestream2_put_ne24(&pb, 0);         // flags
 
210
 
 
211
    // elementary stream descriptor
 
212
    bytestream2_put_byteu(&pb, 0x03);     // ES_DescrTag
 
213
    videotoolbox_write_mp4_descr_length(&pb, full_size);
 
214
    bytestream2_put_ne16(&pb, 0);         // esid
 
215
    bytestream2_put_byteu(&pb, 0);        // stream priority (0-32)
 
216
 
 
217
    // decoder configuration descriptor
 
218
    bytestream2_put_byteu(&pb, 0x04);     // DecoderConfigDescrTag
 
219
    videotoolbox_write_mp4_descr_length(&pb, config_size);
 
220
    bytestream2_put_byteu(&pb, 32);       // object type indication. 32 = AV_CODEC_ID_MPEG4
 
221
    bytestream2_put_byteu(&pb, 0x11);     // stream type
 
222
    bytestream2_put_ne24(&pb, 0);         // buffer size
 
223
    bytestream2_put_ne32(&pb, 0);         // max bitrate
 
224
    bytestream2_put_ne32(&pb, 0);         // avg bitrate
 
225
 
 
226
    // decoder specific descriptor
 
227
    bytestream2_put_byteu(&pb, 0x05);     ///< DecSpecificInfoTag
 
228
    videotoolbox_write_mp4_descr_length(&pb, avctx->extradata_size);
 
229
 
 
230
    bytestream2_put_buffer(&pb, avctx->extradata, avctx->extradata_size);
 
231
 
 
232
    // SLConfigDescriptor
 
233
    bytestream2_put_byteu(&pb, 0x06);     // SLConfigDescrTag
 
234
    bytestream2_put_byteu(&pb, 0x01);     // length
 
235
    bytestream2_put_byteu(&pb, 0x02);     //
 
236
 
 
237
    s = bytestream2_size_p(&pb);
 
238
 
 
239
    data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s);
 
240
 
 
241
    av_freep(&rw_extradata);
 
242
    return data;
 
243
}
 
244
 
 
245
static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
 
246
                                                           void *buffer,
 
247
                                                           int size)
 
248
{
 
249
    OSStatus status;
 
250
    CMBlockBufferRef  block_buf;
 
251
    CMSampleBufferRef sample_buf;
 
252
 
 
253
    block_buf  = NULL;
 
254
    sample_buf = NULL;
 
255
 
 
256
    status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,// structureAllocator
 
257
                                                buffer,             // memoryBlock
 
258
                                                size,               // blockLength
 
259
                                                kCFAllocatorNull,   // blockAllocator
 
260
                                                NULL,               // customBlockSource
 
261
                                                0,                  // offsetToData
 
262
                                                size,               // dataLength
 
263
                                                0,                  // flags
 
264
                                                &block_buf);
 
265
 
 
266
    if (!status) {
 
267
        status = CMSampleBufferCreate(kCFAllocatorDefault,  // allocator
 
268
                                      block_buf,            // dataBuffer
 
269
                                      TRUE,                 // dataReady
 
270
                                      0,                    // makeDataReadyCallback
 
271
                                      0,                    // makeDataReadyRefcon
 
272
                                      fmt_desc,             // formatDescription
 
273
                                      1,                    // numSamples
 
274
                                      0,                    // numSampleTimingEntries
 
275
                                      NULL,                 // sampleTimingArray
 
276
                                      0,                    // numSampleSizeEntries
 
277
                                      NULL,                 // sampleSizeArray
 
278
                                      &sample_buf);
 
279
    }
 
280
 
 
281
    if (block_buf)
 
282
        CFRelease(block_buf);
 
283
 
 
284
    return sample_buf;
 
285
}
 
286
 
 
287
static void videotoolbox_decoder_callback(void *opaque,
 
288
                                          void *sourceFrameRefCon,
 
289
                                          OSStatus status,
 
290
                                          VTDecodeInfoFlags flags,
 
291
                                          CVImageBufferRef image_buffer,
 
292
                                          CMTime pts,
 
293
                                          CMTime duration)
 
294
{
 
295
    AVCodecContext *avctx = opaque;
 
296
    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
 
297
 
 
298
    if (vtctx->frame) {
 
299
        CVPixelBufferRelease(vtctx->frame);
 
300
        vtctx->frame = NULL;
 
301
    }
 
302
 
 
303
    if (!image_buffer) {
 
304
        av_log(NULL, AV_LOG_DEBUG, "vt decoder cb: output image buffer is null\n");
 
305
        return;
 
306
    }
 
307
 
 
308
    vtctx->frame = CVPixelBufferRetain(image_buffer);
 
309
}
 
310
 
 
311
static OSStatus videotoolbox_session_decode_frame(AVCodecContext *avctx)
 
312
{
 
313
    OSStatus status;
 
314
    CMSampleBufferRef sample_buf;
 
315
    AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;
 
316
    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
 
317
 
 
318
    sample_buf = videotoolbox_sample_buffer_create(videotoolbox->cm_fmt_desc,
 
319
                                                   vtctx->bitstream,
 
320
                                                   vtctx->bitstream_size);
 
321
 
 
322
    if (!sample_buf)
 
323
        return -1;
 
324
 
 
325
    status = VTDecompressionSessionDecodeFrame(videotoolbox->session,
 
326
                                               sample_buf,
 
327
                                               0,       // decodeFlags
 
328
                                               NULL,    // sourceFrameRefCon
 
329
                                               0);      // infoFlagsOut
 
330
    if (status == noErr)
 
331
        status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->session);
 
332
 
 
333
    CFRelease(sample_buf);
 
334
 
 
335
    return status;
 
336
}
 
337
 
 
338
static int videotoolbox_common_end_frame(AVCodecContext *avctx, AVFrame *frame)
 
339
{
 
340
    int status;
 
341
    AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;
 
342
    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
 
343
 
 
344
    if (!videotoolbox->session || !vtctx->bitstream)
 
345
        return AVERROR_INVALIDDATA;
 
346
 
 
347
    status = videotoolbox_session_decode_frame(avctx);
 
348
 
 
349
    if (status) {
 
350
        av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
 
351
        return AVERROR_UNKNOWN;
 
352
    }
 
353
 
 
354
    if (!vtctx->frame)
 
355
        return AVERROR_UNKNOWN;
 
356
 
 
357
    return ff_videotoolbox_buffer_create(vtctx, frame);
 
358
}
 
359
 
 
360
static int videotoolbox_h264_end_frame(AVCodecContext *avctx)
 
361
{
 
362
    H264Context *h = avctx->priv_data;
 
363
    AVFrame *frame = h->cur_pic_ptr->f;
 
364
 
 
365
    return videotoolbox_common_end_frame(avctx, frame);
 
366
}
 
367
 
 
368
static int videotoolbox_mpeg_start_frame(AVCodecContext *avctx,
 
369
                                         const uint8_t *buffer,
 
370
                                         uint32_t size)
 
371
{
 
372
    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
 
373
 
 
374
    return videotoolbox_buffer_copy(vtctx, buffer, size);
 
375
}
 
376
 
 
377
static int videotoolbox_mpeg_decode_slice(AVCodecContext *avctx,
 
378
                                          const uint8_t *buffer,
 
379
                                          uint32_t size)
 
380
{
 
381
    return 0;
 
382
}
 
383
 
 
384
static int videotoolbox_mpeg_end_frame(AVCodecContext *avctx)
 
385
{
 
386
    MpegEncContext *s = avctx->priv_data;
 
387
    AVFrame *frame = s->current_picture_ptr->f;
 
388
 
 
389
    return videotoolbox_common_end_frame(avctx, frame);
 
390
}
 
391
 
 
392
static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType codec_type,
 
393
                                                          AVCodecContext *avctx)
 
394
{
 
395
    CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
 
396
                                                                   1,
 
397
                                                                   &kCFTypeDictionaryKeyCallBacks,
 
398
                                                                   &kCFTypeDictionaryValueCallBacks);
 
399
 
 
400
    CFDictionarySetValue(config_info,
 
401
                         kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder,
 
402
                         kCFBooleanTrue);
 
403
 
 
404
    if (avctx->extradata_size) {
 
405
        CFMutableDictionaryRef avc_info;
 
406
        CFDataRef data = NULL;
 
407
 
 
408
        avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
 
409
                                             1,
 
410
                                             &kCFTypeDictionaryKeyCallBacks,
 
411
                                             &kCFTypeDictionaryValueCallBacks);
 
412
 
 
413
        switch (codec_type) {
 
414
        case kCMVideoCodecType_MPEG4Video :
 
415
            data = videotoolbox_esds_extradata_create(avctx);
 
416
            if (data)
 
417
                CFDictionarySetValue(avc_info, CFSTR("esds"), data);
 
418
            break;
 
419
        case kCMVideoCodecType_H264 :
 
420
            data = ff_videotoolbox_avcc_extradata_create(avctx);
 
421
            if (data)
 
422
                CFDictionarySetValue(avc_info, CFSTR("avcC"), data);
 
423
            break;
 
424
        default:
 
425
            break;
 
426
        }
 
427
 
 
428
        CFDictionarySetValue(config_info,
 
429
                kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
 
430
                avc_info);
 
431
 
 
432
        if (data)
 
433
            CFRelease(data);
 
434
 
 
435
        CFRelease(avc_info);
 
436
    }
 
437
    return config_info;
 
438
}
 
439
 
 
440
static CFDictionaryRef videotoolbox_buffer_attributes_create(int width,
 
441
                                                             int height,
 
442
                                                             OSType pix_fmt)
 
443
{
 
444
    CFMutableDictionaryRef buffer_attributes;
 
445
    CFMutableDictionaryRef io_surface_properties;
 
446
    CFNumberRef cv_pix_fmt;
 
447
    CFNumberRef w;
 
448
    CFNumberRef h;
 
449
 
 
450
    w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
 
451
    h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
 
452
    cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt);
 
453
 
 
454
    buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
 
455
                                                  4,
 
456
                                                  &kCFTypeDictionaryKeyCallBacks,
 
457
                                                  &kCFTypeDictionaryValueCallBacks);
 
458
    io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
 
459
                                                      0,
 
460
                                                      &kCFTypeDictionaryKeyCallBacks,
 
461
                                                      &kCFTypeDictionaryValueCallBacks);
 
462
 
 
463
    CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
 
464
    CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
 
465
    CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w);
 
466
    CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h);
 
467
 
 
468
    CFRelease(io_surface_properties);
 
469
    CFRelease(cv_pix_fmt);
 
470
    CFRelease(w);
 
471
    CFRelease(h);
 
472
 
 
473
    return buffer_attributes;
 
474
}
 
475
 
 
476
static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType codec_type,
 
477
                                                                   CFDictionaryRef decoder_spec,
 
478
                                                                   int width,
 
479
                                                                   int height)
 
480
{
 
481
    CMFormatDescriptionRef cm_fmt_desc;
 
482
    OSStatus status;
 
483
 
 
484
    status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
 
485
                                            codec_type,
 
486
                                            width,
 
487
                                            height,
 
488
                                            decoder_spec, // Dictionary of extension
 
489
                                            &cm_fmt_desc);
 
490
 
 
491
    if (status)
 
492
        return NULL;
 
493
 
 
494
    return cm_fmt_desc;
 
495
}
 
496
 
 
497
static int videotoolbox_default_init(AVCodecContext *avctx)
 
498
{
 
499
    AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;
 
500
    OSStatus status;
 
501
    VTDecompressionOutputCallbackRecord decoder_cb;
 
502
    CFDictionaryRef decoder_spec;
 
503
    CFDictionaryRef buf_attr;
 
504
    int32_t pix_fmt;
 
505
 
 
506
    if (!videotoolbox) {
 
507
        av_log(avctx, AV_LOG_ERROR, "hwaccel context is not set\n");
 
508
        return -1;
 
509
    }
 
510
 
 
511
    switch( avctx->codec_id ) {
 
512
    case AV_CODEC_ID_H263 :
 
513
        videotoolbox->cm_codec_type = kCMVideoCodecType_H263;
 
514
        break;
 
515
    case AV_CODEC_ID_H264 :
 
516
        videotoolbox->cm_codec_type = kCMVideoCodecType_H264;
 
517
        break;
 
518
    case AV_CODEC_ID_MPEG1VIDEO :
 
519
        videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG1Video;
 
520
        break;
 
521
    case AV_CODEC_ID_MPEG2VIDEO :
 
522
        videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG2Video;
 
523
        break;
 
524
    case AV_CODEC_ID_MPEG4 :
 
525
        videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG4Video;
 
526
        break;
 
527
    default :
 
528
        break;
 
529
    }
 
530
 
 
531
    pix_fmt = videotoolbox->cv_pix_fmt_type;
 
532
 
 
533
    decoder_spec = videotoolbox_decoder_config_create(videotoolbox->cm_codec_type, avctx);
 
534
 
 
535
    videotoolbox->cm_fmt_desc = videotoolbox_format_desc_create(videotoolbox->cm_codec_type,
 
536
                                                                decoder_spec,
 
537
                                                                avctx->width,
 
538
                                                                avctx->height);
 
539
    if (!videotoolbox->cm_fmt_desc) {
 
540
        if (decoder_spec)
 
541
            CFRelease(decoder_spec);
 
542
 
 
543
        av_log(avctx, AV_LOG_ERROR, "format description creation failed\n");
 
544
        return -1;
 
545
    }
 
546
 
 
547
    buf_attr = videotoolbox_buffer_attributes_create(avctx->width,
 
548
                                                     avctx->height,
 
549
                                                     videotoolbox->cv_pix_fmt_type);
 
550
 
 
551
    decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
 
552
    decoder_cb.decompressionOutputRefCon   = avctx;
 
553
 
 
554
    status = VTDecompressionSessionCreate(NULL,                      // allocator
 
555
                                          videotoolbox->cm_fmt_desc, // videoFormatDescription
 
556
                                          decoder_spec,              // videoDecoderSpecification
 
557
                                          buf_attr,                  // destinationImageBufferAttributes
 
558
                                          &decoder_cb,               // outputCallback
 
559
                                          &videotoolbox->session);   // decompressionSessionOut
 
560
 
 
561
    if (decoder_spec)
 
562
        CFRelease(decoder_spec);
 
563
    if (buf_attr)
 
564
        CFRelease(buf_attr);
 
565
 
 
566
    switch (status) {
 
567
    case kVTVideoDecoderNotAvailableNowErr:
 
568
    case kVTVideoDecoderUnsupportedDataFormatErr:
 
569
        return AVERROR(ENOSYS);
 
570
    case kVTVideoDecoderMalfunctionErr:
 
571
        return AVERROR(EINVAL);
 
572
    case kVTVideoDecoderBadDataErr :
 
573
        return AVERROR_INVALIDDATA;
 
574
    case 0:
 
575
        return 0;
 
576
    default:
 
577
        return AVERROR_UNKNOWN;
 
578
    }
 
579
}
 
580
 
 
581
static void videotoolbox_default_free(AVCodecContext *avctx)
 
582
{
 
583
    AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;
 
584
 
 
585
    if (videotoolbox) {
 
586
        if (videotoolbox->cm_fmt_desc)
 
587
            CFRelease(videotoolbox->cm_fmt_desc);
 
588
 
 
589
        if (videotoolbox->session)
 
590
            VTDecompressionSessionInvalidate(videotoolbox->session);
 
591
    }
 
592
}
 
593
 
 
594
AVHWAccel ff_h263_videotoolbox_hwaccel = {
 
595
    .name           = "h263_videotoolbox",
 
596
    .type           = AVMEDIA_TYPE_VIDEO,
 
597
    .id             = AV_CODEC_ID_H263,
 
598
    .pix_fmt        = AV_PIX_FMT_VIDEOTOOLBOX,
 
599
    .alloc_frame    = ff_videotoolbox_alloc_frame,
 
600
    .start_frame    = videotoolbox_mpeg_start_frame,
 
601
    .decode_slice   = videotoolbox_mpeg_decode_slice,
 
602
    .end_frame      = videotoolbox_mpeg_end_frame,
 
603
    .uninit         = ff_videotoolbox_uninit,
 
604
    .priv_data_size = sizeof(VTContext),
 
605
};
 
606
 
 
607
AVHWAccel ff_h264_videotoolbox_hwaccel = {
 
608
    .name           = "h264_videotoolbox",
 
609
    .type           = AVMEDIA_TYPE_VIDEO,
 
610
    .id             = AV_CODEC_ID_H264,
 
611
    .pix_fmt        = AV_PIX_FMT_VIDEOTOOLBOX,
 
612
    .alloc_frame    = ff_videotoolbox_alloc_frame,
 
613
    .start_frame    = ff_videotoolbox_h264_start_frame,
 
614
    .decode_slice   = ff_videotoolbox_h264_decode_slice,
 
615
    .end_frame      = videotoolbox_h264_end_frame,
 
616
    .uninit         = ff_videotoolbox_uninit,
 
617
    .priv_data_size = sizeof(VTContext),
 
618
};
 
619
 
 
620
AVHWAccel ff_mpeg1_videotoolbox_hwaccel = {
 
621
    .name           = "mpeg1_videotoolbox",
 
622
    .type           = AVMEDIA_TYPE_VIDEO,
 
623
    .id             = AV_CODEC_ID_MPEG1VIDEO,
 
624
    .pix_fmt        = AV_PIX_FMT_VIDEOTOOLBOX,
 
625
    .alloc_frame    = ff_videotoolbox_alloc_frame,
 
626
    .start_frame    = videotoolbox_mpeg_start_frame,
 
627
    .decode_slice   = videotoolbox_mpeg_decode_slice,
 
628
    .end_frame      = videotoolbox_mpeg_end_frame,
 
629
    .uninit         = ff_videotoolbox_uninit,
 
630
    .priv_data_size = sizeof(VTContext),
 
631
};
 
632
 
 
633
AVHWAccel ff_mpeg2_videotoolbox_hwaccel = {
 
634
    .name           = "mpeg2_videotoolbox",
 
635
    .type           = AVMEDIA_TYPE_VIDEO,
 
636
    .id             = AV_CODEC_ID_MPEG2VIDEO,
 
637
    .pix_fmt        = AV_PIX_FMT_VIDEOTOOLBOX,
 
638
    .alloc_frame    = ff_videotoolbox_alloc_frame,
 
639
    .start_frame    = videotoolbox_mpeg_start_frame,
 
640
    .decode_slice   = videotoolbox_mpeg_decode_slice,
 
641
    .end_frame      = videotoolbox_mpeg_end_frame,
 
642
    .uninit         = ff_videotoolbox_uninit,
 
643
    .priv_data_size = sizeof(VTContext),
 
644
};
 
645
 
 
646
AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
 
647
    .name           = "mpeg4_videotoolbox",
 
648
    .type           = AVMEDIA_TYPE_VIDEO,
 
649
    .id             = AV_CODEC_ID_MPEG4,
 
650
    .pix_fmt        = AV_PIX_FMT_VIDEOTOOLBOX,
 
651
    .alloc_frame    = ff_videotoolbox_alloc_frame,
 
652
    .start_frame    = videotoolbox_mpeg_start_frame,
 
653
    .decode_slice   = videotoolbox_mpeg_decode_slice,
 
654
    .end_frame      = videotoolbox_mpeg_end_frame,
 
655
    .uninit         = ff_videotoolbox_uninit,
 
656
    .priv_data_size = sizeof(VTContext),
 
657
};
 
658
 
 
659
AVVideotoolboxContext *av_videotoolbox_alloc_context(void)
 
660
{
 
661
    AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret));
 
662
 
 
663
    if (ret) {
 
664
        ret->output_callback = videotoolbox_decoder_callback;
 
665
        ret->cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
 
666
    }
 
667
 
 
668
    return ret;
 
669
}
 
670
 
 
671
int av_videotoolbox_default_init(AVCodecContext *avctx)
 
672
{
 
673
    return av_videotoolbox_default_init2(avctx, NULL);
 
674
}
 
675
 
 
676
int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx)
 
677
{
 
678
    avctx->hwaccel_context = vtctx ?: av_videotoolbox_alloc_context();
 
679
    if (!avctx->hwaccel_context)
 
680
        return AVERROR(ENOMEM);
 
681
    return videotoolbox_default_init(avctx);
 
682
}
 
683
 
 
684
void av_videotoolbox_default_free(AVCodecContext *avctx)
 
685
{
 
686
 
 
687
    videotoolbox_default_free(avctx);
 
688
    av_freep(&avctx->hwaccel_context);
 
689
}
 
690
#endif /* CONFIG_VIDEOTOOLBOX */