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