FFmpeg
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 #include "config_components.h"
25 #include "videotoolbox.h"
26 #include "libavutil/attributes.h"
28 #include "libavutil/mem.h"
29 #include "vt_internal.h"
30 #include "libavutil/avutil.h"
31 #include "libavutil/hwcontext.h"
32 #include "libavutil/pixdesc.h"
33 #include "bytestream.h"
34 #include "decode.h"
35 #include "internal.h"
36 #include "h264dec.h"
37 #include "hevc/hevcdec.h"
38 #include "hwaccel_internal.h"
39 #include "mpegvideo.h"
40 #include "proresdec.h"
41 #include "prores_raw.h"
42 #include <Availability.h>
43 #include <AvailabilityMacros.h>
44 #include <TargetConditionals.h>
45 
46 #ifndef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
47 # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder")
48 #endif
49 #ifndef kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder
50 # define kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder CFSTR("EnableHardwareAcceleratedVideoDecoder")
51 #endif
52 
53 #if !HAVE_KCMVIDEOCODECTYPE_HEVC
54 enum { kCMVideoCodecType_HEVC = 'hvc1' };
55 #endif
56 
57 #if !HAVE_KCMVIDEOCODECTYPE_VP9
58 enum { kCMVideoCodecType_VP9 = 'vp09' };
59 #endif
60 
61 #if !HAVE_KCMVIDEOCODECTYPE_AV1
62 enum { kCMVideoCodecType_AV1 = 'av01' };
63 #endif
64 
65 #define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12
66 
67 typedef struct VTHWFrame {
68  CVPixelBufferRef pixbuf;
70 } VTHWFrame;
71 
72 static void videotoolbox_buffer_release(void *opaque, uint8_t *data)
73 {
75  av_buffer_unref(&ref->hw_frames_ctx);
76  CVPixelBufferRelease(ref->pixbuf);
77 
78  av_free(data);
79 }
80 
82  const uint8_t *buffer,
83  uint32_t size)
84 {
85  void *tmp;
86 
87  tmp = av_fast_realloc(vtctx->bitstream,
88  &vtctx->allocated_size,
89  size);
90 
91  if (!tmp)
92  return AVERROR(ENOMEM);
93 
94  vtctx->bitstream = tmp;
95  memcpy(vtctx->bitstream, buffer, size);
96  vtctx->bitstream_size = size;
97 
98  return 0;
99 }
100 
102  const uint8_t *buffer,
103  uint32_t size)
104 {
105  void *tmp;
106 
107  tmp = av_fast_realloc(vtctx->bitstream,
108  &vtctx->allocated_size,
109  vtctx->bitstream_size + size);
110 
111  if (!tmp)
112  return AVERROR(ENOMEM);
113 
114  vtctx->bitstream = tmp;
115  memcpy(vtctx->bitstream + vtctx->bitstream_size, buffer, size);
116  vtctx->bitstream_size += size;
117 
118  return 0;
119 }
120 
121 static int videotoolbox_postproc_frame(void *avctx, AVFrame *frame)
122 {
123  int ret;
124  VTHWFrame *ref = (VTHWFrame *)frame->buf[0]->data;
125 
126  if (!ref->pixbuf) {
127  av_log(avctx, AV_LOG_ERROR, "No frame decoded?\n");
129  return AVERROR_EXTERNAL;
130  }
131 
132  frame->crop_right = 0;
133  frame->crop_left = 0;
134  frame->crop_top = 0;
135  frame->crop_bottom = 0;
136 
137  if ((ret = av_vt_pixbuf_set_attachments(avctx, ref->pixbuf, frame)) < 0)
138  return ret;
139 
140  frame->data[3] = (uint8_t*)ref->pixbuf;
141 
142  if (ref->hw_frames_ctx) {
143  av_buffer_unref(&frame->hw_frames_ctx);
144  frame->hw_frames_ctx = av_buffer_ref(ref->hw_frames_ctx);
145  if (!frame->hw_frames_ctx)
146  return AVERROR(ENOMEM);
147  }
148 
149  return 0;
150 }
151 
153 {
154  size_t size = sizeof(VTHWFrame);
155  uint8_t *data = NULL;
156  AVBufferRef *buf = NULL;
157  int ret = ff_attach_decode_data(avctx, frame);
158  FrameDecodeData *fdd;
159  if (ret < 0)
160  return ret;
161 
162  data = av_mallocz(size);
163  if (!data)
164  return AVERROR(ENOMEM);
166  if (!buf) {
167  av_freep(&data);
168  return AVERROR(ENOMEM);
169  }
170  frame->buf[0] = buf;
171 
172  fdd = frame->private_ref;
174 
175  frame->width = avctx->width;
176  frame->height = avctx->height;
177  frame->format = avctx->pix_fmt;
178 
179  return 0;
180 }
181 
182 #define AV_W8(p, v) *(p) = (v)
183 
184 static int escape_ps(uint8_t* dst, const uint8_t* src, int src_size)
185 {
186  int i;
187  int size = src_size;
188  uint8_t* p = dst;
189 
190  for (i = 0; i < src_size; i++) {
191  if (i + 2 < src_size &&
192  src[i] == 0x00 &&
193  src[i + 1] == 0x00 &&
194  src[i + 2] <= 0x03) {
195  if (dst) {
196  *p++ = src[i++];
197  *p++ = src[i];
198  *p++ = 0x03;
199  } else {
200  i++;
201  }
202  size++;
203  } else if (dst)
204  *p++ = src[i];
205  }
206 
207  if (dst)
208  av_assert0((p - dst) == size);
209 
210  return size;
211 }
212 
214 {
215  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
216  H264Context *h = avctx->priv_data;
217  CFDataRef data = NULL;
218  uint8_t *p;
219  int sps_size = escape_ps(NULL, h->ps.sps->data, h->ps.sps->data_size);
220  int pps_size = escape_ps(NULL, h->ps.pps->data, h->ps.pps->data_size);
221  int vt_extradata_size;
222  uint8_t *vt_extradata;
223 
224  vt_extradata_size = 6 + 2 + sps_size + 3 + pps_size;
225  vt_extradata = av_malloc(vt_extradata_size);
226 
227  if (!vt_extradata)
228  return NULL;
229 
230  p = vt_extradata;
231 
232  AV_W8(p + 0, 1); /* version */
233  AV_W8(p + 1, h->ps.sps->data[1]); /* profile */
234  AV_W8(p + 2, h->ps.sps->data[2]); /* profile compat */
235  AV_W8(p + 3, h->ps.sps->data[3]); /* level */
236  AV_W8(p + 4, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 3 (11) */
237  AV_W8(p + 5, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
238  AV_WB16(p + 6, sps_size);
239  p += 8;
240  p += escape_ps(p, h->ps.sps->data, h->ps.sps->data_size);
241  AV_W8(p + 0, 1); /* number of pps */
242  AV_WB16(p + 1, pps_size);
243  p += 3;
244  p += escape_ps(p, h->ps.pps->data, h->ps.pps->data_size);
245 
246  av_assert0(p - vt_extradata == vt_extradata_size);
247 
248  // save sps header (profile/level) used to create decoder session,
249  // so we can detect changes and recreate it.
250  if (vtctx)
251  memcpy(vtctx->sps, h->ps.sps->data + 1, 3);
252 
253  data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
254  av_free(vt_extradata);
255  return data;
256 }
257 
259 {
260  HEVCContext *h = avctx->priv_data;
261  int i, num_vps = 0, num_sps = 0, num_pps = 0;
262  const HEVCPPS *pps = h->pps;
263  const HEVCSPS *sps = pps->sps;
264  const HEVCVPS *vps = sps->vps;
265  PTLCommon ptlc = vps->ptl.general_ptl;
266  VUI vui = sps->vui;
267  uint8_t parallelismType;
268  CFDataRef data = NULL;
269  uint8_t *p;
270  int vt_extradata_size = 23 + 3 + 3 + 3;
271  uint8_t *vt_extradata;
272 
273 #define COUNT_SIZE_PS(T, t) \
274  for (i = 0; i < HEVC_MAX_##T##PS_COUNT; i++) { \
275  if (h->ps.t##ps_list[i]) { \
276  const HEVC##T##PS *lps = h->ps.t##ps_list[i]; \
277  vt_extradata_size += 2 + escape_ps(NULL, lps->data, lps->data_size); \
278  num_##t##ps++; \
279  } \
280  }
281 
282  COUNT_SIZE_PS(V, v)
283  COUNT_SIZE_PS(S, s)
284  COUNT_SIZE_PS(P, p)
285 
286  vt_extradata = av_malloc(vt_extradata_size);
287  if (!vt_extradata)
288  return NULL;
289  p = vt_extradata;
290 
291  /* unsigned int(8) configurationVersion = 1; */
292  AV_W8(p + 0, 1);
293 
294  /*
295  * unsigned int(2) general_profile_space;
296  * unsigned int(1) general_tier_flag;
297  * unsigned int(5) general_profile_idc;
298  */
299  AV_W8(p + 1, ptlc.profile_space << 6 |
300  ptlc.tier_flag << 5 |
301  ptlc.profile_idc);
302 
303  /* unsigned int(32) general_profile_compatibility_flags; */
304  for (i = 0; i < 4; i++) {
305  AV_W8(p + 2 + i, ptlc.profile_compatibility_flag[i * 8] << 7 |
306  ptlc.profile_compatibility_flag[i * 8 + 1] << 6 |
307  ptlc.profile_compatibility_flag[i * 8 + 2] << 5 |
308  ptlc.profile_compatibility_flag[i * 8 + 3] << 4 |
309  ptlc.profile_compatibility_flag[i * 8 + 4] << 3 |
310  ptlc.profile_compatibility_flag[i * 8 + 5] << 2 |
311  ptlc.profile_compatibility_flag[i * 8 + 6] << 1 |
312  ptlc.profile_compatibility_flag[i * 8 + 7]);
313  }
314 
315  /* unsigned int(48) general_constraint_indicator_flags; */
316  AV_W8(p + 6, ptlc.progressive_source_flag << 7 |
317  ptlc.interlaced_source_flag << 6 |
318  ptlc.non_packed_constraint_flag << 5 |
319  ptlc.frame_only_constraint_flag << 4);
320  AV_W8(p + 7, 0);
321  AV_WN32(p + 8, 0);
322 
323  /* unsigned int(8) general_level_idc; */
324  AV_W8(p + 12, ptlc.level_idc);
325 
326  /*
327  * bit(4) reserved = ‘1111’b;
328  * unsigned int(12) min_spatial_segmentation_idc;
329  */
330  AV_W8(p + 13, 0xf0 | (vui.min_spatial_segmentation_idc >> 4));
331  AV_W8(p + 14, vui.min_spatial_segmentation_idc & 0xff);
332 
333  /*
334  * bit(6) reserved = ‘111111’b;
335  * unsigned int(2) parallelismType;
336  */
338  parallelismType = 0;
339  else if (pps->entropy_coding_sync_enabled_flag && pps->tiles_enabled_flag)
340  parallelismType = 0;
341  else if (pps->entropy_coding_sync_enabled_flag)
342  parallelismType = 3;
343  else if (pps->tiles_enabled_flag)
344  parallelismType = 2;
345  else
346  parallelismType = 1;
347  AV_W8(p + 15, 0xfc | parallelismType);
348 
349  /*
350  * bit(6) reserved = ‘111111’b;
351  * unsigned int(2) chromaFormat;
352  */
353  AV_W8(p + 16, sps->chroma_format_idc | 0xfc);
354 
355  /*
356  * bit(5) reserved = ‘11111’b;
357  * unsigned int(3) bitDepthLumaMinus8;
358  */
359  AV_W8(p + 17, (sps->bit_depth - 8) | 0xf8);
360 
361  /*
362  * bit(5) reserved = ‘11111’b;
363  * unsigned int(3) bitDepthChromaMinus8;
364  */
365  AV_W8(p + 18, (sps->bit_depth_chroma - 8) | 0xf8);
366 
367  /* bit(16) avgFrameRate; */
368  AV_WB16(p + 19, 0);
369 
370  /*
371  * bit(2) constantFrameRate;
372  * bit(3) numTemporalLayers;
373  * bit(1) temporalIdNested;
374  * unsigned int(2) lengthSizeMinusOne;
375  */
376  AV_W8(p + 21, 0 << 6 |
377  sps->max_sub_layers << 3 |
378  sps->temporal_id_nesting << 2 |
379  3);
380 
381  /* unsigned int(8) numOfArrays; */
382  AV_W8(p + 22, 3);
383 
384  p += 23;
385 
386 #define APPEND_PS(T, t) \
387  /* \
388  * bit(1) array_completeness; \
389  * unsigned int(1) reserved = 0; \
390  * unsigned int(6) NAL_unit_type; \
391  */ \
392  AV_W8(p, 1 << 7 | \
393  HEVC_NAL_##T##PS & 0x3f); \
394  /* unsigned int(16) numNalus; */ \
395  AV_WB16(p + 1, num_##t##ps); \
396  p += 3; \
397  for (i = 0; i < HEVC_MAX_##T##PS_COUNT; i++) { \
398  if (h->ps.t##ps_list[i]) { \
399  const HEVC##T##PS *lps = h->ps.t##ps_list[i]; \
400  int size = escape_ps(p + 2, lps->data, lps->data_size); \
401  /* unsigned int(16) nalUnitLength; */ \
402  AV_WB16(p, size); \
403  /* bit(8*nalUnitLength) nalUnit; */ \
404  p += 2 + size; \
405  } \
406  }
407 
408  APPEND_PS(V, v)
409  APPEND_PS(S, s)
410  APPEND_PS(P, p)
411 
412  av_assert0(p - vt_extradata == vt_extradata_size);
413 
414  data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
415  av_free(vt_extradata);
416  return data;
417 }
418 
420  const AVBufferRef *buffer_ref,
421  const uint8_t *buffer,
422  uint32_t size)
423 {
424  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
425  H264Context *h = avctx->priv_data;
426 
427  if (h->is_avc == 1) {
428  return ff_videotoolbox_buffer_copy(vtctx, buffer, size);
429  }
430 
431  return 0;
432 }
433 
435  int type,
436  const uint8_t *buffer,
437  uint32_t size)
438 {
439  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
440  H264Context *h = avctx->priv_data;
441 
442  // save sps header (profile/level) used to create decoder session
443  if (!vtctx->sps[0])
444  memcpy(vtctx->sps, h->ps.sps->data + 1, 3);
445 
446  if (type == H264_NAL_SPS) {
447  if (size > 4 && memcmp(vtctx->sps, buffer + 1, 3) != 0) {
448  vtctx->reconfig_needed = true;
449  memcpy(vtctx->sps, buffer + 1, 3);
450  }
451  }
452 
453  // pass-through SPS/PPS changes to the decoder
455 }
456 
458  const uint8_t *buffer,
459  uint32_t size)
460 {
461  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
462  void *tmp;
463 
464  tmp = av_fast_realloc(vtctx->bitstream,
465  &vtctx->allocated_size,
466  vtctx->bitstream_size+size+4);
467  if (!tmp)
468  return AVERROR(ENOMEM);
469 
470  vtctx->bitstream = tmp;
471 
472  AV_WB32(vtctx->bitstream + vtctx->bitstream_size, size);
473  memcpy(vtctx->bitstream + vtctx->bitstream_size + 4, buffer, size);
474 
475  vtctx->bitstream_size += size + 4;
476 
477  return 0;
478 }
479 
481  const uint8_t *buffer,
482  uint32_t size)
483 {
484  H264Context *h = avctx->priv_data;
485 
486  if (h->is_avc == 1)
487  return 0;
488 
490 }
491 
492 #if CONFIG_VIDEOTOOLBOX
493 // Return the AVVideotoolboxContext that matters currently. Where it comes from
494 // depends on the API used.
495 static AVVideotoolboxContext *videotoolbox_get_context(AVCodecContext *avctx)
496 {
497  // Somewhat tricky because the user can call av_videotoolbox_default_free()
498  // at any time, even when the codec is closed.
499  if (avctx->internal && avctx->internal->hwaccel_priv_data) {
500  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
501  if (vtctx->vt_ctx)
502  return vtctx->vt_ctx;
503  }
504  return avctx->hwaccel_context;
505 }
506 
507 static void videotoolbox_stop(AVCodecContext *avctx)
508 {
509  AVVideotoolboxContext *videotoolbox = videotoolbox_get_context(avctx);
510  if (!videotoolbox)
511  return;
512 
513  if (videotoolbox->cm_fmt_desc) {
514  CFRelease(videotoolbox->cm_fmt_desc);
515  videotoolbox->cm_fmt_desc = NULL;
516  }
517 
518  if (videotoolbox->session) {
519  VTDecompressionSessionInvalidate(videotoolbox->session);
520  CFRelease(videotoolbox->session);
521  videotoolbox->session = NULL;
522  }
523 }
524 
526 {
527  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
528  if (!vtctx)
529  return 0;
530 
531  av_freep(&vtctx->bitstream);
532  if (vtctx->frame)
533  CVPixelBufferRelease(vtctx->frame);
534 
535  if (vtctx->vt_ctx)
536  videotoolbox_stop(avctx);
537 
539  av_freep(&vtctx->vt_ctx);
540 
541  return 0;
542 }
543 
544 static int videotoolbox_buffer_create(AVCodecContext *avctx, AVFrame *frame)
545 {
546  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
547  CVPixelBufferRef pixbuf = (CVPixelBufferRef)vtctx->frame;
548  OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);
549  enum AVPixelFormat sw_format = av_map_videotoolbox_format_to_pixfmt(pixel_format);
550  int width = CVPixelBufferGetWidth(pixbuf);
551  int height = CVPixelBufferGetHeight(pixbuf);
552  AVHWFramesContext *cached_frames;
553  VTHWFrame *ref;
554  int ret;
555 
556  if (!frame->buf[0] || frame->data[3]) {
557  av_log(avctx, AV_LOG_ERROR, "videotoolbox: invalid state\n");
559  return AVERROR_EXTERNAL;
560  }
561 
562  ref = (VTHWFrame *)frame->buf[0]->data;
563 
564  if (ref->pixbuf)
565  CVPixelBufferRelease(ref->pixbuf);
566  ref->pixbuf = vtctx->frame;
567  vtctx->frame = NULL;
568 
569  // Old API code path.
570  if (!vtctx->cached_hw_frames_ctx)
571  return 0;
572 
573  cached_frames = (AVHWFramesContext*)vtctx->cached_hw_frames_ctx->data;
574 
575  if (cached_frames->sw_format != sw_format ||
576  cached_frames->width != width ||
577  cached_frames->height != height) {
578  AVBufferRef *hw_frames_ctx = av_hwframe_ctx_alloc(cached_frames->device_ref);
579  AVHWFramesContext *hw_frames;
580  AVVTFramesContext *hw_ctx;
581  if (!hw_frames_ctx)
582  return AVERROR(ENOMEM);
583 
584  hw_frames = (AVHWFramesContext*)hw_frames_ctx->data;
585  hw_frames->format = cached_frames->format;
586  hw_frames->sw_format = sw_format;
587  hw_frames->width = width;
588  hw_frames->height = height;
589  hw_ctx = hw_frames->hwctx;
590  hw_ctx->color_range = avctx->color_range;
591 
592  ret = av_hwframe_ctx_init(hw_frames_ctx);
593  if (ret < 0) {
594  av_buffer_unref(&hw_frames_ctx);
595  return ret;
596  }
597 
599  vtctx->cached_hw_frames_ctx = hw_frames_ctx;
600  }
601 
602  av_buffer_unref(&ref->hw_frames_ctx);
603  ref->hw_frames_ctx = av_buffer_ref(vtctx->cached_hw_frames_ctx);
604  if (!ref->hw_frames_ctx)
605  return AVERROR(ENOMEM);
606 
607  return 0;
608 }
609 
610 static void videotoolbox_write_mp4_descr_length(PutByteContext *pb, int length)
611 {
612  int i;
613  uint8_t b;
614 
615  for (i = 3; i >= 0; i--) {
616  b = (length >> (i * 7)) & 0x7F;
617  if (i != 0)
618  b |= 0x80;
619 
620  bytestream2_put_byteu(pb, b);
621  }
622 }
623 
624 static CFDataRef videotoolbox_esds_extradata_create(AVCodecContext *avctx)
625 {
626  CFDataRef data;
627  uint8_t *rw_extradata;
628  PutByteContext pb;
629  int full_size = 3 + 5 + 13 + 5 + avctx->extradata_size + 3;
630  // ES_DescrTag data + DecoderConfigDescrTag + data + DecSpecificInfoTag + size + SLConfigDescriptor
631  int config_size = 13 + 5 + avctx->extradata_size;
632  int s;
633 
634  if (!(rw_extradata = av_mallocz(full_size + VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING)))
635  return NULL;
636 
637  bytestream2_init_writer(&pb, rw_extradata, full_size + VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING);
638  bytestream2_put_byteu(&pb, 0); // version
639  bytestream2_put_ne24(&pb, 0); // flags
640 
641  // elementary stream descriptor
642  bytestream2_put_byteu(&pb, 0x03); // ES_DescrTag
643  videotoolbox_write_mp4_descr_length(&pb, full_size);
644  bytestream2_put_ne16(&pb, 0); // esid
645  bytestream2_put_byteu(&pb, 0); // stream priority (0-32)
646 
647  // decoder configuration descriptor
648  bytestream2_put_byteu(&pb, 0x04); // DecoderConfigDescrTag
649  videotoolbox_write_mp4_descr_length(&pb, config_size);
650  bytestream2_put_byteu(&pb, 32); // object type indication. 32 = AV_CODEC_ID_MPEG4
651  bytestream2_put_byteu(&pb, 0x11); // stream type
652  bytestream2_put_ne24(&pb, 0); // buffer size
653  bytestream2_put_ne32(&pb, 0); // max bitrate
654  bytestream2_put_ne32(&pb, 0); // avg bitrate
655 
656  // decoder specific descriptor
657  bytestream2_put_byteu(&pb, 0x05); ///< DecSpecificInfoTag
658  videotoolbox_write_mp4_descr_length(&pb, avctx->extradata_size);
659 
660  bytestream2_put_buffer(&pb, avctx->extradata, avctx->extradata_size);
661 
662  // SLConfigDescriptor
663  bytestream2_put_byteu(&pb, 0x06); // SLConfigDescrTag
664  bytestream2_put_byteu(&pb, 0x01); // length
665  bytestream2_put_byteu(&pb, 0x02); //
666 
667  s = bytestream2_size_p(&pb);
668 
669  data = CFDataCreate(kCFAllocatorDefault, rw_extradata, s);
670 
671  av_freep(&rw_extradata);
672  return data;
673 }
674 
675 static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
676  void *buffer,
677  int size)
678 {
679  OSStatus status;
680  CMBlockBufferRef block_buf;
681  CMSampleBufferRef sample_buf;
682 
683  block_buf = NULL;
684  sample_buf = NULL;
685 
686  status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,// structureAllocator
687  buffer, // memoryBlock
688  size, // blockLength
689  kCFAllocatorNull, // blockAllocator
690  NULL, // customBlockSource
691  0, // offsetToData
692  size, // dataLength
693  0, // flags
694  &block_buf);
695 
696  if (!status) {
697  status = CMSampleBufferCreate(kCFAllocatorDefault, // allocator
698  block_buf, // dataBuffer
699  TRUE, // dataReady
700  0, // makeDataReadyCallback
701  0, // makeDataReadyRefcon
702  fmt_desc, // formatDescription
703  1, // numSamples
704  0, // numSampleTimingEntries
705  NULL, // sampleTimingArray
706  0, // numSampleSizeEntries
707  NULL, // sampleSizeArray
708  &sample_buf);
709  }
710 
711  if (block_buf)
712  CFRelease(block_buf);
713 
714  return sample_buf;
715 }
716 
717 static void videotoolbox_decoder_callback(void *opaque,
718  void *sourceFrameRefCon,
719  OSStatus status,
720  VTDecodeInfoFlags flags,
721  CVImageBufferRef image_buffer,
722  CMTime pts,
723  CMTime duration)
724 {
725  VTContext *vtctx = opaque;
726 
727  if (vtctx->frame) {
728  CVPixelBufferRelease(vtctx->frame);
729  vtctx->frame = NULL;
730  }
731 
732  if (!image_buffer) {
733  // kVTVideoDecoderReferenceMissingErr, defined since the macOS 12 SDKs
734  if (status != -17694)
735  vtctx->reconfig_needed = true;
736 
738  "vt decoder cb: output image buffer is null: %i, reconfig %d\n",
739  status, vtctx->reconfig_needed);
740  return;
741  }
742 
743  vtctx->frame = CVPixelBufferRetain(image_buffer);
744 }
745 
746 static OSStatus videotoolbox_session_decode_frame(AVCodecContext *avctx)
747 {
748  OSStatus status;
749  CMSampleBufferRef sample_buf;
750  AVVideotoolboxContext *videotoolbox = videotoolbox_get_context(avctx);
751  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
752 
753  sample_buf = videotoolbox_sample_buffer_create(videotoolbox->cm_fmt_desc,
754  vtctx->bitstream,
755  vtctx->bitstream_size);
756 
757  if (!sample_buf)
758  return -1;
759 
760  status = VTDecompressionSessionDecodeFrame(videotoolbox->session,
761  sample_buf,
762  0, // decodeFlags
763  NULL, // sourceFrameRefCon
764  0); // infoFlagsOut
765  if (status == noErr)
766  status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->session);
767 
768  CFRelease(sample_buf);
769 
770  return status;
771 }
772 
773 static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType codec_type,
774  CFDictionaryRef decoder_spec,
775  int width,
776  int height)
777 {
778  CMFormatDescriptionRef cm_fmt_desc;
779  OSStatus status;
780 
781  status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
782  codec_type,
783  width,
784  height,
785  decoder_spec, // Dictionary of extension
786  &cm_fmt_desc);
787 
788  if (status)
789  return NULL;
790 
791  return cm_fmt_desc;
792 }
793 
794 static CFDictionaryRef videotoolbox_buffer_attributes_create(int width,
795  int height,
796  OSType pix_fmt)
797 {
798  CFMutableDictionaryRef buffer_attributes;
799  CFMutableDictionaryRef io_surface_properties;
800  CFNumberRef cv_pix_fmt;
801  CFNumberRef w;
802  CFNumberRef h;
803 
804  w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width);
805  h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height);
806  cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pix_fmt);
807 
808  buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
809  4,
810  &kCFTypeDictionaryKeyCallBacks,
811  &kCFTypeDictionaryValueCallBacks);
812  io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
813  0,
814  &kCFTypeDictionaryKeyCallBacks,
815  &kCFTypeDictionaryValueCallBacks);
816 
817  if (pix_fmt)
818  CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
819  CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
820  CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey, w);
821  CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey, h);
822 #if TARGET_OS_IPHONE
823  CFDictionarySetValue(buffer_attributes, kCVPixelBufferOpenGLESCompatibilityKey, kCFBooleanTrue);
824 #else
825  CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey, kCFBooleanTrue);
826 #endif
827 
828  CFRelease(io_surface_properties);
829  CFRelease(cv_pix_fmt);
830  CFRelease(w);
831  CFRelease(h);
832 
833  return buffer_attributes;
834 }
835 
836 static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType codec_type,
837  AVCodecContext *avctx)
838 {
839  CFMutableDictionaryRef avc_info;
840  CFDataRef data = NULL;
841 
842  CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
843  0,
844  &kCFTypeDictionaryKeyCallBacks,
845  &kCFTypeDictionaryValueCallBacks);
846 
847  CFDictionarySetValue(config_info,
848  avctx->codec_id == AV_CODEC_ID_HEVC
849  || avctx->codec_id == AV_CODEC_ID_PRORES
850  || avctx->codec_id == AV_CODEC_ID_PRORES_RAW
851  ?
854  kCFBooleanTrue);
855 
856  avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
857  1,
858  &kCFTypeDictionaryKeyCallBacks,
859  &kCFTypeDictionaryValueCallBacks);
860 
861  switch (codec_type) {
862  case kCMVideoCodecType_MPEG4Video :
863  if (avctx->extradata_size)
864  data = videotoolbox_esds_extradata_create(avctx);
865  if (data)
866  CFDictionarySetValue(avc_info, CFSTR("esds"), data);
867  break;
868  case kCMVideoCodecType_H264 :
870  if (data)
871  CFDictionarySetValue(avc_info, CFSTR("avcC"), data);
872  break;
875  if (data)
876  CFDictionarySetValue(avc_info, CFSTR("hvcC"), data);
877  break;
878 #if CONFIG_VP9_VIDEOTOOLBOX_HWACCEL
879  case kCMVideoCodecType_VP9 :
881  if (data)
882  CFDictionarySetValue(avc_info, CFSTR("vpcC"), data);
883  break;
884 #endif
885 #if CONFIG_AV1_VIDEOTOOLBOX_HWACCEL
886  case kCMVideoCodecType_AV1 :
888  if (data)
889  CFDictionarySetValue(avc_info, CFSTR("av1C"), data);
890  break;
891 #endif
892  default:
893  break;
894  }
895 
896  CFDictionarySetValue(config_info,
897  kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
898  avc_info);
899 
900  if (data)
901  CFRelease(data);
902 
903  CFRelease(avc_info);
904  return config_info;
905 }
906 
907 static int videotoolbox_start(AVCodecContext *avctx)
908 {
909  AVVideotoolboxContext *videotoolbox = videotoolbox_get_context(avctx);
910  OSStatus status;
911  VTDecompressionOutputCallbackRecord decoder_cb;
912  CFDictionaryRef decoder_spec;
913  CFDictionaryRef buf_attr;
914 
915  if (!videotoolbox) {
916  av_log(avctx, AV_LOG_ERROR, "hwaccel context is not set\n");
917  return -1;
918  }
919 
920  switch( avctx->codec_id ) {
921  case AV_CODEC_ID_H263 :
922  videotoolbox->cm_codec_type = kCMVideoCodecType_H263;
923  break;
924  case AV_CODEC_ID_H264 :
925  videotoolbox->cm_codec_type = kCMVideoCodecType_H264;
926  break;
927  case AV_CODEC_ID_HEVC :
928  videotoolbox->cm_codec_type = kCMVideoCodecType_HEVC;
929  break;
931  videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG1Video;
932  break;
934  videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG2Video;
935  break;
936  case AV_CODEC_ID_MPEG4 :
937  videotoolbox->cm_codec_type = kCMVideoCodecType_MPEG4Video;
938  break;
939  case AV_CODEC_ID_PRORES :
940  switch (avctx->codec_tag) {
941  default:
942  av_log(avctx, AV_LOG_WARNING, "Unknown prores profile %d\n", avctx->codec_tag);
944  case MKTAG('a','p','c','o'): // kCMVideoCodecType_AppleProRes422Proxy
945  case MKTAG('a','p','c','s'): // kCMVideoCodecType_AppleProRes422LT
946  case MKTAG('a','p','c','n'): // kCMVideoCodecType_AppleProRes422
947  case MKTAG('a','p','c','h'): // kCMVideoCodecType_AppleProRes422HQ
948  case MKTAG('a','p','4','h'): // kCMVideoCodecType_AppleProRes4444
949  case MKTAG('a','p','4','x'): // kCMVideoCodecType_AppleProRes4444XQ
950  videotoolbox->cm_codec_type = av_bswap32(avctx->codec_tag);
951  break;
952  }
953  break;
955  videotoolbox->cm_codec_type = av_bswap32(avctx->codec_tag);
956  break;
957  case AV_CODEC_ID_VP9 :
958  videotoolbox->cm_codec_type = kCMVideoCodecType_VP9;
959  break;
960  case AV_CODEC_ID_AV1 :
961  videotoolbox->cm_codec_type = kCMVideoCodecType_AV1;
962  break;
963  default :
964  break;
965  }
966 
967 #if defined(MAC_OS_X_VERSION_10_9) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9) && AV_HAS_BUILTIN(__builtin_available)
968  if (avctx->codec_id == AV_CODEC_ID_PRORES || avctx->codec_id == AV_CODEC_ID_PRORES_RAW) {
969  if (__builtin_available(macOS 10.9, *)) {
970  VTRegisterProfessionalVideoWorkflowVideoDecoders();
971  }
972  }
973 #endif
974 
975 #if defined(MAC_OS_VERSION_11_0) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0) && AV_HAS_BUILTIN(__builtin_available)
976  if (__builtin_available(macOS 11.0, *)) {
977  VTRegisterSupplementalVideoDecoderIfAvailable(videotoolbox->cm_codec_type);
978  }
979 #endif
980 
981  decoder_spec = videotoolbox_decoder_config_create(videotoolbox->cm_codec_type, avctx);
982 
983  if (!decoder_spec) {
984  av_log(avctx, AV_LOG_ERROR, "decoder specification creation failed\n");
985  return -1;
986  }
987 
988  videotoolbox->cm_fmt_desc = videotoolbox_format_desc_create(videotoolbox->cm_codec_type,
989  decoder_spec,
990  avctx->width,
991  avctx->height);
992  if (!videotoolbox->cm_fmt_desc) {
993  if (decoder_spec)
994  CFRelease(decoder_spec);
995 
996  av_log(avctx, AV_LOG_ERROR, "format description creation failed\n");
997  return -1;
998  }
999 
1000  buf_attr = videotoolbox_buffer_attributes_create(avctx->width,
1001  avctx->height,
1002  videotoolbox->cv_pix_fmt_type);
1003 
1004  decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
1005  decoder_cb.decompressionOutputRefCon = avctx->internal->hwaccel_priv_data;
1006 
1007  status = VTDecompressionSessionCreate(NULL, // allocator
1008  videotoolbox->cm_fmt_desc, // videoFormatDescription
1009  decoder_spec, // videoDecoderSpecification
1010  buf_attr, // destinationImageBufferAttributes
1011  &decoder_cb, // outputCallback
1012  &videotoolbox->session); // decompressionSessionOut
1013 
1014  if (decoder_spec)
1015  CFRelease(decoder_spec);
1016  if (buf_attr)
1017  CFRelease(buf_attr);
1018 
1019  switch (status) {
1020  case kVTVideoDecoderNotAvailableNowErr:
1021  av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox session not available.\n");
1022  return AVERROR(ENOSYS);
1023  case kVTVideoDecoderUnsupportedDataFormatErr:
1024  av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox does not support this format.\n");
1025  return AVERROR(ENOSYS);
1026  case kVTCouldNotFindVideoDecoderErr:
1027  av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox decoder for this format not found.\n");
1028  return AVERROR(ENOSYS);
1029  case kVTVideoDecoderMalfunctionErr:
1030  av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox malfunction.\n");
1031  return AVERROR(EINVAL);
1032  case kVTVideoDecoderBadDataErr:
1033  av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox reported invalid data.\n");
1034  return AVERROR_INVALIDDATA;
1035  case 0:
1036  return 0;
1037  default:
1038  av_log(avctx, AV_LOG_VERBOSE, "Unknown VideoToolbox session creation error %d\n", (int)status);
1039  return AVERROR_UNKNOWN;
1040  }
1041 }
1042 
1043 static const char *videotoolbox_error_string(OSStatus status)
1044 {
1045  switch (status) {
1046  case kVTVideoDecoderBadDataErr:
1047  return "bad data";
1048  case kVTVideoDecoderMalfunctionErr:
1049  return "decoder malfunction";
1050  case kVTInvalidSessionErr:
1051  return "invalid session";
1052  }
1053  return "unknown";
1054 }
1055 
1057 {
1058  OSStatus status;
1059  AVVideotoolboxContext *videotoolbox = videotoolbox_get_context(avctx);
1060  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
1061 
1062  if (vtctx->reconfig_needed == true) {
1063  vtctx->reconfig_needed = false;
1064  av_log(avctx, AV_LOG_VERBOSE, "VideoToolbox decoder needs reconfig, restarting..\n");
1065  videotoolbox_stop(avctx);
1066  if (videotoolbox_start(avctx) != 0) {
1067  return AVERROR_EXTERNAL;
1068  }
1069  }
1070 
1071  if (!videotoolbox->session || !vtctx->bitstream || !vtctx->bitstream_size)
1072  return AVERROR_INVALIDDATA;
1073 
1074  status = videotoolbox_session_decode_frame(avctx);
1075  if (status != noErr) {
1076  if (status == kVTVideoDecoderMalfunctionErr || status == kVTInvalidSessionErr)
1077  vtctx->reconfig_needed = true;
1078  av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%s, %d)\n", videotoolbox_error_string(status), (int)status);
1079  return AVERROR_UNKNOWN;
1080  }
1081 
1082  if (!vtctx->frame)
1083  return AVERROR_UNKNOWN;
1084 
1085  return videotoolbox_buffer_create(avctx, frame);
1086 }
1087 
1088 static int videotoolbox_h264_end_frame(AVCodecContext *avctx)
1089 {
1090  H264Context *h = avctx->priv_data;
1091  AVFrame *frame = h->cur_pic_ptr->f;
1092  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
1094  vtctx->bitstream_size = 0;
1095  return ret;
1096 }
1097 
1098 static int videotoolbox_hevc_start_frame(AVCodecContext *avctx,
1099  const AVBufferRef *buffer_ref,
1100  const uint8_t *buffer,
1101  uint32_t size)
1102 {
1103  HEVCContext *h = avctx->priv_data;
1104  AVFrame *frame = h->cur_frame->f;
1105 
1106  frame->crop_right = 0;
1107  frame->crop_left = 0;
1108  frame->crop_top = 0;
1109  frame->crop_bottom = 0;
1110 
1111  return 0;
1112 }
1113 
1114 static int videotoolbox_hevc_decode_slice(AVCodecContext *avctx,
1115  const uint8_t *buffer,
1116  uint32_t size)
1117 {
1119 }
1120 
1121 
1122 static int videotoolbox_hevc_decode_params(AVCodecContext *avctx,
1123  int type,
1124  const uint8_t *buffer,
1125  uint32_t size)
1126 {
1128 }
1129 
1130 static int videotoolbox_hevc_end_frame(AVCodecContext *avctx)
1131 {
1132  HEVCContext *h = avctx->priv_data;
1133  AVFrame *frame = h->cur_frame->f;
1134  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
1135  int ret;
1136 
1138  vtctx->bitstream_size = 0;
1139  return ret;
1140 }
1141 
1142 static int videotoolbox_mpeg_start_frame(AVCodecContext *avctx,
1143  const AVBufferRef *buffer_ref,
1144  const uint8_t *buffer,
1145  uint32_t size)
1146 {
1147  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
1148 
1149  return ff_videotoolbox_buffer_copy(vtctx, buffer, size);
1150 }
1151 
1152 static int videotoolbox_mpeg_decode_slice(AVCodecContext *avctx,
1153  const uint8_t *buffer,
1154  uint32_t size)
1155 {
1156  return 0;
1157 }
1158 
1159 static int videotoolbox_mpeg_end_frame(AVCodecContext *avctx)
1160 {
1161  MpegEncContext *s = avctx->priv_data;
1162  AVFrame *frame = s->cur_pic.ptr->f;
1163 
1164  return ff_videotoolbox_common_end_frame(avctx, frame);
1165 }
1166 
1167 static int videotoolbox_prores_start_frame(AVCodecContext *avctx,
1168  const AVBufferRef *buffer_ref,
1169  const uint8_t *buffer,
1170  uint32_t size)
1171 {
1172  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
1173  ProresContext *ctx = avctx->priv_data;
1174 
1175  /* Videotoolbox decodes both fields simultaneously */
1176  if (!ctx->first_field)
1177  return 0;
1178 
1179  return ff_videotoolbox_buffer_copy(vtctx, buffer, size);
1180 }
1181 
1182 static int videotoolbox_prores_decode_slice(AVCodecContext *avctx,
1183  const uint8_t *buffer,
1184  uint32_t size)
1185 {
1186  return 0;
1187 }
1188 
1189 static int videotoolbox_prores_end_frame(AVCodecContext *avctx)
1190 {
1191  ProresContext *ctx = avctx->priv_data;
1192  AVFrame *frame = ctx->frame;
1193 
1194  if (!ctx->first_field)
1195  return 0;
1196 
1197  return ff_videotoolbox_common_end_frame(avctx, frame);
1198 }
1199 
1200 static int videotoolbox_prores_raw_start_frame(AVCodecContext *avctx,
1201  const AVBufferRef *buffer_ref,
1202  const uint8_t *buffer,
1203  uint32_t size)
1204 {
1205  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
1206 
1207  return ff_videotoolbox_buffer_copy(vtctx, buffer, size);
1208 }
1209 
1210 static int videotoolbox_prores_raw_decode_slice(AVCodecContext *avctx,
1211  const uint8_t *buffer,
1212  uint32_t size)
1213 {
1214  return 0;
1215 }
1216 
1217 static int videotoolbox_prores_raw_end_frame(AVCodecContext *avctx)
1218 {
1219  ProResRAWContext *ctx = avctx->priv_data;
1220  AVFrame *frame = ctx->frame;
1221 
1222  return ff_videotoolbox_common_end_frame(avctx, frame);
1223 }
1224 
1225 static enum AVPixelFormat videotoolbox_best_pixel_format(AVCodecContext *avctx) {
1226  int depth;
1227  const AVPixFmtDescriptor *descriptor = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
1228  if (!descriptor)
1229  return AV_PIX_FMT_NV12; // same as av_videotoolbox_alloc_context()
1230 
1231  depth = descriptor->comp[0].depth;
1232 
1233  if (descriptor->flags & AV_PIX_FMT_FLAG_ALPHA)
1234  return (depth > 8) ? AV_PIX_FMT_AYUV64 : AV_PIX_FMT_AYUV;
1235 
1236  if (descriptor->flags & AV_PIX_FMT_FLAG_BAYER)
1237  return AV_PIX_FMT_BAYER_RGGB16;
1238 
1239 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE
1240  if (depth > 10)
1241  return descriptor->log2_chroma_w == 0 ? AV_PIX_FMT_P416 : AV_PIX_FMT_P216;
1242 #endif
1243 
1244 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE
1245  if (descriptor->log2_chroma_w == 0) {
1246 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE
1247  if (depth <= 8)
1248  return AV_PIX_FMT_NV24;
1249 #endif
1250  return AV_PIX_FMT_P410;
1251  }
1252 #endif
1253 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE
1254  if (descriptor->log2_chroma_h == 0) {
1255 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE
1256  if (depth <= 8)
1257  return AV_PIX_FMT_NV16;
1258 #endif
1259  return AV_PIX_FMT_P210;
1260  }
1261 #endif
1262 #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
1263  if (depth > 8) {
1264  return AV_PIX_FMT_P010;
1265  }
1266 #endif
1267 
1268  return AV_PIX_FMT_NV12;
1269 }
1270 
1271 static AVVideotoolboxContext *videotoolbox_alloc_context_with_pix_fmt(enum AVPixelFormat pix_fmt,
1272  bool full_range)
1273 {
1274  AVVideotoolboxContext *ret = av_mallocz(sizeof(*ret));
1275 
1276  if (ret) {
1277  OSType cv_pix_fmt_type = av_map_videotoolbox_format_from_pixfmt2(pix_fmt, full_range);
1278  if (cv_pix_fmt_type == 0) {
1279  cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
1280  }
1281  ret->cv_pix_fmt_type = cv_pix_fmt_type;
1282  }
1283 
1284  return ret;
1285 }
1286 
1288 {
1289  VTContext *vtctx = avctx->internal->hwaccel_priv_data;
1290  AVHWFramesContext *hw_frames;
1291  AVVTFramesContext *hw_ctx;
1292  int err;
1293  bool full_range;
1294 
1295  vtctx->logctx = avctx;
1296 
1297  if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx &&
1298  avctx->hwaccel_context)
1299  return videotoolbox_start(avctx);
1300 
1301  if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) {
1302  av_log(avctx, AV_LOG_ERROR,
1303  "Either hw_frames_ctx or hw_device_ctx must be set.\n");
1304  return AVERROR(EINVAL);
1305  }
1306 
1307  vtctx->vt_ctx = videotoolbox_alloc_context_with_pix_fmt(AV_PIX_FMT_NONE, false);
1308  if (!vtctx->vt_ctx) {
1309  err = AVERROR(ENOMEM);
1310  goto fail;
1311  }
1312 
1313  if (avctx->hw_frames_ctx) {
1314  hw_frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1315  } else {
1317  if (!avctx->hw_frames_ctx) {
1318  err = AVERROR(ENOMEM);
1319  goto fail;
1320  }
1321 
1322  hw_frames = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1323  hw_frames->format = AV_PIX_FMT_VIDEOTOOLBOX;
1324  hw_frames->sw_format = videotoolbox_best_pixel_format(avctx);
1325  hw_frames->width = avctx->width;
1326  hw_frames->height = avctx->height;
1327  hw_ctx = hw_frames->hwctx;
1328  hw_ctx->color_range = avctx->color_range;
1329 
1330  err = av_hwframe_ctx_init(avctx->hw_frames_ctx);
1331  if (err < 0) {
1332  av_buffer_unref(&avctx->hw_frames_ctx);
1333  goto fail;
1334  }
1335  }
1336 
1338  if (!vtctx->cached_hw_frames_ctx) {
1339  err = AVERROR(ENOMEM);
1340  goto fail;
1341  }
1342 
1344  vtctx->vt_ctx->cv_pix_fmt_type =
1346  if (!vtctx->vt_ctx->cv_pix_fmt_type) {
1347  const AVPixFmtDescriptor *attempted_format =
1348  av_pix_fmt_desc_get(hw_frames->sw_format);
1349  av_log(avctx, AV_LOG_ERROR,
1350  "Failed to map underlying FFmpeg pixel format %s (%s range) to "
1351  "a VideoToolbox format!\n",
1352  attempted_format ? attempted_format->name : "<unknown>",
1354  err = AVERROR(EINVAL);
1355  goto fail;
1356  }
1357 
1358  err = videotoolbox_start(avctx);
1359  if (err < 0)
1360  goto fail;
1361 
1362  return 0;
1363 
1364 fail:
1365  ff_videotoolbox_uninit(avctx);
1366  return err;
1367 }
1368 
1370  AVBufferRef *hw_frames_ctx)
1371 {
1372  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
1373 
1374  frames_ctx->format = AV_PIX_FMT_VIDEOTOOLBOX;
1375  frames_ctx->width = avctx->coded_width;
1376  frames_ctx->height = avctx->coded_height;
1377  frames_ctx->sw_format = videotoolbox_best_pixel_format(avctx);
1378 
1379  return 0;
1380 }
1381 
1383  .p.name = "h263_videotoolbox",
1384  .p.type = AVMEDIA_TYPE_VIDEO,
1385  .p.id = AV_CODEC_ID_H263,
1386  .p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
1387  .alloc_frame = ff_videotoolbox_alloc_frame,
1388  .start_frame = videotoolbox_mpeg_start_frame,
1389  .decode_slice = videotoolbox_mpeg_decode_slice,
1390  .end_frame = videotoolbox_mpeg_end_frame,
1391  .frame_params = ff_videotoolbox_frame_params,
1393  .uninit = ff_videotoolbox_uninit,
1394  .priv_data_size = sizeof(VTContext),
1395 };
1396 
1398  .p.name = "hevc_videotoolbox",
1399  .p.type = AVMEDIA_TYPE_VIDEO,
1400  .p.id = AV_CODEC_ID_HEVC,
1401  .p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
1402  .alloc_frame = ff_videotoolbox_alloc_frame,
1403  .start_frame = videotoolbox_hevc_start_frame,
1404  .decode_slice = videotoolbox_hevc_decode_slice,
1405  .decode_params = videotoolbox_hevc_decode_params,
1406  .end_frame = videotoolbox_hevc_end_frame,
1407  .frame_params = ff_videotoolbox_frame_params,
1409  .uninit = ff_videotoolbox_uninit,
1410  .priv_data_size = sizeof(VTContext),
1411 };
1412 
1414  .p.name = "h264_videotoolbox",
1415  .p.type = AVMEDIA_TYPE_VIDEO,
1416  .p.id = AV_CODEC_ID_H264,
1417  .p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
1418  .alloc_frame = ff_videotoolbox_alloc_frame,
1419  .start_frame = ff_videotoolbox_h264_start_frame,
1420  .decode_slice = ff_videotoolbox_h264_decode_slice,
1421  .decode_params = videotoolbox_h264_decode_params,
1422  .end_frame = videotoolbox_h264_end_frame,
1423  .frame_params = ff_videotoolbox_frame_params,
1425  .uninit = ff_videotoolbox_uninit,
1426  .priv_data_size = sizeof(VTContext),
1427 };
1428 
1430  .p.name = "mpeg1_videotoolbox",
1431  .p.type = AVMEDIA_TYPE_VIDEO,
1432  .p.id = AV_CODEC_ID_MPEG1VIDEO,
1433  .p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
1434  .alloc_frame = ff_videotoolbox_alloc_frame,
1435  .start_frame = videotoolbox_mpeg_start_frame,
1436  .decode_slice = videotoolbox_mpeg_decode_slice,
1437  .end_frame = videotoolbox_mpeg_end_frame,
1438  .frame_params = ff_videotoolbox_frame_params,
1440  .uninit = ff_videotoolbox_uninit,
1441  .priv_data_size = sizeof(VTContext),
1442 };
1443 
1445  .p.name = "mpeg2_videotoolbox",
1446  .p.type = AVMEDIA_TYPE_VIDEO,
1447  .p.id = AV_CODEC_ID_MPEG2VIDEO,
1448  .p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
1449  .alloc_frame = ff_videotoolbox_alloc_frame,
1450  .start_frame = videotoolbox_mpeg_start_frame,
1451  .decode_slice = videotoolbox_mpeg_decode_slice,
1452  .end_frame = videotoolbox_mpeg_end_frame,
1453  .frame_params = ff_videotoolbox_frame_params,
1455  .uninit = ff_videotoolbox_uninit,
1456  .priv_data_size = sizeof(VTContext),
1457 };
1458 
1460  .p.name = "mpeg4_videotoolbox",
1461  .p.type = AVMEDIA_TYPE_VIDEO,
1462  .p.id = AV_CODEC_ID_MPEG4,
1463  .p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
1464  .alloc_frame = ff_videotoolbox_alloc_frame,
1465  .start_frame = videotoolbox_mpeg_start_frame,
1466  .decode_slice = videotoolbox_mpeg_decode_slice,
1467  .end_frame = videotoolbox_mpeg_end_frame,
1468  .frame_params = ff_videotoolbox_frame_params,
1470  .uninit = ff_videotoolbox_uninit,
1471  .priv_data_size = sizeof(VTContext),
1472 };
1473 
1475  .p.name = "prores_videotoolbox",
1476  .p.type = AVMEDIA_TYPE_VIDEO,
1477  .p.id = AV_CODEC_ID_PRORES,
1478  .p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
1479  .alloc_frame = ff_videotoolbox_alloc_frame,
1480  .start_frame = videotoolbox_prores_start_frame,
1481  .decode_slice = videotoolbox_prores_decode_slice,
1482  .end_frame = videotoolbox_prores_end_frame,
1483  .frame_params = ff_videotoolbox_frame_params,
1485  .uninit = ff_videotoolbox_uninit,
1486  .priv_data_size = sizeof(VTContext),
1487 };
1488 
1490  .p.name = "prores_raw_videotoolbox",
1491  .p.type = AVMEDIA_TYPE_VIDEO,
1492  .p.id = AV_CODEC_ID_PRORES_RAW,
1493  .p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX,
1494  .alloc_frame = ff_videotoolbox_alloc_frame,
1495  .start_frame = videotoolbox_prores_raw_start_frame,
1496  .decode_slice = videotoolbox_prores_raw_decode_slice,
1497  .end_frame = videotoolbox_prores_raw_end_frame,
1498  .frame_params = ff_videotoolbox_frame_params,
1500  .uninit = ff_videotoolbox_uninit,
1501  .priv_data_size = sizeof(VTContext),
1502 };
1503 
1504 #endif /* CONFIG_VIDEOTOOLBOX */
videotoolbox_buffer_release
static void videotoolbox_buffer_release(void *opaque, uint8_t *data)
Definition: videotoolbox.c:72
flags
const SwsFlags flags[]
Definition: swscale.c:72
AVVideotoolboxContext::cm_codec_type
int cm_codec_type
CoreMedia codec type that Videotoolbox will use to create the decompression session.
Definition: videotoolbox.h:78
AVCodecContext::hwaccel_context
void * hwaccel_context
Legacy hardware accelerator context.
Definition: avcodec.h:1447
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:216
APPEND_PS
#define APPEND_PS(T, t)
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ff_videotoolbox_common_end_frame
int ff_videotoolbox_common_end_frame(AVCodecContext *avctx, AVFrame *frame)
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3456
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
ff_videotoolbox_uninit
int ff_videotoolbox_uninit(AVCodecContext *avctx)
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
kCMVideoCodecType_AV1
@ kCMVideoCodecType_AV1
Definition: videotoolbox.c:62
ff_videotoolbox_buffer_append
int ff_videotoolbox_buffer_append(VTContext *vtctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:101
FFHWAccel::p
AVHWAccel p
The public AVHWAccel.
Definition: hwaccel_internal.h:38
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
FrameDecodeData
This struct stores per-frame lavc-internal data and is attached to it via private_ref.
Definition: decode.h:33
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:337
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:459
pixdesc.h
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:777
av_hwframe_ctx_alloc
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:263
internal.h
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
AVPixFmtDescriptor::name
const char * name
Definition: pixdesc.h:70
b
#define b
Definition: input.c:43
av_vt_pixbuf_set_attachments
int av_vt_pixbuf_set_attachments(void *log_ctx, CVPixelBufferRef pixbuf, const AVFrame *src)
Definition: hwcontext_videotoolbox.c:677
data
const char data[16]
Definition: mxf.c:149
ProresContext
Definition: proresdec.h:43
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
AV_W8
#define AV_W8(p, v)
Definition: videotoolbox.c:182
PTLCommon::profile_space
uint8_t profile_space
Definition: ps.h:128
COUNT_SIZE_PS
#define COUNT_SIZE_PS(T, t)
mpegvideo.h
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
ff_mpeg2_videotoolbox_hwaccel
const struct FFHWAccel ff_mpeg2_videotoolbox_hwaccel
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:220
codec_type
enum AVMediaType codec_type
Definition: rtp.c:37
AVVideotoolboxContext
This struct holds all the information that needs to be passed between the caller and libavcodec for i...
Definition: videotoolbox.h:57
PTLCommon::profile_compatibility_flag
uint8_t profile_compatibility_flag[32]
Definition: ps.h:131
escape_ps
static int escape_ps(uint8_t *dst, const uint8_t *src, int src_size)
Definition: videotoolbox.c:184
S
#define S(s, c, i)
Definition: flacdsp_template.c:46
PTLCommon::progressive_source_flag
uint8_t progressive_source_flag
Definition: ps.h:132
ff_hevc_videotoolbox_hwaccel
const struct FFHWAccel ff_hevc_videotoolbox_hwaccel
ff_videotoolbox_h264_start_frame
int ff_videotoolbox_h264_start_frame(AVCodecContext *avctx, const AVBufferRef *buffer_ref, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:415
FFHWAccel
Definition: hwaccel_internal.h:34
PTLCommon::interlaced_source_flag
uint8_t interlaced_source_flag
Definition: ps.h:133
ff_videotoolbox_avcc_extradata_create
CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
Definition: videotoolbox.c:213
fail
#define fail()
Definition: checkasm.h:225
ff_h263_videotoolbox_hwaccel
const struct FFHWAccel ff_h263_videotoolbox_hwaccel
proresdec.h
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
pts
static int64_t pts
Definition: transcode_aac.c:644
kCMVideoCodecType_HEVC
@ kCMVideoCodecType_HEVC
Definition: videotoolbox.c:54
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:619
VTContext::allocated_size
int allocated_size
Definition: vt_internal.h:33
AV_CODEC_ID_PRORES_RAW
@ AV_CODEC_ID_PRORES_RAW
Definition: codec_id.h:333
ff_videotoolbox_common_init
int ff_videotoolbox_common_init(AVCodecContext *avctx)
PTLCommon::frame_only_constraint_flag
uint8_t frame_only_constraint_flag
Definition: ps.h:135
videotoolbox.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
VTContext::bitstream
uint8_t * bitstream
Definition: vt_internal.h:27
kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder
#define kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder
Definition: videotoolbox.c:50
AVHWFramesContext::height
int height
Definition: hwcontext.h:220
bytestream2_init_writer
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition: bytestream.h:147
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:527
bytestream2_put_ne24
#define bytestream2_put_ne24
Definition: bytestream.h:128
full_range
bool full_range
Definition: hwcontext_videotoolbox.c:47
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
vt_internal.h
PTLCommon
Definition: ps.h:127
FrameDecodeData::hwaccel_priv_post_process
int(* hwaccel_priv_post_process)(void *logctx, AVFrame *frame)
Per-frame private data for hwaccels.
Definition: decode.h:53
s
#define s(width, name)
Definition: cbs_vp9.c:198
VTHWFrame
Definition: videotoolbox.c:67
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
bytestream2_put_buffer
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition: bytestream.h:286
ff_mpeg1_videotoolbox_hwaccel
const struct FFHWAccel ff_mpeg1_videotoolbox_hwaccel
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:222
prores_raw.h
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
ff_videotoolbox_vpcc_extradata_create
CFDataRef ff_videotoolbox_vpcc_extradata_create(AVCodecContext *avctx)
Definition: videotoolbox_vp9.c:65
kCMVideoCodecType_VP9
@ kCMVideoCodecType_VP9
Definition: videotoolbox.c:58
P
#define P
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
AV_PIX_FMT_FLAG_ALPHA
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:147
ctx
static AVFormatContext * ctx
Definition: movenc.c:49
decode.h
PTLCommon::non_packed_constraint_flag
uint8_t non_packed_constraint_flag
Definition: ps.h:134
AVPixFmtDescriptor::log2_chroma_w
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
Definition: pixdesc.h:80
PTLCommon::profile_idc
uint8_t profile_idc
Definition: ps.h:130
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
av_fallthrough
#define av_fallthrough
Definition: attributes.h:67
AVVTFramesContext
Definition: hwcontext_videotoolbox.h:45
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
tmp
static uint8_t tmp[40]
Definition: aes_ctr.c:52
PTLCommon::tier_flag
uint8_t tier_flag
Definition: ps.h:129
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:453
if
if(ret)
Definition: filter_design.txt:179
VTContext::bitstream_size
int bitstream_size
Definition: vt_internal.h:30
ff_attach_decode_data
int ff_attach_decode_data(AVCodecContext *avctx, AVFrame *frame)
Definition: decode.c:1695
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:3772
ff_prores_raw_videotoolbox_hwaccel
const struct FFHWAccel ff_prores_raw_videotoolbox_hwaccel
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:681
av_buffer_unref
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:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:284
hwaccel_internal.h
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:401
AVVTFramesContext::color_range
enum AVColorRange color_range
Definition: hwcontext_videotoolbox.h:46
AVHWFramesContext::device_ref
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:129
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:478
V
#define V
Definition: avdct.c:32
AV_PIX_FMT_P410
#define AV_PIX_FMT_P410
Definition: pixfmt.h:617
ProResRAWContext
Definition: prores_raw.h:39
AVVideotoolboxContext::session
VTDecompressionSessionRef session
Videotoolbox decompression session object.
Definition: videotoolbox.h:61
vps
static int FUNC() vps(CodedBitstreamContext *ctx, RWContext *rw, H265RawVPS *current)
Definition: cbs_h265_syntax_template.c:423
AVPixFmtDescriptor::flags
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:94
ff_videotoolbox_frame_params
int ff_videotoolbox_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
ff_videotoolbox_h264_decode_slice
int ff_videotoolbox_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:476
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
videotoolbox_common_decode_slice
static int videotoolbox_common_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:453
VTHWFrame::pixbuf
CVPixelBufferRef pixbuf
Definition: videotoolbox.c:68
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:415
PutByteContext
Definition: bytestream.h:37
hwcontext_videotoolbox.h
ff_prores_videotoolbox_hwaccel
const struct FFHWAccel ff_prores_videotoolbox_hwaccel
ff_videotoolbox_hvcc_extradata_create
CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx)
Definition: videotoolbox.c:258
hevcdec.h
height
#define height
Definition: dsp.h:89
AV_WN32
#define AV_WN32(p, v)
Definition: intreadwrite.h:372
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:130
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:87
av_bswap32
#define av_bswap32
Definition: bswap.h:47
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
AV_CODEC_ID_H263
@ AV_CODEC_ID_H263
Definition: codec_id.h:56
size
int size
Definition: twinvq_data.h:10344
VUI
Definition: ps.h:98
AV_PIX_FMT_AYUV64
#define AV_PIX_FMT_AYUV64
Definition: pixfmt.h:601
ff_videotoolbox_av1c_extradata_create
CFDataRef ff_videotoolbox_av1c_extradata_create(AVCodecContext *avctx)
Definition: videotoolbox_av1.c:31
AVVideotoolboxContext::cm_fmt_desc
CMVideoFormatDescriptionRef cm_fmt_desc
CoreMedia Format Description that Videotoolbox will use to create the decompression session.
Definition: videotoolbox.h:73
AV_PIX_FMT_NV16
@ AV_PIX_FMT_NV16
interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:198
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
attributes.h
AV_PIX_FMT_P216
#define AV_PIX_FMT_P216
Definition: pixfmt.h:620
AV_PIX_FMT_P210
#define AV_PIX_FMT_P210
Definition: pixfmt.h:616
AV_PIX_FMT_FLAG_BAYER
#define AV_PIX_FMT_FLAG_BAYER
The pixel format is following a Bayer pattern.
Definition: pixdesc.h:152
VTContext
Definition: vt_internal.h:25
AV_PIX_FMT_AYUV
@ AV_PIX_FMT_AYUV
packed AYUV 4:4:4:4, 32bpp (1 Cr & Cb sample per 1x1 Y & A samples), AYUVAYUV...
Definition: pixfmt.h:442
AVHWAccel::name
const char * name
Name of the hardware accelerated codec.
Definition: avcodec.h:1967
kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
#define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
Definition: videotoolbox.c:47
AV_PIX_FMT_VIDEOTOOLBOX
@ AV_PIX_FMT_VIDEOTOOLBOX
hardware decoding through Videotoolbox
Definition: pixfmt.h:305
h264dec.h
H264Context
H264Context.
Definition: h264dec.h:338
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
AVCodecContext::extradata
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition: avcodec.h:526
AV_PIX_FMT_NV24
@ AV_PIX_FMT_NV24
planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:371
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:228
VTContext::frame
CVImageBufferRef frame
Definition: vt_internal.h:36
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:496
AVCodecContext::hw_device_ctx
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
Definition: avcodec.h:1493
bytestream2_put_ne32
#define bytestream2_put_ne32
Definition: bytestream.h:129
AVCodecContext::height
int height
Definition: avcodec.h:604
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:643
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1471
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
bytestream2_put_ne16
#define bytestream2_put_ne16
Definition: bytestream.h:127
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
ff_videotoolbox_alloc_frame
int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: videotoolbox.c:152
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:153
sps
static int FUNC() sps(CodedBitstreamContext *ctx, RWContext *rw, H264RawSPS *current)
Definition: cbs_h264_syntax_template.c:260
VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING
#define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING
Definition: videotoolbox.c:65
av_map_videotoolbox_format_to_pixfmt
enum AVPixelFormat av_map_videotoolbox_format_to_pixfmt(uint32_t cv_fmt)
Convert a VideoToolbox (actually CoreVideo) format to AVPixelFormat.
Definition: hwcontext_videotoolbox.c:153
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
AVCodecContext
main external API structure.
Definition: avcodec.h:443
status
ov_status_e status
Definition: dnn_backend_openvino.c:100
VTContext::vt_ctx
struct AVVideotoolboxContext * vt_ctx
Definition: vt_internal.h:43
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
ff_mpeg4_videotoolbox_hwaccel
const struct FFHWAccel ff_mpeg4_videotoolbox_hwaccel
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
HEVCContext
Definition: hevcdec.h:490
PTLCommon::level_idc
uint8_t level_idc
Definition: ps.h:147
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
pps
uint64_t pps
Definition: dovi_rpuenc.c:36
videotoolbox_postproc_frame
static int videotoolbox_postproc_frame(void *avctx, AVFrame *frame)
Definition: videotoolbox.c:121
VTContext::logctx
void * logctx
Definition: vt_internal.h:49
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
VTHWFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
Definition: videotoolbox.c:69
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:602
VUI::min_spatial_segmentation_idc
int min_spatial_segmentation_idc
Definition: ps.h:120
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:619
VTContext::cached_hw_frames_ctx
struct AVBufferRef * cached_hw_frames_ctx
Definition: vt_internal.h:39
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
avutil.h
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
HEVCVPS
Definition: ps.h:171
HEVCSPS
Definition: ps.h:255
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
HEVCPPS
Definition: ps.h:374
w
uint8_t w
Definition: llvidencdsp.c:39
ff_videotoolbox_buffer_copy
int ff_videotoolbox_buffer_copy(VTContext *vtctx, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:81
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVCodecContext::codec_tag
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:468
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:470
AV_PIX_FMT_P416
#define AV_PIX_FMT_P416
Definition: pixfmt.h:621
ff_h264_videotoolbox_hwaccel
const struct FFHWAccel ff_h264_videotoolbox_hwaccel
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AVVideotoolboxContext::cv_pix_fmt_type
OSType cv_pix_fmt_type
CVPixelBuffer Format Type that Videotoolbox will use for decoded frames.
Definition: videotoolbox.h:68
av_map_videotoolbox_format_from_pixfmt2
uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range)
Same as av_map_videotoolbox_format_from_pixfmt function, but can map and return full range pixel form...
Definition: hwcontext_videotoolbox.c:187
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:604
bytestream.h
hwcontext.h
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
MKTAG
#define MKTAG(a, b, c, d)
Definition: macros.h:55
h
h
Definition: vp9dsp_template.c:2070
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:650
videotoolbox_h264_decode_params
static int videotoolbox_h264_decode_params(AVCodecContext *avctx, int type, const uint8_t *buffer, uint32_t size)
Definition: videotoolbox.c:430
width
#define width
Definition: dsp.h:89
AV_PIX_FMT_BAYER_RGGB16
#define AV_PIX_FMT_BAYER_RGGB16
Definition: pixfmt.h:572
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
MpegEncContext
MpegEncContext.
Definition: mpegvideo.h:67
VTContext::reconfig_needed
bool reconfig_needed
Definition: vt_internal.h:47
VTContext::sps
uint8_t sps[3]
Definition: vt_internal.h:46
AVPixFmtDescriptor::log2_chroma_h
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:89
src
#define src
Definition: vp8dsp.c:248
duration
static int64_t duration
Definition: ffplay.c:329
bytestream2_size_p
static av_always_inline int bytestream2_size_p(const PutByteContext *p)
Definition: bytestream.h:207
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:200