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