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