FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
videotoolbox.c
Go to the documentation of this file.
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_RequireHardwareAcceleratedVideoDecoder
36 # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder")
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 
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 
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 #define AV_W8(p, v) *(p) = (v)
81 
83 {
84  H264Context *h = avctx->priv_data;
85  CFDataRef data = NULL;
86  uint8_t *p;
87  int vt_extradata_size = 6 + 2 + h->ps.sps->data_size + 3 + h->ps.pps->data_size;
88  uint8_t *vt_extradata = av_malloc(vt_extradata_size);
89  if (!vt_extradata)
90  return NULL;
91 
92  p = vt_extradata;
93 
94  AV_W8(p + 0, 1); /* version */
95  AV_W8(p + 1, h->ps.sps->data[1]); /* profile */
96  AV_W8(p + 2, h->ps.sps->data[2]); /* profile compat */
97  AV_W8(p + 3, h->ps.sps->data[3]); /* level */
98  AV_W8(p + 4, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 3 (11) */
99  AV_W8(p + 5, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
100  AV_WB16(p + 6, h->ps.sps->data_size);
101  memcpy(p + 8, h->ps.sps->data, h->ps.sps->data_size);
102  p += 8 + h->ps.sps->data_size;
103  AV_W8(p + 0, 1); /* number of pps */
104  AV_WB16(p + 1, h->ps.pps->data_size);
105  memcpy(p + 3, h->ps.pps->data, h->ps.pps->data_size);
106 
107  p += 3 + h->ps.pps->data_size;
108  av_assert0(p - vt_extradata == vt_extradata_size);
109 
110  data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
111  av_free(vt_extradata);
112  return data;
113 }
114 
116 {
117  av_buffer_unref(&frame->buf[0]);
118 
119  frame->buf[0] = av_buffer_create((uint8_t*)vtctx->frame,
120  sizeof(vtctx->frame),
122  NULL,
124  if (!frame->buf[0]) {
125  return AVERROR(ENOMEM);
126  }
127 
128  frame->data[3] = (uint8_t*)vtctx->frame;
129  vtctx->frame = NULL;
130 
131  return 0;
132 }
133 
135  const uint8_t *buffer,
136  uint32_t size)
137 {
138  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
139  H264Context *h = avctx->priv_data;
140 
141  vtctx->bitstream_size = 0;
142 
143  if (h->is_avc == 1) {
144  return videotoolbox_buffer_copy(vtctx, buffer, size);
145  }
146 
147  return 0;
148 }
149 
151  const uint8_t *buffer,
152  uint32_t size)
153 {
154  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
155  H264Context *h = avctx->priv_data;
156  void *tmp;
157 
158  if (h->is_avc == 1)
159  return 0;
160 
161  tmp = av_fast_realloc(vtctx->bitstream,
162  &vtctx->allocated_size,
163  vtctx->bitstream_size+size+4);
164  if (!tmp)
165  return AVERROR(ENOMEM);
166 
167  vtctx->bitstream = tmp;
168 
169  AV_WB32(vtctx->bitstream + vtctx->bitstream_size, size);
170  memcpy(vtctx->bitstream + vtctx->bitstream_size + 4, buffer, size);
171 
172  vtctx->bitstream_size += size + 4;
173 
174  return 0;
175 }
176 
178 {
179  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
180  if (vtctx) {
181  av_freep(&vtctx->bitstream);
182  if (vtctx->frame)
183  CVPixelBufferRelease(vtctx->frame);
184  }
185 
186  return 0;
187 }
188 
189 #if CONFIG_VIDEOTOOLBOX
190 static void videotoolbox_write_mp4_descr_length(PutByteContext *pb, int length)
191 {
192  int i;
193  uint8_t b;
194 
195  for (i = 3; i >= 0; i--) {
196  b = (length >> (i * 7)) & 0x7F;
197  if (i != 0)
198  b |= 0x80;
199 
200  bytestream2_put_byteu(pb, b);
201  }
202 }
203 
204 static CFDataRef videotoolbox_esds_extradata_create(AVCodecContext *avctx)
205 {
206  CFDataRef data;
207  uint8_t *rw_extradata;
208  PutByteContext pb;
209  int full_size = 3 + 5 + 13 + 5 + avctx->extradata_size + 3;
210  // ES_DescrTag data + DecoderConfigDescrTag + data + DecSpecificInfoTag + size + SLConfigDescriptor
211  int config_size = 13 + 5 + avctx->extradata_size;
212  int s;
213 
214  if (!(rw_extradata = av_mallocz(full_size + VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING)))
215  return NULL;
216 
217  bytestream2_init_writer(&pb, rw_extradata, full_size + VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING);
218  bytestream2_put_byteu(&pb, 0); // version
219  bytestream2_put_ne24(&pb, 0); // flags
220 
221  // elementary stream descriptor
222  bytestream2_put_byteu(&pb, 0x03); // ES_DescrTag
223  videotoolbox_write_mp4_descr_length(&pb, full_size);
224  bytestream2_put_ne16(&pb, 0); // esid
225  bytestream2_put_byteu(&pb, 0); // stream priority (0-32)
226 
227  // decoder configuration descriptor
228  bytestream2_put_byteu(&pb, 0x04); // DecoderConfigDescrTag
229  videotoolbox_write_mp4_descr_length(&pb, config_size);
230  bytestream2_put_byteu(&pb, 32); // object type indication. 32 = AV_CODEC_ID_MPEG4
231  bytestream2_put_byteu(&pb, 0x11); // stream type
232  bytestream2_put_ne24(&pb, 0); // buffer size
233  bytestream2_put_ne32(&pb, 0); // max bitrate
234  bytestream2_put_ne32(&pb, 0); // avg bitrate
235 
236  // decoder specific descriptor
237  bytestream2_put_byteu(&pb, 0x05); ///< DecSpecificInfoTag
238  videotoolbox_write_mp4_descr_length(&pb, avctx->extradata_size);
239 
240  bytestream2_put_buffer(&pb, avctx->extradata, avctx->extradata_size);
241 
242  // SLConfigDescriptor
243  bytestream2_put_byteu(&pb, 0x06); // SLConfigDescrTag
244  bytestream2_put_byteu(&pb, 0x01); // length
245  bytestream2_put_byteu(&pb, 0x02); //
246 
247  s = bytestream2_size_p(&pb);
248 
249  data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s);
250 
251  av_freep(&rw_extradata);
252  return data;
253 }
254 
255 static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
256  void *buffer,
257  int size)
258 {
259  OSStatus status;
260  CMBlockBufferRef block_buf;
261  CMSampleBufferRef sample_buf;
262 
263  block_buf = NULL;
264  sample_buf = NULL;
265 
266  status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,// structureAllocator
267  buffer, // memoryBlock
268  size, // blockLength
269  kCFAllocatorNull, // blockAllocator
270  NULL, // customBlockSource
271  0, // offsetToData
272  size, // dataLength
273  0, // flags
274  &block_buf);
275 
276  if (!status) {
277  status = CMSampleBufferCreate(kCFAllocatorDefault, // allocator
278  block_buf, // dataBuffer
279  TRUE, // dataReady
280  0, // makeDataReadyCallback
281  0, // makeDataReadyRefcon
282  fmt_desc, // formatDescription
283  1, // numSamples
284  0, // numSampleTimingEntries
285  NULL, // sampleTimingArray
286  0, // numSampleSizeEntries
287  NULL, // sampleSizeArray
288  &sample_buf);
289  }
290 
291  if (block_buf)
292  CFRelease(block_buf);
293 
294  return sample_buf;
295 }
296 
297 static void videotoolbox_decoder_callback(void *opaque,
298  void *sourceFrameRefCon,
299  OSStatus status,
300  VTDecodeInfoFlags flags,
301  CVImageBufferRef image_buffer,
302  CMTime pts,
303  CMTime duration)
304 {
305  AVCodecContext *avctx = opaque;
306  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
307 
308  if (vtctx->frame) {
309  CVPixelBufferRelease(vtctx->frame);
310  vtctx->frame = NULL;
311  }
312 
313  if (!image_buffer) {
314  av_log(NULL, AV_LOG_DEBUG, "vt decoder cb: output image buffer is null\n");
315  return;
316  }
317 
318  vtctx->frame = CVPixelBufferRetain(image_buffer);
319 }
320 
321 static OSStatus videotoolbox_session_decode_frame(AVCodecContext *avctx)
322 {
323  OSStatus status;
324  CMSampleBufferRef sample_buf;
325  AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;
326  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
327 
328  sample_buf = videotoolbox_sample_buffer_create(videotoolbox->cm_fmt_desc,
329  vtctx->bitstream,
330  vtctx->bitstream_size);
331 
332  if (!sample_buf)
333  return -1;
334 
335  status = VTDecompressionSessionDecodeFrame(videotoolbox->session,
336  sample_buf,
337  0, // decodeFlags
338  NULL, // sourceFrameRefCon
339  0); // infoFlagsOut
340  if (status == noErr)
341  status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->session);
342 
343  CFRelease(sample_buf);
344 
345  return status;
346 }
347 
348 static int videotoolbox_common_end_frame(AVCodecContext *avctx, AVFrame *frame)
349 {
350  int status;
351  AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;
352  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
353 
354  av_buffer_unref(&frame->buf[0]);
355 
356  if (!videotoolbox->session || !vtctx->bitstream)
357  return AVERROR_INVALIDDATA;
358 
359  status = videotoolbox_session_decode_frame(avctx);
360 
361  if (status) {
362  av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);
363  return AVERROR_UNKNOWN;
364  }
365 
366  if (!vtctx->frame)
367  return AVERROR_UNKNOWN;
368 
369  return ff_videotoolbox_buffer_create(vtctx, frame);
370 }
371 
372 static int videotoolbox_h264_end_frame(AVCodecContext *avctx)
373 {
374  H264Context *h = avctx->priv_data;
375  AVFrame *frame = h->cur_pic_ptr->f;
376 
377  return videotoolbox_common_end_frame(avctx, frame);
378 }
379 
380 static int videotoolbox_mpeg_start_frame(AVCodecContext *avctx,
381  const uint8_t *buffer,
382  uint32_t size)
383 {
384  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
385 
386  return videotoolbox_buffer_copy(vtctx, buffer, size);
387 }
388 
389 static int videotoolbox_mpeg_decode_slice(AVCodecContext *avctx,
390  const uint8_t *buffer,
391  uint32_t size)
392 {
393  return 0;
394 }
395 
396 static int videotoolbox_mpeg_end_frame(AVCodecContext *avctx)
397 {
398  MpegEncContext *s = avctx->priv_data;
399  AVFrame *frame = s->current_picture_ptr->f;
400 
401  return videotoolbox_common_end_frame(avctx, frame);
402 }
403 
404 static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType codec_type,
405  AVCodecContext *avctx)
406 {
407  CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
408  0,
409  &kCFTypeDictionaryKeyCallBacks,
410  &kCFTypeDictionaryValueCallBacks);
411 
412  CFDictionarySetValue(config_info,
414  kCFBooleanTrue);
415 
416  if (avctx->extradata_size) {
417  CFMutableDictionaryRef avc_info;
418  CFDataRef data = NULL;
419 
420  avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
421  1,
422  &kCFTypeDictionaryKeyCallBacks,
423  &kCFTypeDictionaryValueCallBacks);
424 
425  switch (codec_type) {
426  case kCMVideoCodecType_MPEG4Video :
427  data = videotoolbox_esds_extradata_create(avctx);
428  if (data)
429  CFDictionarySetValue(avc_info, CFSTR("esds"), data);
430  break;
431  case kCMVideoCodecType_H264 :
433  if (data)
434  CFDictionarySetValue(avc_info, CFSTR("avcC"), data);
435  break;
436  default:
437  break;
438  }
439 
440  CFDictionarySetValue(config_info,
441  kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
442  avc_info);
443 
444  if (data)
445  CFRelease(data);
446 
447  CFRelease(avc_info);
448  }
449  return config_info;
450 }
451 
452 static CFDictionaryRef videotoolbox_buffer_attributes_create(int width,
453  int height,
454  OSType pix_fmt)
455 {
456  CFMutableDictionaryRef buffer_attributes;
457  CFMutableDictionaryRef io_surface_properties;
458  CFNumberRef cv_pix_fmt;
459  CFNumberRef w;
460  CFNumberRef h;
461 
462  w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
463  h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
464  cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt);
465 
466  buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
467  4,
468  &kCFTypeDictionaryKeyCallBacks,
469  &kCFTypeDictionaryValueCallBacks);
470  io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
471  0,
472  &kCFTypeDictionaryKeyCallBacks,
473  &kCFTypeDictionaryValueCallBacks);
474 
475  CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
476  CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
477  CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w);
478  CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h);
479 
480  CFRelease(io_surface_properties);
481  CFRelease(cv_pix_fmt);
482  CFRelease(w);
483  CFRelease(h);
484 
485  return buffer_attributes;
486 }
487 
488 static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType codec_type,
489  CFDictionaryRef decoder_spec,
490  int width,
491  int height)
492 {
493  CMFormatDescriptionRef cm_fmt_desc;
494  OSStatus status;
495 
496  status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
497  codec_type,
498  width,
499  height,
500  decoder_spec, // Dictionary of extension
501  &cm_fmt_desc);
502 
503  if (status)
504  return NULL;
505 
506  return cm_fmt_desc;
507 }
508 
509 static int videotoolbox_default_init(AVCodecContext *avctx)
510 {
511  AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;
512  OSStatus status;
513  VTDecompressionOutputCallbackRecord decoder_cb;
514  CFDictionaryRef decoder_spec;
515  CFDictionaryRef buf_attr;
516 
517  if (!videotoolbox) {
518  av_log(avctx, AV_LOG_ERROR, "hwaccel context is not set\n");
519  return -1;
520  }
521 
522  switch( avctx->codec_id ) {
523  case AV_CODEC_ID_H263 :
524  videotoolbox->cm_codec_type = kCMVideoCodecType_H263;
525  break;
526  case AV_CODEC_ID_H264 :
527  videotoolbox->cm_codec_type = kCMVideoCodecType_H264;
528  break;
530  videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG1Video;
531  break;
533  videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG2Video;
534  break;
535  case AV_CODEC_ID_MPEG4 :
536  videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG4Video;
537  break;
538  default :
539  break;
540  }
541 
542  decoder_spec = videotoolbox_decoder_config_create(videotoolbox->cm_codec_type, avctx);
543 
544  videotoolbox->cm_fmt_desc = videotoolbox_format_desc_create(videotoolbox->cm_codec_type,
545  decoder_spec,
546  avctx->width,
547  avctx->height);
548  if (!videotoolbox->cm_fmt_desc) {
549  if (decoder_spec)
550  CFRelease(decoder_spec);
551 
552  av_log(avctx, AV_LOG_ERROR, "format description creation failed\n");
553  return -1;
554  }
555 
556  buf_attr = videotoolbox_buffer_attributes_create(avctx->width,
557  avctx->height,
558  videotoolbox->cv_pix_fmt_type);
559 
560  decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
561  decoder_cb.decompressionOutputRefCon = avctx;
562 
563  status = VTDecompressionSessionCreate(NULL, // allocator
564  videotoolbox->cm_fmt_desc, // videoFormatDescription
565  decoder_spec, // videoDecoderSpecification
566  buf_attr, // destinationImageBufferAttributes
567  &decoder_cb, // outputCallback
568  &videotoolbox->session); // decompressionSessionOut
569 
570  if (decoder_spec)
571  CFRelease(decoder_spec);
572  if (buf_attr)
573  CFRelease(buf_attr);
574 
575  switch (status) {
576  case kVTVideoDecoderNotAvailableNowErr:
577  case kVTVideoDecoderUnsupportedDataFormatErr:
578  return AVERROR(ENOSYS);
579  case kVTVideoDecoderMalfunctionErr:
580  return AVERROR(EINVAL);
581  case kVTVideoDecoderBadDataErr :
582  return AVERROR_INVALIDDATA;
583  case 0:
584  return 0;
585  default:
586  return AVERROR_UNKNOWN;
587  }
588 }
589 
590 static void videotoolbox_default_free(AVCodecContext *avctx)
591 {
592  AVVideotoolboxContext *videotoolbox = avctx->hwaccel_context;
593 
594  if (videotoolbox) {
595  if (videotoolbox->cm_fmt_desc)
596  CFRelease(videotoolbox->cm_fmt_desc);
597 
598  if (videotoolbox->session) {
599  VTDecompressionSessionInvalidate(videotoolbox->session);
600  CFRelease(videotoolbox->session);
601  }
602  }
603 }
604 
605 AVHWAccel ff_h263_videotoolbox_hwaccel = {
606  .name = "h263_videotoolbox",
607  .type = AVMEDIA_TYPE_VIDEO,
608  .id = AV_CODEC_ID_H263,
609  .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
610  .alloc_frame = ff_videotoolbox_alloc_frame,
611  .start_frame = videotoolbox_mpeg_start_frame,
612  .decode_slice = videotoolbox_mpeg_decode_slice,
613  .end_frame = videotoolbox_mpeg_end_frame,
614  .uninit = ff_videotoolbox_uninit,
615  .priv_data_size = sizeof(VTContext),
616 };
617 
618 AVHWAccel ff_h264_videotoolbox_hwaccel = {
619  .name = "h264_videotoolbox",
620  .type = AVMEDIA_TYPE_VIDEO,
621  .id = AV_CODEC_ID_H264,
622  .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
623  .alloc_frame = ff_videotoolbox_alloc_frame,
624  .start_frame = ff_videotoolbox_h264_start_frame,
625  .decode_slice = ff_videotoolbox_h264_decode_slice,
626  .end_frame = videotoolbox_h264_end_frame,
627  .uninit = ff_videotoolbox_uninit,
628  .priv_data_size = sizeof(VTContext),
629 };
630 
631 AVHWAccel ff_mpeg1_videotoolbox_hwaccel = {
632  .name = "mpeg1_videotoolbox",
633  .type = AVMEDIA_TYPE_VIDEO,
635  .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
636  .alloc_frame = ff_videotoolbox_alloc_frame,
637  .start_frame = videotoolbox_mpeg_start_frame,
638  .decode_slice = videotoolbox_mpeg_decode_slice,
639  .end_frame = videotoolbox_mpeg_end_frame,
640  .uninit = ff_videotoolbox_uninit,
641  .priv_data_size = sizeof(VTContext),
642 };
643 
644 AVHWAccel ff_mpeg2_videotoolbox_hwaccel = {
645  .name = "mpeg2_videotoolbox",
646  .type = AVMEDIA_TYPE_VIDEO,
648  .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
649  .alloc_frame = ff_videotoolbox_alloc_frame,
650  .start_frame = videotoolbox_mpeg_start_frame,
651  .decode_slice = videotoolbox_mpeg_decode_slice,
652  .end_frame = videotoolbox_mpeg_end_frame,
653  .uninit = ff_videotoolbox_uninit,
654  .priv_data_size = sizeof(VTContext),
655 };
656 
657 AVHWAccel ff_mpeg4_videotoolbox_hwaccel = {
658  .name = "mpeg4_videotoolbox",
659  .type = AVMEDIA_TYPE_VIDEO,
660  .id = AV_CODEC_ID_MPEG4,
661  .pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
662  .alloc_frame = ff_videotoolbox_alloc_frame,
663  .start_frame = videotoolbox_mpeg_start_frame,
664  .decode_slice = videotoolbox_mpeg_decode_slice,
665  .end_frame = videotoolbox_mpeg_end_frame,
666  .uninit = ff_videotoolbox_uninit,
667  .priv_data_size = sizeof(VTContext),
668 };
669 
671 {
672  AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret));
673 
674  if (ret) {
675  ret->output_callback = videotoolbox_decoder_callback;
676  ret->cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
677  }
678 
679  return ret;
680 }
681 
683 {
684  return av_videotoolbox_default_init2(avctx, NULL);
685 }
686 
688 {
690  if (!avctx->hwaccel_context)
691  return AVERROR(ENOMEM);
692  return videotoolbox_default_init(avctx);
693 }
694 
696 {
697 
698  videotoolbox_default_free(avctx);
699  av_freep(&avctx->hwaccel_context);
700 }
701 #endif /* CONFIG_VIDEOTOOLBOX */
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:631
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static enum AVPixelFormat pix_fmt
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
Definition: buffer.c:124
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
uint8_t * bitstream
int cm_codec_type
CoreMedia codec type that Videotoolbox will use to create the decompression session.
Definition: videotoolbox.h:75
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:363
hardware decoding through Videotoolbox
Definition: pixfmt.h:295
AVVideotoolboxContext * av_videotoolbox_alloc_context(void)
Allocate and initialize a Videotoolbox context.
const char * b
Definition: vf_curves.c:109
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:143
enum AVMediaType codec_type
Definition: rtp.c:37
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1877
external API header
int is_avc
Used to parse AVC variant of H.264.
Definition: h264.h:568
mpegvideo header.
H264Context.
Definition: h264.h:456
int ff_videotoolbox_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:134
AVFrame * f
Definition: h264.h:264
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define AV_W8(p, v)
Definition: videotoolbox.c:80
const PPS * pps
Definition: h264.h:236
int ff_videotoolbox_buffer_create(VTContext *vtctx, AVFrame *frame)
Definition: videotoolbox.c:115
uint8_t
#define av_malloc(s)
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:2980
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1764
int64_t duration
Definition: movenc.c:63
static AVFrame * frame
#define height
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
Definition: videotoolbox.c:82
int av_videotoolbox_default_init(AVCodecContext *avctx)
This is a convenience function that creates and sets up the Videotoolbox context using an internal im...
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:113
ptrdiff_t size
Definition: opengl_enc.c:101
#define AV_WB16(p, v)
Definition: intreadwrite.h:405
#define av_log(a,...)
static int videotoolbox_buffer_copy(VTContext *vtctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:47
H.264 / AVC / MPEG-4 part10 codec.
int width
width and height of the video frame
Definition: frame.h:236
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given block if it is not large enough, otherwise do nothing.
Definition: mem.c:480
#define AVERROR(e)
Definition: error.h:43
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
int allocated_size
GLsizei GLsizei * length
Definition: opengl_enc.c:115
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:28
VTDecompressionSessionRef session
Videotoolbox decompression session object.
Definition: videotoolbox.h:51
size_t data_size
Definition: h264.h:194
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:3668
uint8_t data[4096]
Definition: h264.h:220
#define width
int width
picture width / height.
Definition: avcodec.h:1836
Picture * current_picture_ptr
pointer to the current picture
Definition: mpegvideo.h:181
#define TRUE
Definition: windows2linux.h:33
int bitstream_size
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:282
preferred ID for MPEG-1/2 video decoding
Definition: avcodec.h:194
int av_videotoolbox_default_init2(AVCodecContext *avctx, AVVideotoolboxContext *vtctx)
This is a convenience function that creates and sets up the Videotoolbox context using an internal im...
#define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
Definition: videotoolbox.c:36
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:248
enum AVCodecID codec_id
Definition: avcodec.h:1666
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:66
Public libavcodec VDA header.
#define bytestream2_put_ne24
Definition: bytestream.h:124
main external API structure.
Definition: avcodec.h:1649
int ff_videotoolbox_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:150
CMVideoFormatDescriptionRef cm_fmt_desc
CoreMedia Format Description that Videotoolbox will use to create the decompression session...
Definition: videotoolbox.h:69
int extradata_size
Definition: avcodec.h:1765
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
struct AVFrame * f
Definition: mpegpicture.h:46
H264Picture * cur_pic_ptr
Definition: h264.h:466
OSType cv_pix_fmt_type
CVPixelBuffer Format Type that Videotoolbox will use for decoded frames.
Definition: videotoolbox.h:63
static int64_t pts
Global timestamp for the audio frames.
int ff_videotoolbox_uninit(AVCodecContext *avctx)
Definition: videotoolbox.c:177
static int flags
Definition: cpu.c:47
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:198
MpegEncContext.
Definition: mpegvideo.h:78
VTDecompressionOutputCallback output_callback
The output callback that must be passed to the session.
Definition: videotoolbox.h:57
uint8_t data[4096]
Definition: h264.h:193
size_t data_size
Definition: h264.h:221
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:162
H264ParamSets ps
Definition: h264.h:574
#define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING
Definition: videotoolbox.c:39
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: videotoolbox.c:67
void * priv_data
Definition: avcodec.h:1691
#define av_free(p)
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:1699
static uint8_t tmp[8]
Definition: des.c:38
#define bytestream2_put_ne32
Definition: bytestream.h:125
SPS * sps
Definition: h264.h:238
int height
Definition: frame.h:236
static void videotoolbox_buffer_release(void *opaque, uint8_t *data)
Definition: videotoolbox.c:41
#define av_freep(p)
void av_videotoolbox_default_free(AVCodecContext *avctx)
This function must be called to free the Videotoolbox context initialized with av_videotoolbox_defaul...
#define bytestream2_put_ne16
Definition: bytestream.h:123
This struct holds all the information that needs to be passed between the caller and libavcodec for i...
Definition: videotoolbox.h:46
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:252
static av_always_inline int bytestream2_size_p(PutByteContext *p)
Definition: bytestream.h:203
GLuint buffer
Definition: opengl_enc.c:102
CVImageBufferRef frame
Public libavcodec Videotoolbox header.