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