FFmpeg
videotoolboxenc.c
Go to the documentation of this file.
1 /*
2  * copyright (c) 2015 Rick Kern <kernrj@gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <VideoToolbox/VideoToolbox.h>
22 #include <CoreVideo/CoreVideo.h>
23 #include <CoreMedia/CoreMedia.h>
24 #include <TargetConditionals.h>
25 #include <Availability.h>
26 #include "avcodec.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/avassert.h"
29 #include "libavutil/avstring.h"
30 #include "libavcodec/avcodec.h"
31 #include "libavutil/pixdesc.h"
33 #include "internal.h"
34 #include <pthread.h>
35 #include "atsc_a53.h"
36 #include "encode.h"
37 #include "h264.h"
38 #include "h264_sei.h"
39 #include <dlfcn.h>
40 
41 #if !HAVE_KCMVIDEOCODECTYPE_HEVC
42 enum { kCMVideoCodecType_HEVC = 'hvc1' };
43 #endif
44 
45 #if !HAVE_KCMVIDEOCODECTYPE_HEVCWITHALPHA
47 #endif
48 
49 #if !HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
52 #endif
53 
54 #ifndef TARGET_CPU_ARM64
55 # define TARGET_CPU_ARM64 0
56 #endif
57 
58 typedef OSStatus (*getParameterSetAtIndex)(CMFormatDescriptionRef videoDesc,
59  size_t parameterSetIndex,
60  const uint8_t **parameterSetPointerOut,
61  size_t *parameterSetSizeOut,
62  size_t *parameterSetCountOut,
63  int *NALUnitHeaderLengthOut);
64 
65 //These symbols may not be present
66 static struct{
70 
74 
96 
99 
102 
105 
107 } compat_keys;
108 
109 #define GET_SYM(symbol, defaultVal) \
110 do{ \
111  CFStringRef* handle = (CFStringRef*)dlsym(RTLD_DEFAULT, #symbol); \
112  if(!handle) \
113  compat_keys.symbol = CFSTR(defaultVal); \
114  else \
115  compat_keys.symbol = *handle; \
116 }while(0)
117 
119 
120 static void loadVTEncSymbols(){
121  compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex =
122  (getParameterSetAtIndex)dlsym(
123  RTLD_DEFAULT,
124  "CMVideoFormatDescriptionGetHEVCParameterSetAtIndex"
125  );
126 
130 
134 
135  GET_SYM(kVTProfileLevel_H264_Baseline_4_0, "H264_Baseline_4_0");
136  GET_SYM(kVTProfileLevel_H264_Baseline_4_2, "H264_Baseline_4_2");
137  GET_SYM(kVTProfileLevel_H264_Baseline_5_0, "H264_Baseline_5_0");
138  GET_SYM(kVTProfileLevel_H264_Baseline_5_1, "H264_Baseline_5_1");
139  GET_SYM(kVTProfileLevel_H264_Baseline_5_2, "H264_Baseline_5_2");
140  GET_SYM(kVTProfileLevel_H264_Baseline_AutoLevel, "H264_Baseline_AutoLevel");
141  GET_SYM(kVTProfileLevel_H264_Main_4_2, "H264_Main_4_2");
142  GET_SYM(kVTProfileLevel_H264_Main_5_1, "H264_Main_5_1");
143  GET_SYM(kVTProfileLevel_H264_Main_5_2, "H264_Main_5_2");
144  GET_SYM(kVTProfileLevel_H264_Main_AutoLevel, "H264_Main_AutoLevel");
145  GET_SYM(kVTProfileLevel_H264_High_3_0, "H264_High_3_0");
146  GET_SYM(kVTProfileLevel_H264_High_3_1, "H264_High_3_1");
147  GET_SYM(kVTProfileLevel_H264_High_3_2, "H264_High_3_2");
148  GET_SYM(kVTProfileLevel_H264_High_4_0, "H264_High_4_0");
149  GET_SYM(kVTProfileLevel_H264_High_4_1, "H264_High_4_1");
150  GET_SYM(kVTProfileLevel_H264_High_4_2, "H264_High_4_2");
151  GET_SYM(kVTProfileLevel_H264_High_5_1, "H264_High_5_1");
152  GET_SYM(kVTProfileLevel_H264_High_5_2, "H264_High_5_2");
153  GET_SYM(kVTProfileLevel_H264_High_AutoLevel, "H264_High_AutoLevel");
154  GET_SYM(kVTProfileLevel_H264_Extended_5_0, "H264_Extended_5_0");
155  GET_SYM(kVTProfileLevel_H264_Extended_AutoLevel, "H264_Extended_AutoLevel");
156 
157  GET_SYM(kVTProfileLevel_HEVC_Main_AutoLevel, "HEVC_Main_AutoLevel");
158  GET_SYM(kVTProfileLevel_HEVC_Main10_AutoLevel, "HEVC_Main10_AutoLevel");
159 
162  "TargetQualityForAlpha");
163 
165  "EnableHardwareAcceleratedVideoEncoder");
167  "RequireHardwareAcceleratedVideoEncoder");
168 }
169 
170 typedef enum VT_H264Profile {
178 
179 typedef enum VTH264Entropy{
183 } VTH264Entropy;
184 
185 typedef enum VT_HEVCProfile {
191 
192 static const uint8_t start_code[] = { 0, 0, 0, 1 };
193 
194 typedef struct ExtraSEI {
195  void *data;
196  size_t size;
197 } ExtraSEI;
198 
199 typedef struct BufNode {
200  CMSampleBufferRef cm_buffer;
202  struct BufNode* next;
203  int error;
204 } BufNode;
205 
206 typedef struct VTEncContext {
207  AVClass *class;
209  VTCompressionSessionRef session;
210  CFStringRef ycbcr_matrix;
211  CFStringRef color_primaries;
212  CFStringRef transfer_function;
214 
217 
219 
222 
223  int64_t frame_ct_out;
224  int64_t frame_ct_in;
225 
226  int64_t first_pts;
227  int64_t dts_delta;
228 
229  int64_t profile;
230  int level;
231  int entropy;
232  int realtime;
235 
236  int allow_sw;
239 
240  bool flushing;
243 
244  /* can't be bool type since AVOption will access it as int */
245  int a53_cc;
246 } VTEncContext;
247 
248 static int vtenc_populate_extradata(AVCodecContext *avctx,
249  CMVideoCodecType codec_type,
250  CFStringRef profile_level,
251  CFNumberRef gamma_level,
252  CFDictionaryRef enc_info,
253  CFDictionaryRef pixel_buffer_info);
254 
255 /**
256  * NULL-safe release of *refPtr, and sets value to NULL.
257  */
258 static void vt_release_num(CFNumberRef* refPtr){
259  if (!*refPtr) {
260  return;
261  }
262 
263  CFRelease(*refPtr);
264  *refPtr = NULL;
265 }
266 
267 static void set_async_error(VTEncContext *vtctx, int err)
268 {
269  BufNode *info;
270 
271  pthread_mutex_lock(&vtctx->lock);
272 
273  vtctx->async_error = err;
274 
275  info = vtctx->q_head;
276  vtctx->q_head = vtctx->q_tail = NULL;
277 
278  while (info) {
279  BufNode *next = info->next;
280  CFRelease(info->cm_buffer);
281  av_free(info);
282  info = next;
283  }
284 
285  pthread_mutex_unlock(&vtctx->lock);
286 }
287 
288 static void clear_frame_queue(VTEncContext *vtctx)
289 {
290  set_async_error(vtctx, 0);
291 }
292 
293 static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf, ExtraSEI **sei)
294 {
295  BufNode *info;
296 
297  pthread_mutex_lock(&vtctx->lock);
298 
299  if (vtctx->async_error) {
300  pthread_mutex_unlock(&vtctx->lock);
301  return vtctx->async_error;
302  }
303 
304  if (vtctx->flushing && vtctx->frame_ct_in == vtctx->frame_ct_out) {
305  *buf = NULL;
306 
307  pthread_mutex_unlock(&vtctx->lock);
308  return 0;
309  }
310 
311  while (!vtctx->q_head && !vtctx->async_error && wait && !vtctx->flushing) {
312  pthread_cond_wait(&vtctx->cv_sample_sent, &vtctx->lock);
313  }
314 
315  if (!vtctx->q_head) {
316  pthread_mutex_unlock(&vtctx->lock);
317  *buf = NULL;
318  return 0;
319  }
320 
321  info = vtctx->q_head;
322  vtctx->q_head = vtctx->q_head->next;
323  if (!vtctx->q_head) {
324  vtctx->q_tail = NULL;
325  }
326 
327  vtctx->frame_ct_out++;
328  pthread_mutex_unlock(&vtctx->lock);
329 
330  *buf = info->cm_buffer;
331  if (sei && *buf) {
332  *sei = info->sei;
333  } else if (info->sei) {
334  if (info->sei->data) av_free(info->sei->data);
335  av_free(info->sei);
336  }
337  av_free(info);
338 
339 
340  return 0;
341 }
342 
343 static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer, ExtraSEI *sei)
344 {
345  BufNode *info = av_malloc(sizeof(BufNode));
346  if (!info) {
347  set_async_error(vtctx, AVERROR(ENOMEM));
348  return;
349  }
350 
351  CFRetain(buffer);
352  info->cm_buffer = buffer;
353  info->sei = sei;
354  info->next = NULL;
355 
356  pthread_mutex_lock(&vtctx->lock);
357 
358  if (!vtctx->q_head) {
359  vtctx->q_head = info;
360  } else {
361  vtctx->q_tail->next = info;
362  }
363 
364  vtctx->q_tail = info;
365 
367  pthread_mutex_unlock(&vtctx->lock);
368 }
369 
370 static int count_nalus(size_t length_code_size,
371  CMSampleBufferRef sample_buffer,
372  int *count)
373 {
374  size_t offset = 0;
375  int status;
376  int nalu_ct = 0;
377  uint8_t size_buf[4];
378  size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
379  CMBlockBufferRef block = CMSampleBufferGetDataBuffer(sample_buffer);
380 
381  if (length_code_size > 4)
382  return AVERROR_INVALIDDATA;
383 
384  while (offset < src_size) {
385  size_t curr_src_len;
386  size_t box_len = 0;
387  size_t i;
388 
389  status = CMBlockBufferCopyDataBytes(block,
390  offset,
391  length_code_size,
392  size_buf);
393 
394  for (i = 0; i < length_code_size; i++) {
395  box_len <<= 8;
396  box_len |= size_buf[i];
397  }
398 
399  curr_src_len = box_len + length_code_size;
400  offset += curr_src_len;
401 
402  nalu_ct++;
403  }
404 
405  *count = nalu_ct;
406  return 0;
407 }
408 
409 static CMVideoCodecType get_cm_codec_type(AVCodecContext *avctx,
410  int64_t profile,
411  double alpha_quality)
412 {
414  switch (avctx->codec_id) {
415  case AV_CODEC_ID_H264: return kCMVideoCodecType_H264;
416  case AV_CODEC_ID_HEVC:
417  if (desc && (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpha_quality > 0.0) {
419  }
420  return kCMVideoCodecType_HEVC;
421  case AV_CODEC_ID_PRORES:
422  switch (profile) {
424  return MKBETAG('a','p','c','o'); // kCMVideoCodecType_AppleProRes422Proxy
426  return MKBETAG('a','p','c','s'); // kCMVideoCodecType_AppleProRes422LT
428  return MKBETAG('a','p','c','n'); // kCMVideoCodecType_AppleProRes422
430  return MKBETAG('a','p','c','h'); // kCMVideoCodecType_AppleProRes422HQ
432  return MKBETAG('a','p','4','h'); // kCMVideoCodecType_AppleProRes4444
434  return MKBETAG('a','p','4','x'); // kCMVideoCodecType_AppleProRes4444XQ
435 
436  default:
437  av_log(avctx, AV_LOG_ERROR, "Unknown profile ID: %"PRId64", using auto\n", profile);
438  case FF_PROFILE_UNKNOWN:
439  if (desc &&
440  ((desc->flags & AV_PIX_FMT_FLAG_ALPHA) ||
441  desc->log2_chroma_w == 0))
442  return MKBETAG('a','p','4','h'); // kCMVideoCodecType_AppleProRes4444
443  else
444  return MKBETAG('a','p','c','n'); // kCMVideoCodecType_AppleProRes422
445  }
446  default: return 0;
447  }
448 }
449 
450 /**
451  * Get the parameter sets from a CMSampleBufferRef.
452  * @param dst If *dst isn't NULL, the parameters are copied into existing
453  * memory. *dst_size must be set accordingly when *dst != NULL.
454  * If *dst is NULL, it will be allocated.
455  * In all cases, *dst_size is set to the number of bytes used starting
456  * at *dst.
457  */
458 static int get_params_size(
459  AVCodecContext *avctx,
460  CMVideoFormatDescriptionRef vid_fmt,
461  size_t *size)
462 {
463  VTEncContext *vtctx = avctx->priv_data;
464  size_t total_size = 0;
465  size_t ps_count;
466  int is_count_bad = 0;
467  size_t i;
468  int status;
469  status = vtctx->get_param_set_func(vid_fmt,
470  0,
471  NULL,
472  NULL,
473  &ps_count,
474  NULL);
475  if (status) {
476  is_count_bad = 1;
477  ps_count = 0;
478  status = 0;
479  }
480 
481  for (i = 0; i < ps_count || is_count_bad; i++) {
482  const uint8_t *ps;
483  size_t ps_size;
484  status = vtctx->get_param_set_func(vid_fmt,
485  i,
486  &ps,
487  &ps_size,
488  NULL,
489  NULL);
490  if (status) {
491  /*
492  * When ps_count is invalid, status != 0 ends the loop normally
493  * unless we didn't get any parameter sets.
494  */
495  if (i > 0 && is_count_bad) status = 0;
496 
497  break;
498  }
499 
500  total_size += ps_size + sizeof(start_code);
501  }
502 
503  if (status) {
504  av_log(avctx, AV_LOG_ERROR, "Error getting parameter set sizes: %d\n", status);
505  return AVERROR_EXTERNAL;
506  }
507 
508  *size = total_size;
509  return 0;
510 }
511 
512 static int copy_param_sets(
513  AVCodecContext *avctx,
514  CMVideoFormatDescriptionRef vid_fmt,
515  uint8_t *dst,
516  size_t dst_size)
517 {
518  VTEncContext *vtctx = avctx->priv_data;
519  size_t ps_count;
520  int is_count_bad = 0;
521  int status;
522  size_t offset = 0;
523  size_t i;
524 
525  status = vtctx->get_param_set_func(vid_fmt,
526  0,
527  NULL,
528  NULL,
529  &ps_count,
530  NULL);
531  if (status) {
532  is_count_bad = 1;
533  ps_count = 0;
534  status = 0;
535  }
536 
537 
538  for (i = 0; i < ps_count || is_count_bad; i++) {
539  const uint8_t *ps;
540  size_t ps_size;
541  size_t next_offset;
542 
543  status = vtctx->get_param_set_func(vid_fmt,
544  i,
545  &ps,
546  &ps_size,
547  NULL,
548  NULL);
549  if (status) {
550  if (i > 0 && is_count_bad) status = 0;
551 
552  break;
553  }
554 
555  next_offset = offset + sizeof(start_code) + ps_size;
556  if (dst_size < next_offset) {
557  av_log(avctx, AV_LOG_ERROR, "Error: buffer too small for parameter sets.\n");
559  }
560 
561  memcpy(dst + offset, start_code, sizeof(start_code));
562  offset += sizeof(start_code);
563 
564  memcpy(dst + offset, ps, ps_size);
565  offset = next_offset;
566  }
567 
568  if (status) {
569  av_log(avctx, AV_LOG_ERROR, "Error getting parameter set data: %d\n", status);
570  return AVERROR_EXTERNAL;
571  }
572 
573  return 0;
574 }
575 
576 static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer)
577 {
578  VTEncContext *vtctx = avctx->priv_data;
579  CMVideoFormatDescriptionRef vid_fmt;
580  size_t total_size;
581  int status;
582 
583  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
584  if (!vid_fmt) {
585  av_log(avctx, AV_LOG_ERROR, "No video format.\n");
586  return AVERROR_EXTERNAL;
587  }
588 
589  if (vtctx->get_param_set_func) {
590  status = get_params_size(avctx, vid_fmt, &total_size);
591  if (status) {
592  av_log(avctx, AV_LOG_ERROR, "Could not get parameter sets.\n");
593  return status;
594  }
595 
596  avctx->extradata = av_mallocz(total_size + AV_INPUT_BUFFER_PADDING_SIZE);
597  if (!avctx->extradata) {
598  return AVERROR(ENOMEM);
599  }
600  avctx->extradata_size = total_size;
601 
602  status = copy_param_sets(avctx, vid_fmt, avctx->extradata, total_size);
603 
604  if (status) {
605  av_log(avctx, AV_LOG_ERROR, "Could not copy param sets.\n");
606  return status;
607  }
608  } else {
609  CFDataRef data = CMFormatDescriptionGetExtension(vid_fmt, kCMFormatDescriptionExtension_VerbatimSampleDescription);
610  if (data && CFGetTypeID(data) == CFDataGetTypeID()) {
611  CFIndex size = CFDataGetLength(data);
612 
614  if (!avctx->extradata)
615  return AVERROR(ENOMEM);
616  avctx->extradata_size = size;
617 
618  CFDataGetBytes(data, CFRangeMake(0, size), avctx->extradata);
619  }
620  }
621 
622  return 0;
623 }
624 
626  void *ctx,
627  void *sourceFrameCtx,
628  OSStatus status,
629  VTEncodeInfoFlags flags,
630  CMSampleBufferRef sample_buffer)
631 {
632  AVCodecContext *avctx = ctx;
633  VTEncContext *vtctx = avctx->priv_data;
634  ExtraSEI *sei = sourceFrameCtx;
635 
636  if (vtctx->async_error) {
637  return;
638  }
639 
640  if (status) {
641  av_log(avctx, AV_LOG_ERROR, "Error encoding frame: %d\n", (int)status);
643  return;
644  }
645 
646  if (!sample_buffer) {
647  return;
648  }
649 
650  if (!avctx->extradata && (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
651  int set_status = set_extradata(avctx, sample_buffer);
652  if (set_status) {
653  set_async_error(vtctx, set_status);
654  return;
655  }
656  }
657 
658  vtenc_q_push(vtctx, sample_buffer, sei);
659 }
660 
662  AVCodecContext *avctx,
663  CMSampleBufferRef sample_buffer,
664  size_t *size)
665 {
666  VTEncContext *vtctx = avctx->priv_data;
667  CMVideoFormatDescriptionRef vid_fmt;
668  int isize;
669  int status;
670 
671  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
672  if (!vid_fmt) {
673  av_log(avctx, AV_LOG_ERROR, "Error getting buffer format description.\n");
674  return AVERROR_EXTERNAL;
675  }
676 
677  status = vtctx->get_param_set_func(vid_fmt,
678  0,
679  NULL,
680  NULL,
681  NULL,
682  &isize);
683  if (status) {
684  av_log(avctx, AV_LOG_ERROR, "Error getting length code size: %d\n", status);
685  return AVERROR_EXTERNAL;
686  }
687 
688  *size = isize;
689  return 0;
690 }
691 
692 /*
693  * Returns true on success.
694  *
695  * If profile_level_val is NULL and this method returns true, don't specify the
696  * profile/level to the encoder.
697  */
699  CFStringRef *profile_level_val)
700 {
701  VTEncContext *vtctx = avctx->priv_data;
702  int64_t profile = vtctx->profile;
703 
704  if (profile == H264_PROF_AUTO && vtctx->level) {
705  //Need to pick a profile if level is not auto-selected.
707  }
708 
709  *profile_level_val = NULL;
710 
711  switch (profile) {
712  case H264_PROF_AUTO:
713  return true;
714 
715  case H264_PROF_BASELINE:
716  switch (vtctx->level) {
717  case 0: *profile_level_val =
718  compat_keys.kVTProfileLevel_H264_Baseline_AutoLevel; break;
719  case 13: *profile_level_val = kVTProfileLevel_H264_Baseline_1_3; break;
720  case 30: *profile_level_val = kVTProfileLevel_H264_Baseline_3_0; break;
721  case 31: *profile_level_val = kVTProfileLevel_H264_Baseline_3_1; break;
722  case 32: *profile_level_val = kVTProfileLevel_H264_Baseline_3_2; break;
723  case 40: *profile_level_val =
724  compat_keys.kVTProfileLevel_H264_Baseline_4_0; break;
725  case 41: *profile_level_val = kVTProfileLevel_H264_Baseline_4_1; break;
726  case 42: *profile_level_val =
727  compat_keys.kVTProfileLevel_H264_Baseline_4_2; break;
728  case 50: *profile_level_val =
729  compat_keys.kVTProfileLevel_H264_Baseline_5_0; break;
730  case 51: *profile_level_val =
731  compat_keys.kVTProfileLevel_H264_Baseline_5_1; break;
732  case 52: *profile_level_val =
733  compat_keys.kVTProfileLevel_H264_Baseline_5_2; break;
734  }
735  break;
736 
737  case H264_PROF_MAIN:
738  switch (vtctx->level) {
739  case 0: *profile_level_val =
740  compat_keys.kVTProfileLevel_H264_Main_AutoLevel; break;
741  case 30: *profile_level_val = kVTProfileLevel_H264_Main_3_0; break;
742  case 31: *profile_level_val = kVTProfileLevel_H264_Main_3_1; break;
743  case 32: *profile_level_val = kVTProfileLevel_H264_Main_3_2; break;
744  case 40: *profile_level_val = kVTProfileLevel_H264_Main_4_0; break;
745  case 41: *profile_level_val = kVTProfileLevel_H264_Main_4_1; break;
746  case 42: *profile_level_val =
747  compat_keys.kVTProfileLevel_H264_Main_4_2; break;
748  case 50: *profile_level_val = kVTProfileLevel_H264_Main_5_0; break;
749  case 51: *profile_level_val =
750  compat_keys.kVTProfileLevel_H264_Main_5_1; break;
751  case 52: *profile_level_val =
752  compat_keys.kVTProfileLevel_H264_Main_5_2; break;
753  }
754  break;
755 
756  case H264_PROF_HIGH:
757  switch (vtctx->level) {
758  case 0: *profile_level_val =
759  compat_keys.kVTProfileLevel_H264_High_AutoLevel; break;
760  case 30: *profile_level_val =
761  compat_keys.kVTProfileLevel_H264_High_3_0; break;
762  case 31: *profile_level_val =
763  compat_keys.kVTProfileLevel_H264_High_3_1; break;
764  case 32: *profile_level_val =
765  compat_keys.kVTProfileLevel_H264_High_3_2; break;
766  case 40: *profile_level_val =
767  compat_keys.kVTProfileLevel_H264_High_4_0; break;
768  case 41: *profile_level_val =
769  compat_keys.kVTProfileLevel_H264_High_4_1; break;
770  case 42: *profile_level_val =
771  compat_keys.kVTProfileLevel_H264_High_4_2; break;
772  case 50: *profile_level_val = kVTProfileLevel_H264_High_5_0; break;
773  case 51: *profile_level_val =
774  compat_keys.kVTProfileLevel_H264_High_5_1; break;
775  case 52: *profile_level_val =
776  compat_keys.kVTProfileLevel_H264_High_5_2; break;
777  }
778  break;
779  case H264_PROF_EXTENDED:
780  switch (vtctx->level) {
781  case 0: *profile_level_val =
782  compat_keys.kVTProfileLevel_H264_Extended_AutoLevel; break;
783  case 50: *profile_level_val =
784  compat_keys.kVTProfileLevel_H264_Extended_5_0; break;
785  }
786  break;
787  }
788 
789  if (!*profile_level_val) {
790  av_log(avctx, AV_LOG_ERROR, "Invalid Profile/Level.\n");
791  return false;
792  }
793 
794  return true;
795 }
796 
797 /*
798  * Returns true on success.
799  *
800  * If profile_level_val is NULL and this method returns true, don't specify the
801  * profile/level to the encoder.
802  */
804  CFStringRef *profile_level_val)
805 {
806  VTEncContext *vtctx = avctx->priv_data;
807  int64_t profile = vtctx->profile;
808 
809  *profile_level_val = NULL;
810 
811  switch (profile) {
812  case HEVC_PROF_AUTO:
813  return true;
814  case HEVC_PROF_MAIN:
815  *profile_level_val =
816  compat_keys.kVTProfileLevel_HEVC_Main_AutoLevel;
817  break;
818  case HEVC_PROF_MAIN10:
819  *profile_level_val =
820  compat_keys.kVTProfileLevel_HEVC_Main10_AutoLevel;
821  break;
822  }
823 
824  if (!*profile_level_val) {
825  av_log(avctx, AV_LOG_ERROR, "Invalid Profile/Level.\n");
826  return false;
827  }
828 
829  return true;
830 }
831 
833  enum AVPixelFormat fmt,
834  enum AVColorRange range,
835  int* av_pixel_format,
836  int* range_guessed)
837 {
838  if (range_guessed) *range_guessed = range != AVCOL_RANGE_MPEG &&
839  range != AVCOL_RANGE_JPEG;
840 
841  //MPEG range is used when no range is set
842  *av_pixel_format = av_map_videotoolbox_format_from_pixfmt2(fmt, range == AVCOL_RANGE_JPEG);
843 
844  return *av_pixel_format ? 0 : AVERROR(EINVAL);
845 }
846 
847 static void add_color_attr(AVCodecContext *avctx, CFMutableDictionaryRef dict) {
848  VTEncContext *vtctx = avctx->priv_data;
849 
850  if (vtctx->color_primaries) {
851  CFDictionarySetValue(dict,
852  kCVImageBufferColorPrimariesKey,
853  vtctx->color_primaries);
854  }
855 
856  if (vtctx->transfer_function) {
857  CFDictionarySetValue(dict,
858  kCVImageBufferTransferFunctionKey,
859  vtctx->transfer_function);
860  }
861 
862  if (vtctx->ycbcr_matrix) {
863  CFDictionarySetValue(dict,
864  kCVImageBufferYCbCrMatrixKey,
865  vtctx->ycbcr_matrix);
866  }
867 }
868 
870  CFMutableDictionaryRef* dict)
871 {
872  CFNumberRef cv_color_format_num = NULL;
873  CFNumberRef width_num = NULL;
874  CFNumberRef height_num = NULL;
875  CFMutableDictionaryRef pixel_buffer_info = NULL;
876  int cv_color_format;
877  int status = get_cv_pixel_format(avctx,
878  avctx->pix_fmt,
879  avctx->color_range,
880  &cv_color_format,
881  NULL);
882  if (status) return status;
883 
884  pixel_buffer_info = CFDictionaryCreateMutable(
885  kCFAllocatorDefault,
886  20,
887  &kCFCopyStringDictionaryKeyCallBacks,
888  &kCFTypeDictionaryValueCallBacks);
889 
890  if (!pixel_buffer_info) goto pbinfo_nomem;
891 
892  cv_color_format_num = CFNumberCreate(kCFAllocatorDefault,
893  kCFNumberSInt32Type,
894  &cv_color_format);
895  if (!cv_color_format_num) goto pbinfo_nomem;
896 
897  CFDictionarySetValue(pixel_buffer_info,
898  kCVPixelBufferPixelFormatTypeKey,
899  cv_color_format_num);
900  vt_release_num(&cv_color_format_num);
901 
902  width_num = CFNumberCreate(kCFAllocatorDefault,
903  kCFNumberSInt32Type,
904  &avctx->width);
905  if (!width_num) goto pbinfo_nomem;
906 
907  CFDictionarySetValue(pixel_buffer_info,
908  kCVPixelBufferWidthKey,
909  width_num);
910  vt_release_num(&width_num);
911 
912  height_num = CFNumberCreate(kCFAllocatorDefault,
913  kCFNumberSInt32Type,
914  &avctx->height);
915  if (!height_num) goto pbinfo_nomem;
916 
917  CFDictionarySetValue(pixel_buffer_info,
918  kCVPixelBufferHeightKey,
919  height_num);
920  vt_release_num(&height_num);
921 
922  add_color_attr(avctx, pixel_buffer_info);
923 
924  *dict = pixel_buffer_info;
925  return 0;
926 
927 pbinfo_nomem:
928  vt_release_num(&cv_color_format_num);
929  vt_release_num(&width_num);
930  vt_release_num(&height_num);
931  if (pixel_buffer_info) CFRelease(pixel_buffer_info);
932 
933  return AVERROR(ENOMEM);
934 }
935 
937  CFStringRef *primaries)
938 {
939  enum AVColorPrimaries pri = avctx->color_primaries;
940  switch (pri) {
942  *primaries = NULL;
943  break;
944 
945  case AVCOL_PRI_BT470BG:
946  *primaries = kCVImageBufferColorPrimaries_EBU_3213;
947  break;
948 
949  case AVCOL_PRI_SMPTE170M:
950  *primaries = kCVImageBufferColorPrimaries_SMPTE_C;
951  break;
952 
953  case AVCOL_PRI_BT709:
954  *primaries = kCVImageBufferColorPrimaries_ITU_R_709_2;
955  break;
956 
957  case AVCOL_PRI_BT2020:
958  *primaries = compat_keys.kCVImageBufferColorPrimaries_ITU_R_2020;
959  break;
960 
961  default:
962  av_log(avctx, AV_LOG_ERROR, "Color primaries %s is not supported.\n", av_color_primaries_name(pri));
963  *primaries = NULL;
964  return -1;
965  }
966 
967  return 0;
968 }
969 
971  CFStringRef *transfer_fnc,
972  CFNumberRef *gamma_level)
973 {
974  enum AVColorTransferCharacteristic trc = avctx->color_trc;
975  Float32 gamma;
976  *gamma_level = NULL;
977 
978  switch (trc) {
980  *transfer_fnc = NULL;
981  break;
982 
983  case AVCOL_TRC_BT709:
984  *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_709_2;
985  break;
986 
987  case AVCOL_TRC_SMPTE240M:
988  *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_240M_1995;
989  break;
990 
991 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_2084_PQ
992  case AVCOL_TRC_SMPTE2084:
993  *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ;
994  break;
995 #endif
996 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_LINEAR
997  case AVCOL_TRC_LINEAR:
998  *transfer_fnc = kCVImageBufferTransferFunction_Linear;
999  break;
1000 #endif
1001 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG
1003  *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_2100_HLG;
1004  break;
1005 #endif
1006 
1007  case AVCOL_TRC_GAMMA22:
1008  gamma = 2.2;
1009  *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
1010  *gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
1011  break;
1012 
1013  case AVCOL_TRC_GAMMA28:
1014  gamma = 2.8;
1015  *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
1016  *gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
1017  break;
1018 
1019  case AVCOL_TRC_BT2020_10:
1020  case AVCOL_TRC_BT2020_12:
1021  *transfer_fnc = compat_keys.kCVImageBufferTransferFunction_ITU_R_2020;
1022  break;
1023 
1024  default:
1025  *transfer_fnc = NULL;
1026  av_log(avctx, AV_LOG_ERROR, "Transfer function %s is not supported.\n", av_color_transfer_name(trc));
1027  return -1;
1028  }
1029 
1030  return 0;
1031 }
1032 
1033 static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix) {
1034  switch(avctx->colorspace) {
1035  case AVCOL_SPC_BT709:
1036  *matrix = kCVImageBufferYCbCrMatrix_ITU_R_709_2;
1037  break;
1038 
1039  case AVCOL_SPC_UNSPECIFIED:
1040  case AVCOL_SPC_RGB:
1041  *matrix = NULL;
1042  break;
1043 
1044  case AVCOL_SPC_BT470BG:
1045  case AVCOL_SPC_SMPTE170M:
1046  *matrix = kCVImageBufferYCbCrMatrix_ITU_R_601_4;
1047  break;
1048 
1049  case AVCOL_SPC_SMPTE240M:
1050  *matrix = kCVImageBufferYCbCrMatrix_SMPTE_240M_1995;
1051  break;
1052 
1053  case AVCOL_SPC_BT2020_NCL:
1054  *matrix = compat_keys.kCVImageBufferYCbCrMatrix_ITU_R_2020;
1055  break;
1056 
1057  default:
1058  av_log(avctx, AV_LOG_ERROR, "Color space %s is not supported.\n", av_color_space_name(avctx->colorspace));
1059  return -1;
1060  }
1061 
1062  return 0;
1063 }
1064 
1065 // constant quality only on Macs with Apple Silicon
1066 static bool vtenc_qscale_enabled(void)
1067 {
1068  return !TARGET_OS_IPHONE && TARGET_CPU_ARM64;
1069 }
1070 
1072  CMVideoCodecType codec_type,
1073  CFStringRef profile_level,
1074  CFNumberRef gamma_level,
1075  CFDictionaryRef enc_info,
1076  CFDictionaryRef pixel_buffer_info,
1077  VTCompressionSessionRef *session)
1078 {
1079  VTEncContext *vtctx = avctx->priv_data;
1080  SInt32 bit_rate = avctx->bit_rate;
1081  SInt32 max_rate = avctx->rc_max_rate;
1082  Float32 quality = avctx->global_quality / FF_QP2LAMBDA;
1083  CFNumberRef bit_rate_num;
1084  CFNumberRef quality_num;
1085  CFNumberRef bytes_per_second;
1086  CFNumberRef one_second;
1087  CFArrayRef data_rate_limits;
1088  int64_t bytes_per_second_value = 0;
1089  int64_t one_second_value = 0;
1090  void *nums[2];
1091 
1092  int status = VTCompressionSessionCreate(kCFAllocatorDefault,
1093  avctx->width,
1094  avctx->height,
1095  codec_type,
1096  enc_info,
1097  pixel_buffer_info,
1098  kCFAllocatorDefault,
1100  avctx,
1101  session);
1102 
1103  if (status || !vtctx->session) {
1104  av_log(avctx, AV_LOG_ERROR, "Error: cannot create compression session: %d\n", status);
1105 
1106 #if !TARGET_OS_IPHONE
1107  if (!vtctx->allow_sw) {
1108  av_log(avctx, AV_LOG_ERROR, "Try -allow_sw 1. The hardware encoder may be busy, or not supported.\n");
1109  }
1110 #endif
1111 
1112  return AVERROR_EXTERNAL;
1113  }
1114 
1115  if (avctx->flags & AV_CODEC_FLAG_QSCALE && !vtenc_qscale_enabled()) {
1116  av_log(avctx, AV_LOG_ERROR, "Error: -q:v qscale not available for encoder. Use -b:v bitrate instead.\n");
1117  return AVERROR_EXTERNAL;
1118  }
1119 
1120  if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
1121  quality = quality >= 100 ? 1.0 : quality / 100;
1122  quality_num = CFNumberCreate(kCFAllocatorDefault,
1123  kCFNumberFloat32Type,
1124  &quality);
1125  if (!quality_num) return AVERROR(ENOMEM);
1126 
1127  status = VTSessionSetProperty(vtctx->session,
1128  kVTCompressionPropertyKey_Quality,
1129  quality_num);
1130  CFRelease(quality_num);
1131  } else if (avctx->codec_id != AV_CODEC_ID_PRORES) {
1132  bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
1133  kCFNumberSInt32Type,
1134  &bit_rate);
1135  if (!bit_rate_num) return AVERROR(ENOMEM);
1136 
1137  status = VTSessionSetProperty(vtctx->session,
1138  kVTCompressionPropertyKey_AverageBitRate,
1139  bit_rate_num);
1140  CFRelease(bit_rate_num);
1141  }
1142 
1143  if (status) {
1144  av_log(avctx, AV_LOG_ERROR, "Error setting bitrate property: %d\n", status);
1145  return AVERROR_EXTERNAL;
1146  }
1147 
1148  if ((vtctx->codec_id == AV_CODEC_ID_H264 || vtctx->codec_id == AV_CODEC_ID_HEVC)
1149  && max_rate > 0) {
1150  bytes_per_second_value = max_rate >> 3;
1151  bytes_per_second = CFNumberCreate(kCFAllocatorDefault,
1152  kCFNumberSInt64Type,
1153  &bytes_per_second_value);
1154  if (!bytes_per_second) {
1155  return AVERROR(ENOMEM);
1156  }
1157  one_second_value = 1;
1158  one_second = CFNumberCreate(kCFAllocatorDefault,
1159  kCFNumberSInt64Type,
1160  &one_second_value);
1161  if (!one_second) {
1162  CFRelease(bytes_per_second);
1163  return AVERROR(ENOMEM);
1164  }
1165  nums[0] = (void *)bytes_per_second;
1166  nums[1] = (void *)one_second;
1167  data_rate_limits = CFArrayCreate(kCFAllocatorDefault,
1168  (const void **)nums,
1169  2,
1170  &kCFTypeArrayCallBacks);
1171 
1172  if (!data_rate_limits) {
1173  CFRelease(bytes_per_second);
1174  CFRelease(one_second);
1175  return AVERROR(ENOMEM);
1176  }
1177  status = VTSessionSetProperty(vtctx->session,
1178  kVTCompressionPropertyKey_DataRateLimits,
1179  data_rate_limits);
1180 
1181  CFRelease(bytes_per_second);
1182  CFRelease(one_second);
1183  CFRelease(data_rate_limits);
1184 
1185  if (status) {
1186  av_log(avctx, AV_LOG_ERROR, "Error setting max bitrate property: %d\n", status);
1187  // kVTCompressionPropertyKey_DataRateLimits is available for HEVC
1188  // now but not on old release. There is no document about since
1189  // when. So ignore the error if it failed for hevc.
1190  if (vtctx->codec_id != AV_CODEC_ID_HEVC)
1191  return AVERROR_EXTERNAL;
1192  }
1193  }
1194 
1195  if (vtctx->codec_id == AV_CODEC_ID_HEVC) {
1196  if (avctx->pix_fmt == AV_PIX_FMT_BGRA && vtctx->alpha_quality > 0.0) {
1197  CFNumberRef alpha_quality_num = CFNumberCreate(kCFAllocatorDefault,
1198  kCFNumberDoubleType,
1199  &vtctx->alpha_quality);
1200  if (!alpha_quality_num) return AVERROR(ENOMEM);
1201 
1202  status = VTSessionSetProperty(vtctx->session,
1203  compat_keys.kVTCompressionPropertyKey_TargetQualityForAlpha,
1204  alpha_quality_num);
1205  CFRelease(alpha_quality_num);
1206  }
1207  }
1208 
1209  if (profile_level) {
1210  status = VTSessionSetProperty(vtctx->session,
1211  kVTCompressionPropertyKey_ProfileLevel,
1212  profile_level);
1213  if (status) {
1214  av_log(avctx, AV_LOG_ERROR, "Error setting profile/level property: %d. Output will be encoded using a supported profile/level combination.\n", status);
1215  }
1216  }
1217 
1218  if (avctx->gop_size > 0 && avctx->codec_id != AV_CODEC_ID_PRORES) {
1219  CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
1220  kCFNumberIntType,
1221  &avctx->gop_size);
1222  if (!interval) {
1223  return AVERROR(ENOMEM);
1224  }
1225 
1226  status = VTSessionSetProperty(vtctx->session,
1227  kVTCompressionPropertyKey_MaxKeyFrameInterval,
1228  interval);
1229  CFRelease(interval);
1230 
1231  if (status) {
1232  av_log(avctx, AV_LOG_ERROR, "Error setting 'max key-frame interval' property: %d\n", status);
1233  return AVERROR_EXTERNAL;
1234  }
1235  }
1236 
1237  if (vtctx->frames_before) {
1238  status = VTSessionSetProperty(vtctx->session,
1239  kVTCompressionPropertyKey_MoreFramesBeforeStart,
1240  kCFBooleanTrue);
1241 
1242  if (status == kVTPropertyNotSupportedErr) {
1243  av_log(avctx, AV_LOG_WARNING, "frames_before property is not supported on this device. Ignoring.\n");
1244  } else if (status) {
1245  av_log(avctx, AV_LOG_ERROR, "Error setting frames_before property: %d\n", status);
1246  }
1247  }
1248 
1249  if (vtctx->frames_after) {
1250  status = VTSessionSetProperty(vtctx->session,
1251  kVTCompressionPropertyKey_MoreFramesAfterEnd,
1252  kCFBooleanTrue);
1253 
1254  if (status == kVTPropertyNotSupportedErr) {
1255  av_log(avctx, AV_LOG_WARNING, "frames_after property is not supported on this device. Ignoring.\n");
1256  } else if (status) {
1257  av_log(avctx, AV_LOG_ERROR, "Error setting frames_after property: %d\n", status);
1258  }
1259  }
1260 
1261  if (avctx->sample_aspect_ratio.num != 0) {
1262  CFNumberRef num;
1263  CFNumberRef den;
1264  CFMutableDictionaryRef par;
1265  AVRational *avpar = &avctx->sample_aspect_ratio;
1266 
1267  av_reduce(&avpar->num, &avpar->den,
1268  avpar->num, avpar->den,
1269  0xFFFFFFFF);
1270 
1271  num = CFNumberCreate(kCFAllocatorDefault,
1272  kCFNumberIntType,
1273  &avpar->num);
1274 
1275  den = CFNumberCreate(kCFAllocatorDefault,
1276  kCFNumberIntType,
1277  &avpar->den);
1278 
1279 
1280 
1281  par = CFDictionaryCreateMutable(kCFAllocatorDefault,
1282  2,
1283  &kCFCopyStringDictionaryKeyCallBacks,
1284  &kCFTypeDictionaryValueCallBacks);
1285 
1286  if (!par || !num || !den) {
1287  if (par) CFRelease(par);
1288  if (num) CFRelease(num);
1289  if (den) CFRelease(den);
1290 
1291  return AVERROR(ENOMEM);
1292  }
1293 
1294  CFDictionarySetValue(
1295  par,
1296  kCMFormatDescriptionKey_PixelAspectRatioHorizontalSpacing,
1297  num);
1298 
1299  CFDictionarySetValue(
1300  par,
1301  kCMFormatDescriptionKey_PixelAspectRatioVerticalSpacing,
1302  den);
1303 
1304  status = VTSessionSetProperty(vtctx->session,
1305  kVTCompressionPropertyKey_PixelAspectRatio,
1306  par);
1307 
1308  CFRelease(par);
1309  CFRelease(num);
1310  CFRelease(den);
1311 
1312  if (status) {
1313  av_log(avctx,
1314  AV_LOG_ERROR,
1315  "Error setting pixel aspect ratio to %d:%d: %d.\n",
1316  avctx->sample_aspect_ratio.num,
1317  avctx->sample_aspect_ratio.den,
1318  status);
1319 
1320  return AVERROR_EXTERNAL;
1321  }
1322  }
1323 
1324 
1325  if (vtctx->transfer_function) {
1326  status = VTSessionSetProperty(vtctx->session,
1327  kVTCompressionPropertyKey_TransferFunction,
1328  vtctx->transfer_function);
1329 
1330  if (status) {
1331  av_log(avctx, AV_LOG_WARNING, "Could not set transfer function: %d\n", status);
1332  }
1333  }
1334 
1335 
1336  if (vtctx->ycbcr_matrix) {
1337  status = VTSessionSetProperty(vtctx->session,
1338  kVTCompressionPropertyKey_YCbCrMatrix,
1339  vtctx->ycbcr_matrix);
1340 
1341  if (status) {
1342  av_log(avctx, AV_LOG_WARNING, "Could not set ycbcr matrix: %d\n", status);
1343  }
1344  }
1345 
1346 
1347  if (vtctx->color_primaries) {
1348  status = VTSessionSetProperty(vtctx->session,
1349  kVTCompressionPropertyKey_ColorPrimaries,
1350  vtctx->color_primaries);
1351 
1352  if (status) {
1353  av_log(avctx, AV_LOG_WARNING, "Could not set color primaries: %d\n", status);
1354  }
1355  }
1356 
1357  if (gamma_level) {
1358  status = VTSessionSetProperty(vtctx->session,
1359  kCVImageBufferGammaLevelKey,
1360  gamma_level);
1361 
1362  if (status) {
1363  av_log(avctx, AV_LOG_WARNING, "Could not set gamma level: %d\n", status);
1364  }
1365  }
1366 
1367  if (!vtctx->has_b_frames && avctx->codec_id != AV_CODEC_ID_PRORES) {
1368  status = VTSessionSetProperty(vtctx->session,
1369  kVTCompressionPropertyKey_AllowFrameReordering,
1370  kCFBooleanFalse);
1371 
1372  if (status) {
1373  av_log(avctx, AV_LOG_ERROR, "Error setting 'allow frame reordering' property: %d\n", status);
1374  return AVERROR_EXTERNAL;
1375  }
1376  }
1377 
1378  if (vtctx->entropy != VT_ENTROPY_NOT_SET) {
1379  CFStringRef entropy = vtctx->entropy == VT_CABAC ?
1380  compat_keys.kVTH264EntropyMode_CABAC:
1381  compat_keys.kVTH264EntropyMode_CAVLC;
1382 
1383  status = VTSessionSetProperty(vtctx->session,
1384  compat_keys.kVTCompressionPropertyKey_H264EntropyMode,
1385  entropy);
1386 
1387  if (status) {
1388  av_log(avctx, AV_LOG_ERROR, "Error setting entropy property: %d\n", status);
1389  }
1390  }
1391 
1392  if (vtctx->realtime >= 0) {
1393  status = VTSessionSetProperty(vtctx->session,
1394  compat_keys.kVTCompressionPropertyKey_RealTime,
1395  vtctx->realtime ? kCFBooleanTrue : kCFBooleanFalse);
1396 
1397  if (status) {
1398  av_log(avctx, AV_LOG_ERROR, "Error setting realtime property: %d\n", status);
1399  }
1400  }
1401 
1402  status = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
1403  if (status) {
1404  av_log(avctx, AV_LOG_ERROR, "Error: cannot prepare encoder: %d\n", status);
1405  return AVERROR_EXTERNAL;
1406  }
1407 
1408  return 0;
1409 }
1410 
1412 {
1413  CFMutableDictionaryRef enc_info;
1414  CFMutableDictionaryRef pixel_buffer_info;
1415  CMVideoCodecType codec_type;
1416  VTEncContext *vtctx = avctx->priv_data;
1417  CFStringRef profile_level = NULL;
1418  CFNumberRef gamma_level = NULL;
1419  int status;
1420 
1421  codec_type = get_cm_codec_type(avctx, vtctx->profile, vtctx->alpha_quality);
1422  if (!codec_type) {
1423  av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id);
1424  return AVERROR(EINVAL);
1425  }
1426 
1427 #if defined(MAC_OS_X_VERSION_10_9) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9)
1428  if (avctx->codec_id == AV_CODEC_ID_PRORES) {
1429  if (__builtin_available(macOS 10.10, *)) {
1430  VTRegisterProfessionalVideoWorkflowVideoEncoders();
1431  }
1432  }
1433 #endif
1434 
1435  vtctx->codec_id = avctx->codec_id;
1436 
1437  if (vtctx->codec_id == AV_CODEC_ID_H264) {
1438  vtctx->get_param_set_func = CMVideoFormatDescriptionGetH264ParameterSetAtIndex;
1439 
1440  vtctx->has_b_frames = avctx->max_b_frames > 0;
1441  if(vtctx->has_b_frames && vtctx->profile == H264_PROF_BASELINE){
1442  av_log(avctx, AV_LOG_WARNING, "Cannot use B-frames with baseline profile. Output will not contain B-frames.\n");
1443  vtctx->has_b_frames = 0;
1444  }
1445 
1446  if (vtctx->entropy == VT_CABAC && vtctx->profile == H264_PROF_BASELINE) {
1447  av_log(avctx, AV_LOG_WARNING, "CABAC entropy requires 'main' or 'high' profile, but baseline was requested. Encode will not use CABAC entropy.\n");
1448  vtctx->entropy = VT_ENTROPY_NOT_SET;
1449  }
1450 
1451  if (!get_vt_h264_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1452  } else if (vtctx->codec_id == AV_CODEC_ID_HEVC) {
1453  vtctx->get_param_set_func = compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex;
1454  if (!vtctx->get_param_set_func) return AVERROR(EINVAL);
1455  if (!get_vt_hevc_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1456  // HEVC has b-byramid
1457  vtctx->has_b_frames = avctx->max_b_frames > 0 ? 2 : 0;
1458  } else if (vtctx->codec_id == AV_CODEC_ID_PRORES) {
1459  avctx->codec_tag = av_bswap32(codec_type);
1460  }
1461 
1462  enc_info = CFDictionaryCreateMutable(
1463  kCFAllocatorDefault,
1464  20,
1465  &kCFCopyStringDictionaryKeyCallBacks,
1466  &kCFTypeDictionaryValueCallBacks
1467  );
1468 
1469  if (!enc_info) return AVERROR(ENOMEM);
1470 
1471 #if !TARGET_OS_IPHONE
1472  if(vtctx->require_sw) {
1473  CFDictionarySetValue(enc_info,
1474  compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1475  kCFBooleanFalse);
1476  } else if (!vtctx->allow_sw) {
1477  CFDictionarySetValue(enc_info,
1478  compat_keys.kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder,
1479  kCFBooleanTrue);
1480  } else {
1481  CFDictionarySetValue(enc_info,
1482  compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1483  kCFBooleanTrue);
1484  }
1485 #endif
1486 
1487  if (avctx->pix_fmt != AV_PIX_FMT_VIDEOTOOLBOX) {
1488  status = create_cv_pixel_buffer_info(avctx, &pixel_buffer_info);
1489  if (status)
1490  goto init_cleanup;
1491  } else {
1492  pixel_buffer_info = NULL;
1493  }
1494 
1495  vtctx->dts_delta = vtctx->has_b_frames ? -1 : 0;
1496 
1497  get_cv_transfer_function(avctx, &vtctx->transfer_function, &gamma_level);
1498  get_cv_ycbcr_matrix(avctx, &vtctx->ycbcr_matrix);
1499  get_cv_color_primaries(avctx, &vtctx->color_primaries);
1500 
1501 
1502  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1504  codec_type,
1505  profile_level,
1506  gamma_level,
1507  enc_info,
1508  pixel_buffer_info);
1509  if (status)
1510  goto init_cleanup;
1511  }
1512 
1513  status = vtenc_create_encoder(avctx,
1514  codec_type,
1515  profile_level,
1516  gamma_level,
1517  enc_info,
1518  pixel_buffer_info,
1519  &vtctx->session);
1520 
1521 init_cleanup:
1522  if (gamma_level)
1523  CFRelease(gamma_level);
1524 
1525  if (pixel_buffer_info)
1526  CFRelease(pixel_buffer_info);
1527 
1528  CFRelease(enc_info);
1529 
1530  return status;
1531 }
1532 
1534 {
1535  VTEncContext *vtctx = avctx->priv_data;
1536  CFBooleanRef has_b_frames_cfbool;
1537  int status;
1538 
1540 
1541  pthread_mutex_init(&vtctx->lock, NULL);
1543 
1544  vtctx->session = NULL;
1546  if (status) return status;
1547 
1548  status = VTSessionCopyProperty(vtctx->session,
1549  kVTCompressionPropertyKey_AllowFrameReordering,
1550  kCFAllocatorDefault,
1551  &has_b_frames_cfbool);
1552 
1553  if (!status && has_b_frames_cfbool) {
1554  //Some devices don't output B-frames for main profile, even if requested.
1555  // HEVC has b-pyramid
1556  if (CFBooleanGetValue(has_b_frames_cfbool))
1557  vtctx->has_b_frames = avctx->codec_id == AV_CODEC_ID_HEVC ? 2 : 1;
1558  else
1559  vtctx->has_b_frames = 0;
1560  CFRelease(has_b_frames_cfbool);
1561  }
1562  avctx->has_b_frames = vtctx->has_b_frames;
1563 
1564  return 0;
1565 }
1566 
1567 static void vtenc_get_frame_info(CMSampleBufferRef buffer, bool *is_key_frame)
1568 {
1569  CFArrayRef attachments;
1570  CFDictionaryRef attachment;
1571  CFBooleanRef not_sync;
1572  CFIndex len;
1573 
1574  attachments = CMSampleBufferGetSampleAttachmentsArray(buffer, false);
1575  len = !attachments ? 0 : CFArrayGetCount(attachments);
1576 
1577  if (!len) {
1578  *is_key_frame = true;
1579  return;
1580  }
1581 
1582  attachment = CFArrayGetValueAtIndex(attachments, 0);
1583 
1584  if (CFDictionaryGetValueIfPresent(attachment,
1585  kCMSampleAttachmentKey_NotSync,
1586  (const void **)&not_sync))
1587  {
1588  *is_key_frame = !CFBooleanGetValue(not_sync);
1589  } else {
1590  *is_key_frame = true;
1591  }
1592 }
1593 
1594 static int is_post_sei_nal_type(int nal_type){
1595  return nal_type != H264_NAL_SEI &&
1596  nal_type != H264_NAL_SPS &&
1597  nal_type != H264_NAL_PPS &&
1598  nal_type != H264_NAL_AUD;
1599 }
1600 
1601 /*
1602  * Finds the sei message start/size of type find_sei_type.
1603  * If more than one of that type exists, the last one is returned.
1604  */
1605 static int find_sei_end(AVCodecContext *avctx,
1606  uint8_t *nal_data,
1607  size_t nal_size,
1608  uint8_t **sei_end)
1609 {
1610  int nal_type;
1611  size_t sei_payload_size = 0;
1612  int sei_payload_type = 0;
1613  *sei_end = NULL;
1614  uint8_t *nal_start = nal_data;
1615 
1616  if (!nal_size)
1617  return 0;
1618 
1619  nal_type = *nal_data & 0x1F;
1620  if (nal_type != H264_NAL_SEI)
1621  return 0;
1622 
1623  nal_data++;
1624  nal_size--;
1625 
1626  if (nal_data[nal_size - 1] == 0x80)
1627  nal_size--;
1628 
1629  while (nal_size > 0 && *nal_data > 0) {
1630  do{
1631  sei_payload_type += *nal_data;
1632  nal_data++;
1633  nal_size--;
1634  } while (nal_size > 0 && *nal_data == 0xFF);
1635 
1636  if (!nal_size) {
1637  av_log(avctx, AV_LOG_ERROR, "Unexpected end of SEI NAL Unit parsing type.\n");
1638  return AVERROR_INVALIDDATA;
1639  }
1640 
1641  do{
1642  sei_payload_size += *nal_data;
1643  nal_data++;
1644  nal_size--;
1645  } while (nal_size > 0 && *nal_data == 0xFF);
1646 
1647  if (nal_size < sei_payload_size) {
1648  av_log(avctx, AV_LOG_ERROR, "Unexpected end of SEI NAL Unit parsing size.\n");
1649  return AVERROR_INVALIDDATA;
1650  }
1651 
1652  nal_data += sei_payload_size;
1653  nal_size -= sei_payload_size;
1654  }
1655 
1656  *sei_end = nal_data;
1657 
1658  return nal_data - nal_start + 1;
1659 }
1660 
1661 /**
1662  * Copies the data inserting emulation prevention bytes as needed.
1663  * Existing data in the destination can be taken into account by providing
1664  * dst with a dst_offset > 0.
1665  *
1666  * @return The number of bytes copied on success. On failure, the negative of
1667  * the number of bytes needed to copy src is returned.
1668  */
1669 static int copy_emulation_prev(const uint8_t *src,
1670  size_t src_size,
1671  uint8_t *dst,
1672  ssize_t dst_offset,
1673  size_t dst_size)
1674 {
1675  int zeros = 0;
1676  int wrote_bytes;
1677  uint8_t* dst_start;
1678  uint8_t* dst_end = dst + dst_size;
1679  const uint8_t* src_end = src + src_size;
1680  int start_at = dst_offset > 2 ? dst_offset - 2 : 0;
1681  int i;
1682  for (i = start_at; i < dst_offset && i < dst_size; i++) {
1683  if (!dst[i])
1684  zeros++;
1685  else
1686  zeros = 0;
1687  }
1688 
1689  dst += dst_offset;
1690  dst_start = dst;
1691  for (; src < src_end; src++, dst++) {
1692  if (zeros == 2) {
1693  int insert_ep3_byte = *src <= 3;
1694  if (insert_ep3_byte) {
1695  if (dst < dst_end)
1696  *dst = 3;
1697  dst++;
1698  }
1699 
1700  zeros = 0;
1701  }
1702 
1703  if (dst < dst_end)
1704  *dst = *src;
1705 
1706  if (!*src)
1707  zeros++;
1708  else
1709  zeros = 0;
1710  }
1711 
1712  wrote_bytes = dst - dst_start;
1713 
1714  if (dst > dst_end)
1715  return -wrote_bytes;
1716 
1717  return wrote_bytes;
1718 }
1719 
1720 static int write_sei(const ExtraSEI *sei,
1721  int sei_type,
1722  uint8_t *dst,
1723  size_t dst_size)
1724 {
1725  uint8_t *sei_start = dst;
1726  size_t remaining_sei_size = sei->size;
1727  size_t remaining_dst_size = dst_size;
1728  int header_bytes;
1729  int bytes_written;
1730  ssize_t offset;
1731 
1732  if (!remaining_dst_size)
1733  return AVERROR_BUFFER_TOO_SMALL;
1734 
1735  while (sei_type && remaining_dst_size != 0) {
1736  int sei_byte = sei_type > 255 ? 255 : sei_type;
1737  *dst = sei_byte;
1738 
1739  sei_type -= sei_byte;
1740  dst++;
1741  remaining_dst_size--;
1742  }
1743 
1744  if (!dst_size)
1745  return AVERROR_BUFFER_TOO_SMALL;
1746 
1747  while (remaining_sei_size && remaining_dst_size != 0) {
1748  int size_byte = remaining_sei_size > 255 ? 255 : remaining_sei_size;
1749  *dst = size_byte;
1750 
1751  remaining_sei_size -= size_byte;
1752  dst++;
1753  remaining_dst_size--;
1754  }
1755 
1756  if (remaining_dst_size < sei->size)
1757  return AVERROR_BUFFER_TOO_SMALL;
1758 
1759  header_bytes = dst - sei_start;
1760 
1761  offset = header_bytes;
1762  bytes_written = copy_emulation_prev(sei->data,
1763  sei->size,
1764  sei_start,
1765  offset,
1766  dst_size);
1767  if (bytes_written < 0)
1768  return AVERROR_BUFFER_TOO_SMALL;
1769 
1770  bytes_written += header_bytes;
1771  return bytes_written;
1772 }
1773 
1774 /**
1775  * Copies NAL units and replaces length codes with
1776  * H.264 Annex B start codes. On failure, the contents of
1777  * dst_data may have been modified.
1778  *
1779  * @param length_code_size Byte length of each length code
1780  * @param sample_buffer NAL units prefixed with length codes.
1781  * @param sei Optional A53 closed captions SEI data.
1782  * @param dst_data Must be zeroed before calling this function.
1783  * Contains the copied NAL units prefixed with
1784  * start codes when the function returns
1785  * successfully.
1786  * @param dst_size Length of dst_data
1787  * @return 0 on success
1788  * AVERROR_INVALIDDATA if length_code_size is invalid
1789  * AVERROR_BUFFER_TOO_SMALL if dst_data is too small
1790  * or if a length_code in src_data specifies data beyond
1791  * the end of its buffer.
1792  */
1794  AVCodecContext *avctx,
1795  size_t length_code_size,
1796  CMSampleBufferRef sample_buffer,
1797  ExtraSEI *sei,
1798  uint8_t *dst_data,
1799  size_t dst_size)
1800 {
1801  size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
1802  size_t remaining_src_size = src_size;
1803  size_t remaining_dst_size = dst_size;
1804  size_t src_offset = 0;
1805  int wrote_sei = 0;
1806  int status;
1807  uint8_t size_buf[4];
1808  uint8_t nal_type;
1809  CMBlockBufferRef block = CMSampleBufferGetDataBuffer(sample_buffer);
1810 
1811  if (length_code_size > 4) {
1812  return AVERROR_INVALIDDATA;
1813  }
1814 
1815  while (remaining_src_size > 0) {
1816  size_t curr_src_len;
1817  size_t curr_dst_len;
1818  size_t box_len = 0;
1819  size_t i;
1820 
1821  uint8_t *dst_box;
1822 
1823  status = CMBlockBufferCopyDataBytes(block,
1824  src_offset,
1825  length_code_size,
1826  size_buf);
1827  if (status) {
1828  av_log(avctx, AV_LOG_ERROR, "Cannot copy length: %d\n", status);
1829  return AVERROR_EXTERNAL;
1830  }
1831 
1832  status = CMBlockBufferCopyDataBytes(block,
1833  src_offset + length_code_size,
1834  1,
1835  &nal_type);
1836 
1837  if (status) {
1838  av_log(avctx, AV_LOG_ERROR, "Cannot copy type: %d\n", status);
1839  return AVERROR_EXTERNAL;
1840  }
1841 
1842  nal_type &= 0x1F;
1843 
1844  for (i = 0; i < length_code_size; i++) {
1845  box_len <<= 8;
1846  box_len |= size_buf[i];
1847  }
1848 
1849  if (sei && !wrote_sei && is_post_sei_nal_type(nal_type)) {
1850  //No SEI NAL unit - insert.
1851  int wrote_bytes;
1852 
1853  memcpy(dst_data, start_code, sizeof(start_code));
1854  dst_data += sizeof(start_code);
1855  remaining_dst_size -= sizeof(start_code);
1856 
1857  *dst_data = H264_NAL_SEI;
1858  dst_data++;
1859  remaining_dst_size--;
1860 
1861  wrote_bytes = write_sei(sei,
1863  dst_data,
1864  remaining_dst_size);
1865 
1866  if (wrote_bytes < 0)
1867  return wrote_bytes;
1868 
1869  remaining_dst_size -= wrote_bytes;
1870  dst_data += wrote_bytes;
1871 
1872  if (remaining_dst_size <= 0)
1873  return AVERROR_BUFFER_TOO_SMALL;
1874 
1875  *dst_data = 0x80;
1876 
1877  dst_data++;
1878  remaining_dst_size--;
1879 
1880  wrote_sei = 1;
1881  }
1882 
1883  curr_src_len = box_len + length_code_size;
1884  curr_dst_len = box_len + sizeof(start_code);
1885 
1886  if (remaining_src_size < curr_src_len) {
1887  return AVERROR_BUFFER_TOO_SMALL;
1888  }
1889 
1890  if (remaining_dst_size < curr_dst_len) {
1891  return AVERROR_BUFFER_TOO_SMALL;
1892  }
1893 
1894  dst_box = dst_data + sizeof(start_code);
1895 
1896  memcpy(dst_data, start_code, sizeof(start_code));
1897  status = CMBlockBufferCopyDataBytes(block,
1898  src_offset + length_code_size,
1899  box_len,
1900  dst_box);
1901 
1902  if (status) {
1903  av_log(avctx, AV_LOG_ERROR, "Cannot copy data: %d\n", status);
1904  return AVERROR_EXTERNAL;
1905  }
1906 
1907  if (sei && !wrote_sei && nal_type == H264_NAL_SEI) {
1908  //Found SEI NAL unit - append.
1909  int wrote_bytes;
1910  int old_sei_length;
1911  int extra_bytes;
1912  uint8_t *new_sei;
1913  old_sei_length = find_sei_end(avctx, dst_box, box_len, &new_sei);
1914  if (old_sei_length < 0)
1915  return status;
1916 
1917  wrote_bytes = write_sei(sei,
1919  new_sei,
1920  remaining_dst_size - old_sei_length);
1921  if (wrote_bytes < 0)
1922  return wrote_bytes;
1923 
1924  if (new_sei + wrote_bytes >= dst_data + remaining_dst_size)
1925  return AVERROR_BUFFER_TOO_SMALL;
1926 
1927  new_sei[wrote_bytes++] = 0x80;
1928  extra_bytes = wrote_bytes - (dst_box + box_len - new_sei);
1929 
1930  dst_data += extra_bytes;
1931  remaining_dst_size -= extra_bytes;
1932 
1933  wrote_sei = 1;
1934  }
1935 
1936  src_offset += curr_src_len;
1937  dst_data += curr_dst_len;
1938 
1939  remaining_src_size -= curr_src_len;
1940  remaining_dst_size -= curr_dst_len;
1941  }
1942 
1943  return 0;
1944 }
1945 
1946 /**
1947  * Returns a sufficient number of bytes to contain the sei data.
1948  * It may be greater than the minimum required.
1949  */
1950 static int get_sei_msg_bytes(const ExtraSEI* sei, int type){
1951  int copied_size;
1952  if (sei->size == 0)
1953  return 0;
1954 
1955  copied_size = -copy_emulation_prev(sei->data,
1956  sei->size,
1957  NULL,
1958  0,
1959  0);
1960 
1961  if ((sei->size % 255) == 0) //may result in an extra byte
1962  copied_size++;
1963 
1964  return copied_size + sei->size / 255 + 1 + type / 255 + 1;
1965 }
1966 
1968  AVCodecContext *avctx,
1969  CMSampleBufferRef sample_buffer,
1970  AVPacket *pkt,
1971  ExtraSEI *sei)
1972 {
1973  VTEncContext *vtctx = avctx->priv_data;
1974 
1975  int status;
1976  bool is_key_frame;
1977  bool add_header;
1978  size_t length_code_size;
1979  size_t header_size = 0;
1980  size_t in_buf_size;
1981  size_t out_buf_size;
1982  size_t sei_nalu_size = 0;
1983  int64_t dts_delta;
1984  int64_t time_base_num;
1985  int nalu_count;
1986  CMTime pts;
1987  CMTime dts;
1988  CMVideoFormatDescriptionRef vid_fmt;
1989 
1990  vtenc_get_frame_info(sample_buffer, &is_key_frame);
1991 
1992  if (vtctx->get_param_set_func) {
1993  status = get_length_code_size(avctx, sample_buffer, &length_code_size);
1994  if (status) return status;
1995 
1996  add_header = is_key_frame && !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER);
1997 
1998  if (add_header) {
1999  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
2000  if (!vid_fmt) {
2001  av_log(avctx, AV_LOG_ERROR, "Cannot get format description.\n");
2002  return AVERROR_EXTERNAL;
2003  }
2004 
2005  int status = get_params_size(avctx, vid_fmt, &header_size);
2006  if (status) return status;
2007  }
2008 
2009  status = count_nalus(length_code_size, sample_buffer, &nalu_count);
2010  if(status)
2011  return status;
2012 
2013  if (sei) {
2014  size_t msg_size = get_sei_msg_bytes(sei,
2016 
2017  sei_nalu_size = sizeof(start_code) + 1 + msg_size + 1;
2018  }
2019 
2020  in_buf_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
2021  out_buf_size = header_size +
2022  in_buf_size +
2023  sei_nalu_size +
2024  nalu_count * ((int)sizeof(start_code) - (int)length_code_size);
2025 
2026  status = ff_get_encode_buffer(avctx, pkt, out_buf_size, 0);
2027  if (status < 0)
2028  return status;
2029 
2030  if (add_header) {
2031  status = copy_param_sets(avctx, vid_fmt, pkt->data, out_buf_size);
2032  if(status) return status;
2033  }
2034 
2036  avctx,
2037  length_code_size,
2038  sample_buffer,
2039  sei,
2040  pkt->data + header_size,
2041  pkt->size - header_size
2042  );
2043 
2044  if (status) {
2045  av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status);
2046  return status;
2047  }
2048  } else {
2049  size_t len;
2050  CMBlockBufferRef buf = CMSampleBufferGetDataBuffer(sample_buffer);
2051  if (!buf) {
2052  av_log(avctx, AV_LOG_ERROR, "Error getting block buffer\n");
2053  return AVERROR_EXTERNAL;
2054  }
2055 
2056  len = CMBlockBufferGetDataLength(buf);
2057 
2058  status = ff_get_encode_buffer(avctx, pkt, len, 0);
2059  if (status < 0)
2060  return status;
2061 
2062  status = CMBlockBufferCopyDataBytes(buf, 0, len, pkt->data);
2063  if (status) {
2064  av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status);
2065  return AVERROR_EXTERNAL;
2066  }
2067  }
2068 
2069  if (is_key_frame) {
2071  }
2072 
2073  pts = CMSampleBufferGetPresentationTimeStamp(sample_buffer);
2074  dts = CMSampleBufferGetDecodeTimeStamp (sample_buffer);
2075 
2076  if (CMTIME_IS_INVALID(dts)) {
2077  if (!vtctx->has_b_frames) {
2078  dts = pts;
2079  } else {
2080  av_log(avctx, AV_LOG_ERROR, "DTS is invalid.\n");
2081  return AVERROR_EXTERNAL;
2082  }
2083  }
2084 
2085  dts_delta = vtctx->dts_delta >= 0 ? vtctx->dts_delta : 0;
2086  time_base_num = avctx->time_base.num;
2087  pkt->pts = pts.value / time_base_num;
2088  pkt->dts = dts.value / time_base_num - dts_delta;
2089 
2090  return 0;
2091 }
2092 
2093 /*
2094  * contiguous_buf_size is 0 if not contiguous, and the size of the buffer
2095  * containing all planes if so.
2096  */
2098  AVCodecContext *avctx,
2099  const AVFrame *frame,
2100  int *color,
2101  int *plane_count,
2102  size_t *widths,
2103  size_t *heights,
2104  size_t *strides,
2105  size_t *contiguous_buf_size)
2106 {
2108  VTEncContext *vtctx = avctx->priv_data;
2109  int av_format = frame->format;
2110  int av_color_range = frame->color_range;
2111  int i;
2112  int range_guessed;
2113  int status;
2114 
2115  if (!desc)
2116  return AVERROR(EINVAL);
2117 
2118  status = get_cv_pixel_format(avctx, av_format, av_color_range, color, &range_guessed);
2119  if (status) {
2120  av_log(avctx,
2121  AV_LOG_ERROR,
2122  "Could not get pixel format for color format '%s' range '%s'.\n",
2123  av_get_pix_fmt_name(av_format),
2124  av_color_range > AVCOL_RANGE_UNSPECIFIED &&
2125  av_color_range < AVCOL_RANGE_NB ?
2126  av_color_range_name(av_color_range) :
2127  "Unknown");
2128 
2129  return AVERROR(EINVAL);
2130  }
2131 
2132  if (range_guessed) {
2133  if (!vtctx->warned_color_range) {
2134  vtctx->warned_color_range = true;
2135  av_log(avctx,
2137  "Color range not set for %s. Using MPEG range.\n",
2138  av_get_pix_fmt_name(av_format));
2139  }
2140  }
2141 
2142  *plane_count = av_pix_fmt_count_planes(avctx->pix_fmt);
2143 
2144  for (i = 0; i < desc->nb_components; i++) {
2145  int p = desc->comp[i].plane;
2146  bool hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA);
2147  bool isAlpha = hasAlpha && (p + 1 == *plane_count);
2148  bool isChroma = (p != 0) && !isAlpha;
2149  int shiftw = isChroma ? desc->log2_chroma_w : 0;
2150  int shifth = isChroma ? desc->log2_chroma_h : 0;
2151  widths[p] = (avctx->width + ((1 << shiftw) >> 1)) >> shiftw;
2152  heights[p] = (avctx->height + ((1 << shifth) >> 1)) >> shifth;
2153  strides[p] = frame->linesize[p];
2154  }
2155 
2156  *contiguous_buf_size = 0;
2157  for (i = 0; i < *plane_count; i++) {
2158  if (i < *plane_count - 1 &&
2159  frame->data[i] + strides[i] * heights[i] != frame->data[i + 1]) {
2160  *contiguous_buf_size = 0;
2161  break;
2162  }
2163 
2164  *contiguous_buf_size += strides[i] * heights[i];
2165  }
2166 
2167  return 0;
2168 }
2169 
2170 //Not used on OSX - frame is never copied.
2172  const AVFrame *frame,
2173  CVPixelBufferRef cv_img,
2174  const size_t *plane_strides,
2175  const size_t *plane_rows)
2176 {
2177  int i, j;
2178  size_t plane_count;
2179  int status;
2180  int rows;
2181  int src_stride;
2182  int dst_stride;
2183  uint8_t *src_addr;
2184  uint8_t *dst_addr;
2185  size_t copy_bytes;
2186 
2187  status = CVPixelBufferLockBaseAddress(cv_img, 0);
2188  if (status) {
2189  av_log(
2190  avctx,
2191  AV_LOG_ERROR,
2192  "Error: Could not lock base address of CVPixelBuffer: %d.\n",
2193  status
2194  );
2195  }
2196 
2197  if (CVPixelBufferIsPlanar(cv_img)) {
2198  plane_count = CVPixelBufferGetPlaneCount(cv_img);
2199  for (i = 0; frame->data[i]; i++) {
2200  if (i == plane_count) {
2201  CVPixelBufferUnlockBaseAddress(cv_img, 0);
2202  av_log(avctx,
2203  AV_LOG_ERROR,
2204  "Error: different number of planes in AVFrame and CVPixelBuffer.\n"
2205  );
2206 
2207  return AVERROR_EXTERNAL;
2208  }
2209 
2210  dst_addr = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(cv_img, i);
2211  src_addr = (uint8_t*)frame->data[i];
2212  dst_stride = CVPixelBufferGetBytesPerRowOfPlane(cv_img, i);
2213  src_stride = plane_strides[i];
2214  rows = plane_rows[i];
2215 
2216  if (dst_stride == src_stride) {
2217  memcpy(dst_addr, src_addr, src_stride * rows);
2218  } else {
2219  copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
2220 
2221  for (j = 0; j < rows; j++) {
2222  memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
2223  }
2224  }
2225  }
2226  } else {
2227  if (frame->data[1]) {
2228  CVPixelBufferUnlockBaseAddress(cv_img, 0);
2229  av_log(avctx,
2230  AV_LOG_ERROR,
2231  "Error: different number of planes in AVFrame and non-planar CVPixelBuffer.\n"
2232  );
2233 
2234  return AVERROR_EXTERNAL;
2235  }
2236 
2237  dst_addr = (uint8_t*)CVPixelBufferGetBaseAddress(cv_img);
2238  src_addr = (uint8_t*)frame->data[0];
2239  dst_stride = CVPixelBufferGetBytesPerRow(cv_img);
2240  src_stride = plane_strides[0];
2241  rows = plane_rows[0];
2242 
2243  if (dst_stride == src_stride) {
2244  memcpy(dst_addr, src_addr, src_stride * rows);
2245  } else {
2246  copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
2247 
2248  for (j = 0; j < rows; j++) {
2249  memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
2250  }
2251  }
2252  }
2253 
2254  status = CVPixelBufferUnlockBaseAddress(cv_img, 0);
2255  if (status) {
2256  av_log(avctx, AV_LOG_ERROR, "Error: Could not unlock CVPixelBuffer base address: %d.\n", status);
2257  return AVERROR_EXTERNAL;
2258  }
2259 
2260  return 0;
2261 }
2262 
2264  const AVFrame *frame,
2265  CVPixelBufferRef *cv_img)
2266 {
2267  int plane_count;
2268  int color;
2269  size_t widths [AV_NUM_DATA_POINTERS];
2270  size_t heights[AV_NUM_DATA_POINTERS];
2271  size_t strides[AV_NUM_DATA_POINTERS];
2272  int status;
2273  size_t contiguous_buf_size;
2274  CVPixelBufferPoolRef pix_buf_pool;
2275  VTEncContext* vtctx = avctx->priv_data;
2276 
2277  if (avctx->pix_fmt == AV_PIX_FMT_VIDEOTOOLBOX) {
2279 
2280  *cv_img = (CVPixelBufferRef)frame->data[3];
2281  av_assert0(*cv_img);
2282 
2283  CFRetain(*cv_img);
2284  return 0;
2285  }
2286 
2287  memset(widths, 0, sizeof(widths));
2288  memset(heights, 0, sizeof(heights));
2289  memset(strides, 0, sizeof(strides));
2290 
2292  avctx,
2293  frame,
2294  &color,
2295  &plane_count,
2296  widths,
2297  heights,
2298  strides,
2299  &contiguous_buf_size
2300  );
2301 
2302  if (status) {
2303  av_log(
2304  avctx,
2305  AV_LOG_ERROR,
2306  "Error: Cannot convert format %d color_range %d: %d\n",
2307  frame->format,
2308  frame->color_range,
2309  status
2310  );
2311 
2312  return AVERROR_EXTERNAL;
2313  }
2314 
2315  pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2316  if (!pix_buf_pool) {
2317  /* On iOS, the VT session is invalidated when the APP switches from
2318  * foreground to background and vice versa. Fetch the actual error code
2319  * of the VT session to detect that case and restart the VT session
2320  * accordingly. */
2321  OSStatus vtstatus;
2322 
2323  vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
2324  if (vtstatus == kVTInvalidSessionErr) {
2325  CFRelease(vtctx->session);
2326  vtctx->session = NULL;
2328  if (status == 0)
2329  pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2330  }
2331  if (!pix_buf_pool) {
2332  av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer pool.\n");
2333  return AVERROR_EXTERNAL;
2334  }
2335  else
2336  av_log(avctx, AV_LOG_WARNING, "VT session restarted because of a "
2337  "kVTInvalidSessionErr error.\n");
2338  }
2339 
2340  status = CVPixelBufferPoolCreatePixelBuffer(NULL,
2341  pix_buf_pool,
2342  cv_img);
2343 
2344 
2345  if (status) {
2346  av_log(avctx, AV_LOG_ERROR, "Could not create pixel buffer from pool: %d.\n", status);
2347  return AVERROR_EXTERNAL;
2348  }
2349 
2350  status = copy_avframe_to_pixel_buffer(avctx, frame, *cv_img, strides, heights);
2351  if (status) {
2352  CFRelease(*cv_img);
2353  *cv_img = NULL;
2354  return status;
2355  }
2356 
2357  return 0;
2358 }
2359 
2361  CFDictionaryRef* dict_out)
2362 {
2363  CFDictionaryRef dict = NULL;
2364  if (frame->pict_type == AV_PICTURE_TYPE_I) {
2365  const void *keys[] = { kVTEncodeFrameOptionKey_ForceKeyFrame };
2366  const void *vals[] = { kCFBooleanTrue };
2367 
2368  dict = CFDictionaryCreate(NULL, keys, vals, 1, NULL, NULL);
2369  if(!dict) return AVERROR(ENOMEM);
2370  }
2371 
2372  *dict_out = dict;
2373  return 0;
2374 }
2375 
2377  VTEncContext *vtctx,
2378  const AVFrame *frame)
2379 {
2380  CMTime time;
2381  CFDictionaryRef frame_dict;
2382  CVPixelBufferRef cv_img = NULL;
2383  AVFrameSideData *side_data = NULL;
2384  ExtraSEI *sei = NULL;
2385  int status = create_cv_pixel_buffer(avctx, frame, &cv_img);
2386 
2387  if (status) return status;
2388 
2389  status = create_encoder_dict_h264(frame, &frame_dict);
2390  if (status) {
2391  CFRelease(cv_img);
2392  return status;
2393  }
2394 
2395 #if CONFIG_ATSC_A53
2397  if (vtctx->a53_cc && side_data && side_data->size) {
2398  sei = av_mallocz(sizeof(*sei));
2399  if (!sei) {
2400  av_log(avctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2401  } else {
2402  int ret = ff_alloc_a53_sei(frame, 0, &sei->data, &sei->size);
2403  if (ret < 0) {
2404  av_log(avctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2405  av_free(sei);
2406  sei = NULL;
2407  }
2408  }
2409  }
2410 #endif
2411 
2412  time = CMTimeMake(frame->pts * avctx->time_base.num, avctx->time_base.den);
2413  status = VTCompressionSessionEncodeFrame(
2414  vtctx->session,
2415  cv_img,
2416  time,
2417  kCMTimeInvalid,
2418  frame_dict,
2419  sei,
2420  NULL
2421  );
2422 
2423  if (frame_dict) CFRelease(frame_dict);
2424  CFRelease(cv_img);
2425 
2426  if (status) {
2427  av_log(avctx, AV_LOG_ERROR, "Error: cannot encode frame: %d\n", status);
2428  return AVERROR_EXTERNAL;
2429  }
2430 
2431  return 0;
2432 }
2433 
2435  AVCodecContext *avctx,
2436  AVPacket *pkt,
2437  const AVFrame *frame,
2438  int *got_packet)
2439 {
2440  VTEncContext *vtctx = avctx->priv_data;
2441  bool get_frame;
2442  int status;
2443  CMSampleBufferRef buf = NULL;
2444  ExtraSEI *sei = NULL;
2445 
2446  if (frame) {
2447  status = vtenc_send_frame(avctx, vtctx, frame);
2448 
2449  if (status) {
2451  goto end_nopkt;
2452  }
2453 
2454  if (vtctx->frame_ct_in == 0) {
2455  vtctx->first_pts = frame->pts;
2456  } else if(vtctx->frame_ct_in == vtctx->has_b_frames) {
2457  vtctx->dts_delta = frame->pts - vtctx->first_pts;
2458  }
2459 
2460  vtctx->frame_ct_in++;
2461  } else if(!vtctx->flushing) {
2462  vtctx->flushing = true;
2463 
2464  status = VTCompressionSessionCompleteFrames(vtctx->session,
2465  kCMTimeIndefinite);
2466 
2467  if (status) {
2468  av_log(avctx, AV_LOG_ERROR, "Error flushing frames: %d\n", status);
2470  goto end_nopkt;
2471  }
2472  }
2473 
2474  *got_packet = 0;
2475  get_frame = vtctx->dts_delta >= 0 || !frame;
2476  if (!get_frame) {
2477  status = 0;
2478  goto end_nopkt;
2479  }
2480 
2481  status = vtenc_q_pop(vtctx, !frame, &buf, &sei);
2482  if (status) goto end_nopkt;
2483  if (!buf) goto end_nopkt;
2484 
2485  status = vtenc_cm_to_avpacket(avctx, buf, pkt, sei);
2486  if (sei) {
2487  if (sei->data) av_free(sei->data);
2488  av_free(sei);
2489  }
2490  CFRelease(buf);
2491  if (status) goto end_nopkt;
2492 
2493  *got_packet = 1;
2494  return 0;
2495 
2496 end_nopkt:
2498  return status;
2499 }
2500 
2502  CMVideoCodecType codec_type,
2503  CFStringRef profile_level,
2504  CFNumberRef gamma_level,
2505  CFDictionaryRef enc_info,
2506  CFDictionaryRef pixel_buffer_info)
2507 {
2508  VTEncContext *vtctx = avctx->priv_data;
2509  int status;
2510  CVPixelBufferPoolRef pool = NULL;
2511  CVPixelBufferRef pix_buf = NULL;
2512  CMTime time;
2513  CMSampleBufferRef buf = NULL;
2514 
2515  status = vtenc_create_encoder(avctx,
2516  codec_type,
2517  profile_level,
2518  gamma_level,
2519  enc_info,
2520  pixel_buffer_info,
2521  &vtctx->session);
2522  if (status)
2523  goto pe_cleanup;
2524 
2525  pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2526  if(!pool){
2527  av_log(avctx, AV_LOG_ERROR, "Error getting pixel buffer pool.\n");
2528  goto pe_cleanup;
2529  }
2530 
2531  status = CVPixelBufferPoolCreatePixelBuffer(NULL,
2532  pool,
2533  &pix_buf);
2534 
2535  if(status != kCVReturnSuccess){
2536  av_log(avctx, AV_LOG_ERROR, "Error creating frame from pool: %d\n", status);
2537  goto pe_cleanup;
2538  }
2539 
2540  time = CMTimeMake(0, avctx->time_base.den);
2541  status = VTCompressionSessionEncodeFrame(vtctx->session,
2542  pix_buf,
2543  time,
2544  kCMTimeInvalid,
2545  NULL,
2546  NULL,
2547  NULL);
2548 
2549  if (status) {
2550  av_log(avctx,
2551  AV_LOG_ERROR,
2552  "Error sending frame for extradata: %d\n",
2553  status);
2554 
2555  goto pe_cleanup;
2556  }
2557 
2558  //Populates extradata - output frames are flushed and param sets are available.
2559  status = VTCompressionSessionCompleteFrames(vtctx->session,
2560  kCMTimeIndefinite);
2561 
2562  if (status)
2563  goto pe_cleanup;
2564 
2565  status = vtenc_q_pop(vtctx, 0, &buf, NULL);
2566  if (status) {
2567  av_log(avctx, AV_LOG_ERROR, "popping: %d\n", status);
2568  goto pe_cleanup;
2569  }
2570 
2571  CFRelease(buf);
2572 
2573 
2574 
2575 pe_cleanup:
2576  CVPixelBufferRelease(pix_buf);
2577  if(vtctx->session)
2578  CFRelease(vtctx->session);
2579 
2580  vtctx->session = NULL;
2581  vtctx->frame_ct_out = 0;
2582 
2583  av_assert0(status != 0 || (avctx->extradata && avctx->extradata_size > 0));
2584 
2585  return status;
2586 }
2587 
2589 {
2590  VTEncContext *vtctx = avctx->priv_data;
2591 
2592  if(!vtctx->session) {
2594  pthread_mutex_destroy(&vtctx->lock);
2595  return 0;
2596  }
2597 
2598  VTCompressionSessionCompleteFrames(vtctx->session,
2599  kCMTimeIndefinite);
2600  clear_frame_queue(vtctx);
2602  pthread_mutex_destroy(&vtctx->lock);
2603  CFRelease(vtctx->session);
2604  vtctx->session = NULL;
2605 
2606  if (vtctx->color_primaries) {
2607  CFRelease(vtctx->color_primaries);
2608  vtctx->color_primaries = NULL;
2609  }
2610 
2611  if (vtctx->transfer_function) {
2612  CFRelease(vtctx->transfer_function);
2613  vtctx->transfer_function = NULL;
2614  }
2615 
2616  if (vtctx->ycbcr_matrix) {
2617  CFRelease(vtctx->ycbcr_matrix);
2618  vtctx->ycbcr_matrix = NULL;
2619  }
2620 
2621  return 0;
2622 }
2623 
2624 static const enum AVPixelFormat avc_pix_fmts[] = {
2629 };
2630 
2631 static const enum AVPixelFormat hevc_pix_fmts[] = {
2638 };
2639 
2640 static const enum AVPixelFormat prores_pix_fmts[] = {
2643 #ifdef kCFCoreFoundationVersionNumber10_7
2646 #endif
2648 #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
2650 #endif
2651 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE
2653 #endif
2654 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE
2656 #endif
2657 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE
2659 #endif
2660 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE
2662 #endif
2663 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE
2665 #endif
2666 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE
2668 #endif
2671 };
2672 
2673 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
2674 #define COMMON_OPTIONS \
2675  { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \
2676  { .i64 = 0 }, 0, 1, VE }, \
2677  { "require_sw", "Require software encoding", OFFSET(require_sw), AV_OPT_TYPE_BOOL, \
2678  { .i64 = 0 }, 0, 1, VE }, \
2679  { "realtime", "Hint that encoding should happen in real-time if not faster (e.g. capturing from camera).", \
2680  OFFSET(realtime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, -1, 1, VE }, \
2681  { "frames_before", "Other frames will come before the frames in this session. This helps smooth concatenation issues.", \
2682  OFFSET(frames_before), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \
2683  { "frames_after", "Other frames will come after the frames in this session. This helps smooth concatenation issues.", \
2684  OFFSET(frames_after), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
2685 
2686 #define OFFSET(x) offsetof(VTEncContext, x)
2687 static const AVOption h264_options[] = {
2688  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = H264_PROF_AUTO }, H264_PROF_AUTO, H264_PROF_COUNT, VE, "profile" },
2689  { "baseline", "Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_BASELINE }, INT_MIN, INT_MAX, VE, "profile" },
2690  { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
2691  { "high", "High Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_HIGH }, INT_MIN, INT_MAX, VE, "profile" },
2692  { "extended", "Extend Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_EXTENDED }, INT_MIN, INT_MAX, VE, "profile" },
2693 
2694  { "level", "Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, VE, "level" },
2695  { "1.3", "Level 1.3, only available with Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = 13 }, INT_MIN, INT_MAX, VE, "level" },
2696  { "3.0", "Level 3.0", 0, AV_OPT_TYPE_CONST, { .i64 = 30 }, INT_MIN, INT_MAX, VE, "level" },
2697  { "3.1", "Level 3.1", 0, AV_OPT_TYPE_CONST, { .i64 = 31 }, INT_MIN, INT_MAX, VE, "level" },
2698  { "3.2", "Level 3.2", 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, INT_MIN, INT_MAX, VE, "level" },
2699  { "4.0", "Level 4.0", 0, AV_OPT_TYPE_CONST, { .i64 = 40 }, INT_MIN, INT_MAX, VE, "level" },
2700  { "4.1", "Level 4.1", 0, AV_OPT_TYPE_CONST, { .i64 = 41 }, INT_MIN, INT_MAX, VE, "level" },
2701  { "4.2", "Level 4.2", 0, AV_OPT_TYPE_CONST, { .i64 = 42 }, INT_MIN, INT_MAX, VE, "level" },
2702  { "5.0", "Level 5.0", 0, AV_OPT_TYPE_CONST, { .i64 = 50 }, INT_MIN, INT_MAX, VE, "level" },
2703  { "5.1", "Level 5.1", 0, AV_OPT_TYPE_CONST, { .i64 = 51 }, INT_MIN, INT_MAX, VE, "level" },
2704  { "5.2", "Level 5.2", 0, AV_OPT_TYPE_CONST, { .i64 = 52 }, INT_MIN, INT_MAX, VE, "level" },
2705 
2706  { "coder", "Entropy coding", OFFSET(entropy), AV_OPT_TYPE_INT, { .i64 = VT_ENTROPY_NOT_SET }, VT_ENTROPY_NOT_SET, VT_CABAC, VE, "coder" },
2707  { "cavlc", "CAVLC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CAVLC }, INT_MIN, INT_MAX, VE, "coder" },
2708  { "vlc", "CAVLC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CAVLC }, INT_MIN, INT_MAX, VE, "coder" },
2709  { "cabac", "CABAC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CABAC }, INT_MIN, INT_MAX, VE, "coder" },
2710  { "ac", "CABAC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CABAC }, INT_MIN, INT_MAX, VE, "coder" },
2711 
2712  { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, VE },
2713 
2715  { NULL },
2716 };
2717 
2719  .class_name = "h264_videotoolbox",
2720  .item_name = av_default_item_name,
2721  .option = h264_options,
2722  .version = LIBAVUTIL_VERSION_INT,
2723 };
2724 
2726  .name = "h264_videotoolbox",
2727  .long_name = NULL_IF_CONFIG_SMALL("VideoToolbox H.264 Encoder"),
2728  .type = AVMEDIA_TYPE_VIDEO,
2729  .id = AV_CODEC_ID_H264,
2730  .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
2731  .priv_data_size = sizeof(VTEncContext),
2733  .init = vtenc_init,
2734  .encode2 = vtenc_frame,
2735  .close = vtenc_close,
2736  .priv_class = &h264_videotoolbox_class,
2737  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
2739 };
2740 
2741 static const AVOption hevc_options[] = {
2742  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = HEVC_PROF_AUTO }, HEVC_PROF_AUTO, HEVC_PROF_COUNT, VE, "profile" },
2743  { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 = HEVC_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
2744  { "main10", "Main10 Profile", 0, AV_OPT_TYPE_CONST, { .i64 = HEVC_PROF_MAIN10 }, INT_MIN, INT_MAX, VE, "profile" },
2745 
2746  { "alpha_quality", "Compression quality for the alpha channel", OFFSET(alpha_quality), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0.0, 1.0, VE },
2747 
2749  { NULL },
2750 };
2751 
2753  .class_name = "hevc_videotoolbox",
2754  .item_name = av_default_item_name,
2755  .option = hevc_options,
2756  .version = LIBAVUTIL_VERSION_INT,
2757 };
2758 
2760  .name = "hevc_videotoolbox",
2761  .long_name = NULL_IF_CONFIG_SMALL("VideoToolbox H.265 Encoder"),
2762  .type = AVMEDIA_TYPE_VIDEO,
2763  .id = AV_CODEC_ID_HEVC,
2764  .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2766  .priv_data_size = sizeof(VTEncContext),
2768  .init = vtenc_init,
2769  .encode2 = vtenc_frame,
2770  .close = vtenc_close,
2771  .priv_class = &hevc_videotoolbox_class,
2772  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
2774  .wrapper_name = "videotoolbox",
2775 };
2776 
2777 static const AVOption prores_options[] = {
2778  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_PRORES_XQ, VE, "profile" },
2779  { "auto", "Automatically determine based on input format", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, VE, "profile" },
2780  { "proxy", "ProRes 422 Proxy", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_PROXY }, INT_MIN, INT_MAX, VE, "profile" },
2781  { "lt", "ProRes 422 LT", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_LT }, INT_MIN, INT_MAX, VE, "profile" },
2782  { "standard", "ProRes 422", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_STANDARD }, INT_MIN, INT_MAX, VE, "profile" },
2783  { "hq", "ProRes 422 HQ", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_HQ }, INT_MIN, INT_MAX, VE, "profile" },
2784  { "4444", "ProRes 4444", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_4444 }, INT_MIN, INT_MAX, VE, "profile" },
2785  { "xq", "ProRes 4444 XQ", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_XQ }, INT_MIN, INT_MAX, VE, "profile" },
2786 
2788  { NULL },
2789 };
2790 
2792  .class_name = "prores_videotoolbox",
2793  .item_name = av_default_item_name,
2794  .option = prores_options,
2795  .version = LIBAVUTIL_VERSION_INT,
2796 };
2797 
2799  .name = "prores_videotoolbox",
2800  .long_name = NULL_IF_CONFIG_SMALL("VideoToolbox ProRes Encoder"),
2801  .type = AVMEDIA_TYPE_VIDEO,
2802  .id = AV_CODEC_ID_PRORES,
2803  .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2805  .priv_data_size = sizeof(VTEncContext),
2807  .init = vtenc_init,
2808  .encode2 = vtenc_frame,
2809  .close = vtenc_close,
2810  .priv_class = &prores_videotoolbox_class,
2811  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
2813  .wrapper_name = "videotoolbox",
2814 };
ff_hevc_videotoolbox_encoder
const AVCodec ff_hevc_videotoolbox_encoder
Definition: videotoolboxenc.c:2759
get_vt_hevc_profile_level
static bool get_vt_hevc_profile_level(AVCodecContext *avctx, CFStringRef *profile_level_val)
Definition: videotoolboxenc.c:803
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
kVTProfileLevel_H264_Main_5_1
CFStringRef kVTProfileLevel_H264_Main_5_1
Definition: videotoolboxenc.c:82
H264_PROF_EXTENDED
@ H264_PROF_EXTENDED
Definition: videotoolboxenc.c:175
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:424
AVCodec
AVCodec.
Definition: codec.h:202
kVTCompressionPropertyKey_H264EntropyMode
CFStringRef kVTCompressionPropertyKey_H264EntropyMode
Definition: videotoolboxenc.c:71
ff_alloc_a53_sei
int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size)
Check AVFrame for A53 side data and allocate and fill SEI message with A53 info.
Definition: atsc_a53.c:25
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
FF_CODEC_CAP_INIT_THREADSAFE
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:42
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
kVTProfileLevel_H264_Extended_AutoLevel
CFStringRef kVTProfileLevel_H264_Extended_AutoLevel
Definition: videotoolboxenc.c:95
FF_PROFILE_PRORES_XQ
#define FF_PROFILE_PRORES_XQ
Definition: avcodec.h:1638
ExtraSEI::size
size_t size
Definition: videotoolboxenc.c:196
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
level
uint8_t level
Definition: svq3.c:204
kVTCompressionPropertyKey_RealTime
CFStringRef kVTCompressionPropertyKey_RealTime
Definition: videotoolboxenc.c:100
hevc_pix_fmts
static enum AVPixelFormat hevc_pix_fmts[]
Definition: videotoolboxenc.c:2631
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
opt.h
get_frame
static int get_frame(AVFilterContext *ctx, int is_second)
Definition: vf_nnedi.c:656
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:960
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:494
color
Definition: vf_paletteuse.c:599
vtenc_populate_extradata
static int vtenc_populate_extradata(AVCodecContext *avctx, CMVideoCodecType codec_type, CFStringRef profile_level, CFNumberRef gamma_level, CFDictionaryRef enc_info, CFDictionaryRef pixel_buffer_info)
Definition: videotoolboxenc.c:2501
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:617
vtenc_cm_to_avpacket
static int vtenc_cm_to_avpacket(AVCodecContext *avctx, CMSampleBufferRef sample_buffer, AVPacket *pkt, ExtraSEI *sei)
Definition: videotoolboxenc.c:1967
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2660
AV_CODEC_CAP_HARDWARE
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition: codec.h:162
H264_PROF_AUTO
@ H264_PROF_AUTO
Definition: videotoolboxenc.c:171
AV_FRAME_DATA_A53_CC
@ AV_FRAME_DATA_A53_CC
ATSC A53 Part 4 Closed Captions.
Definition: frame.h:58
AVCOL_TRC_LINEAR
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
Definition: pixfmt.h:503
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
ff_prores_videotoolbox_encoder
const AVCodec ff_prores_videotoolbox_encoder
Definition: videotoolboxenc.c:2798
copy_avframe_to_pixel_buffer
static int copy_avframe_to_pixel_buffer(AVCodecContext *avctx, const AVFrame *frame, CVPixelBufferRef cv_img, const size_t *plane_strides, const size_t *plane_rows)
Definition: videotoolboxenc.c:2171
vtenc_output_callback
static void vtenc_output_callback(void *ctx, void *sourceFrameCtx, OSStatus status, VTEncodeInfoFlags flags, CMSampleBufferRef sample_buffer)
Definition: videotoolboxenc.c:625
AV_CODEC_FLAG_QSCALE
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition: avcodec.h:210
H264_NAL_SEI
@ H264_NAL_SEI
Definition: h264.h:40
get_vt_h264_profile_level
static bool get_vt_h264_profile_level(AVCodecContext *avctx, CFStringRef *profile_level_val)
Definition: videotoolboxenc.c:698
write_sei
static int write_sei(const ExtraSEI *sei, int sei_type, uint8_t *dst, size_t dst_size)
Definition: videotoolboxenc.c:1720
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:317
start_code
static const uint8_t start_code[]
Definition: videotoolboxenc.c:192
pixdesc.h
kVTProfileLevel_H264_High_AutoLevel
CFStringRef kVTProfileLevel_H264_High_AutoLevel
Definition: videotoolboxenc.c:93
AVCodecContext::color_trc
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:953
AVCOL_RANGE_JPEG
@ AVCOL_RANGE_JPEG
Full range content.
Definition: pixfmt.h:597
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:373
AVOption
AVOption.
Definition: opt.h:247
encode.h
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:497
kVTProfileLevel_H264_High_4_0
CFStringRef kVTProfileLevel_H264_High_4_0
Definition: videotoolboxenc.c:88
data
const char data[16]
Definition: mxf.c:143
VTEncContext::lock
pthread_mutex_t lock
Definition: videotoolboxenc.c:215
AVCOL_SPC_RGB
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
Definition: pixfmt.h:524
AVCOL_TRC_BT2020_12
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:510
AV_PIX_FMT_BGRA
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
Definition: pixfmt.h:95
VTEncContext::profile
int64_t profile
Definition: videotoolboxenc.c:229
AVColorPrimaries
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:469
HEVC_PROF_MAIN10
@ HEVC_PROF_MAIN10
Definition: videotoolboxenc.c:188
codec_type
enum AVMediaType codec_type
Definition: rtp.c:37
BufNode::sei
ExtraSEI * sei
Definition: videotoolboxenc.c:201
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:428
quality
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But a word about quality
Definition: rate_distortion.txt:12
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:268
copy_replace_length_codes
static int copy_replace_length_codes(AVCodecContext *avctx, size_t length_code_size, CMSampleBufferRef sample_buffer, ExtraSEI *sei, uint8_t *dst_data, size_t dst_size)
Copies NAL units and replaces length codes with H.264 Annex B start codes.
Definition: videotoolboxenc.c:1793
init
static int init
Definition: av_tx.c:47
vtenc_create_encoder
static int vtenc_create_encoder(AVCodecContext *avctx, CMVideoCodecType codec_type, CFStringRef profile_level, CFNumberRef gamma_level, CFDictionaryRef enc_info, CFDictionaryRef pixel_buffer_info, VTCompressionSessionRef *session)
Definition: videotoolboxenc.c:1071
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2700
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:529
vtenc_get_frame_info
static void vtenc_get_frame_info(CMSampleBufferRef buffer, bool *is_key_frame)
Definition: videotoolboxenc.c:1567
get_cv_pixel_format
static int get_cv_pixel_format(AVCodecContext *avctx, enum AVPixelFormat fmt, enum AVColorRange range, int *av_pixel_format, int *range_guessed)
Definition: videotoolboxenc.c:832
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3048
vtenc_close
static av_cold int vtenc_close(AVCodecContext *avctx)
Definition: videotoolboxenc.c:2588
AVCOL_RANGE_NB
@ AVCOL_RANGE_NB
Not part of ABI.
Definition: pixfmt.h:598
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:500
add_color_attr
static void add_color_attr(AVCodecContext *avctx, CFMutableDictionaryRef dict)
Definition: videotoolboxenc.c:847
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:463
VTEncContext::allow_sw
int allow_sw
Definition: videotoolboxenc.c:236
kCVImageBufferYCbCrMatrix_ITU_R_2020
CFStringRef kCVImageBufferYCbCrMatrix_ITU_R_2020
Definition: videotoolboxenc.c:69
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
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
pts
static int64_t pts
Definition: transcode_aac.c:653
VTEncContext::flushing
bool flushing
Definition: videotoolboxenc.c:240
HEVC_PROF_COUNT
@ HEVC_PROF_COUNT
Definition: videotoolboxenc.c:189
create_encoder_dict_h264
static int create_encoder_dict_h264(const AVFrame *frame, CFDictionaryRef *dict_out)
Definition: videotoolboxenc.c:2360
av_reduce
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
AVRational::num
int num
Numerator.
Definition: rational.h:59
FF_PROFILE_PRORES_LT
#define FF_PROFILE_PRORES_LT
Definition: avcodec.h:1634
AVCOL_TRC_GAMMA22
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:499
kVTProfileLevel_HEVC_Main10_AutoLevel
CFStringRef kVTProfileLevel_HEVC_Main10_AutoLevel
Definition: videotoolboxenc.c:98
av_bswap32
#define av_bswap32
Definition: bswap.h:33
kCMVideoCodecType_HEVC
@ kCMVideoCodecType_HEVC
Definition: videotoolboxenc.c:42
h264_options
static const AVOption h264_options[]
Definition: videotoolboxenc.c:2687
VTEncContext::realtime
int realtime
Definition: videotoolboxenc.c:232
ff_h264_videotoolbox_encoder
const AVCodec ff_h264_videotoolbox_encoder
Definition: videotoolboxenc.c:2725
avassert.h
get_params_size
static int get_params_size(AVCodecContext *avctx, CMVideoFormatDescriptionRef vid_fmt, size_t *size)
Get the parameter sets from a CMSampleBufferRef.
Definition: videotoolboxenc.c:458
AVCodecContext::color_primaries
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:946
VTEncContext::dts_delta
int64_t dts_delta
Definition: videotoolboxenc.c:227
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
H264_NAL_PPS
@ H264_NAL_PPS
Definition: h264.h:42
AVFrameSideData::size
size_t size
Definition: frame.h:226
av_cold
#define av_cold
Definition: attributes.h:90
VTEncContext::first_pts
int64_t first_pts
Definition: videotoolboxenc.c:226
avc_pix_fmts
static enum AVPixelFormat avc_pix_fmts[]
Definition: videotoolboxenc.c:2624
kVTProfileLevel_H264_High_4_2
CFStringRef kVTProfileLevel_H264_High_4_2
Definition: videotoolboxenc.c:90
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:485
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:679
VTEncContext::frames_after
int frames_after
Definition: videotoolboxenc.c:234
VTEncContext::async_error
int async_error
Definition: videotoolboxenc.c:218
hevc_options
static const AVOption hevc_options[]
Definition: videotoolboxenc.c:2741
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:449
prores_pix_fmts
static enum AVPixelFormat prores_pix_fmts[]
Definition: videotoolboxenc.c:2640
VT_H264Profile
VT_H264Profile
Definition: videotoolboxenc.c:170
VT_CABAC
@ VT_CABAC
Definition: videotoolboxenc.c:182
SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
@ SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
Definition: sei.h:34
prores_options
static const AVOption prores_options[]
Definition: videotoolboxenc.c:2777
AVCOL_SPC_SMPTE170M
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
Definition: pixfmt.h:530
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:226
VTEncContext::cv_sample_sent
pthread_cond_t cv_sample_sent
Definition: videotoolboxenc.c:216
VTEncContext::transfer_function
CFStringRef transfer_function
Definition: videotoolboxenc.c:212
info
MIPS optimizations info
Definition: mips.txt:2
H264_PROF_MAIN
@ H264_PROF_MAIN
Definition: videotoolboxenc.c:173
loadVTEncSymbols
static void loadVTEncSymbols()
Definition: videotoolboxenc.c:120
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:225
FF_PROFILE_UNKNOWN
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:1526
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:296
VTEncContext::alpha_quality
double alpha_quality
Definition: videotoolboxenc.c:238
CMVideoFormatDescriptionGetHEVCParameterSetAtIndex
getParameterSetAtIndex CMVideoFormatDescriptionGetHEVCParameterSetAtIndex
Definition: videotoolboxenc.c:106
AV_PIX_FMT_FLAG_ALPHA
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
Definition: pixdesc.h:147
ctx
AVFormatContext * ctx
Definition: movenc.c:48
HEVC_PROF_AUTO
@ HEVC_PROF_AUTO
Definition: videotoolboxenc.c:186
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
AVCodecContext::rc_max_rate
int64_t rc_max_rate
maximum bitrate
Definition: avcodec.h:1194
AVCOL_PRI_UNSPECIFIED
@ AVCOL_PRI_UNSPECIFIED
Definition: pixfmt.h:472
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
AVCOL_PRI_BT470BG
@ AVCOL_PRI_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:476
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:393
getParameterSetAtIndex
OSStatus(* getParameterSetAtIndex)(CMFormatDescriptionRef videoDesc, size_t parameterSetIndex, const uint8_t **parameterSetPointerOut, size_t *parameterSetSizeOut, size_t *parameterSetCountOut, int *NALUnitHeaderLengthOut)
Definition: videotoolboxenc.c:58
set_extradata
static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer)
Definition: videotoolboxenc.c:576
AVCOL_PRI_SMPTE170M
@ AVCOL_PRI_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:477
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:2988
VTEncContext::frame_ct_in
int64_t frame_ct_in
Definition: videotoolboxenc.c:224
kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder
CFStringRef kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder
Definition: videotoolboxenc.c:104
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
kVTProfileLevel_HEVC_Main_AutoLevel
CFStringRef kVTProfileLevel_HEVC_Main_AutoLevel
Definition: videotoolboxenc.c:97
AVCodecContext::color_range
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:967
prores_videotoolbox_class
static const AVClass prores_videotoolbox_class
Definition: videotoolboxenc.c:2791
BufNode
Definition: videotoolboxenc.c:199
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
kVTProfileLevel_H264_Baseline_5_2
CFStringRef kVTProfileLevel_H264_Baseline_5_2
Definition: videotoolboxenc.c:79
h264_videotoolbox_class
static const AVClass h264_videotoolbox_class
Definition: videotoolboxenc.c:2718
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:433
AVCOL_PRI_BT709
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
Definition: pixfmt.h:471
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
AV_PIX_FMT_P410
#define AV_PIX_FMT_P410
Definition: pixfmt.h:461
src
#define src
Definition: vp8dsp.c:255
create_cv_pixel_buffer_info
static int create_cv_pixel_buffer_info(AVCodecContext *avctx, CFMutableDictionaryRef *dict)
Definition: videotoolboxenc.c:869
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3006
AVCOL_TRC_BT2020_10
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:509
kCMVideoCodecType_HEVCWithAlpha
@ kCMVideoCodecType_HEVCWithAlpha
Definition: videotoolboxenc.c:46
pthread_once
static av_always_inline int pthread_once(pthread_once_t *once_control, void(*init_routine)(void))
Definition: os2threads.h:210
H264_PROF_BASELINE
@ H264_PROF_BASELINE
Definition: videotoolboxenc.c:172
vtenc_qscale_enabled
static bool vtenc_qscale_enabled(void)
Definition: videotoolboxenc.c:1066
VTH264Entropy
VTH264Entropy
Definition: videotoolboxenc.c:179
sei
static int FUNC() sei(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current)
Definition: cbs_h264_syntax_template.c:825
ExtraSEI::data
void * data
Definition: videotoolboxenc.c:195
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:563
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:68
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
AVCOL_PRI_BT2020
@ AVCOL_PRI_BT2020
ITU-R BT2020.
Definition: pixfmt.h:480
get_cv_transfer_function
static int get_cv_transfer_function(AVCodecContext *avctx, CFStringRef *transfer_fnc, CFNumberRef *gamma_level)
Definition: videotoolboxenc.c:970
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:506
AVCOL_TRC_SMPTE2084
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
Definition: pixfmt.h:511
hwcontext_videotoolbox.h
VTEncContext::a53_cc
int a53_cc
Definition: videotoolboxenc.c:245
VT_ENTROPY_NOT_SET
@ VT_ENTROPY_NOT_SET
Definition: videotoolboxenc.c:180
AV_CODEC_CAP_DR1
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
AVPacket::size
int size
Definition: packet.h:374
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:578
AVCOL_TRC_SMPTE240M
@ AVCOL_TRC_SMPTE240M
Definition: pixfmt.h:502
FF_PROFILE_PRORES_HQ
#define FF_PROFILE_PRORES_HQ
Definition: avcodec.h:1636
kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
@ kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
Definition: videotoolboxenc.c:51
FF_PROFILE_PRORES_STANDARD
#define FF_PROFILE_PRORES_STANDARD
Definition: avcodec.h:1635
vt_release_num
static void vt_release_num(CFNumberRef *refPtr)
NULL-safe release of *refPtr, and sets value to NULL.
Definition: videotoolboxenc.c:258
kCVImageBufferTransferFunction_ITU_R_2020
CFStringRef kCVImageBufferTransferFunction_ITU_R_2020
Definition: videotoolboxenc.c:68
size
int size
Definition: twinvq_data.h:10344
color
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:92
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:318
compat_keys
static struct @160 compat_keys
MKBETAG
#define MKBETAG(a, b, c, d)
Definition: macros.h:56
H264_PROF_COUNT
@ H264_PROF_COUNT
Definition: videotoolboxenc.c:176
VTEncContext::frame_ct_out
int64_t frame_ct_out
Definition: videotoolboxenc.c:223
VTEncContext::entropy
int entropy
Definition: videotoolboxenc.c:231
create_cv_pixel_buffer
static int create_cv_pixel_buffer(AVCodecContext *avctx, const AVFrame *frame, CVPixelBufferRef *cv_img)
Definition: videotoolboxenc.c:2263
AV_PIX_FMT_AYUV64
#define AV_PIX_FMT_AYUV64
Definition: pixfmt.h:452
kVTProfileLevel_H264_Baseline_4_2
CFStringRef kVTProfileLevel_H264_Baseline_4_2
Definition: videotoolboxenc.c:76
kVTProfileLevel_H264_Main_5_2
CFStringRef kVTProfileLevel_H264_Main_5_2
Definition: videotoolboxenc.c:83
hevc_videotoolbox_class
static const AVClass hevc_videotoolbox_class
Definition: videotoolboxenc.c:2752
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:191
kVTProfileLevel_H264_Main_AutoLevel
CFStringRef kVTProfileLevel_H264_Main_AutoLevel
Definition: videotoolboxenc.c:84
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:372
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
AVERROR_EXTERNAL
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:59
offset
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 offset
Definition: writing_filters.txt:86
VTEncContext::frames_before
int frames_before
Definition: videotoolboxenc.c:233
ExtraSEI
Definition: videotoolboxenc.c:194
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:379
AV_PIX_FMT_P216
#define AV_PIX_FMT_P216
Definition: pixfmt.h:462
AV_PIX_FMT_P210
#define AV_PIX_FMT_P210
Definition: pixfmt.h:460
pthread_cond_destroy
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition: os2threads.h:144
AVCOL_TRC_BT709
@ AVCOL_TRC_BT709
also ITU-R BT1361
Definition: pixfmt.h:496
kVTH264EntropyMode_CABAC
CFStringRef kVTH264EntropyMode_CABAC
Definition: videotoolboxenc.c:73
VTEncContext::get_param_set_func
getParameterSetAtIndex get_param_set_func
Definition: videotoolboxenc.c:213
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
kVTProfileLevel_H264_Baseline_AutoLevel
CFStringRef kVTProfileLevel_H264_Baseline_AutoLevel
Definition: videotoolboxenc.c:80
AVCOL_SPC_SMPTE240M
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
Definition: pixfmt.h:531
AV_PIX_FMT_VIDEOTOOLBOX
@ AV_PIX_FMT_VIDEOTOOLBOX
hardware decoding through Videotoolbox
Definition: pixfmt.h:272
h264_sei.h
TARGET_CPU_ARM64
#define TARGET_CPU_ARM64
Definition: videotoolboxenc.c:55
BufNode::error
int error
Definition: videotoolboxenc.c:203
vtenc_q_pop
static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf, ExtraSEI **sei)
Definition: videotoolboxenc.c:293
set_async_error
static void set_async_error(VTEncContext *vtctx, int err)
Definition: videotoolboxenc.c:267
COMMON_OPTIONS
#define COMMON_OPTIONS
Definition: videotoolboxenc.c:2674
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:366
AVCOL_SPC_BT2020_NCL
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:534
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:484
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:50
VTEncContext::ycbcr_matrix
CFStringRef ycbcr_matrix
Definition: videotoolboxenc.c:210
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:338
GET_SYM
#define GET_SYM(symbol, defaultVal)
Definition: videotoolboxenc.c:109
copy_emulation_prev
static int copy_emulation_prev(const uint8_t *src, size_t src_size, uint8_t *dst, ssize_t dst_offset, size_t dst_size)
Copies the data inserting emulation prevention bytes as needed.
Definition: videotoolboxenc.c:1669
VTEncContext::has_b_frames
int has_b_frames
Definition: videotoolboxenc.c:241
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:224
kVTProfileLevel_H264_Baseline_5_1
CFStringRef kVTProfileLevel_H264_Baseline_5_1
Definition: videotoolboxenc.c:78
count_nalus
static int count_nalus(size_t length_code_size, CMSampleBufferRef sample_buffer, int *count)
Definition: videotoolboxenc.c:370
VTEncContext::level
int level
Definition: videotoolboxenc.c:230
is_post_sei_nal_type
static int is_post_sei_nal_type(int nal_type)
Definition: videotoolboxenc.c:1594
BufNode::next
struct BufNode * next
Definition: videotoolboxenc.c:202
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:263
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:209
len
int len
Definition: vorbis_enc_data.h:426
H264_NAL_AUD
@ H264_NAL_AUD
Definition: h264.h:43
pthread_cond_t
Definition: os2threads.h:58
profile
int profile
Definition: mxfenc.c:2003
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:526
AVCodecContext::height
int height
Definition: avcodec.h:556
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:593
vtenc_q_push
static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer, ExtraSEI *sei)
Definition: videotoolboxenc.c:343
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:580
once_ctrl
static pthread_once_t once_ctrl
Definition: videotoolboxenc.c:118
kVTProfileLevel_H264_Baseline_5_0
CFStringRef kVTProfileLevel_H264_Baseline_5_0
Definition: videotoolboxenc.c:77
avcodec.h
ret
ret
Definition: filter_design.txt:187
VTEncContext
Definition: videotoolboxenc.c:206
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:89
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
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:264
FF_PROFILE_PRORES_4444
#define FF_PROFILE_PRORES_4444
Definition: avcodec.h:1637
FF_PROFILE_PRORES_PROXY
#define FF_PROFILE_PRORES_PROXY
Definition: avcodec.h:1633
atsc_a53.h
kVTProfileLevel_H264_Baseline_4_0
CFStringRef kVTProfileLevel_H264_Baseline_4_0
Definition: videotoolboxenc.c:75
clear_frame_queue
static void clear_frame_queue(VTEncContext *vtctx)
Definition: videotoolboxenc.c:288
vtenc_configure_encoder
static int vtenc_configure_encoder(AVCodecContext *avctx)
Definition: videotoolboxenc.c:1411
kVTProfileLevel_H264_High_5_2
CFStringRef kVTProfileLevel_H264_High_5_2
Definition: videotoolboxenc.c:92
VTEncContext::session
VTCompressionSessionRef session
Definition: videotoolboxenc.c:209
HEVC_PROF_MAIN
@ HEVC_PROF_MAIN
Definition: videotoolboxenc.c:187
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
pthread_cond_signal
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:152
kCVPixelFormatType_420YpCbCr10BiPlanarFullRange
@ kCVPixelFormatType_420YpCbCr10BiPlanarFullRange
Definition: videotoolboxenc.c:50
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:81
AVCodecContext
main external API structure.
Definition: avcodec.h:383
VT_HEVCProfile
VT_HEVCProfile
Definition: videotoolboxenc.c:185
AVCOL_TRC_ARIB_STD_B67
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
Definition: pixfmt.h:515
kCVImageBufferColorPrimaries_ITU_R_2020
CFStringRef kCVImageBufferColorPrimaries_ITU_R_2020
Definition: videotoolboxenc.c:67
kVTH264EntropyMode_CAVLC
CFStringRef kVTH264EntropyMode_CAVLC
Definition: videotoolboxenc.c:72
kVTProfileLevel_H264_High_3_1
CFStringRef kVTProfileLevel_H264_High_3_1
Definition: videotoolboxenc.c:86
kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder
CFStringRef kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder
Definition: videotoolboxenc.c:103
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_get_encode_buffer
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition: encode.c:78
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
get_cv_pixel_info
static int get_cv_pixel_info(AVCodecContext *avctx, const AVFrame *frame, int *color, int *plane_count, size_t *widths, size_t *heights, size_t *strides, size_t *contiguous_buf_size)
Definition: videotoolboxenc.c:2097
AV_CODEC_CAP_DELAY
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: codec.h:82
pthread_once_t
Definition: os2threads.h:66
copy_param_sets
static int copy_param_sets(AVCodecContext *avctx, CMVideoFormatDescriptionRef vid_fmt, uint8_t *dst, size_t dst_size)
Definition: videotoolboxenc.c:512
pthread_cond_wait
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:192
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:453
desc
const char * desc
Definition: libsvtav1.c:79
get_cv_ycbcr_matrix
static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix)
Definition: videotoolboxenc.c:1033
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
OFFSET
#define OFFSET(x)
Definition: videotoolboxenc.c:2686
kVTProfileLevel_H264_Extended_5_0
CFStringRef kVTProfileLevel_H264_Extended_5_0
Definition: videotoolboxenc.c:94
AVCodecContext::max_b_frames
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
Definition: avcodec.h:655
kVTProfileLevel_H264_High_5_1
CFStringRef kVTProfileLevel_H264_High_5_1
Definition: videotoolboxenc.c:91
vtenc_send_frame
static int vtenc_send_frame(AVCodecContext *avctx, VTEncContext *vtctx, const AVFrame *frame)
Definition: videotoolboxenc.c:2376
VE
#define VE
Definition: videotoolboxenc.c:2673
kVTProfileLevel_H264_High_4_1
CFStringRef kVTProfileLevel_H264_High_4_1
Definition: videotoolboxenc.c:89
AV_PIX_FMT_P010LE
@ AV_PIX_FMT_P010LE
like NV12, with 10bpp per component, data in the high bits, zeros in the low bits,...
Definition: pixfmt.h:274
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:223
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
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:408
AVPacket
This structure stores compressed data.
Definition: packet.h:350
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:410
AV_PIX_FMT_P416
#define AV_PIX_FMT_P416
Definition: pixfmt.h:463
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:241
get_sei_msg_bytes
static int get_sei_msg_bytes(const ExtraSEI *sei, int type)
Returns a sufficient number of bytes to contain the sei data.
Definition: videotoolboxenc.c:1950
vtenc_frame
static av_cold int vtenc_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: videotoolboxenc.c:2434
kVTProfileLevel_H264_High_3_2
CFStringRef kVTProfileLevel_H264_High_3_2
Definition: videotoolboxenc.c:87
kVTProfileLevel_H264_High_3_0
CFStringRef kVTProfileLevel_H264_High_3_0
Definition: videotoolboxenc.c:85
VTEncContext::require_sw
int require_sw
Definition: videotoolboxenc.c:237
find_sei_end
static int find_sei_end(AVCodecContext *avctx, uint8_t *nal_data, size_t nal_size, uint8_t **sei_end)
Definition: videotoolboxenc.c:1605
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:152
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:556
VTEncContext::q_tail
BufNode * q_tail
Definition: videotoolboxenc.c:221
h264.h
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
VTEncContext::codec_id
enum AVCodecID codec_id
Definition: videotoolboxenc.c:208
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
pthread_cond_init
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition: os2threads.h:133
VTEncContext::q_head
BufNode * q_head
Definition: videotoolboxenc.c:220
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1717
avstring.h
FF_QP2LAMBDA
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:227
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:525
H264_PROF_HIGH
@ H264_PROF_HIGH
Definition: videotoolboxenc.c:174
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:562
get_cm_codec_type
static CMVideoCodecType get_cm_codec_type(AVCodecContext *avctx, int64_t profile, double alpha_quality)
Definition: videotoolboxenc.c:409
int
int
Definition: ffmpeg_filter.c:153
kVTProfileLevel_H264_Main_4_2
CFStringRef kVTProfileLevel_H264_Main_4_2
Definition: videotoolboxenc.c:81
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:233
VT_CAVLC
@ VT_CAVLC
Definition: videotoolboxenc.c:181
PTHREAD_ONCE_INIT
#define PTHREAD_ONCE_INIT
Definition: os2threads.h:71
VTEncContext::color_primaries
CFStringRef color_primaries
Definition: videotoolboxenc.c:211
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3027
BufNode::cm_buffer
CMSampleBufferRef cm_buffer
Definition: videotoolboxenc.c:200
AVCodecContext::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition: avcodec.h:753
VTEncContext::warned_color_range
bool warned_color_range
Definition: videotoolboxenc.c:242
get_length_code_size
static int get_length_code_size(AVCodecContext *avctx, CMSampleBufferRef sample_buffer, size_t *size)
Definition: videotoolboxenc.c:661
av_get_pix_fmt_name
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition: pixdesc.c:2580
vtenc_init
static av_cold int vtenc_init(AVCodecContext *avctx)
Definition: videotoolboxenc.c:1533
AV_CODEC_ID_PRORES
@ AV_CODEC_ID_PRORES
Definition: codec_id.h:198
get_cv_color_primaries
static int get_cv_color_primaries(AVCodecContext *avctx, CFStringRef *primaries)
Definition: videotoolboxenc.c:936
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:64
kVTCompressionPropertyKey_TargetQualityForAlpha
CFStringRef kVTCompressionPropertyKey_TargetQualityForAlpha
Definition: videotoolboxenc.c:101