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_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 
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 
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 
106 {
107  av_buffer_unref(&frame->buf[0]);
108 
109  frame->buf[0] = av_buffer_create((uint8_t*)vtctx->frame,
110  sizeof(vtctx->frame),
112  NULL,
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 
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 
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 
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,
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 :
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;
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;
519  videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG1Video;
520  break;
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,
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,
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 
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 
672 {
673  return av_videotoolbox_default_init2(avctx, NULL);
674 }
675 
677 {
679  if (!avctx->hwaccel_context)
680  return AVERROR(ENOMEM);
681  return videotoolbox_default_init(avctx);
682 }
683 
685 {
686 
687  videotoolbox_default_free(avctx);
688  av_freep(&avctx->hwaccel_context);
689 }
690 #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:171
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:441
hardware decoding through Videotoolbox
Definition: pixfmt.h:326
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:1722
external API header
int is_avc
Used to parse AVC variant of h264.
Definition: h264.h:632
mpegvideo header.
H264Context.
Definition: h264.h:517
int ff_videotoolbox_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:124
AVFrame * f
Definition: h264.h:310
#define kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder
Definition: videotoolbox.c:36
int ff_videotoolbox_buffer_create(VTContext *vtctx, AVFrame *frame)
Definition: videotoolbox.c:105
uint8_t
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:2934
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1617
static AVFrame * frame
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
Definition: videotoolbox.c:80
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
static int64_t duration
Definition: ffplay.c:326
#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 / MPEG4 part10 codec.
int width
width and height of the video frame
Definition: frame.h:220
#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
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:3583
int width
picture width / height.
Definition: avcodec.h:1681
Picture * current_picture_ptr
pointer to the current picture
Definition: mpegvideo.h:191
int32_t
#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:107
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...
void * av_memdup(const void *p, size_t size)
Duplicate the buffer p.
Definition: mem.c:299
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:232
enum AVCodecID codec_id
Definition: avcodec.h:1519
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:1502
int ff_videotoolbox_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:140
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:1618
BYTE int const BYTE int int int height
Definition: avisynth_c.h:676
#define AV_WB32(p, v)
Definition: intreadwrite.h:419
struct AVFrame * f
Definition: mpegpicture.h:46
H264Picture * cur_pic_ptr
Definition: h264.h:527
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:167
static int flags
Definition: cpu.c:47
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:182
MpegEncContext.
Definition: mpegvideo.h:88
VTDecompressionOutputCallback output_callback
The output callback that must be passed to the session.
Definition: videotoolbox.h:57
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:159
#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:1544
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:1552
#define bytestream2_put_ne32
Definition: bytestream.h:125
int height
Definition: frame.h:220
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.
static int width