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  if (range_guessed) *range_guessed = range != AVCOL_RANGE_MPEG &&
851  range != AVCOL_RANGE_JPEG;
852 
853  //MPEG range is used when no range is set
854  *av_pixel_format = av_map_videotoolbox_format_from_pixfmt2(fmt, range == AVCOL_RANGE_JPEG);
855 
856  return *av_pixel_format ? 0 : AVERROR(EINVAL);
857 }
858 
859 static void add_color_attr(AVCodecContext *avctx, CFMutableDictionaryRef dict) {
860  VTEncContext *vtctx = avctx->priv_data;
861 
862  if (vtctx->color_primaries) {
863  CFDictionarySetValue(dict,
864  kCVImageBufferColorPrimariesKey,
865  vtctx->color_primaries);
866  }
867 
868  if (vtctx->transfer_function) {
869  CFDictionarySetValue(dict,
870  kCVImageBufferTransferFunctionKey,
871  vtctx->transfer_function);
872  }
873 
874  if (vtctx->ycbcr_matrix) {
875  CFDictionarySetValue(dict,
876  kCVImageBufferYCbCrMatrixKey,
877  vtctx->ycbcr_matrix);
878  }
879 }
880 
882  CFMutableDictionaryRef* dict)
883 {
884  CFNumberRef cv_color_format_num = NULL;
885  CFNumberRef width_num = NULL;
886  CFNumberRef height_num = NULL;
887  CFMutableDictionaryRef pixel_buffer_info = NULL;
888  int cv_color_format;
889  int status = get_cv_pixel_format(avctx,
890  avctx->pix_fmt,
891  avctx->color_range,
892  &cv_color_format,
893  NULL);
894  if (status) return status;
895 
896  pixel_buffer_info = CFDictionaryCreateMutable(
897  kCFAllocatorDefault,
898  20,
899  &kCFCopyStringDictionaryKeyCallBacks,
900  &kCFTypeDictionaryValueCallBacks);
901 
902  if (!pixel_buffer_info) goto pbinfo_nomem;
903 
904  cv_color_format_num = CFNumberCreate(kCFAllocatorDefault,
905  kCFNumberSInt32Type,
906  &cv_color_format);
907  if (!cv_color_format_num) goto pbinfo_nomem;
908 
909  CFDictionarySetValue(pixel_buffer_info,
910  kCVPixelBufferPixelFormatTypeKey,
911  cv_color_format_num);
912  vt_release_num(&cv_color_format_num);
913 
914  width_num = CFNumberCreate(kCFAllocatorDefault,
915  kCFNumberSInt32Type,
916  &avctx->width);
917  if (!width_num) goto pbinfo_nomem;
918 
919  CFDictionarySetValue(pixel_buffer_info,
920  kCVPixelBufferWidthKey,
921  width_num);
922  vt_release_num(&width_num);
923 
924  height_num = CFNumberCreate(kCFAllocatorDefault,
925  kCFNumberSInt32Type,
926  &avctx->height);
927  if (!height_num) goto pbinfo_nomem;
928 
929  CFDictionarySetValue(pixel_buffer_info,
930  kCVPixelBufferHeightKey,
931  height_num);
932  vt_release_num(&height_num);
933 
934  add_color_attr(avctx, pixel_buffer_info);
935 
936  *dict = pixel_buffer_info;
937  return 0;
938 
939 pbinfo_nomem:
940  vt_release_num(&cv_color_format_num);
941  vt_release_num(&width_num);
942  vt_release_num(&height_num);
943  if (pixel_buffer_info) CFRelease(pixel_buffer_info);
944 
945  return AVERROR(ENOMEM);
946 }
947 
949  CFStringRef *primaries)
950 {
951  enum AVColorPrimaries pri = avctx->color_primaries;
952  switch (pri) {
954  *primaries = NULL;
955  break;
956 
957  case AVCOL_PRI_BT470BG:
958  *primaries = kCVImageBufferColorPrimaries_EBU_3213;
959  break;
960 
961  case AVCOL_PRI_SMPTE170M:
962  *primaries = kCVImageBufferColorPrimaries_SMPTE_C;
963  break;
964 
965  case AVCOL_PRI_BT709:
966  *primaries = kCVImageBufferColorPrimaries_ITU_R_709_2;
967  break;
968 
969  case AVCOL_PRI_BT2020:
970  *primaries = compat_keys.kCVImageBufferColorPrimaries_ITU_R_2020;
971  break;
972 
973  default:
974  av_log(avctx, AV_LOG_ERROR, "Color primaries %s is not supported.\n", av_color_primaries_name(pri));
975  *primaries = NULL;
976  return -1;
977  }
978 
979  return 0;
980 }
981 
983  CFStringRef *transfer_fnc,
984  CFNumberRef *gamma_level)
985 {
986  enum AVColorTransferCharacteristic trc = avctx->color_trc;
987  Float32 gamma;
988  *gamma_level = NULL;
989 
990  switch (trc) {
992  *transfer_fnc = NULL;
993  break;
994 
995  case AVCOL_TRC_BT709:
996  *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_709_2;
997  break;
998 
999  case AVCOL_TRC_SMPTE240M:
1000  *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_240M_1995;
1001  break;
1002 
1003 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_2084_PQ
1004  case AVCOL_TRC_SMPTE2084:
1005  *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ;
1006  break;
1007 #endif
1008 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_LINEAR
1009  case AVCOL_TRC_LINEAR:
1010  *transfer_fnc = kCVImageBufferTransferFunction_Linear;
1011  break;
1012 #endif
1013 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG
1015  *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_2100_HLG;
1016  break;
1017 #endif
1018 
1019  case AVCOL_TRC_GAMMA22:
1020  gamma = 2.2;
1021  *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
1022  *gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
1023  break;
1024 
1025  case AVCOL_TRC_GAMMA28:
1026  gamma = 2.8;
1027  *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
1028  *gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
1029  break;
1030 
1031  case AVCOL_TRC_BT2020_10:
1032  case AVCOL_TRC_BT2020_12:
1033  *transfer_fnc = compat_keys.kCVImageBufferTransferFunction_ITU_R_2020;
1034  break;
1035 
1036  default:
1037  *transfer_fnc = NULL;
1038  av_log(avctx, AV_LOG_ERROR, "Transfer function %s is not supported.\n", av_color_transfer_name(trc));
1039  return -1;
1040  }
1041 
1042  return 0;
1043 }
1044 
1045 static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix) {
1046  switch(avctx->colorspace) {
1047  case AVCOL_SPC_BT709:
1048  *matrix = kCVImageBufferYCbCrMatrix_ITU_R_709_2;
1049  break;
1050 
1051  case AVCOL_SPC_UNSPECIFIED:
1052  case AVCOL_SPC_RGB:
1053  *matrix = NULL;
1054  break;
1055 
1056  case AVCOL_SPC_BT470BG:
1057  case AVCOL_SPC_SMPTE170M:
1058  *matrix = kCVImageBufferYCbCrMatrix_ITU_R_601_4;
1059  break;
1060 
1061  case AVCOL_SPC_SMPTE240M:
1062  *matrix = kCVImageBufferYCbCrMatrix_SMPTE_240M_1995;
1063  break;
1064 
1065  case AVCOL_SPC_BT2020_NCL:
1066  *matrix = compat_keys.kCVImageBufferYCbCrMatrix_ITU_R_2020;
1067  break;
1068 
1069  default:
1070  av_log(avctx, AV_LOG_ERROR, "Color space %s is not supported.\n", av_color_space_name(avctx->colorspace));
1071  return -1;
1072  }
1073 
1074  return 0;
1075 }
1076 
1077 // constant quality only on Macs with Apple Silicon
1078 static bool vtenc_qscale_enabled(void)
1079 {
1080  return !TARGET_OS_IPHONE && TARGET_CPU_ARM64;
1081 }
1082 
1084  CMVideoCodecType codec_type,
1085  CFStringRef profile_level,
1086  CFNumberRef gamma_level,
1087  CFDictionaryRef enc_info,
1088  CFDictionaryRef pixel_buffer_info,
1089  bool constant_bit_rate,
1090  VTCompressionSessionRef *session)
1091 {
1092  VTEncContext *vtctx = avctx->priv_data;
1093  SInt32 bit_rate = avctx->bit_rate;
1094  SInt32 max_rate = avctx->rc_max_rate;
1095  Float32 quality = avctx->global_quality / FF_QP2LAMBDA;
1096  CFNumberRef bit_rate_num;
1097  CFNumberRef quality_num;
1098  CFNumberRef bytes_per_second;
1099  CFNumberRef one_second;
1100  CFArrayRef data_rate_limits;
1101  int64_t bytes_per_second_value = 0;
1102  int64_t one_second_value = 0;
1103  void *nums[2];
1104 
1105  int status = VTCompressionSessionCreate(kCFAllocatorDefault,
1106  avctx->width,
1107  avctx->height,
1108  codec_type,
1109  enc_info,
1110  pixel_buffer_info,
1111  kCFAllocatorDefault,
1113  avctx,
1114  session);
1115 
1116  if (status || !vtctx->session) {
1117  av_log(avctx, AV_LOG_ERROR, "Error: cannot create compression session: %d\n", status);
1118 
1119 #if !TARGET_OS_IPHONE
1120  if (!vtctx->allow_sw) {
1121  av_log(avctx, AV_LOG_ERROR, "Try -allow_sw 1. The hardware encoder may be busy, or not supported.\n");
1122  }
1123 #endif
1124 
1125  return AVERROR_EXTERNAL;
1126  }
1127 
1128  if (avctx->flags & AV_CODEC_FLAG_QSCALE && !vtenc_qscale_enabled()) {
1129  av_log(avctx, AV_LOG_ERROR, "Error: -q:v qscale not available for encoder. Use -b:v bitrate instead.\n");
1130  return AVERROR_EXTERNAL;
1131  }
1132 
1133  if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
1134  quality = quality >= 100 ? 1.0 : quality / 100;
1135  quality_num = CFNumberCreate(kCFAllocatorDefault,
1136  kCFNumberFloat32Type,
1137  &quality);
1138  if (!quality_num) return AVERROR(ENOMEM);
1139 
1140  status = VTSessionSetProperty(vtctx->session,
1141  kVTCompressionPropertyKey_Quality,
1142  quality_num);
1143  CFRelease(quality_num);
1144  } else if (avctx->codec_id != AV_CODEC_ID_PRORES) {
1145  bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
1146  kCFNumberSInt32Type,
1147  &bit_rate);
1148  if (!bit_rate_num) return AVERROR(ENOMEM);
1149 
1150  if (constant_bit_rate) {
1151  status = VTSessionSetProperty(vtctx->session,
1152  compat_keys.kVTCompressionPropertyKey_ConstantBitRate,
1153  bit_rate_num);
1154  if (status == kVTPropertyNotSupportedErr) {
1155  av_log(avctx, AV_LOG_ERROR, "Error: -constant_bit_rate true is not supported by the encoder.\n");
1156  return AVERROR_EXTERNAL;
1157  }
1158  } else {
1159  status = VTSessionSetProperty(vtctx->session,
1160  kVTCompressionPropertyKey_AverageBitRate,
1161  bit_rate_num);
1162  }
1163 
1164  CFRelease(bit_rate_num);
1165  }
1166 
1167  if (status) {
1168  av_log(avctx, AV_LOG_ERROR, "Error setting bitrate property: %d\n", status);
1169  return AVERROR_EXTERNAL;
1170  }
1171 
1172  if (vtctx->prio_speed >= 0) {
1173  status = VTSessionSetProperty(vtctx->session,
1174  compat_keys.kVTCompressionPropertyKey_PrioritizeEncodingSpeedOverQuality,
1175  vtctx->prio_speed ? kCFBooleanTrue : kCFBooleanFalse);
1176  if (status) {
1177  av_log(avctx, AV_LOG_WARNING, "PrioritizeEncodingSpeedOverQuality property is not supported on this device. Ignoring.\n");
1178  }
1179  }
1180 
1181  if ((vtctx->codec_id == AV_CODEC_ID_H264 || vtctx->codec_id == AV_CODEC_ID_HEVC)
1182  && max_rate > 0) {
1183  bytes_per_second_value = max_rate >> 3;
1184  bytes_per_second = CFNumberCreate(kCFAllocatorDefault,
1185  kCFNumberSInt64Type,
1186  &bytes_per_second_value);
1187  if (!bytes_per_second) {
1188  return AVERROR(ENOMEM);
1189  }
1190  one_second_value = 1;
1191  one_second = CFNumberCreate(kCFAllocatorDefault,
1192  kCFNumberSInt64Type,
1193  &one_second_value);
1194  if (!one_second) {
1195  CFRelease(bytes_per_second);
1196  return AVERROR(ENOMEM);
1197  }
1198  nums[0] = (void *)bytes_per_second;
1199  nums[1] = (void *)one_second;
1200  data_rate_limits = CFArrayCreate(kCFAllocatorDefault,
1201  (const void **)nums,
1202  2,
1203  &kCFTypeArrayCallBacks);
1204 
1205  if (!data_rate_limits) {
1206  CFRelease(bytes_per_second);
1207  CFRelease(one_second);
1208  return AVERROR(ENOMEM);
1209  }
1210  status = VTSessionSetProperty(vtctx->session,
1211  kVTCompressionPropertyKey_DataRateLimits,
1212  data_rate_limits);
1213 
1214  CFRelease(bytes_per_second);
1215  CFRelease(one_second);
1216  CFRelease(data_rate_limits);
1217 
1218  if (status) {
1219  av_log(avctx, AV_LOG_ERROR, "Error setting max bitrate property: %d\n", status);
1220  // kVTCompressionPropertyKey_DataRateLimits is available for HEVC
1221  // now but not on old release. There is no document about since
1222  // when. So ignore the error if it failed for hevc.
1223  if (vtctx->codec_id != AV_CODEC_ID_HEVC)
1224  return AVERROR_EXTERNAL;
1225  }
1226  }
1227 
1228  if (vtctx->codec_id == AV_CODEC_ID_HEVC) {
1229  if (avctx->pix_fmt == AV_PIX_FMT_BGRA && vtctx->alpha_quality > 0.0) {
1230  CFNumberRef alpha_quality_num = CFNumberCreate(kCFAllocatorDefault,
1231  kCFNumberDoubleType,
1232  &vtctx->alpha_quality);
1233  if (!alpha_quality_num) return AVERROR(ENOMEM);
1234 
1235  status = VTSessionSetProperty(vtctx->session,
1236  compat_keys.kVTCompressionPropertyKey_TargetQualityForAlpha,
1237  alpha_quality_num);
1238  CFRelease(alpha_quality_num);
1239  }
1240  }
1241 
1242  if (profile_level) {
1243  status = VTSessionSetProperty(vtctx->session,
1244  kVTCompressionPropertyKey_ProfileLevel,
1245  profile_level);
1246  if (status) {
1247  av_log(avctx, AV_LOG_ERROR, "Error setting profile/level property: %d. Output will be encoded using a supported profile/level combination.\n", status);
1248  }
1249  }
1250 
1251  if (avctx->gop_size > 0 && avctx->codec_id != AV_CODEC_ID_PRORES) {
1252  CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
1253  kCFNumberIntType,
1254  &avctx->gop_size);
1255  if (!interval) {
1256  return AVERROR(ENOMEM);
1257  }
1258 
1259  status = VTSessionSetProperty(vtctx->session,
1260  kVTCompressionPropertyKey_MaxKeyFrameInterval,
1261  interval);
1262  CFRelease(interval);
1263 
1264  if (status) {
1265  av_log(avctx, AV_LOG_ERROR, "Error setting 'max key-frame interval' property: %d\n", status);
1266  return AVERROR_EXTERNAL;
1267  }
1268  }
1269 
1270  if (vtctx->frames_before) {
1271  status = VTSessionSetProperty(vtctx->session,
1272  kVTCompressionPropertyKey_MoreFramesBeforeStart,
1273  kCFBooleanTrue);
1274 
1275  if (status == kVTPropertyNotSupportedErr) {
1276  av_log(avctx, AV_LOG_WARNING, "frames_before property is not supported on this device. Ignoring.\n");
1277  } else if (status) {
1278  av_log(avctx, AV_LOG_ERROR, "Error setting frames_before property: %d\n", status);
1279  }
1280  }
1281 
1282  if (vtctx->frames_after) {
1283  status = VTSessionSetProperty(vtctx->session,
1284  kVTCompressionPropertyKey_MoreFramesAfterEnd,
1285  kCFBooleanTrue);
1286 
1287  if (status == kVTPropertyNotSupportedErr) {
1288  av_log(avctx, AV_LOG_WARNING, "frames_after property is not supported on this device. Ignoring.\n");
1289  } else if (status) {
1290  av_log(avctx, AV_LOG_ERROR, "Error setting frames_after property: %d\n", status);
1291  }
1292  }
1293 
1294  if (avctx->sample_aspect_ratio.num != 0) {
1295  CFNumberRef num;
1296  CFNumberRef den;
1297  CFMutableDictionaryRef par;
1298  AVRational *avpar = &avctx->sample_aspect_ratio;
1299 
1300  av_reduce(&avpar->num, &avpar->den,
1301  avpar->num, avpar->den,
1302  0xFFFFFFFF);
1303 
1304  num = CFNumberCreate(kCFAllocatorDefault,
1305  kCFNumberIntType,
1306  &avpar->num);
1307 
1308  den = CFNumberCreate(kCFAllocatorDefault,
1309  kCFNumberIntType,
1310  &avpar->den);
1311 
1312 
1313 
1314  par = CFDictionaryCreateMutable(kCFAllocatorDefault,
1315  2,
1316  &kCFCopyStringDictionaryKeyCallBacks,
1317  &kCFTypeDictionaryValueCallBacks);
1318 
1319  if (!par || !num || !den) {
1320  if (par) CFRelease(par);
1321  if (num) CFRelease(num);
1322  if (den) CFRelease(den);
1323 
1324  return AVERROR(ENOMEM);
1325  }
1326 
1327  CFDictionarySetValue(
1328  par,
1329  kCMFormatDescriptionKey_PixelAspectRatioHorizontalSpacing,
1330  num);
1331 
1332  CFDictionarySetValue(
1333  par,
1334  kCMFormatDescriptionKey_PixelAspectRatioVerticalSpacing,
1335  den);
1336 
1337  status = VTSessionSetProperty(vtctx->session,
1338  kVTCompressionPropertyKey_PixelAspectRatio,
1339  par);
1340 
1341  CFRelease(par);
1342  CFRelease(num);
1343  CFRelease(den);
1344 
1345  if (status) {
1346  av_log(avctx,
1347  AV_LOG_ERROR,
1348  "Error setting pixel aspect ratio to %d:%d: %d.\n",
1349  avctx->sample_aspect_ratio.num,
1350  avctx->sample_aspect_ratio.den,
1351  status);
1352 
1353  return AVERROR_EXTERNAL;
1354  }
1355  }
1356 
1357 
1358  if (vtctx->transfer_function) {
1359  status = VTSessionSetProperty(vtctx->session,
1360  kVTCompressionPropertyKey_TransferFunction,
1361  vtctx->transfer_function);
1362 
1363  if (status) {
1364  av_log(avctx, AV_LOG_WARNING, "Could not set transfer function: %d\n", status);
1365  }
1366  }
1367 
1368 
1369  if (vtctx->ycbcr_matrix) {
1370  status = VTSessionSetProperty(vtctx->session,
1371  kVTCompressionPropertyKey_YCbCrMatrix,
1372  vtctx->ycbcr_matrix);
1373 
1374  if (status) {
1375  av_log(avctx, AV_LOG_WARNING, "Could not set ycbcr matrix: %d\n", status);
1376  }
1377  }
1378 
1379 
1380  if (vtctx->color_primaries) {
1381  status = VTSessionSetProperty(vtctx->session,
1382  kVTCompressionPropertyKey_ColorPrimaries,
1383  vtctx->color_primaries);
1384 
1385  if (status) {
1386  av_log(avctx, AV_LOG_WARNING, "Could not set color primaries: %d\n", status);
1387  }
1388  }
1389 
1390  if (gamma_level) {
1391  status = VTSessionSetProperty(vtctx->session,
1392  kCVImageBufferGammaLevelKey,
1393  gamma_level);
1394 
1395  if (status) {
1396  av_log(avctx, AV_LOG_WARNING, "Could not set gamma level: %d\n", status);
1397  }
1398  }
1399 
1400  if (!vtctx->has_b_frames && avctx->codec_id != AV_CODEC_ID_PRORES) {
1401  status = VTSessionSetProperty(vtctx->session,
1402  kVTCompressionPropertyKey_AllowFrameReordering,
1403  kCFBooleanFalse);
1404 
1405  if (status) {
1406  av_log(avctx, AV_LOG_ERROR, "Error setting 'allow frame reordering' property: %d\n", status);
1407  return AVERROR_EXTERNAL;
1408  }
1409  }
1410 
1411  if (vtctx->entropy != VT_ENTROPY_NOT_SET) {
1412  CFStringRef entropy = vtctx->entropy == VT_CABAC ?
1413  compat_keys.kVTH264EntropyMode_CABAC:
1414  compat_keys.kVTH264EntropyMode_CAVLC;
1415 
1416  status = VTSessionSetProperty(vtctx->session,
1417  compat_keys.kVTCompressionPropertyKey_H264EntropyMode,
1418  entropy);
1419 
1420  if (status) {
1421  av_log(avctx, AV_LOG_ERROR, "Error setting entropy property: %d\n", status);
1422  }
1423  }
1424 
1425  if (vtctx->realtime >= 0) {
1426  status = VTSessionSetProperty(vtctx->session,
1427  compat_keys.kVTCompressionPropertyKey_RealTime,
1428  vtctx->realtime ? kCFBooleanTrue : kCFBooleanFalse);
1429 
1430  if (status) {
1431  av_log(avctx, AV_LOG_ERROR, "Error setting realtime property: %d\n", status);
1432  }
1433  }
1434 
1435  status = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
1436  if (status) {
1437  av_log(avctx, AV_LOG_ERROR, "Error: cannot prepare encoder: %d\n", status);
1438  return AVERROR_EXTERNAL;
1439  }
1440 
1441  return 0;
1442 }
1443 
1445 {
1446  CFMutableDictionaryRef enc_info;
1447  CFMutableDictionaryRef pixel_buffer_info = NULL;
1448  CMVideoCodecType codec_type;
1449  VTEncContext *vtctx = avctx->priv_data;
1450  CFStringRef profile_level = NULL;
1451  CFNumberRef gamma_level = NULL;
1452  int status;
1453 
1454  codec_type = get_cm_codec_type(avctx, vtctx->profile, vtctx->alpha_quality);
1455  if (!codec_type) {
1456  av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id);
1457  return AVERROR(EINVAL);
1458  }
1459 
1460 #if defined(MAC_OS_X_VERSION_10_9) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9)
1461  if (avctx->codec_id == AV_CODEC_ID_PRORES) {
1462  if (__builtin_available(macOS 10.10, *)) {
1463  VTRegisterProfessionalVideoWorkflowVideoEncoders();
1464  }
1465  }
1466 #endif
1467 
1468  vtctx->codec_id = avctx->codec_id;
1469 
1470  if (vtctx->codec_id == AV_CODEC_ID_H264) {
1471  vtctx->get_param_set_func = CMVideoFormatDescriptionGetH264ParameterSetAtIndex;
1472 
1473  vtctx->has_b_frames = avctx->max_b_frames > 0;
1474  if(vtctx->has_b_frames && vtctx->profile == H264_PROF_BASELINE){
1475  av_log(avctx, AV_LOG_WARNING, "Cannot use B-frames with baseline profile. Output will not contain B-frames.\n");
1476  vtctx->has_b_frames = 0;
1477  }
1478 
1479  if (vtctx->entropy == VT_CABAC && vtctx->profile == H264_PROF_BASELINE) {
1480  av_log(avctx, AV_LOG_WARNING, "CABAC entropy requires 'main' or 'high' profile, but baseline was requested. Encode will not use CABAC entropy.\n");
1481  vtctx->entropy = VT_ENTROPY_NOT_SET;
1482  }
1483 
1484  if (!get_vt_h264_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1485  } else if (vtctx->codec_id == AV_CODEC_ID_HEVC) {
1486  vtctx->get_param_set_func = compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex;
1487  if (!vtctx->get_param_set_func) return AVERROR(EINVAL);
1488  if (!get_vt_hevc_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1489  // HEVC has b-byramid
1490  vtctx->has_b_frames = avctx->max_b_frames > 0 ? 2 : 0;
1491  } else if (vtctx->codec_id == AV_CODEC_ID_PRORES) {
1492  avctx->codec_tag = av_bswap32(codec_type);
1493  }
1494 
1495  enc_info = CFDictionaryCreateMutable(
1496  kCFAllocatorDefault,
1497  20,
1498  &kCFCopyStringDictionaryKeyCallBacks,
1499  &kCFTypeDictionaryValueCallBacks
1500  );
1501 
1502  if (!enc_info) return AVERROR(ENOMEM);
1503 
1504 #if !TARGET_OS_IPHONE
1505  if(vtctx->require_sw) {
1506  CFDictionarySetValue(enc_info,
1507  compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1508  kCFBooleanFalse);
1509  } else if (!vtctx->allow_sw) {
1510  CFDictionarySetValue(enc_info,
1511  compat_keys.kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder,
1512  kCFBooleanTrue);
1513  } else {
1514  CFDictionarySetValue(enc_info,
1515  compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1516  kCFBooleanTrue);
1517  }
1518 #endif
1519 
1520  if (avctx->pix_fmt != AV_PIX_FMT_VIDEOTOOLBOX) {
1521  status = create_cv_pixel_buffer_info(avctx, &pixel_buffer_info);
1522  if (status)
1523  goto init_cleanup;
1524  }
1525 
1526  vtctx->dts_delta = vtctx->has_b_frames ? -1 : 0;
1527 
1528  get_cv_transfer_function(avctx, &vtctx->transfer_function, &gamma_level);
1529  get_cv_ycbcr_matrix(avctx, &vtctx->ycbcr_matrix);
1530  get_cv_color_primaries(avctx, &vtctx->color_primaries);
1531 
1532 
1533  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1535  codec_type,
1536  profile_level,
1537  gamma_level,
1538  enc_info,
1539  pixel_buffer_info);
1540  if (status)
1541  goto init_cleanup;
1542  }
1543 
1544  status = vtenc_create_encoder(avctx,
1545  codec_type,
1546  profile_level,
1547  gamma_level,
1548  enc_info,
1549  pixel_buffer_info,
1550  vtctx->constant_bit_rate,
1551  &vtctx->session);
1552 
1553 init_cleanup:
1554  if (gamma_level)
1555  CFRelease(gamma_level);
1556 
1557  if (pixel_buffer_info)
1558  CFRelease(pixel_buffer_info);
1559 
1560  CFRelease(enc_info);
1561 
1562  return status;
1563 }
1564 
1566 {
1567  VTEncContext *vtctx = avctx->priv_data;
1568  CFBooleanRef has_b_frames_cfbool;
1569  int status;
1570 
1572 
1573  pthread_mutex_init(&vtctx->lock, NULL);
1575 
1576  vtctx->session = NULL;
1578  if (status) return status;
1579 
1580  status = VTSessionCopyProperty(vtctx->session,
1581  kVTCompressionPropertyKey_AllowFrameReordering,
1582  kCFAllocatorDefault,
1583  &has_b_frames_cfbool);
1584 
1585  if (!status && has_b_frames_cfbool) {
1586  //Some devices don't output B-frames for main profile, even if requested.
1587  // HEVC has b-pyramid
1588  if (CFBooleanGetValue(has_b_frames_cfbool))
1589  vtctx->has_b_frames = avctx->codec_id == AV_CODEC_ID_HEVC ? 2 : 1;
1590  else
1591  vtctx->has_b_frames = 0;
1592  CFRelease(has_b_frames_cfbool);
1593  }
1594  avctx->has_b_frames = vtctx->has_b_frames;
1595 
1596  return 0;
1597 }
1598 
1599 static void vtenc_get_frame_info(CMSampleBufferRef buffer, bool *is_key_frame)
1600 {
1601  CFArrayRef attachments;
1602  CFDictionaryRef attachment;
1603  CFBooleanRef not_sync;
1604  CFIndex len;
1605 
1606  attachments = CMSampleBufferGetSampleAttachmentsArray(buffer, false);
1607  len = !attachments ? 0 : CFArrayGetCount(attachments);
1608 
1609  if (!len) {
1610  *is_key_frame = true;
1611  return;
1612  }
1613 
1614  attachment = CFArrayGetValueAtIndex(attachments, 0);
1615 
1616  if (CFDictionaryGetValueIfPresent(attachment,
1617  kCMSampleAttachmentKey_NotSync,
1618  (const void **)&not_sync))
1619  {
1620  *is_key_frame = !CFBooleanGetValue(not_sync);
1621  } else {
1622  *is_key_frame = true;
1623  }
1624 }
1625 
1626 static int is_post_sei_nal_type(int nal_type){
1627  return nal_type != H264_NAL_SEI &&
1628  nal_type != H264_NAL_SPS &&
1629  nal_type != H264_NAL_PPS &&
1630  nal_type != H264_NAL_AUD;
1631 }
1632 
1633 /*
1634  * Finds the sei message start/size of type find_sei_type.
1635  * If more than one of that type exists, the last one is returned.
1636  */
1637 static int find_sei_end(AVCodecContext *avctx,
1638  uint8_t *nal_data,
1639  size_t nal_size,
1640  uint8_t **sei_end)
1641 {
1642  int nal_type;
1643  size_t sei_payload_size = 0;
1644  *sei_end = NULL;
1645  uint8_t *nal_start = nal_data;
1646 
1647  if (!nal_size)
1648  return 0;
1649 
1650  nal_type = *nal_data & 0x1F;
1651  if (nal_type != H264_NAL_SEI)
1652  return 0;
1653 
1654  nal_data++;
1655  nal_size--;
1656 
1657  if (nal_data[nal_size - 1] == 0x80)
1658  nal_size--;
1659 
1660  while (nal_size > 0 && *nal_data > 0) {
1661  do{
1662  nal_data++;
1663  nal_size--;
1664  } while (nal_size > 0 && *nal_data == 0xFF);
1665 
1666  if (!nal_size) {
1667  av_log(avctx, AV_LOG_ERROR, "Unexpected end of SEI NAL Unit parsing type.\n");
1668  return AVERROR_INVALIDDATA;
1669  }
1670 
1671  do{
1672  sei_payload_size += *nal_data;
1673  nal_data++;
1674  nal_size--;
1675  } while (nal_size > 0 && *nal_data == 0xFF);
1676 
1677  if (nal_size < sei_payload_size) {
1678  av_log(avctx, AV_LOG_ERROR, "Unexpected end of SEI NAL Unit parsing size.\n");
1679  return AVERROR_INVALIDDATA;
1680  }
1681 
1682  nal_data += sei_payload_size;
1683  nal_size -= sei_payload_size;
1684  }
1685 
1686  *sei_end = nal_data;
1687 
1688  return nal_data - nal_start + 1;
1689 }
1690 
1691 /**
1692  * Copies the data inserting emulation prevention bytes as needed.
1693  * Existing data in the destination can be taken into account by providing
1694  * dst with a dst_offset > 0.
1695  *
1696  * @return The number of bytes copied on success. On failure, the negative of
1697  * the number of bytes needed to copy src is returned.
1698  */
1699 static int copy_emulation_prev(const uint8_t *src,
1700  size_t src_size,
1701  uint8_t *dst,
1702  ssize_t dst_offset,
1703  size_t dst_size)
1704 {
1705  int zeros = 0;
1706  int wrote_bytes;
1707  uint8_t* dst_start;
1708  uint8_t* dst_end = dst + dst_size;
1709  const uint8_t* src_end = src + src_size;
1710  int start_at = dst_offset > 2 ? dst_offset - 2 : 0;
1711  int i;
1712  for (i = start_at; i < dst_offset && i < dst_size; i++) {
1713  if (!dst[i])
1714  zeros++;
1715  else
1716  zeros = 0;
1717  }
1718 
1719  dst += dst_offset;
1720  dst_start = dst;
1721  for (; src < src_end; src++, dst++) {
1722  if (zeros == 2) {
1723  int insert_ep3_byte = *src <= 3;
1724  if (insert_ep3_byte) {
1725  if (dst < dst_end)
1726  *dst = 3;
1727  dst++;
1728  }
1729 
1730  zeros = 0;
1731  }
1732 
1733  if (dst < dst_end)
1734  *dst = *src;
1735 
1736  if (!*src)
1737  zeros++;
1738  else
1739  zeros = 0;
1740  }
1741 
1742  wrote_bytes = dst - dst_start;
1743 
1744  if (dst > dst_end)
1745  return -wrote_bytes;
1746 
1747  return wrote_bytes;
1748 }
1749 
1750 static int write_sei(const ExtraSEI *sei,
1751  int sei_type,
1752  uint8_t *dst,
1753  size_t dst_size)
1754 {
1755  uint8_t *sei_start = dst;
1756  size_t remaining_sei_size = sei->size;
1757  size_t remaining_dst_size = dst_size;
1758  int header_bytes;
1759  int bytes_written;
1760  ssize_t offset;
1761 
1762  if (!remaining_dst_size)
1763  return AVERROR_BUFFER_TOO_SMALL;
1764 
1765  while (sei_type && remaining_dst_size != 0) {
1766  int sei_byte = sei_type > 255 ? 255 : sei_type;
1767  *dst = sei_byte;
1768 
1769  sei_type -= sei_byte;
1770  dst++;
1771  remaining_dst_size--;
1772  }
1773 
1774  if (!dst_size)
1775  return AVERROR_BUFFER_TOO_SMALL;
1776 
1777  while (remaining_sei_size && remaining_dst_size != 0) {
1778  int size_byte = remaining_sei_size > 255 ? 255 : remaining_sei_size;
1779  *dst = size_byte;
1780 
1781  remaining_sei_size -= size_byte;
1782  dst++;
1783  remaining_dst_size--;
1784  }
1785 
1786  if (remaining_dst_size < sei->size)
1787  return AVERROR_BUFFER_TOO_SMALL;
1788 
1789  header_bytes = dst - sei_start;
1790 
1791  offset = header_bytes;
1792  bytes_written = copy_emulation_prev(sei->data,
1793  sei->size,
1794  sei_start,
1795  offset,
1796  dst_size);
1797  if (bytes_written < 0)
1798  return AVERROR_BUFFER_TOO_SMALL;
1799 
1800  bytes_written += header_bytes;
1801  return bytes_written;
1802 }
1803 
1804 /**
1805  * Copies NAL units and replaces length codes with
1806  * H.264 Annex B start codes. On failure, the contents of
1807  * dst_data may have been modified.
1808  *
1809  * @param length_code_size Byte length of each length code
1810  * @param sample_buffer NAL units prefixed with length codes.
1811  * @param sei Optional A53 closed captions SEI data.
1812  * @param dst_data Must be zeroed before calling this function.
1813  * Contains the copied NAL units prefixed with
1814  * start codes when the function returns
1815  * successfully.
1816  * @param dst_size Length of dst_data
1817  * @return 0 on success
1818  * AVERROR_INVALIDDATA if length_code_size is invalid
1819  * AVERROR_BUFFER_TOO_SMALL if dst_data is too small
1820  * or if a length_code in src_data specifies data beyond
1821  * the end of its buffer.
1822  */
1824  AVCodecContext *avctx,
1825  size_t length_code_size,
1826  CMSampleBufferRef sample_buffer,
1827  ExtraSEI *sei,
1828  uint8_t *dst_data,
1829  size_t dst_size)
1830 {
1831  size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
1832  size_t remaining_src_size = src_size;
1833  size_t remaining_dst_size = dst_size;
1834  size_t src_offset = 0;
1835  int wrote_sei = 0;
1836  int status;
1837  uint8_t size_buf[4];
1838  uint8_t nal_type;
1839  CMBlockBufferRef block = CMSampleBufferGetDataBuffer(sample_buffer);
1840 
1841  if (length_code_size > 4) {
1842  return AVERROR_INVALIDDATA;
1843  }
1844 
1845  while (remaining_src_size > 0) {
1846  size_t curr_src_len;
1847  size_t curr_dst_len;
1848  size_t box_len = 0;
1849  size_t i;
1850 
1851  uint8_t *dst_box;
1852 
1853  status = CMBlockBufferCopyDataBytes(block,
1854  src_offset,
1855  length_code_size,
1856  size_buf);
1857  if (status) {
1858  av_log(avctx, AV_LOG_ERROR, "Cannot copy length: %d\n", status);
1859  return AVERROR_EXTERNAL;
1860  }
1861 
1862  status = CMBlockBufferCopyDataBytes(block,
1863  src_offset + length_code_size,
1864  1,
1865  &nal_type);
1866 
1867  if (status) {
1868  av_log(avctx, AV_LOG_ERROR, "Cannot copy type: %d\n", status);
1869  return AVERROR_EXTERNAL;
1870  }
1871 
1872  nal_type &= 0x1F;
1873 
1874  for (i = 0; i < length_code_size; i++) {
1875  box_len <<= 8;
1876  box_len |= size_buf[i];
1877  }
1878 
1879  if (sei && !wrote_sei && is_post_sei_nal_type(nal_type)) {
1880  //No SEI NAL unit - insert.
1881  int wrote_bytes;
1882 
1883  memcpy(dst_data, start_code, sizeof(start_code));
1884  dst_data += sizeof(start_code);
1885  remaining_dst_size -= sizeof(start_code);
1886 
1887  *dst_data = H264_NAL_SEI;
1888  dst_data++;
1889  remaining_dst_size--;
1890 
1891  wrote_bytes = write_sei(sei,
1893  dst_data,
1894  remaining_dst_size);
1895 
1896  if (wrote_bytes < 0)
1897  return wrote_bytes;
1898 
1899  remaining_dst_size -= wrote_bytes;
1900  dst_data += wrote_bytes;
1901 
1902  if (remaining_dst_size <= 0)
1903  return AVERROR_BUFFER_TOO_SMALL;
1904 
1905  *dst_data = 0x80;
1906 
1907  dst_data++;
1908  remaining_dst_size--;
1909 
1910  wrote_sei = 1;
1911  }
1912 
1913  curr_src_len = box_len + length_code_size;
1914  curr_dst_len = box_len + sizeof(start_code);
1915 
1916  if (remaining_src_size < curr_src_len) {
1917  return AVERROR_BUFFER_TOO_SMALL;
1918  }
1919 
1920  if (remaining_dst_size < curr_dst_len) {
1921  return AVERROR_BUFFER_TOO_SMALL;
1922  }
1923 
1924  dst_box = dst_data + sizeof(start_code);
1925 
1926  memcpy(dst_data, start_code, sizeof(start_code));
1927  status = CMBlockBufferCopyDataBytes(block,
1928  src_offset + length_code_size,
1929  box_len,
1930  dst_box);
1931 
1932  if (status) {
1933  av_log(avctx, AV_LOG_ERROR, "Cannot copy data: %d\n", status);
1934  return AVERROR_EXTERNAL;
1935  }
1936 
1937  if (sei && !wrote_sei && nal_type == H264_NAL_SEI) {
1938  //Found SEI NAL unit - append.
1939  int wrote_bytes;
1940  int old_sei_length;
1941  int extra_bytes;
1942  uint8_t *new_sei;
1943  old_sei_length = find_sei_end(avctx, dst_box, box_len, &new_sei);
1944  if (old_sei_length < 0)
1945  return status;
1946 
1947  wrote_bytes = write_sei(sei,
1949  new_sei,
1950  remaining_dst_size - old_sei_length);
1951  if (wrote_bytes < 0)
1952  return wrote_bytes;
1953 
1954  if (new_sei + wrote_bytes >= dst_data + remaining_dst_size)
1955  return AVERROR_BUFFER_TOO_SMALL;
1956 
1957  new_sei[wrote_bytes++] = 0x80;
1958  extra_bytes = wrote_bytes - (dst_box + box_len - new_sei);
1959 
1960  dst_data += extra_bytes;
1961  remaining_dst_size -= extra_bytes;
1962 
1963  wrote_sei = 1;
1964  }
1965 
1966  src_offset += curr_src_len;
1967  dst_data += curr_dst_len;
1968 
1969  remaining_src_size -= curr_src_len;
1970  remaining_dst_size -= curr_dst_len;
1971  }
1972 
1973  return 0;
1974 }
1975 
1976 /**
1977  * Returns a sufficient number of bytes to contain the sei data.
1978  * It may be greater than the minimum required.
1979  */
1980 static int get_sei_msg_bytes(const ExtraSEI* sei, int type){
1981  int copied_size;
1982  if (sei->size == 0)
1983  return 0;
1984 
1985  copied_size = -copy_emulation_prev(sei->data,
1986  sei->size,
1987  NULL,
1988  0,
1989  0);
1990 
1991  if ((sei->size % 255) == 0) //may result in an extra byte
1992  copied_size++;
1993 
1994  return copied_size + sei->size / 255 + 1 + type / 255 + 1;
1995 }
1996 
1998  AVCodecContext *avctx,
1999  CMSampleBufferRef sample_buffer,
2000  AVPacket *pkt,
2001  ExtraSEI *sei)
2002 {
2003  VTEncContext *vtctx = avctx->priv_data;
2004 
2005  int status;
2006  bool is_key_frame;
2007  bool add_header;
2008  size_t length_code_size;
2009  size_t header_size = 0;
2010  size_t in_buf_size;
2011  size_t out_buf_size;
2012  size_t sei_nalu_size = 0;
2013  int64_t dts_delta;
2014  int64_t time_base_num;
2015  int nalu_count;
2016  CMTime pts;
2017  CMTime dts;
2018  CMVideoFormatDescriptionRef vid_fmt;
2019 
2020  vtenc_get_frame_info(sample_buffer, &is_key_frame);
2021 
2022  if (vtctx->get_param_set_func) {
2023  status = get_length_code_size(avctx, sample_buffer, &length_code_size);
2024  if (status) return status;
2025 
2026  add_header = is_key_frame && !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER);
2027 
2028  if (add_header) {
2029  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
2030  if (!vid_fmt) {
2031  av_log(avctx, AV_LOG_ERROR, "Cannot get format description.\n");
2032  return AVERROR_EXTERNAL;
2033  }
2034 
2035  int status = get_params_size(avctx, vid_fmt, &header_size);
2036  if (status) return status;
2037  }
2038 
2039  status = count_nalus(length_code_size, sample_buffer, &nalu_count);
2040  if(status)
2041  return status;
2042 
2043  if (sei) {
2044  size_t msg_size = get_sei_msg_bytes(sei,
2046 
2047  sei_nalu_size = sizeof(start_code) + 1 + msg_size + 1;
2048  }
2049 
2050  in_buf_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
2051  out_buf_size = header_size +
2052  in_buf_size +
2053  sei_nalu_size +
2054  nalu_count * ((int)sizeof(start_code) - (int)length_code_size);
2055 
2056  status = ff_get_encode_buffer(avctx, pkt, out_buf_size, 0);
2057  if (status < 0)
2058  return status;
2059 
2060  if (add_header) {
2061  status = copy_param_sets(avctx, vid_fmt, pkt->data, out_buf_size);
2062  if(status) return status;
2063  }
2064 
2066  avctx,
2067  length_code_size,
2068  sample_buffer,
2069  sei,
2070  pkt->data + header_size,
2071  pkt->size - header_size
2072  );
2073 
2074  if (status) {
2075  av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status);
2076  return status;
2077  }
2078  } else {
2079  size_t len;
2080  CMBlockBufferRef buf = CMSampleBufferGetDataBuffer(sample_buffer);
2081  if (!buf) {
2082  av_log(avctx, AV_LOG_ERROR, "Error getting block buffer\n");
2083  return AVERROR_EXTERNAL;
2084  }
2085 
2086  len = CMBlockBufferGetDataLength(buf);
2087 
2088  status = ff_get_encode_buffer(avctx, pkt, len, 0);
2089  if (status < 0)
2090  return status;
2091 
2092  status = CMBlockBufferCopyDataBytes(buf, 0, len, pkt->data);
2093  if (status) {
2094  av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status);
2095  return AVERROR_EXTERNAL;
2096  }
2097  }
2098 
2099  if (is_key_frame) {
2101  }
2102 
2103  pts = CMSampleBufferGetPresentationTimeStamp(sample_buffer);
2104  dts = CMSampleBufferGetDecodeTimeStamp (sample_buffer);
2105 
2106  if (CMTIME_IS_INVALID(dts)) {
2107  if (!vtctx->has_b_frames) {
2108  dts = pts;
2109  } else {
2110  av_log(avctx, AV_LOG_ERROR, "DTS is invalid.\n");
2111  return AVERROR_EXTERNAL;
2112  }
2113  }
2114 
2115  dts_delta = vtctx->dts_delta >= 0 ? vtctx->dts_delta : 0;
2116  time_base_num = avctx->time_base.num;
2117  pkt->pts = pts.value / time_base_num;
2118  pkt->dts = dts.value / time_base_num - dts_delta;
2119 
2120  return 0;
2121 }
2122 
2123 /*
2124  * contiguous_buf_size is 0 if not contiguous, and the size of the buffer
2125  * containing all planes if so.
2126  */
2128  AVCodecContext *avctx,
2129  const AVFrame *frame,
2130  int *color,
2131  int *plane_count,
2132  size_t *widths,
2133  size_t *heights,
2134  size_t *strides,
2135  size_t *contiguous_buf_size)
2136 {
2138  VTEncContext *vtctx = avctx->priv_data;
2139  int av_format = frame->format;
2140  int av_color_range = frame->color_range;
2141  int i;
2142  int range_guessed;
2143  int status;
2144 
2145  if (!desc)
2146  return AVERROR(EINVAL);
2147 
2148  status = get_cv_pixel_format(avctx, av_format, av_color_range, color, &range_guessed);
2149  if (status) {
2150  av_log(avctx,
2151  AV_LOG_ERROR,
2152  "Could not get pixel format for color format '%s' range '%s'.\n",
2153  av_get_pix_fmt_name(av_format),
2154  av_color_range > AVCOL_RANGE_UNSPECIFIED &&
2155  av_color_range < AVCOL_RANGE_NB ?
2156  av_color_range_name(av_color_range) :
2157  "Unknown");
2158 
2159  return AVERROR(EINVAL);
2160  }
2161 
2162  if (range_guessed) {
2163  if (!vtctx->warned_color_range) {
2164  vtctx->warned_color_range = true;
2165  av_log(avctx,
2167  "Color range not set for %s. Using MPEG range.\n",
2168  av_get_pix_fmt_name(av_format));
2169  }
2170  }
2171 
2172  *plane_count = av_pix_fmt_count_planes(avctx->pix_fmt);
2173 
2174  for (i = 0; i < desc->nb_components; i++) {
2175  int p = desc->comp[i].plane;
2176  bool hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA);
2177  bool isAlpha = hasAlpha && (p + 1 == *plane_count);
2178  bool isChroma = (p != 0) && !isAlpha;
2179  int shiftw = isChroma ? desc->log2_chroma_w : 0;
2180  int shifth = isChroma ? desc->log2_chroma_h : 0;
2181  widths[p] = (avctx->width + ((1 << shiftw) >> 1)) >> shiftw;
2182  heights[p] = (avctx->height + ((1 << shifth) >> 1)) >> shifth;
2183  strides[p] = frame->linesize[p];
2184  }
2185 
2186  *contiguous_buf_size = 0;
2187  for (i = 0; i < *plane_count; i++) {
2188  if (i < *plane_count - 1 &&
2189  frame->data[i] + strides[i] * heights[i] != frame->data[i + 1]) {
2190  *contiguous_buf_size = 0;
2191  break;
2192  }
2193 
2194  *contiguous_buf_size += strides[i] * heights[i];
2195  }
2196 
2197  return 0;
2198 }
2199 
2200 //Not used on OSX - frame is never copied.
2202  const AVFrame *frame,
2203  CVPixelBufferRef cv_img,
2204  const size_t *plane_strides,
2205  const size_t *plane_rows)
2206 {
2207  int i, j;
2208  size_t plane_count;
2209  int status;
2210  int rows;
2211  int src_stride;
2212  int dst_stride;
2213  uint8_t *src_addr;
2214  uint8_t *dst_addr;
2215  size_t copy_bytes;
2216 
2217  status = CVPixelBufferLockBaseAddress(cv_img, 0);
2218  if (status) {
2219  av_log(
2220  avctx,
2221  AV_LOG_ERROR,
2222  "Error: Could not lock base address of CVPixelBuffer: %d.\n",
2223  status
2224  );
2225  }
2226 
2227  if (CVPixelBufferIsPlanar(cv_img)) {
2228  plane_count = CVPixelBufferGetPlaneCount(cv_img);
2229  for (i = 0; frame->data[i]; i++) {
2230  if (i == plane_count) {
2231  CVPixelBufferUnlockBaseAddress(cv_img, 0);
2232  av_log(avctx,
2233  AV_LOG_ERROR,
2234  "Error: different number of planes in AVFrame and CVPixelBuffer.\n"
2235  );
2236 
2237  return AVERROR_EXTERNAL;
2238  }
2239 
2240  dst_addr = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(cv_img, i);
2241  src_addr = (uint8_t*)frame->data[i];
2242  dst_stride = CVPixelBufferGetBytesPerRowOfPlane(cv_img, i);
2243  src_stride = plane_strides[i];
2244  rows = plane_rows[i];
2245 
2246  if (dst_stride == src_stride) {
2247  memcpy(dst_addr, src_addr, src_stride * rows);
2248  } else {
2249  copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
2250 
2251  for (j = 0; j < rows; j++) {
2252  memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
2253  }
2254  }
2255  }
2256  } else {
2257  if (frame->data[1]) {
2258  CVPixelBufferUnlockBaseAddress(cv_img, 0);
2259  av_log(avctx,
2260  AV_LOG_ERROR,
2261  "Error: different number of planes in AVFrame and non-planar CVPixelBuffer.\n"
2262  );
2263 
2264  return AVERROR_EXTERNAL;
2265  }
2266 
2267  dst_addr = (uint8_t*)CVPixelBufferGetBaseAddress(cv_img);
2268  src_addr = (uint8_t*)frame->data[0];
2269  dst_stride = CVPixelBufferGetBytesPerRow(cv_img);
2270  src_stride = plane_strides[0];
2271  rows = plane_rows[0];
2272 
2273  if (dst_stride == src_stride) {
2274  memcpy(dst_addr, src_addr, src_stride * rows);
2275  } else {
2276  copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
2277 
2278  for (j = 0; j < rows; j++) {
2279  memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
2280  }
2281  }
2282  }
2283 
2284  status = CVPixelBufferUnlockBaseAddress(cv_img, 0);
2285  if (status) {
2286  av_log(avctx, AV_LOG_ERROR, "Error: Could not unlock CVPixelBuffer base address: %d.\n", status);
2287  return AVERROR_EXTERNAL;
2288  }
2289 
2290  return 0;
2291 }
2292 
2294  const AVFrame *frame,
2295  CVPixelBufferRef *cv_img)
2296 {
2297  int plane_count;
2298  int color;
2299  size_t widths [AV_NUM_DATA_POINTERS];
2300  size_t heights[AV_NUM_DATA_POINTERS];
2301  size_t strides[AV_NUM_DATA_POINTERS];
2302  int status;
2303  size_t contiguous_buf_size;
2304  CVPixelBufferPoolRef pix_buf_pool;
2305  VTEncContext* vtctx = avctx->priv_data;
2306 
2307  if (avctx->pix_fmt == AV_PIX_FMT_VIDEOTOOLBOX) {
2309 
2310  *cv_img = (CVPixelBufferRef)frame->data[3];
2311  av_assert0(*cv_img);
2312 
2313  CFRetain(*cv_img);
2314  return 0;
2315  }
2316 
2317  memset(widths, 0, sizeof(widths));
2318  memset(heights, 0, sizeof(heights));
2319  memset(strides, 0, sizeof(strides));
2320 
2322  avctx,
2323  frame,
2324  &color,
2325  &plane_count,
2326  widths,
2327  heights,
2328  strides,
2329  &contiguous_buf_size
2330  );
2331 
2332  if (status) {
2333  av_log(
2334  avctx,
2335  AV_LOG_ERROR,
2336  "Error: Cannot convert format %d color_range %d: %d\n",
2337  frame->format,
2338  frame->color_range,
2339  status
2340  );
2341 
2342  return AVERROR_EXTERNAL;
2343  }
2344 
2345  pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2346  if (!pix_buf_pool) {
2347  /* On iOS, the VT session is invalidated when the APP switches from
2348  * foreground to background and vice versa. Fetch the actual error code
2349  * of the VT session to detect that case and restart the VT session
2350  * accordingly. */
2351  OSStatus vtstatus;
2352 
2353  vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
2354  if (vtstatus == kVTInvalidSessionErr) {
2355  CFRelease(vtctx->session);
2356  vtctx->session = NULL;
2358  if (status == 0)
2359  pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2360  }
2361  if (!pix_buf_pool) {
2362  av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer pool.\n");
2363  return AVERROR_EXTERNAL;
2364  }
2365  else
2366  av_log(avctx, AV_LOG_WARNING, "VT session restarted because of a "
2367  "kVTInvalidSessionErr error.\n");
2368  }
2369 
2370  status = CVPixelBufferPoolCreatePixelBuffer(NULL,
2371  pix_buf_pool,
2372  cv_img);
2373 
2374 
2375  if (status) {
2376  av_log(avctx, AV_LOG_ERROR, "Could not create pixel buffer from pool: %d.\n", status);
2377  return AVERROR_EXTERNAL;
2378  }
2379 
2380  status = copy_avframe_to_pixel_buffer(avctx, frame, *cv_img, strides, heights);
2381  if (status) {
2382  CFRelease(*cv_img);
2383  *cv_img = NULL;
2384  return status;
2385  }
2386 
2387  return 0;
2388 }
2389 
2391  CFDictionaryRef* dict_out)
2392 {
2393  CFDictionaryRef dict = NULL;
2394  if (frame->pict_type == AV_PICTURE_TYPE_I) {
2395  const void *keys[] = { kVTEncodeFrameOptionKey_ForceKeyFrame };
2396  const void *vals[] = { kCFBooleanTrue };
2397 
2398  dict = CFDictionaryCreate(NULL, keys, vals, 1, NULL, NULL);
2399  if(!dict) return AVERROR(ENOMEM);
2400  }
2401 
2402  *dict_out = dict;
2403  return 0;
2404 }
2405 
2407  VTEncContext *vtctx,
2408  const AVFrame *frame)
2409 {
2410  CMTime time;
2411  CFDictionaryRef frame_dict;
2412  CVPixelBufferRef cv_img = NULL;
2413  AVFrameSideData *side_data = NULL;
2414  ExtraSEI *sei = NULL;
2415  int status = create_cv_pixel_buffer(avctx, frame, &cv_img);
2416 
2417  if (status) return status;
2418 
2419  status = create_encoder_dict_h264(frame, &frame_dict);
2420  if (status) {
2421  CFRelease(cv_img);
2422  return status;
2423  }
2424 
2425 #if CONFIG_ATSC_A53
2427  if (vtctx->a53_cc && side_data && side_data->size) {
2428  sei = av_mallocz(sizeof(*sei));
2429  if (!sei) {
2430  av_log(avctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2431  } else {
2432  int ret = ff_alloc_a53_sei(frame, 0, &sei->data, &sei->size);
2433  if (ret < 0) {
2434  av_log(avctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2435  av_free(sei);
2436  sei = NULL;
2437  }
2438  }
2439  }
2440 #endif
2441 
2442  time = CMTimeMake(frame->pts * avctx->time_base.num, avctx->time_base.den);
2443  status = VTCompressionSessionEncodeFrame(
2444  vtctx->session,
2445  cv_img,
2446  time,
2447  kCMTimeInvalid,
2448  frame_dict,
2449  sei,
2450  NULL
2451  );
2452 
2453  if (frame_dict) CFRelease(frame_dict);
2454  CFRelease(cv_img);
2455 
2456  if (status) {
2457  av_log(avctx, AV_LOG_ERROR, "Error: cannot encode frame: %d\n", status);
2458  return AVERROR_EXTERNAL;
2459  }
2460 
2461  return 0;
2462 }
2463 
2465  AVCodecContext *avctx,
2466  AVPacket *pkt,
2467  const AVFrame *frame,
2468  int *got_packet)
2469 {
2470  VTEncContext *vtctx = avctx->priv_data;
2471  bool get_frame;
2472  int status;
2473  CMSampleBufferRef buf = NULL;
2474  ExtraSEI *sei = NULL;
2475 
2476  if (frame) {
2477  status = vtenc_send_frame(avctx, vtctx, frame);
2478 
2479  if (status) {
2481  goto end_nopkt;
2482  }
2483 
2484  if (vtctx->frame_ct_in == 0) {
2485  vtctx->first_pts = frame->pts;
2486  } else if(vtctx->frame_ct_in == vtctx->has_b_frames) {
2487  vtctx->dts_delta = frame->pts - vtctx->first_pts;
2488  }
2489 
2490  vtctx->frame_ct_in++;
2491  } else if(!vtctx->flushing) {
2492  vtctx->flushing = true;
2493 
2494  status = VTCompressionSessionCompleteFrames(vtctx->session,
2495  kCMTimeIndefinite);
2496 
2497  if (status) {
2498  av_log(avctx, AV_LOG_ERROR, "Error flushing frames: %d\n", status);
2500  goto end_nopkt;
2501  }
2502  }
2503 
2504  *got_packet = 0;
2505  get_frame = vtctx->dts_delta >= 0 || !frame;
2506  if (!get_frame) {
2507  status = 0;
2508  goto end_nopkt;
2509  }
2510 
2511  status = vtenc_q_pop(vtctx, !frame, &buf, &sei);
2512  if (status) goto end_nopkt;
2513  if (!buf) goto end_nopkt;
2514 
2515  status = vtenc_cm_to_avpacket(avctx, buf, pkt, sei);
2516  if (sei) {
2517  if (sei->data) av_free(sei->data);
2518  av_free(sei);
2519  }
2520  CFRelease(buf);
2521  if (status) goto end_nopkt;
2522 
2523  *got_packet = 1;
2524  return 0;
2525 
2526 end_nopkt:
2528  return status;
2529 }
2530 
2532  CMVideoCodecType codec_type,
2533  CFStringRef profile_level,
2534  CFNumberRef gamma_level,
2535  CFDictionaryRef enc_info,
2536  CFDictionaryRef pixel_buffer_info)
2537 {
2538  VTEncContext *vtctx = avctx->priv_data;
2539  int status;
2540  CVPixelBufferPoolRef pool = NULL;
2541  CVPixelBufferRef pix_buf = NULL;
2542  CMTime time;
2543  CMSampleBufferRef buf = NULL;
2544 
2545  status = vtenc_create_encoder(avctx,
2546  codec_type,
2547  profile_level,
2548  gamma_level,
2549  enc_info,
2550  pixel_buffer_info,
2551  vtctx->constant_bit_rate,
2552  &vtctx->session);
2553  if (status)
2554  goto pe_cleanup;
2555 
2556  pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2557  if(!pool){
2558  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);
2568  goto pe_cleanup;
2569  }
2570 
2571  time = CMTimeMake(0, avctx->time_base.den);
2572  status = VTCompressionSessionEncodeFrame(vtctx->session,
2573  pix_buf,
2574  time,
2575  kCMTimeInvalid,
2576  NULL,
2577  NULL,
2578  NULL);
2579 
2580  if (status) {
2581  av_log(avctx,
2582  AV_LOG_ERROR,
2583  "Error sending frame for extradata: %d\n",
2584  status);
2585 
2586  goto pe_cleanup;
2587  }
2588 
2589  //Populates extradata - output frames are flushed and param sets are available.
2590  status = VTCompressionSessionCompleteFrames(vtctx->session,
2591  kCMTimeIndefinite);
2592 
2593  if (status)
2594  goto pe_cleanup;
2595 
2596  status = vtenc_q_pop(vtctx, 0, &buf, NULL);
2597  if (status) {
2598  av_log(avctx, AV_LOG_ERROR, "popping: %d\n", status);
2599  goto pe_cleanup;
2600  }
2601 
2602  CFRelease(buf);
2603 
2604 
2605 
2606 pe_cleanup:
2607  CVPixelBufferRelease(pix_buf);
2608  if(vtctx->session)
2609  CFRelease(vtctx->session);
2610 
2611  vtctx->session = NULL;
2612  vtctx->frame_ct_out = 0;
2613 
2614  av_assert0(status != 0 || (avctx->extradata && avctx->extradata_size > 0));
2615 
2616  return status;
2617 }
2618 
2620 {
2621  VTEncContext *vtctx = avctx->priv_data;
2622 
2623  if(!vtctx->session) {
2625  pthread_mutex_destroy(&vtctx->lock);
2626  return 0;
2627  }
2628 
2629  VTCompressionSessionCompleteFrames(vtctx->session,
2630  kCMTimeIndefinite);
2631  clear_frame_queue(vtctx);
2633  pthread_mutex_destroy(&vtctx->lock);
2634  CFRelease(vtctx->session);
2635  vtctx->session = NULL;
2636 
2637  if (vtctx->color_primaries) {
2638  CFRelease(vtctx->color_primaries);
2639  vtctx->color_primaries = NULL;
2640  }
2641 
2642  if (vtctx->transfer_function) {
2643  CFRelease(vtctx->transfer_function);
2644  vtctx->transfer_function = NULL;
2645  }
2646 
2647  if (vtctx->ycbcr_matrix) {
2648  CFRelease(vtctx->ycbcr_matrix);
2649  vtctx->ycbcr_matrix = NULL;
2650  }
2651 
2652  return 0;
2653 }
2654 
2655 static const enum AVPixelFormat avc_pix_fmts[] = {
2660 };
2661 
2662 static const enum AVPixelFormat hevc_pix_fmts[] = {
2669 };
2670 
2671 static const enum AVPixelFormat prores_pix_fmts[] = {
2674 #ifdef kCFCoreFoundationVersionNumber10_7
2677 #endif
2679 #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
2681 #endif
2682 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE
2684 #endif
2685 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE
2687 #endif
2688 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE
2690 #endif
2691 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE
2693 #endif
2694 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE
2696 #endif
2697 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE
2699 #endif
2702 };
2703 
2704 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
2705 #define COMMON_OPTIONS \
2706  { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \
2707  { .i64 = 0 }, 0, 1, VE }, \
2708  { "require_sw", "Require software encoding", OFFSET(require_sw), AV_OPT_TYPE_BOOL, \
2709  { .i64 = 0 }, 0, 1, VE }, \
2710  { "realtime", "Hint that encoding should happen in real-time if not faster (e.g. capturing from camera).", \
2711  OFFSET(realtime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, -1, 1, VE }, \
2712  { "frames_before", "Other frames will come before the frames in this session. This helps smooth concatenation issues.", \
2713  OFFSET(frames_before), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \
2714  { "frames_after", "Other frames will come after the frames in this session. This helps smooth concatenation issues.", \
2715  OFFSET(frames_after), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \
2716  { "prio_speed", "prioritize encoding speed", OFFSET(prio_speed), AV_OPT_TYPE_BOOL, \
2717  { .i64 = -1 }, -1, 1, VE }, \
2718 
2719 #define OFFSET(x) offsetof(VTEncContext, x)
2720 static const AVOption h264_options[] = {
2721  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = H264_PROF_AUTO }, H264_PROF_AUTO, H264_PROF_COUNT, VE, "profile" },
2722  { "baseline", "Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_BASELINE }, INT_MIN, INT_MAX, VE, "profile" },
2723  { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
2724  { "high", "High Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_HIGH }, INT_MIN, INT_MAX, VE, "profile" },
2725  { "extended", "Extend Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_EXTENDED }, INT_MIN, INT_MAX, VE, "profile" },
2726 
2727  { "level", "Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, VE, "level" },
2728  { "1.3", "Level 1.3, only available with Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = 13 }, INT_MIN, INT_MAX, VE, "level" },
2729  { "3.0", "Level 3.0", 0, AV_OPT_TYPE_CONST, { .i64 = 30 }, INT_MIN, INT_MAX, VE, "level" },
2730  { "3.1", "Level 3.1", 0, AV_OPT_TYPE_CONST, { .i64 = 31 }, INT_MIN, INT_MAX, VE, "level" },
2731  { "3.2", "Level 3.2", 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, INT_MIN, INT_MAX, VE, "level" },
2732  { "4.0", "Level 4.0", 0, AV_OPT_TYPE_CONST, { .i64 = 40 }, INT_MIN, INT_MAX, VE, "level" },
2733  { "4.1", "Level 4.1", 0, AV_OPT_TYPE_CONST, { .i64 = 41 }, INT_MIN, INT_MAX, VE, "level" },
2734  { "4.2", "Level 4.2", 0, AV_OPT_TYPE_CONST, { .i64 = 42 }, INT_MIN, INT_MAX, VE, "level" },
2735  { "5.0", "Level 5.0", 0, AV_OPT_TYPE_CONST, { .i64 = 50 }, INT_MIN, INT_MAX, VE, "level" },
2736  { "5.1", "Level 5.1", 0, AV_OPT_TYPE_CONST, { .i64 = 51 }, INT_MIN, INT_MAX, VE, "level" },
2737  { "5.2", "Level 5.2", 0, AV_OPT_TYPE_CONST, { .i64 = 52 }, INT_MIN, INT_MAX, VE, "level" },
2738 
2739  { "coder", "Entropy coding", OFFSET(entropy), AV_OPT_TYPE_INT, { .i64 = VT_ENTROPY_NOT_SET }, VT_ENTROPY_NOT_SET, VT_CABAC, VE, "coder" },
2740  { "cavlc", "CAVLC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CAVLC }, INT_MIN, INT_MAX, VE, "coder" },
2741  { "vlc", "CAVLC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CAVLC }, INT_MIN, INT_MAX, VE, "coder" },
2742  { "cabac", "CABAC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CABAC }, INT_MIN, INT_MAX, VE, "coder" },
2743  { "ac", "CABAC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CABAC }, INT_MIN, INT_MAX, VE, "coder" },
2744 
2745  { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, VE },
2746 
2747  { "constant_bit_rate", "Require constant bit rate (macOS 13 or newer)", OFFSET(constant_bit_rate), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
2748 
2750  { NULL },
2751 };
2752 
2754  .class_name = "h264_videotoolbox",
2755  .item_name = av_default_item_name,
2756  .option = h264_options,
2757  .version = LIBAVUTIL_VERSION_INT,
2758 };
2759 
2761  .p.name = "h264_videotoolbox",
2762  CODEC_LONG_NAME("VideoToolbox H.264 Encoder"),
2763  .p.type = AVMEDIA_TYPE_VIDEO,
2764  .p.id = AV_CODEC_ID_H264,
2765  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
2766  .priv_data_size = sizeof(VTEncContext),
2767  .p.pix_fmts = avc_pix_fmts,
2768  .init = vtenc_init,
2770  .close = vtenc_close,
2771  .p.priv_class = &h264_videotoolbox_class,
2772  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
2773 };
2774 
2775 static const AVOption hevc_options[] = {
2776  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = HEVC_PROF_AUTO }, HEVC_PROF_AUTO, HEVC_PROF_COUNT, VE, "profile" },
2777  { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 = HEVC_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
2778  { "main10", "Main10 Profile", 0, AV_OPT_TYPE_CONST, { .i64 = HEVC_PROF_MAIN10 }, INT_MIN, INT_MAX, VE, "profile" },
2779 
2780  { "alpha_quality", "Compression quality for the alpha channel", OFFSET(alpha_quality), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0.0, 1.0, VE },
2781 
2782  { "constant_bit_rate", "Require constant bit rate (macOS 13 or newer)", OFFSET(constant_bit_rate), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
2783 
2785  { NULL },
2786 };
2787 
2789  .class_name = "hevc_videotoolbox",
2790  .item_name = av_default_item_name,
2791  .option = hevc_options,
2792  .version = LIBAVUTIL_VERSION_INT,
2793 };
2794 
2796  .p.name = "hevc_videotoolbox",
2797  CODEC_LONG_NAME("VideoToolbox H.265 Encoder"),
2798  .p.type = AVMEDIA_TYPE_VIDEO,
2799  .p.id = AV_CODEC_ID_HEVC,
2800  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2802  .priv_data_size = sizeof(VTEncContext),
2803  .p.pix_fmts = hevc_pix_fmts,
2804  .init = vtenc_init,
2806  .close = vtenc_close,
2807  .p.priv_class = &hevc_videotoolbox_class,
2808  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
2809  .p.wrapper_name = "videotoolbox",
2810 };
2811 
2812 static const AVOption prores_options[] = {
2813  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_PRORES_XQ, VE, "profile" },
2814  { "auto", "Automatically determine based on input format", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, VE, "profile" },
2815  { "proxy", "ProRes 422 Proxy", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_PROXY }, INT_MIN, INT_MAX, VE, "profile" },
2816  { "lt", "ProRes 422 LT", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_LT }, INT_MIN, INT_MAX, VE, "profile" },
2817  { "standard", "ProRes 422", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_STANDARD }, INT_MIN, INT_MAX, VE, "profile" },
2818  { "hq", "ProRes 422 HQ", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_HQ }, INT_MIN, INT_MAX, VE, "profile" },
2819  { "4444", "ProRes 4444", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_4444 }, INT_MIN, INT_MAX, VE, "profile" },
2820  { "xq", "ProRes 4444 XQ", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_XQ }, INT_MIN, INT_MAX, VE, "profile" },
2821 
2823  { NULL },
2824 };
2825 
2827  .class_name = "prores_videotoolbox",
2828  .item_name = av_default_item_name,
2829  .option = prores_options,
2830  .version = LIBAVUTIL_VERSION_INT,
2831 };
2832 
2834  .p.name = "prores_videotoolbox",
2835  CODEC_LONG_NAME("VideoToolbox ProRes Encoder"),
2836  .p.type = AVMEDIA_TYPE_VIDEO,
2837  .p.id = AV_CODEC_ID_PRORES,
2838  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2840  .priv_data_size = sizeof(VTEncContext),
2841  .p.pix_fmts = prores_pix_fmts,
2842  .init = vtenc_init,
2844  .close = vtenc_close,
2845  .p.priv_class = &prores_videotoolbox_class,
2846  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
2847  .p.wrapper_name = "videotoolbox",
2848 };
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:2760
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:2795
FF_PROFILE_PRORES_XQ
#define FF_PROFILE_PRORES_XQ
Definition: avcodec.h:1663
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:2662
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:975
AVColorTransferCharacteristic
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:558
color
Definition: vf_paletteuse.c:601
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:2531
av_frame_get_side_data
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
Definition: frame.c:691
vtenc_cm_to_avpacket
static int vtenc_cm_to_avpacket(AVCodecContext *avctx, CMSampleBufferRef sample_buffer, AVPacket *pkt, ExtraSEI *sei)
Definition: videotoolboxenc.c:1997
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2858
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:2201
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:1750
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
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:968
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:119
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:1083
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:284
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:1823
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2898
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:1599
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:123
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:3234
vtenc_close
static av_cold int vtenc_close(AVCodecContext *avctx)
Definition: videotoolboxenc.c:2619
AVCOL_RANGE_NB
@ AVCOL_RANGE_NB
Not part of ABI.
Definition: pixfmt.h:662
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:859
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:478
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:307
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:2390
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:1659
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:2720
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:961
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:234
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:2655
kVTProfileLevel_H264_High_4_2
CFStringRef kVTProfileLevel_H264_High_4_2
Definition: videotoolboxenc.c:91
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:500
AVCodecContext::has_b_frames
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:694
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:2775
AVCodecContext::global_quality
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:464
prores_pix_fmts
static enum AVPixelFormat prores_pix_fmts[]
Definition: videotoolboxenc.c:2671
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:2812
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:1551
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:1223
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:264
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:408
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:3174
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:982
prores_videotoolbox_class
static const AVClass prores_videotoolbox_class
Definition: videotoolboxenc.c:2826
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:2753
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:448
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:881
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3192
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:1078
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
AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_UNSPECIFIED
Definition: pixfmt.h:627
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:78
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:982
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:521
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:593
AVCOL_TRC_SMPTE240M
@ AVCOL_TRC_SMPTE240M
Definition: pixfmt.h:566
FF_PROFILE_PRORES_HQ
#define FF_PROFILE_PRORES_HQ
Definition: avcodec.h:1661
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:1660
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:326
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:2293
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:2788
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:2705
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:499
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:1699
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:1626
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:571
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:608
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:1662
FF_PROFILE_PRORES_PROXY
#define FF_PROFILE_PRORES_PROXY
Definition: avcodec.h:1658
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:1444
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:398
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:2127
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:1045
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
OFFSET
#define OFFSET(x)
Definition: videotoolboxenc.c:2719
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:670
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:2406
VE
#define VE
Definition: videotoolboxenc.c:2704
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:231
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:423
ff_prores_videotoolbox_encoder
const FFCodec ff_prores_videotoolbox_encoder
Definition: videotoolboxenc.c:2833
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:425
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:1980
vtenc_frame
static av_cold int vtenc_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: videotoolboxenc.c:2464
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:1637
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:571
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:1742
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:3213
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:768
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:2778
vtenc_init
static av_cold int vtenc_init(AVCodecContext *avctx)
Definition: videotoolboxenc.c:1565
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:948
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:74
kVTCompressionPropertyKey_TargetQualityForAlpha
CFStringRef kVTCompressionPropertyKey_TargetQualityForAlpha
Definition: videotoolboxenc.c:102