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