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