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