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  for (i = 0; i < length_code_size; i++) {
403  box_len <<= 8;
404  box_len |= size_buf[i];
405  }
406 
407  curr_src_len = box_len + length_code_size;
408  offset += curr_src_len;
409 
410  nalu_ct++;
411  }
412 
413  *count = nalu_ct;
414  return 0;
415 }
416 
417 static CMVideoCodecType get_cm_codec_type(AVCodecContext *avctx,
418  int64_t profile,
419  double alpha_quality)
420 {
422  switch (avctx->codec_id) {
423  case AV_CODEC_ID_H264: return kCMVideoCodecType_H264;
424  case AV_CODEC_ID_HEVC:
425  if (desc && (desc->flags & AV_PIX_FMT_FLAG_ALPHA) && alpha_quality > 0.0) {
427  }
428  return kCMVideoCodecType_HEVC;
429  case AV_CODEC_ID_PRORES:
430  switch (profile) {
432  return MKBETAG('a','p','c','o'); // kCMVideoCodecType_AppleProRes422Proxy
434  return MKBETAG('a','p','c','s'); // kCMVideoCodecType_AppleProRes422LT
436  return MKBETAG('a','p','c','n'); // kCMVideoCodecType_AppleProRes422
438  return MKBETAG('a','p','c','h'); // kCMVideoCodecType_AppleProRes422HQ
440  return MKBETAG('a','p','4','h'); // kCMVideoCodecType_AppleProRes4444
442  return MKBETAG('a','p','4','x'); // kCMVideoCodecType_AppleProRes4444XQ
443 
444  default:
445  av_log(avctx, AV_LOG_ERROR, "Unknown profile ID: %"PRId64", using auto\n", profile);
446  case FF_PROFILE_UNKNOWN:
447  if (desc &&
448  ((desc->flags & AV_PIX_FMT_FLAG_ALPHA) ||
449  desc->log2_chroma_w == 0))
450  return MKBETAG('a','p','4','h'); // kCMVideoCodecType_AppleProRes4444
451  else
452  return MKBETAG('a','p','c','n'); // kCMVideoCodecType_AppleProRes422
453  }
454  default: return 0;
455  }
456 }
457 
458 /**
459  * Get the parameter sets from a CMSampleBufferRef.
460  * @param dst If *dst isn't NULL, the parameters are copied into existing
461  * memory. *dst_size must be set accordingly when *dst != NULL.
462  * If *dst is NULL, it will be allocated.
463  * In all cases, *dst_size is set to the number of bytes used starting
464  * at *dst.
465  */
466 static int get_params_size(
467  AVCodecContext *avctx,
468  CMVideoFormatDescriptionRef vid_fmt,
469  size_t *size)
470 {
471  VTEncContext *vtctx = avctx->priv_data;
472  size_t total_size = 0;
473  size_t ps_count;
474  int is_count_bad = 0;
475  size_t i;
476  int status;
477  status = vtctx->get_param_set_func(vid_fmt,
478  0,
479  NULL,
480  NULL,
481  &ps_count,
482  NULL);
483  if (status) {
484  is_count_bad = 1;
485  ps_count = 0;
486  status = 0;
487  }
488 
489  for (i = 0; i < ps_count || is_count_bad; i++) {
490  const uint8_t *ps;
491  size_t ps_size;
492  status = vtctx->get_param_set_func(vid_fmt,
493  i,
494  &ps,
495  &ps_size,
496  NULL,
497  NULL);
498  if (status) {
499  /*
500  * When ps_count is invalid, status != 0 ends the loop normally
501  * unless we didn't get any parameter sets.
502  */
503  if (i > 0 && is_count_bad) status = 0;
504 
505  break;
506  }
507 
508  total_size += ps_size + sizeof(start_code);
509  }
510 
511  if (status) {
512  av_log(avctx, AV_LOG_ERROR, "Error getting parameter set sizes: %d\n", status);
513  return AVERROR_EXTERNAL;
514  }
515 
516  *size = total_size;
517  return 0;
518 }
519 
520 static int copy_param_sets(
521  AVCodecContext *avctx,
522  CMVideoFormatDescriptionRef vid_fmt,
523  uint8_t *dst,
524  size_t dst_size)
525 {
526  VTEncContext *vtctx = avctx->priv_data;
527  size_t ps_count;
528  int is_count_bad = 0;
529  int status;
530  size_t offset = 0;
531  size_t i;
532 
533  status = vtctx->get_param_set_func(vid_fmt,
534  0,
535  NULL,
536  NULL,
537  &ps_count,
538  NULL);
539  if (status) {
540  is_count_bad = 1;
541  ps_count = 0;
542  status = 0;
543  }
544 
545 
546  for (i = 0; i < ps_count || is_count_bad; i++) {
547  const uint8_t *ps;
548  size_t ps_size;
549  size_t next_offset;
550 
551  status = vtctx->get_param_set_func(vid_fmt,
552  i,
553  &ps,
554  &ps_size,
555  NULL,
556  NULL);
557  if (status) {
558  if (i > 0 && is_count_bad) status = 0;
559 
560  break;
561  }
562 
563  next_offset = offset + sizeof(start_code) + ps_size;
564  if (dst_size < next_offset) {
565  av_log(avctx, AV_LOG_ERROR, "Error: buffer too small for parameter sets.\n");
567  }
568 
569  memcpy(dst + offset, start_code, sizeof(start_code));
570  offset += sizeof(start_code);
571 
572  memcpy(dst + offset, ps, ps_size);
573  offset = next_offset;
574  }
575 
576  if (status) {
577  av_log(avctx, AV_LOG_ERROR, "Error getting parameter set data: %d\n", status);
578  return AVERROR_EXTERNAL;
579  }
580 
581  return 0;
582 }
583 
584 static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer)
585 {
586  VTEncContext *vtctx = avctx->priv_data;
587  CMVideoFormatDescriptionRef vid_fmt;
588  size_t total_size;
589  int status;
590 
591  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
592  if (!vid_fmt) {
593  av_log(avctx, AV_LOG_ERROR, "No video format.\n");
594  return AVERROR_EXTERNAL;
595  }
596 
597  if (vtctx->get_param_set_func) {
598  status = get_params_size(avctx, vid_fmt, &total_size);
599  if (status) {
600  av_log(avctx, AV_LOG_ERROR, "Could not get parameter sets.\n");
601  return status;
602  }
603 
604  avctx->extradata = av_mallocz(total_size + AV_INPUT_BUFFER_PADDING_SIZE);
605  if (!avctx->extradata) {
606  return AVERROR(ENOMEM);
607  }
608  avctx->extradata_size = total_size;
609 
610  status = copy_param_sets(avctx, vid_fmt, avctx->extradata, total_size);
611 
612  if (status) {
613  av_log(avctx, AV_LOG_ERROR, "Could not copy param sets.\n");
614  return status;
615  }
616  } else {
617  CFDataRef data = CMFormatDescriptionGetExtension(vid_fmt, kCMFormatDescriptionExtension_VerbatimSampleDescription);
618  if (data && CFGetTypeID(data) == CFDataGetTypeID()) {
619  CFIndex size = CFDataGetLength(data);
620 
622  if (!avctx->extradata)
623  return AVERROR(ENOMEM);
624  avctx->extradata_size = size;
625 
626  CFDataGetBytes(data, CFRangeMake(0, size), avctx->extradata);
627  }
628  }
629 
630  return 0;
631 }
632 
634  void *ctx,
635  void *sourceFrameCtx,
636  OSStatus status,
637  VTEncodeInfoFlags flags,
638  CMSampleBufferRef sample_buffer)
639 {
640  AVCodecContext *avctx = ctx;
641  VTEncContext *vtctx = avctx->priv_data;
642  ExtraSEI *sei = sourceFrameCtx;
643 
644  if (vtctx->async_error) {
645  return;
646  }
647 
648  if (status) {
649  av_log(avctx, AV_LOG_ERROR, "Error encoding frame: %d\n", (int)status);
651  return;
652  }
653 
654  if (!sample_buffer) {
655  return;
656  }
657 
658  if (!avctx->extradata && (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
659  int set_status = set_extradata(avctx, sample_buffer);
660  if (set_status) {
661  set_async_error(vtctx, set_status);
662  return;
663  }
664  }
665 
666  vtenc_q_push(vtctx, sample_buffer, sei);
667 }
668 
670  AVCodecContext *avctx,
671  CMSampleBufferRef sample_buffer,
672  size_t *size)
673 {
674  VTEncContext *vtctx = avctx->priv_data;
675  CMVideoFormatDescriptionRef vid_fmt;
676  int isize;
677  int status;
678 
679  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
680  if (!vid_fmt) {
681  av_log(avctx, AV_LOG_ERROR, "Error getting buffer format description.\n");
682  return AVERROR_EXTERNAL;
683  }
684 
685  status = vtctx->get_param_set_func(vid_fmt,
686  0,
687  NULL,
688  NULL,
689  NULL,
690  &isize);
691  if (status) {
692  av_log(avctx, AV_LOG_ERROR, "Error getting length code size: %d\n", status);
693  return AVERROR_EXTERNAL;
694  }
695 
696  *size = isize;
697  return 0;
698 }
699 
700 /*
701  * Returns true on success.
702  *
703  * If profile_level_val is NULL and this method returns true, don't specify the
704  * profile/level to the encoder.
705  */
707  CFStringRef *profile_level_val)
708 {
709  VTEncContext *vtctx = avctx->priv_data;
710  int64_t profile = vtctx->profile;
711 
712  if (profile == H264_PROF_AUTO && vtctx->level) {
713  //Need to pick a profile if level is not auto-selected.
715  }
716 
717  *profile_level_val = NULL;
718 
719  switch (profile) {
720  case H264_PROF_AUTO:
721  return true;
722 
723  case H264_PROF_BASELINE:
724  switch (vtctx->level) {
725  case 0: *profile_level_val =
726  compat_keys.kVTProfileLevel_H264_Baseline_AutoLevel; break;
727  case 13: *profile_level_val = kVTProfileLevel_H264_Baseline_1_3; break;
728  case 30: *profile_level_val = kVTProfileLevel_H264_Baseline_3_0; break;
729  case 31: *profile_level_val = kVTProfileLevel_H264_Baseline_3_1; break;
730  case 32: *profile_level_val = kVTProfileLevel_H264_Baseline_3_2; break;
731  case 40: *profile_level_val =
732  compat_keys.kVTProfileLevel_H264_Baseline_4_0; break;
733  case 41: *profile_level_val = kVTProfileLevel_H264_Baseline_4_1; break;
734  case 42: *profile_level_val =
735  compat_keys.kVTProfileLevel_H264_Baseline_4_2; break;
736  case 50: *profile_level_val =
737  compat_keys.kVTProfileLevel_H264_Baseline_5_0; break;
738  case 51: *profile_level_val =
739  compat_keys.kVTProfileLevel_H264_Baseline_5_1; break;
740  case 52: *profile_level_val =
741  compat_keys.kVTProfileLevel_H264_Baseline_5_2; break;
742  }
743  break;
744 
745  case H264_PROF_MAIN:
746  switch (vtctx->level) {
747  case 0: *profile_level_val =
748  compat_keys.kVTProfileLevel_H264_Main_AutoLevel; break;
749  case 30: *profile_level_val = kVTProfileLevel_H264_Main_3_0; break;
750  case 31: *profile_level_val = kVTProfileLevel_H264_Main_3_1; break;
751  case 32: *profile_level_val = kVTProfileLevel_H264_Main_3_2; break;
752  case 40: *profile_level_val = kVTProfileLevel_H264_Main_4_0; break;
753  case 41: *profile_level_val = kVTProfileLevel_H264_Main_4_1; break;
754  case 42: *profile_level_val =
755  compat_keys.kVTProfileLevel_H264_Main_4_2; break;
756  case 50: *profile_level_val = kVTProfileLevel_H264_Main_5_0; break;
757  case 51: *profile_level_val =
758  compat_keys.kVTProfileLevel_H264_Main_5_1; break;
759  case 52: *profile_level_val =
760  compat_keys.kVTProfileLevel_H264_Main_5_2; break;
761  }
762  break;
763 
764  case H264_PROF_HIGH:
765  switch (vtctx->level) {
766  case 0: *profile_level_val =
767  compat_keys.kVTProfileLevel_H264_High_AutoLevel; break;
768  case 30: *profile_level_val =
769  compat_keys.kVTProfileLevel_H264_High_3_0; break;
770  case 31: *profile_level_val =
771  compat_keys.kVTProfileLevel_H264_High_3_1; break;
772  case 32: *profile_level_val =
773  compat_keys.kVTProfileLevel_H264_High_3_2; break;
774  case 40: *profile_level_val =
775  compat_keys.kVTProfileLevel_H264_High_4_0; break;
776  case 41: *profile_level_val =
777  compat_keys.kVTProfileLevel_H264_High_4_1; break;
778  case 42: *profile_level_val =
779  compat_keys.kVTProfileLevel_H264_High_4_2; break;
780  case 50: *profile_level_val = kVTProfileLevel_H264_High_5_0; break;
781  case 51: *profile_level_val =
782  compat_keys.kVTProfileLevel_H264_High_5_1; break;
783  case 52: *profile_level_val =
784  compat_keys.kVTProfileLevel_H264_High_5_2; break;
785  }
786  break;
787  case H264_PROF_EXTENDED:
788  switch (vtctx->level) {
789  case 0: *profile_level_val =
790  compat_keys.kVTProfileLevel_H264_Extended_AutoLevel; break;
791  case 50: *profile_level_val =
792  compat_keys.kVTProfileLevel_H264_Extended_5_0; break;
793  }
794  break;
795  }
796 
797  if (!*profile_level_val) {
798  av_log(avctx, AV_LOG_ERROR, "Invalid Profile/Level.\n");
799  return false;
800  }
801 
802  return true;
803 }
804 
805 /*
806  * Returns true on success.
807  *
808  * If profile_level_val is NULL and this method returns true, don't specify the
809  * profile/level to the encoder.
810  */
812  CFStringRef *profile_level_val)
813 {
814  VTEncContext *vtctx = avctx->priv_data;
815  int64_t profile = vtctx->profile;
816 
817  *profile_level_val = NULL;
818 
819  switch (profile) {
820  case HEVC_PROF_AUTO:
821  return true;
822  case HEVC_PROF_MAIN:
823  *profile_level_val =
824  compat_keys.kVTProfileLevel_HEVC_Main_AutoLevel;
825  break;
826  case HEVC_PROF_MAIN10:
827  *profile_level_val =
828  compat_keys.kVTProfileLevel_HEVC_Main10_AutoLevel;
829  break;
830  }
831 
832  if (!*profile_level_val) {
833  av_log(avctx, AV_LOG_ERROR, "Invalid Profile/Level.\n");
834  return false;
835  }
836 
837  return true;
838 }
839 
841  enum AVPixelFormat fmt,
842  enum AVColorRange range,
843  int* av_pixel_format,
844  int* range_guessed)
845 {
846  if (range_guessed) *range_guessed = range != AVCOL_RANGE_MPEG &&
847  range != AVCOL_RANGE_JPEG;
848 
849  //MPEG range is used when no range is set
850  *av_pixel_format = av_map_videotoolbox_format_from_pixfmt2(fmt, range == AVCOL_RANGE_JPEG);
851 
852  return *av_pixel_format ? 0 : AVERROR(EINVAL);
853 }
854 
855 static void add_color_attr(AVCodecContext *avctx, CFMutableDictionaryRef dict) {
856  VTEncContext *vtctx = avctx->priv_data;
857 
858  if (vtctx->color_primaries) {
859  CFDictionarySetValue(dict,
860  kCVImageBufferColorPrimariesKey,
861  vtctx->color_primaries);
862  }
863 
864  if (vtctx->transfer_function) {
865  CFDictionarySetValue(dict,
866  kCVImageBufferTransferFunctionKey,
867  vtctx->transfer_function);
868  }
869 
870  if (vtctx->ycbcr_matrix) {
871  CFDictionarySetValue(dict,
872  kCVImageBufferYCbCrMatrixKey,
873  vtctx->ycbcr_matrix);
874  }
875 }
876 
878  CFMutableDictionaryRef* dict)
879 {
880  CFNumberRef cv_color_format_num = NULL;
881  CFNumberRef width_num = NULL;
882  CFNumberRef height_num = NULL;
883  CFMutableDictionaryRef pixel_buffer_info = NULL;
884  int cv_color_format;
885  int status = get_cv_pixel_format(avctx,
886  avctx->pix_fmt,
887  avctx->color_range,
888  &cv_color_format,
889  NULL);
890  if (status) return status;
891 
892  pixel_buffer_info = CFDictionaryCreateMutable(
893  kCFAllocatorDefault,
894  20,
895  &kCFCopyStringDictionaryKeyCallBacks,
896  &kCFTypeDictionaryValueCallBacks);
897 
898  if (!pixel_buffer_info) goto pbinfo_nomem;
899 
900  cv_color_format_num = CFNumberCreate(kCFAllocatorDefault,
901  kCFNumberSInt32Type,
902  &cv_color_format);
903  if (!cv_color_format_num) goto pbinfo_nomem;
904 
905  CFDictionarySetValue(pixel_buffer_info,
906  kCVPixelBufferPixelFormatTypeKey,
907  cv_color_format_num);
908  vt_release_num(&cv_color_format_num);
909 
910  width_num = CFNumberCreate(kCFAllocatorDefault,
911  kCFNumberSInt32Type,
912  &avctx->width);
913  if (!width_num) goto pbinfo_nomem;
914 
915  CFDictionarySetValue(pixel_buffer_info,
916  kCVPixelBufferWidthKey,
917  width_num);
918  vt_release_num(&width_num);
919 
920  height_num = CFNumberCreate(kCFAllocatorDefault,
921  kCFNumberSInt32Type,
922  &avctx->height);
923  if (!height_num) goto pbinfo_nomem;
924 
925  CFDictionarySetValue(pixel_buffer_info,
926  kCVPixelBufferHeightKey,
927  height_num);
928  vt_release_num(&height_num);
929 
930  add_color_attr(avctx, pixel_buffer_info);
931 
932  *dict = pixel_buffer_info;
933  return 0;
934 
935 pbinfo_nomem:
936  vt_release_num(&cv_color_format_num);
937  vt_release_num(&width_num);
938  vt_release_num(&height_num);
939  if (pixel_buffer_info) CFRelease(pixel_buffer_info);
940 
941  return AVERROR(ENOMEM);
942 }
943 
945  CFStringRef *primaries)
946 {
947  enum AVColorPrimaries pri = avctx->color_primaries;
948  switch (pri) {
950  *primaries = NULL;
951  break;
952 
953  case AVCOL_PRI_BT470BG:
954  *primaries = kCVImageBufferColorPrimaries_EBU_3213;
955  break;
956 
957  case AVCOL_PRI_SMPTE170M:
958  *primaries = kCVImageBufferColorPrimaries_SMPTE_C;
959  break;
960 
961  case AVCOL_PRI_BT709:
962  *primaries = kCVImageBufferColorPrimaries_ITU_R_709_2;
963  break;
964 
965  case AVCOL_PRI_BT2020:
966  *primaries = compat_keys.kCVImageBufferColorPrimaries_ITU_R_2020;
967  break;
968 
969  default:
970  av_log(avctx, AV_LOG_ERROR, "Color primaries %s is not supported.\n", av_color_primaries_name(pri));
971  *primaries = NULL;
972  return -1;
973  }
974 
975  return 0;
976 }
977 
979  CFStringRef *transfer_fnc,
980  CFNumberRef *gamma_level)
981 {
982  enum AVColorTransferCharacteristic trc = avctx->color_trc;
983  Float32 gamma;
984  *gamma_level = NULL;
985 
986  switch (trc) {
988  *transfer_fnc = NULL;
989  break;
990 
991  case AVCOL_TRC_BT709:
992  *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_709_2;
993  break;
994 
995  case AVCOL_TRC_SMPTE240M:
996  *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_240M_1995;
997  break;
998 
999 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_2084_PQ
1000  case AVCOL_TRC_SMPTE2084:
1001  *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ;
1002  break;
1003 #endif
1004 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_LINEAR
1005  case AVCOL_TRC_LINEAR:
1006  *transfer_fnc = kCVImageBufferTransferFunction_Linear;
1007  break;
1008 #endif
1009 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG
1011  *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_2100_HLG;
1012  break;
1013 #endif
1014 
1015  case AVCOL_TRC_GAMMA22:
1016  gamma = 2.2;
1017  *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
1018  *gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
1019  break;
1020 
1021  case AVCOL_TRC_GAMMA28:
1022  gamma = 2.8;
1023  *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
1024  *gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
1025  break;
1026 
1027  case AVCOL_TRC_BT2020_10:
1028  case AVCOL_TRC_BT2020_12:
1029  *transfer_fnc = compat_keys.kCVImageBufferTransferFunction_ITU_R_2020;
1030  break;
1031 
1032  default:
1033  *transfer_fnc = NULL;
1034  av_log(avctx, AV_LOG_ERROR, "Transfer function %s is not supported.\n", av_color_transfer_name(trc));
1035  return -1;
1036  }
1037 
1038  return 0;
1039 }
1040 
1041 static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix) {
1042  switch(avctx->colorspace) {
1043  case AVCOL_SPC_BT709:
1044  *matrix = kCVImageBufferYCbCrMatrix_ITU_R_709_2;
1045  break;
1046 
1047  case AVCOL_SPC_UNSPECIFIED:
1048  case AVCOL_SPC_RGB:
1049  *matrix = NULL;
1050  break;
1051 
1052  case AVCOL_SPC_BT470BG:
1053  case AVCOL_SPC_SMPTE170M:
1054  *matrix = kCVImageBufferYCbCrMatrix_ITU_R_601_4;
1055  break;
1056 
1057  case AVCOL_SPC_SMPTE240M:
1058  *matrix = kCVImageBufferYCbCrMatrix_SMPTE_240M_1995;
1059  break;
1060 
1061  case AVCOL_SPC_BT2020_NCL:
1062  *matrix = compat_keys.kCVImageBufferYCbCrMatrix_ITU_R_2020;
1063  break;
1064 
1065  default:
1066  av_log(avctx, AV_LOG_ERROR, "Color space %s is not supported.\n", av_color_space_name(avctx->colorspace));
1067  return -1;
1068  }
1069 
1070  return 0;
1071 }
1072 
1073 // constant quality only on Macs with Apple Silicon
1074 static bool vtenc_qscale_enabled(void)
1075 {
1076  return !TARGET_OS_IPHONE && TARGET_CPU_ARM64;
1077 }
1078 
1080  CMVideoCodecType codec_type,
1081  CFStringRef profile_level,
1082  CFNumberRef gamma_level,
1083  CFDictionaryRef enc_info,
1084  CFDictionaryRef pixel_buffer_info,
1085  bool constant_bit_rate,
1086  VTCompressionSessionRef *session)
1087 {
1088  VTEncContext *vtctx = avctx->priv_data;
1089  SInt32 bit_rate = avctx->bit_rate;
1090  SInt32 max_rate = avctx->rc_max_rate;
1091  Float32 quality = avctx->global_quality / FF_QP2LAMBDA;
1092  CFNumberRef bit_rate_num;
1093  CFNumberRef quality_num;
1094  CFNumberRef bytes_per_second;
1095  CFNumberRef one_second;
1096  CFArrayRef data_rate_limits;
1097  int64_t bytes_per_second_value = 0;
1098  int64_t one_second_value = 0;
1099  void *nums[2];
1100 
1101  int status = VTCompressionSessionCreate(kCFAllocatorDefault,
1102  avctx->width,
1103  avctx->height,
1104  codec_type,
1105  enc_info,
1106  pixel_buffer_info,
1107  kCFAllocatorDefault,
1109  avctx,
1110  session);
1111 
1112  if (status || !vtctx->session) {
1113  av_log(avctx, AV_LOG_ERROR, "Error: cannot create compression session: %d\n", status);
1114 
1115 #if !TARGET_OS_IPHONE
1116  if (!vtctx->allow_sw) {
1117  av_log(avctx, AV_LOG_ERROR, "Try -allow_sw 1. The hardware encoder may be busy, or not supported.\n");
1118  }
1119 #endif
1120 
1121  return AVERROR_EXTERNAL;
1122  }
1123 
1124  if (avctx->flags & AV_CODEC_FLAG_QSCALE && !vtenc_qscale_enabled()) {
1125  av_log(avctx, AV_LOG_ERROR, "Error: -q:v qscale not available for encoder. Use -b:v bitrate instead.\n");
1126  return AVERROR_EXTERNAL;
1127  }
1128 
1129  if (avctx->flags & AV_CODEC_FLAG_QSCALE) {
1130  quality = quality >= 100 ? 1.0 : quality / 100;
1131  quality_num = CFNumberCreate(kCFAllocatorDefault,
1132  kCFNumberFloat32Type,
1133  &quality);
1134  if (!quality_num) return AVERROR(ENOMEM);
1135 
1136  status = VTSessionSetProperty(vtctx->session,
1137  kVTCompressionPropertyKey_Quality,
1138  quality_num);
1139  CFRelease(quality_num);
1140  } else if (avctx->codec_id != AV_CODEC_ID_PRORES) {
1141  bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
1142  kCFNumberSInt32Type,
1143  &bit_rate);
1144  if (!bit_rate_num) return AVERROR(ENOMEM);
1145 
1146  if (constant_bit_rate) {
1147  status = VTSessionSetProperty(vtctx->session,
1148  compat_keys.kVTCompressionPropertyKey_ConstantBitRate,
1149  bit_rate_num);
1150  if (status == kVTPropertyNotSupportedErr) {
1151  av_log(avctx, AV_LOG_ERROR, "Error: -constant_bit_rate true is not supported by the encoder.\n");
1152  return AVERROR_EXTERNAL;
1153  }
1154  } else {
1155  status = VTSessionSetProperty(vtctx->session,
1156  kVTCompressionPropertyKey_AverageBitRate,
1157  bit_rate_num);
1158  }
1159 
1160  CFRelease(bit_rate_num);
1161  }
1162 
1163  if (status) {
1164  av_log(avctx, AV_LOG_ERROR, "Error setting bitrate property: %d\n", status);
1165  return AVERROR_EXTERNAL;
1166  }
1167 
1168  if (vtctx->prio_speed >= 0) {
1169  status = VTSessionSetProperty(vtctx->session,
1170  compat_keys.kVTCompressionPropertyKey_PrioritizeEncodingSpeedOverQuality,
1171  vtctx->prio_speed ? kCFBooleanTrue : kCFBooleanFalse);
1172  if (status) {
1173  av_log(avctx, AV_LOG_WARNING, "PrioritizeEncodingSpeedOverQuality property is not supported on this device. Ignoring.\n");
1174  }
1175  }
1176 
1177  if ((vtctx->codec_id == AV_CODEC_ID_H264 || vtctx->codec_id == AV_CODEC_ID_HEVC)
1178  && max_rate > 0) {
1179  bytes_per_second_value = max_rate >> 3;
1180  bytes_per_second = CFNumberCreate(kCFAllocatorDefault,
1181  kCFNumberSInt64Type,
1182  &bytes_per_second_value);
1183  if (!bytes_per_second) {
1184  return AVERROR(ENOMEM);
1185  }
1186  one_second_value = 1;
1187  one_second = CFNumberCreate(kCFAllocatorDefault,
1188  kCFNumberSInt64Type,
1189  &one_second_value);
1190  if (!one_second) {
1191  CFRelease(bytes_per_second);
1192  return AVERROR(ENOMEM);
1193  }
1194  nums[0] = (void *)bytes_per_second;
1195  nums[1] = (void *)one_second;
1196  data_rate_limits = CFArrayCreate(kCFAllocatorDefault,
1197  (const void **)nums,
1198  2,
1199  &kCFTypeArrayCallBacks);
1200 
1201  if (!data_rate_limits) {
1202  CFRelease(bytes_per_second);
1203  CFRelease(one_second);
1204  return AVERROR(ENOMEM);
1205  }
1206  status = VTSessionSetProperty(vtctx->session,
1207  kVTCompressionPropertyKey_DataRateLimits,
1208  data_rate_limits);
1209 
1210  CFRelease(bytes_per_second);
1211  CFRelease(one_second);
1212  CFRelease(data_rate_limits);
1213 
1214  if (status) {
1215  av_log(avctx, AV_LOG_ERROR, "Error setting max bitrate property: %d\n", status);
1216  // kVTCompressionPropertyKey_DataRateLimits is available for HEVC
1217  // now but not on old release. There is no document about since
1218  // when. So ignore the error if it failed for hevc.
1219  if (vtctx->codec_id != AV_CODEC_ID_HEVC)
1220  return AVERROR_EXTERNAL;
1221  }
1222  }
1223 
1224  if (vtctx->codec_id == AV_CODEC_ID_HEVC) {
1225  if (avctx->pix_fmt == AV_PIX_FMT_BGRA && vtctx->alpha_quality > 0.0) {
1226  CFNumberRef alpha_quality_num = CFNumberCreate(kCFAllocatorDefault,
1227  kCFNumberDoubleType,
1228  &vtctx->alpha_quality);
1229  if (!alpha_quality_num) return AVERROR(ENOMEM);
1230 
1231  status = VTSessionSetProperty(vtctx->session,
1232  compat_keys.kVTCompressionPropertyKey_TargetQualityForAlpha,
1233  alpha_quality_num);
1234  CFRelease(alpha_quality_num);
1235  }
1236  }
1237 
1238  if (profile_level) {
1239  status = VTSessionSetProperty(vtctx->session,
1240  kVTCompressionPropertyKey_ProfileLevel,
1241  profile_level);
1242  if (status) {
1243  av_log(avctx, AV_LOG_ERROR, "Error setting profile/level property: %d. Output will be encoded using a supported profile/level combination.\n", status);
1244  }
1245  }
1246 
1247  if (avctx->gop_size > 0 && avctx->codec_id != AV_CODEC_ID_PRORES) {
1248  CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
1249  kCFNumberIntType,
1250  &avctx->gop_size);
1251  if (!interval) {
1252  return AVERROR(ENOMEM);
1253  }
1254 
1255  status = VTSessionSetProperty(vtctx->session,
1256  kVTCompressionPropertyKey_MaxKeyFrameInterval,
1257  interval);
1258  CFRelease(interval);
1259 
1260  if (status) {
1261  av_log(avctx, AV_LOG_ERROR, "Error setting 'max key-frame interval' property: %d\n", status);
1262  return AVERROR_EXTERNAL;
1263  }
1264  }
1265 
1266  if (vtctx->frames_before) {
1267  status = VTSessionSetProperty(vtctx->session,
1268  kVTCompressionPropertyKey_MoreFramesBeforeStart,
1269  kCFBooleanTrue);
1270 
1271  if (status == kVTPropertyNotSupportedErr) {
1272  av_log(avctx, AV_LOG_WARNING, "frames_before property is not supported on this device. Ignoring.\n");
1273  } else if (status) {
1274  av_log(avctx, AV_LOG_ERROR, "Error setting frames_before property: %d\n", status);
1275  }
1276  }
1277 
1278  if (vtctx->frames_after) {
1279  status = VTSessionSetProperty(vtctx->session,
1280  kVTCompressionPropertyKey_MoreFramesAfterEnd,
1281  kCFBooleanTrue);
1282 
1283  if (status == kVTPropertyNotSupportedErr) {
1284  av_log(avctx, AV_LOG_WARNING, "frames_after property is not supported on this device. Ignoring.\n");
1285  } else if (status) {
1286  av_log(avctx, AV_LOG_ERROR, "Error setting frames_after property: %d\n", status);
1287  }
1288  }
1289 
1290  if (avctx->sample_aspect_ratio.num != 0) {
1291  CFNumberRef num;
1292  CFNumberRef den;
1293  CFMutableDictionaryRef par;
1294  AVRational *avpar = &avctx->sample_aspect_ratio;
1295 
1296  av_reduce(&avpar->num, &avpar->den,
1297  avpar->num, avpar->den,
1298  0xFFFFFFFF);
1299 
1300  num = CFNumberCreate(kCFAllocatorDefault,
1301  kCFNumberIntType,
1302  &avpar->num);
1303 
1304  den = CFNumberCreate(kCFAllocatorDefault,
1305  kCFNumberIntType,
1306  &avpar->den);
1307 
1308 
1309 
1310  par = CFDictionaryCreateMutable(kCFAllocatorDefault,
1311  2,
1312  &kCFCopyStringDictionaryKeyCallBacks,
1313  &kCFTypeDictionaryValueCallBacks);
1314 
1315  if (!par || !num || !den) {
1316  if (par) CFRelease(par);
1317  if (num) CFRelease(num);
1318  if (den) CFRelease(den);
1319 
1320  return AVERROR(ENOMEM);
1321  }
1322 
1323  CFDictionarySetValue(
1324  par,
1325  kCMFormatDescriptionKey_PixelAspectRatioHorizontalSpacing,
1326  num);
1327 
1328  CFDictionarySetValue(
1329  par,
1330  kCMFormatDescriptionKey_PixelAspectRatioVerticalSpacing,
1331  den);
1332 
1333  status = VTSessionSetProperty(vtctx->session,
1334  kVTCompressionPropertyKey_PixelAspectRatio,
1335  par);
1336 
1337  CFRelease(par);
1338  CFRelease(num);
1339  CFRelease(den);
1340 
1341  if (status) {
1342  av_log(avctx,
1343  AV_LOG_ERROR,
1344  "Error setting pixel aspect ratio to %d:%d: %d.\n",
1345  avctx->sample_aspect_ratio.num,
1346  avctx->sample_aspect_ratio.den,
1347  status);
1348 
1349  return AVERROR_EXTERNAL;
1350  }
1351  }
1352 
1353 
1354  if (vtctx->transfer_function) {
1355  status = VTSessionSetProperty(vtctx->session,
1356  kVTCompressionPropertyKey_TransferFunction,
1357  vtctx->transfer_function);
1358 
1359  if (status) {
1360  av_log(avctx, AV_LOG_WARNING, "Could not set transfer function: %d\n", status);
1361  }
1362  }
1363 
1364 
1365  if (vtctx->ycbcr_matrix) {
1366  status = VTSessionSetProperty(vtctx->session,
1367  kVTCompressionPropertyKey_YCbCrMatrix,
1368  vtctx->ycbcr_matrix);
1369 
1370  if (status) {
1371  av_log(avctx, AV_LOG_WARNING, "Could not set ycbcr matrix: %d\n", status);
1372  }
1373  }
1374 
1375 
1376  if (vtctx->color_primaries) {
1377  status = VTSessionSetProperty(vtctx->session,
1378  kVTCompressionPropertyKey_ColorPrimaries,
1379  vtctx->color_primaries);
1380 
1381  if (status) {
1382  av_log(avctx, AV_LOG_WARNING, "Could not set color primaries: %d\n", status);
1383  }
1384  }
1385 
1386  if (gamma_level) {
1387  status = VTSessionSetProperty(vtctx->session,
1388  kCVImageBufferGammaLevelKey,
1389  gamma_level);
1390 
1391  if (status) {
1392  av_log(avctx, AV_LOG_WARNING, "Could not set gamma level: %d\n", status);
1393  }
1394  }
1395 
1396  if (!vtctx->has_b_frames && avctx->codec_id != AV_CODEC_ID_PRORES) {
1397  status = VTSessionSetProperty(vtctx->session,
1398  kVTCompressionPropertyKey_AllowFrameReordering,
1399  kCFBooleanFalse);
1400 
1401  if (status) {
1402  av_log(avctx, AV_LOG_ERROR, "Error setting 'allow frame reordering' property: %d\n", status);
1403  return AVERROR_EXTERNAL;
1404  }
1405  }
1406 
1407  if (vtctx->entropy != VT_ENTROPY_NOT_SET) {
1408  CFStringRef entropy = vtctx->entropy == VT_CABAC ?
1409  compat_keys.kVTH264EntropyMode_CABAC:
1410  compat_keys.kVTH264EntropyMode_CAVLC;
1411 
1412  status = VTSessionSetProperty(vtctx->session,
1413  compat_keys.kVTCompressionPropertyKey_H264EntropyMode,
1414  entropy);
1415 
1416  if (status) {
1417  av_log(avctx, AV_LOG_ERROR, "Error setting entropy property: %d\n", status);
1418  }
1419  }
1420 
1421  if (vtctx->realtime >= 0) {
1422  status = VTSessionSetProperty(vtctx->session,
1423  compat_keys.kVTCompressionPropertyKey_RealTime,
1424  vtctx->realtime ? kCFBooleanTrue : kCFBooleanFalse);
1425 
1426  if (status) {
1427  av_log(avctx, AV_LOG_ERROR, "Error setting realtime property: %d\n", status);
1428  }
1429  }
1430 
1431  status = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
1432  if (status) {
1433  av_log(avctx, AV_LOG_ERROR, "Error: cannot prepare encoder: %d\n", status);
1434  return AVERROR_EXTERNAL;
1435  }
1436 
1437  return 0;
1438 }
1439 
1441 {
1442  CFMutableDictionaryRef enc_info;
1443  CFMutableDictionaryRef pixel_buffer_info = NULL;
1444  CMVideoCodecType codec_type;
1445  VTEncContext *vtctx = avctx->priv_data;
1446  CFStringRef profile_level = NULL;
1447  CFNumberRef gamma_level = NULL;
1448  int status;
1449 
1450  codec_type = get_cm_codec_type(avctx, vtctx->profile, vtctx->alpha_quality);
1451  if (!codec_type) {
1452  av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id);
1453  return AVERROR(EINVAL);
1454  }
1455 
1456 #if defined(MAC_OS_X_VERSION_10_9) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9)
1457  if (avctx->codec_id == AV_CODEC_ID_PRORES) {
1458  if (__builtin_available(macOS 10.10, *)) {
1459  VTRegisterProfessionalVideoWorkflowVideoEncoders();
1460  }
1461  }
1462 #endif
1463 
1464  vtctx->codec_id = avctx->codec_id;
1465 
1466  if (vtctx->codec_id == AV_CODEC_ID_H264) {
1467  vtctx->get_param_set_func = CMVideoFormatDescriptionGetH264ParameterSetAtIndex;
1468 
1469  vtctx->has_b_frames = avctx->max_b_frames > 0;
1470  if(vtctx->has_b_frames && vtctx->profile == H264_PROF_BASELINE){
1471  av_log(avctx, AV_LOG_WARNING, "Cannot use B-frames with baseline profile. Output will not contain B-frames.\n");
1472  vtctx->has_b_frames = 0;
1473  }
1474 
1475  if (vtctx->entropy == VT_CABAC && vtctx->profile == H264_PROF_BASELINE) {
1476  av_log(avctx, AV_LOG_WARNING, "CABAC entropy requires 'main' or 'high' profile, but baseline was requested. Encode will not use CABAC entropy.\n");
1477  vtctx->entropy = VT_ENTROPY_NOT_SET;
1478  }
1479 
1480  if (!get_vt_h264_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1481  } else if (vtctx->codec_id == AV_CODEC_ID_HEVC) {
1482  vtctx->get_param_set_func = compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex;
1483  if (!vtctx->get_param_set_func) return AVERROR(EINVAL);
1484  if (!get_vt_hevc_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1485  // HEVC has b-byramid
1486  vtctx->has_b_frames = avctx->max_b_frames > 0 ? 2 : 0;
1487  } else if (vtctx->codec_id == AV_CODEC_ID_PRORES) {
1488  avctx->codec_tag = av_bswap32(codec_type);
1489  }
1490 
1491  enc_info = CFDictionaryCreateMutable(
1492  kCFAllocatorDefault,
1493  20,
1494  &kCFCopyStringDictionaryKeyCallBacks,
1495  &kCFTypeDictionaryValueCallBacks
1496  );
1497 
1498  if (!enc_info) return AVERROR(ENOMEM);
1499 
1500 #if !TARGET_OS_IPHONE
1501  if(vtctx->require_sw) {
1502  CFDictionarySetValue(enc_info,
1503  compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1504  kCFBooleanFalse);
1505  } else if (!vtctx->allow_sw) {
1506  CFDictionarySetValue(enc_info,
1507  compat_keys.kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder,
1508  kCFBooleanTrue);
1509  } else {
1510  CFDictionarySetValue(enc_info,
1511  compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1512  kCFBooleanTrue);
1513  }
1514 #endif
1515 
1516  if (avctx->pix_fmt != AV_PIX_FMT_VIDEOTOOLBOX) {
1517  status = create_cv_pixel_buffer_info(avctx, &pixel_buffer_info);
1518  if (status)
1519  goto init_cleanup;
1520  }
1521 
1522  vtctx->dts_delta = vtctx->has_b_frames ? -1 : 0;
1523 
1524  get_cv_transfer_function(avctx, &vtctx->transfer_function, &gamma_level);
1525  get_cv_ycbcr_matrix(avctx, &vtctx->ycbcr_matrix);
1526  get_cv_color_primaries(avctx, &vtctx->color_primaries);
1527 
1528 
1529  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1531  codec_type,
1532  profile_level,
1533  gamma_level,
1534  enc_info,
1535  pixel_buffer_info);
1536  if (status)
1537  goto init_cleanup;
1538  }
1539 
1540  status = vtenc_create_encoder(avctx,
1541  codec_type,
1542  profile_level,
1543  gamma_level,
1544  enc_info,
1545  pixel_buffer_info,
1546  vtctx->constant_bit_rate,
1547  &vtctx->session);
1548 
1549 init_cleanup:
1550  if (gamma_level)
1551  CFRelease(gamma_level);
1552 
1553  if (pixel_buffer_info)
1554  CFRelease(pixel_buffer_info);
1555 
1556  CFRelease(enc_info);
1557 
1558  return status;
1559 }
1560 
1562 {
1563  VTEncContext *vtctx = avctx->priv_data;
1564  CFBooleanRef has_b_frames_cfbool;
1565  int status;
1566 
1568 
1569  pthread_mutex_init(&vtctx->lock, NULL);
1571 
1572  vtctx->session = NULL;
1574  if (status) return status;
1575 
1576  status = VTSessionCopyProperty(vtctx->session,
1577  kVTCompressionPropertyKey_AllowFrameReordering,
1578  kCFAllocatorDefault,
1579  &has_b_frames_cfbool);
1580 
1581  if (!status && has_b_frames_cfbool) {
1582  //Some devices don't output B-frames for main profile, even if requested.
1583  // HEVC has b-pyramid
1584  if (CFBooleanGetValue(has_b_frames_cfbool))
1585  vtctx->has_b_frames = avctx->codec_id == AV_CODEC_ID_HEVC ? 2 : 1;
1586  else
1587  vtctx->has_b_frames = 0;
1588  CFRelease(has_b_frames_cfbool);
1589  }
1590  avctx->has_b_frames = vtctx->has_b_frames;
1591 
1592  return 0;
1593 }
1594 
1595 static void vtenc_get_frame_info(CMSampleBufferRef buffer, bool *is_key_frame)
1596 {
1597  CFArrayRef attachments;
1598  CFDictionaryRef attachment;
1599  CFBooleanRef not_sync;
1600  CFIndex len;
1601 
1602  attachments = CMSampleBufferGetSampleAttachmentsArray(buffer, false);
1603  len = !attachments ? 0 : CFArrayGetCount(attachments);
1604 
1605  if (!len) {
1606  *is_key_frame = true;
1607  return;
1608  }
1609 
1610  attachment = CFArrayGetValueAtIndex(attachments, 0);
1611 
1612  if (CFDictionaryGetValueIfPresent(attachment,
1613  kCMSampleAttachmentKey_NotSync,
1614  (const void **)&not_sync))
1615  {
1616  *is_key_frame = !CFBooleanGetValue(not_sync);
1617  } else {
1618  *is_key_frame = true;
1619  }
1620 }
1621 
1622 static int is_post_sei_nal_type(int nal_type){
1623  return nal_type != H264_NAL_SEI &&
1624  nal_type != H264_NAL_SPS &&
1625  nal_type != H264_NAL_PPS &&
1626  nal_type != H264_NAL_AUD;
1627 }
1628 
1629 /*
1630  * Finds the sei message start/size of type find_sei_type.
1631  * If more than one of that type exists, the last one is returned.
1632  */
1633 static int find_sei_end(AVCodecContext *avctx,
1634  uint8_t *nal_data,
1635  size_t nal_size,
1636  uint8_t **sei_end)
1637 {
1638  int nal_type;
1639  size_t sei_payload_size = 0;
1640  int sei_payload_type = 0;
1641  *sei_end = NULL;
1642  uint8_t *nal_start = nal_data;
1643 
1644  if (!nal_size)
1645  return 0;
1646 
1647  nal_type = *nal_data & 0x1F;
1648  if (nal_type != H264_NAL_SEI)
1649  return 0;
1650 
1651  nal_data++;
1652  nal_size--;
1653 
1654  if (nal_data[nal_size - 1] == 0x80)
1655  nal_size--;
1656 
1657  while (nal_size > 0 && *nal_data > 0) {
1658  do{
1659  sei_payload_type += *nal_data;
1660  nal_data++;
1661  nal_size--;
1662  } while (nal_size > 0 && *nal_data == 0xFF);
1663 
1664  if (!nal_size) {
1665  av_log(avctx, AV_LOG_ERROR, "Unexpected end of SEI NAL Unit parsing type.\n");
1666  return AVERROR_INVALIDDATA;
1667  }
1668 
1669  do{
1670  sei_payload_size += *nal_data;
1671  nal_data++;
1672  nal_size--;
1673  } while (nal_size > 0 && *nal_data == 0xFF);
1674 
1675  if (nal_size < sei_payload_size) {
1676  av_log(avctx, AV_LOG_ERROR, "Unexpected end of SEI NAL Unit parsing size.\n");
1677  return AVERROR_INVALIDDATA;
1678  }
1679 
1680  nal_data += sei_payload_size;
1681  nal_size -= sei_payload_size;
1682  }
1683 
1684  *sei_end = nal_data;
1685 
1686  return nal_data - nal_start + 1;
1687 }
1688 
1689 /**
1690  * Copies the data inserting emulation prevention bytes as needed.
1691  * Existing data in the destination can be taken into account by providing
1692  * dst with a dst_offset > 0.
1693  *
1694  * @return The number of bytes copied on success. On failure, the negative of
1695  * the number of bytes needed to copy src is returned.
1696  */
1697 static int copy_emulation_prev(const uint8_t *src,
1698  size_t src_size,
1699  uint8_t *dst,
1700  ssize_t dst_offset,
1701  size_t dst_size)
1702 {
1703  int zeros = 0;
1704  int wrote_bytes;
1705  uint8_t* dst_start;
1706  uint8_t* dst_end = dst + dst_size;
1707  const uint8_t* src_end = src + src_size;
1708  int start_at = dst_offset > 2 ? dst_offset - 2 : 0;
1709  int i;
1710  for (i = start_at; i < dst_offset && i < dst_size; i++) {
1711  if (!dst[i])
1712  zeros++;
1713  else
1714  zeros = 0;
1715  }
1716 
1717  dst += dst_offset;
1718  dst_start = dst;
1719  for (; src < src_end; src++, dst++) {
1720  if (zeros == 2) {
1721  int insert_ep3_byte = *src <= 3;
1722  if (insert_ep3_byte) {
1723  if (dst < dst_end)
1724  *dst = 3;
1725  dst++;
1726  }
1727 
1728  zeros = 0;
1729  }
1730 
1731  if (dst < dst_end)
1732  *dst = *src;
1733 
1734  if (!*src)
1735  zeros++;
1736  else
1737  zeros = 0;
1738  }
1739 
1740  wrote_bytes = dst - dst_start;
1741 
1742  if (dst > dst_end)
1743  return -wrote_bytes;
1744 
1745  return wrote_bytes;
1746 }
1747 
1748 static int write_sei(const ExtraSEI *sei,
1749  int sei_type,
1750  uint8_t *dst,
1751  size_t dst_size)
1752 {
1753  uint8_t *sei_start = dst;
1754  size_t remaining_sei_size = sei->size;
1755  size_t remaining_dst_size = dst_size;
1756  int header_bytes;
1757  int bytes_written;
1758  ssize_t offset;
1759 
1760  if (!remaining_dst_size)
1761  return AVERROR_BUFFER_TOO_SMALL;
1762 
1763  while (sei_type && remaining_dst_size != 0) {
1764  int sei_byte = sei_type > 255 ? 255 : sei_type;
1765  *dst = sei_byte;
1766 
1767  sei_type -= sei_byte;
1768  dst++;
1769  remaining_dst_size--;
1770  }
1771 
1772  if (!dst_size)
1773  return AVERROR_BUFFER_TOO_SMALL;
1774 
1775  while (remaining_sei_size && remaining_dst_size != 0) {
1776  int size_byte = remaining_sei_size > 255 ? 255 : remaining_sei_size;
1777  *dst = size_byte;
1778 
1779  remaining_sei_size -= size_byte;
1780  dst++;
1781  remaining_dst_size--;
1782  }
1783 
1784  if (remaining_dst_size < sei->size)
1785  return AVERROR_BUFFER_TOO_SMALL;
1786 
1787  header_bytes = dst - sei_start;
1788 
1789  offset = header_bytes;
1790  bytes_written = copy_emulation_prev(sei->data,
1791  sei->size,
1792  sei_start,
1793  offset,
1794  dst_size);
1795  if (bytes_written < 0)
1796  return AVERROR_BUFFER_TOO_SMALL;
1797 
1798  bytes_written += header_bytes;
1799  return bytes_written;
1800 }
1801 
1802 /**
1803  * Copies NAL units and replaces length codes with
1804  * H.264 Annex B start codes. On failure, the contents of
1805  * dst_data may have been modified.
1806  *
1807  * @param length_code_size Byte length of each length code
1808  * @param sample_buffer NAL units prefixed with length codes.
1809  * @param sei Optional A53 closed captions SEI data.
1810  * @param dst_data Must be zeroed before calling this function.
1811  * Contains the copied NAL units prefixed with
1812  * start codes when the function returns
1813  * successfully.
1814  * @param dst_size Length of dst_data
1815  * @return 0 on success
1816  * AVERROR_INVALIDDATA if length_code_size is invalid
1817  * AVERROR_BUFFER_TOO_SMALL if dst_data is too small
1818  * or if a length_code in src_data specifies data beyond
1819  * the end of its buffer.
1820  */
1822  AVCodecContext *avctx,
1823  size_t length_code_size,
1824  CMSampleBufferRef sample_buffer,
1825  ExtraSEI *sei,
1826  uint8_t *dst_data,
1827  size_t dst_size)
1828 {
1829  size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
1830  size_t remaining_src_size = src_size;
1831  size_t remaining_dst_size = dst_size;
1832  size_t src_offset = 0;
1833  int wrote_sei = 0;
1834  int status;
1835  uint8_t size_buf[4];
1836  uint8_t nal_type;
1837  CMBlockBufferRef block = CMSampleBufferGetDataBuffer(sample_buffer);
1838 
1839  if (length_code_size > 4) {
1840  return AVERROR_INVALIDDATA;
1841  }
1842 
1843  while (remaining_src_size > 0) {
1844  size_t curr_src_len;
1845  size_t curr_dst_len;
1846  size_t box_len = 0;
1847  size_t i;
1848 
1849  uint8_t *dst_box;
1850 
1851  status = CMBlockBufferCopyDataBytes(block,
1852  src_offset,
1853  length_code_size,
1854  size_buf);
1855  if (status) {
1856  av_log(avctx, AV_LOG_ERROR, "Cannot copy length: %d\n", status);
1857  return AVERROR_EXTERNAL;
1858  }
1859 
1860  status = CMBlockBufferCopyDataBytes(block,
1861  src_offset + length_code_size,
1862  1,
1863  &nal_type);
1864 
1865  if (status) {
1866  av_log(avctx, AV_LOG_ERROR, "Cannot copy type: %d\n", status);
1867  return AVERROR_EXTERNAL;
1868  }
1869 
1870  nal_type &= 0x1F;
1871 
1872  for (i = 0; i < length_code_size; i++) {
1873  box_len <<= 8;
1874  box_len |= size_buf[i];
1875  }
1876 
1877  if (sei && !wrote_sei && is_post_sei_nal_type(nal_type)) {
1878  //No SEI NAL unit - insert.
1879  int wrote_bytes;
1880 
1881  memcpy(dst_data, start_code, sizeof(start_code));
1882  dst_data += sizeof(start_code);
1883  remaining_dst_size -= sizeof(start_code);
1884 
1885  *dst_data = H264_NAL_SEI;
1886  dst_data++;
1887  remaining_dst_size--;
1888 
1889  wrote_bytes = write_sei(sei,
1891  dst_data,
1892  remaining_dst_size);
1893 
1894  if (wrote_bytes < 0)
1895  return wrote_bytes;
1896 
1897  remaining_dst_size -= wrote_bytes;
1898  dst_data += wrote_bytes;
1899 
1900  if (remaining_dst_size <= 0)
1901  return AVERROR_BUFFER_TOO_SMALL;
1902 
1903  *dst_data = 0x80;
1904 
1905  dst_data++;
1906  remaining_dst_size--;
1907 
1908  wrote_sei = 1;
1909  }
1910 
1911  curr_src_len = box_len + length_code_size;
1912  curr_dst_len = box_len + sizeof(start_code);
1913 
1914  if (remaining_src_size < curr_src_len) {
1915  return AVERROR_BUFFER_TOO_SMALL;
1916  }
1917 
1918  if (remaining_dst_size < curr_dst_len) {
1919  return AVERROR_BUFFER_TOO_SMALL;
1920  }
1921 
1922  dst_box = dst_data + sizeof(start_code);
1923 
1924  memcpy(dst_data, start_code, sizeof(start_code));
1925  status = CMBlockBufferCopyDataBytes(block,
1926  src_offset + length_code_size,
1927  box_len,
1928  dst_box);
1929 
1930  if (status) {
1931  av_log(avctx, AV_LOG_ERROR, "Cannot copy data: %d\n", status);
1932  return AVERROR_EXTERNAL;
1933  }
1934 
1935  if (sei && !wrote_sei && nal_type == H264_NAL_SEI) {
1936  //Found SEI NAL unit - append.
1937  int wrote_bytes;
1938  int old_sei_length;
1939  int extra_bytes;
1940  uint8_t *new_sei;
1941  old_sei_length = find_sei_end(avctx, dst_box, box_len, &new_sei);
1942  if (old_sei_length < 0)
1943  return status;
1944 
1945  wrote_bytes = write_sei(sei,
1947  new_sei,
1948  remaining_dst_size - old_sei_length);
1949  if (wrote_bytes < 0)
1950  return wrote_bytes;
1951 
1952  if (new_sei + wrote_bytes >= dst_data + remaining_dst_size)
1953  return AVERROR_BUFFER_TOO_SMALL;
1954 
1955  new_sei[wrote_bytes++] = 0x80;
1956  extra_bytes = wrote_bytes - (dst_box + box_len - new_sei);
1957 
1958  dst_data += extra_bytes;
1959  remaining_dst_size -= extra_bytes;
1960 
1961  wrote_sei = 1;
1962  }
1963 
1964  src_offset += curr_src_len;
1965  dst_data += curr_dst_len;
1966 
1967  remaining_src_size -= curr_src_len;
1968  remaining_dst_size -= curr_dst_len;
1969  }
1970 
1971  return 0;
1972 }
1973 
1974 /**
1975  * Returns a sufficient number of bytes to contain the sei data.
1976  * It may be greater than the minimum required.
1977  */
1978 static int get_sei_msg_bytes(const ExtraSEI* sei, int type){
1979  int copied_size;
1980  if (sei->size == 0)
1981  return 0;
1982 
1983  copied_size = -copy_emulation_prev(sei->data,
1984  sei->size,
1985  NULL,
1986  0,
1987  0);
1988 
1989  if ((sei->size % 255) == 0) //may result in an extra byte
1990  copied_size++;
1991 
1992  return copied_size + sei->size / 255 + 1 + type / 255 + 1;
1993 }
1994 
1996  AVCodecContext *avctx,
1997  CMSampleBufferRef sample_buffer,
1998  AVPacket *pkt,
1999  ExtraSEI *sei)
2000 {
2001  VTEncContext *vtctx = avctx->priv_data;
2002 
2003  int status;
2004  bool is_key_frame;
2005  bool add_header;
2006  size_t length_code_size;
2007  size_t header_size = 0;
2008  size_t in_buf_size;
2009  size_t out_buf_size;
2010  size_t sei_nalu_size = 0;
2011  int64_t dts_delta;
2012  int64_t time_base_num;
2013  int nalu_count;
2014  CMTime pts;
2015  CMTime dts;
2016  CMVideoFormatDescriptionRef vid_fmt;
2017 
2018  vtenc_get_frame_info(sample_buffer, &is_key_frame);
2019 
2020  if (vtctx->get_param_set_func) {
2021  status = get_length_code_size(avctx, sample_buffer, &length_code_size);
2022  if (status) return status;
2023 
2024  add_header = is_key_frame && !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER);
2025 
2026  if (add_header) {
2027  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
2028  if (!vid_fmt) {
2029  av_log(avctx, AV_LOG_ERROR, "Cannot get format description.\n");
2030  return AVERROR_EXTERNAL;
2031  }
2032 
2033  int status = get_params_size(avctx, vid_fmt, &header_size);
2034  if (status) return status;
2035  }
2036 
2037  status = count_nalus(length_code_size, sample_buffer, &nalu_count);
2038  if(status)
2039  return status;
2040 
2041  if (sei) {
2042  size_t msg_size = get_sei_msg_bytes(sei,
2044 
2045  sei_nalu_size = sizeof(start_code) + 1 + msg_size + 1;
2046  }
2047 
2048  in_buf_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
2049  out_buf_size = header_size +
2050  in_buf_size +
2051  sei_nalu_size +
2052  nalu_count * ((int)sizeof(start_code) - (int)length_code_size);
2053 
2054  status = ff_get_encode_buffer(avctx, pkt, out_buf_size, 0);
2055  if (status < 0)
2056  return status;
2057 
2058  if (add_header) {
2059  status = copy_param_sets(avctx, vid_fmt, pkt->data, out_buf_size);
2060  if(status) return status;
2061  }
2062 
2064  avctx,
2065  length_code_size,
2066  sample_buffer,
2067  sei,
2068  pkt->data + header_size,
2069  pkt->size - header_size
2070  );
2071 
2072  if (status) {
2073  av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status);
2074  return status;
2075  }
2076  } else {
2077  size_t len;
2078  CMBlockBufferRef buf = CMSampleBufferGetDataBuffer(sample_buffer);
2079  if (!buf) {
2080  av_log(avctx, AV_LOG_ERROR, "Error getting block buffer\n");
2081  return AVERROR_EXTERNAL;
2082  }
2083 
2084  len = CMBlockBufferGetDataLength(buf);
2085 
2086  status = ff_get_encode_buffer(avctx, pkt, len, 0);
2087  if (status < 0)
2088  return status;
2089 
2090  status = CMBlockBufferCopyDataBytes(buf, 0, len, pkt->data);
2091  if (status) {
2092  av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d\n", status);
2093  return AVERROR_EXTERNAL;
2094  }
2095  }
2096 
2097  if (is_key_frame) {
2099  }
2100 
2101  pts = CMSampleBufferGetPresentationTimeStamp(sample_buffer);
2102  dts = CMSampleBufferGetDecodeTimeStamp (sample_buffer);
2103 
2104  if (CMTIME_IS_INVALID(dts)) {
2105  if (!vtctx->has_b_frames) {
2106  dts = pts;
2107  } else {
2108  av_log(avctx, AV_LOG_ERROR, "DTS is invalid.\n");
2109  return AVERROR_EXTERNAL;
2110  }
2111  }
2112 
2113  dts_delta = vtctx->dts_delta >= 0 ? vtctx->dts_delta : 0;
2114  time_base_num = avctx->time_base.num;
2115  pkt->pts = pts.value / time_base_num;
2116  pkt->dts = dts.value / time_base_num - dts_delta;
2117 
2118  return 0;
2119 }
2120 
2121 /*
2122  * contiguous_buf_size is 0 if not contiguous, and the size of the buffer
2123  * containing all planes if so.
2124  */
2126  AVCodecContext *avctx,
2127  const AVFrame *frame,
2128  int *color,
2129  int *plane_count,
2130  size_t *widths,
2131  size_t *heights,
2132  size_t *strides,
2133  size_t *contiguous_buf_size)
2134 {
2136  VTEncContext *vtctx = avctx->priv_data;
2137  int av_format = frame->format;
2138  int av_color_range = frame->color_range;
2139  int i;
2140  int range_guessed;
2141  int status;
2142 
2143  if (!desc)
2144  return AVERROR(EINVAL);
2145 
2146  status = get_cv_pixel_format(avctx, av_format, av_color_range, color, &range_guessed);
2147  if (status) {
2148  av_log(avctx,
2149  AV_LOG_ERROR,
2150  "Could not get pixel format for color format '%s' range '%s'.\n",
2151  av_get_pix_fmt_name(av_format),
2152  av_color_range > AVCOL_RANGE_UNSPECIFIED &&
2153  av_color_range < AVCOL_RANGE_NB ?
2154  av_color_range_name(av_color_range) :
2155  "Unknown");
2156 
2157  return AVERROR(EINVAL);
2158  }
2159 
2160  if (range_guessed) {
2161  if (!vtctx->warned_color_range) {
2162  vtctx->warned_color_range = true;
2163  av_log(avctx,
2165  "Color range not set for %s. Using MPEG range.\n",
2166  av_get_pix_fmt_name(av_format));
2167  }
2168  }
2169 
2170  *plane_count = av_pix_fmt_count_planes(avctx->pix_fmt);
2171 
2172  for (i = 0; i < desc->nb_components; i++) {
2173  int p = desc->comp[i].plane;
2174  bool hasAlpha = (desc->flags & AV_PIX_FMT_FLAG_ALPHA);
2175  bool isAlpha = hasAlpha && (p + 1 == *plane_count);
2176  bool isChroma = (p != 0) && !isAlpha;
2177  int shiftw = isChroma ? desc->log2_chroma_w : 0;
2178  int shifth = isChroma ? desc->log2_chroma_h : 0;
2179  widths[p] = (avctx->width + ((1 << shiftw) >> 1)) >> shiftw;
2180  heights[p] = (avctx->height + ((1 << shifth) >> 1)) >> shifth;
2181  strides[p] = frame->linesize[p];
2182  }
2183 
2184  *contiguous_buf_size = 0;
2185  for (i = 0; i < *plane_count; i++) {
2186  if (i < *plane_count - 1 &&
2187  frame->data[i] + strides[i] * heights[i] != frame->data[i + 1]) {
2188  *contiguous_buf_size = 0;
2189  break;
2190  }
2191 
2192  *contiguous_buf_size += strides[i] * heights[i];
2193  }
2194 
2195  return 0;
2196 }
2197 
2198 //Not used on OSX - frame is never copied.
2200  const AVFrame *frame,
2201  CVPixelBufferRef cv_img,
2202  const size_t *plane_strides,
2203  const size_t *plane_rows)
2204 {
2205  int i, j;
2206  size_t plane_count;
2207  int status;
2208  int rows;
2209  int src_stride;
2210  int dst_stride;
2211  uint8_t *src_addr;
2212  uint8_t *dst_addr;
2213  size_t copy_bytes;
2214 
2215  status = CVPixelBufferLockBaseAddress(cv_img, 0);
2216  if (status) {
2217  av_log(
2218  avctx,
2219  AV_LOG_ERROR,
2220  "Error: Could not lock base address of CVPixelBuffer: %d.\n",
2221  status
2222  );
2223  }
2224 
2225  if (CVPixelBufferIsPlanar(cv_img)) {
2226  plane_count = CVPixelBufferGetPlaneCount(cv_img);
2227  for (i = 0; frame->data[i]; i++) {
2228  if (i == plane_count) {
2229  CVPixelBufferUnlockBaseAddress(cv_img, 0);
2230  av_log(avctx,
2231  AV_LOG_ERROR,
2232  "Error: different number of planes in AVFrame and CVPixelBuffer.\n"
2233  );
2234 
2235  return AVERROR_EXTERNAL;
2236  }
2237 
2238  dst_addr = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(cv_img, i);
2239  src_addr = (uint8_t*)frame->data[i];
2240  dst_stride = CVPixelBufferGetBytesPerRowOfPlane(cv_img, i);
2241  src_stride = plane_strides[i];
2242  rows = plane_rows[i];
2243 
2244  if (dst_stride == src_stride) {
2245  memcpy(dst_addr, src_addr, src_stride * rows);
2246  } else {
2247  copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
2248 
2249  for (j = 0; j < rows; j++) {
2250  memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
2251  }
2252  }
2253  }
2254  } else {
2255  if (frame->data[1]) {
2256  CVPixelBufferUnlockBaseAddress(cv_img, 0);
2257  av_log(avctx,
2258  AV_LOG_ERROR,
2259  "Error: different number of planes in AVFrame and non-planar CVPixelBuffer.\n"
2260  );
2261 
2262  return AVERROR_EXTERNAL;
2263  }
2264 
2265  dst_addr = (uint8_t*)CVPixelBufferGetBaseAddress(cv_img);
2266  src_addr = (uint8_t*)frame->data[0];
2267  dst_stride = CVPixelBufferGetBytesPerRow(cv_img);
2268  src_stride = plane_strides[0];
2269  rows = plane_rows[0];
2270 
2271  if (dst_stride == src_stride) {
2272  memcpy(dst_addr, src_addr, src_stride * rows);
2273  } else {
2274  copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
2275 
2276  for (j = 0; j < rows; j++) {
2277  memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
2278  }
2279  }
2280  }
2281 
2282  status = CVPixelBufferUnlockBaseAddress(cv_img, 0);
2283  if (status) {
2284  av_log(avctx, AV_LOG_ERROR, "Error: Could not unlock CVPixelBuffer base address: %d.\n", status);
2285  return AVERROR_EXTERNAL;
2286  }
2287 
2288  return 0;
2289 }
2290 
2292  const AVFrame *frame,
2293  CVPixelBufferRef *cv_img)
2294 {
2295  int plane_count;
2296  int color;
2297  size_t widths [AV_NUM_DATA_POINTERS];
2298  size_t heights[AV_NUM_DATA_POINTERS];
2299  size_t strides[AV_NUM_DATA_POINTERS];
2300  int status;
2301  size_t contiguous_buf_size;
2302  CVPixelBufferPoolRef pix_buf_pool;
2303  VTEncContext* vtctx = avctx->priv_data;
2304 
2305  if (avctx->pix_fmt == AV_PIX_FMT_VIDEOTOOLBOX) {
2307 
2308  *cv_img = (CVPixelBufferRef)frame->data[3];
2309  av_assert0(*cv_img);
2310 
2311  CFRetain(*cv_img);
2312  return 0;
2313  }
2314 
2315  memset(widths, 0, sizeof(widths));
2316  memset(heights, 0, sizeof(heights));
2317  memset(strides, 0, sizeof(strides));
2318 
2320  avctx,
2321  frame,
2322  &color,
2323  &plane_count,
2324  widths,
2325  heights,
2326  strides,
2327  &contiguous_buf_size
2328  );
2329 
2330  if (status) {
2331  av_log(
2332  avctx,
2333  AV_LOG_ERROR,
2334  "Error: Cannot convert format %d color_range %d: %d\n",
2335  frame->format,
2336  frame->color_range,
2337  status
2338  );
2339 
2340  return AVERROR_EXTERNAL;
2341  }
2342 
2343  pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2344  if (!pix_buf_pool) {
2345  /* On iOS, the VT session is invalidated when the APP switches from
2346  * foreground to background and vice versa. Fetch the actual error code
2347  * of the VT session to detect that case and restart the VT session
2348  * accordingly. */
2349  OSStatus vtstatus;
2350 
2351  vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
2352  if (vtstatus == kVTInvalidSessionErr) {
2353  CFRelease(vtctx->session);
2354  vtctx->session = NULL;
2356  if (status == 0)
2357  pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2358  }
2359  if (!pix_buf_pool) {
2360  av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer pool.\n");
2361  return AVERROR_EXTERNAL;
2362  }
2363  else
2364  av_log(avctx, AV_LOG_WARNING, "VT session restarted because of a "
2365  "kVTInvalidSessionErr error.\n");
2366  }
2367 
2368  status = CVPixelBufferPoolCreatePixelBuffer(NULL,
2369  pix_buf_pool,
2370  cv_img);
2371 
2372 
2373  if (status) {
2374  av_log(avctx, AV_LOG_ERROR, "Could not create pixel buffer from pool: %d.\n", status);
2375  return AVERROR_EXTERNAL;
2376  }
2377 
2378  status = copy_avframe_to_pixel_buffer(avctx, frame, *cv_img, strides, heights);
2379  if (status) {
2380  CFRelease(*cv_img);
2381  *cv_img = NULL;
2382  return status;
2383  }
2384 
2385  return 0;
2386 }
2387 
2389  CFDictionaryRef* dict_out)
2390 {
2391  CFDictionaryRef dict = NULL;
2392  if (frame->pict_type == AV_PICTURE_TYPE_I) {
2393  const void *keys[] = { kVTEncodeFrameOptionKey_ForceKeyFrame };
2394  const void *vals[] = { kCFBooleanTrue };
2395 
2396  dict = CFDictionaryCreate(NULL, keys, vals, 1, NULL, NULL);
2397  if(!dict) return AVERROR(ENOMEM);
2398  }
2399 
2400  *dict_out = dict;
2401  return 0;
2402 }
2403 
2405  VTEncContext *vtctx,
2406  const AVFrame *frame)
2407 {
2408  CMTime time;
2409  CFDictionaryRef frame_dict;
2410  CVPixelBufferRef cv_img = NULL;
2411  AVFrameSideData *side_data = NULL;
2412  ExtraSEI *sei = NULL;
2413  int status = create_cv_pixel_buffer(avctx, frame, &cv_img);
2414 
2415  if (status) return status;
2416 
2417  status = create_encoder_dict_h264(frame, &frame_dict);
2418  if (status) {
2419  CFRelease(cv_img);
2420  return status;
2421  }
2422 
2423 #if CONFIG_ATSC_A53
2425  if (vtctx->a53_cc && side_data && side_data->size) {
2426  sei = av_mallocz(sizeof(*sei));
2427  if (!sei) {
2428  av_log(avctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2429  } else {
2430  int ret = ff_alloc_a53_sei(frame, 0, &sei->data, &sei->size);
2431  if (ret < 0) {
2432  av_log(avctx, AV_LOG_ERROR, "Not enough memory for closed captions, skipping\n");
2433  av_free(sei);
2434  sei = NULL;
2435  }
2436  }
2437  }
2438 #endif
2439 
2440  time = CMTimeMake(frame->pts * avctx->time_base.num, avctx->time_base.den);
2441  status = VTCompressionSessionEncodeFrame(
2442  vtctx->session,
2443  cv_img,
2444  time,
2445  kCMTimeInvalid,
2446  frame_dict,
2447  sei,
2448  NULL
2449  );
2450 
2451  if (frame_dict) CFRelease(frame_dict);
2452  CFRelease(cv_img);
2453 
2454  if (status) {
2455  av_log(avctx, AV_LOG_ERROR, "Error: cannot encode frame: %d\n", status);
2456  return AVERROR_EXTERNAL;
2457  }
2458 
2459  return 0;
2460 }
2461 
2463  AVCodecContext *avctx,
2464  AVPacket *pkt,
2465  const AVFrame *frame,
2466  int *got_packet)
2467 {
2468  VTEncContext *vtctx = avctx->priv_data;
2469  bool get_frame;
2470  int status;
2471  CMSampleBufferRef buf = NULL;
2472  ExtraSEI *sei = NULL;
2473 
2474  if (frame) {
2475  status = vtenc_send_frame(avctx, vtctx, frame);
2476 
2477  if (status) {
2479  goto end_nopkt;
2480  }
2481 
2482  if (vtctx->frame_ct_in == 0) {
2483  vtctx->first_pts = frame->pts;
2484  } else if(vtctx->frame_ct_in == vtctx->has_b_frames) {
2485  vtctx->dts_delta = frame->pts - vtctx->first_pts;
2486  }
2487 
2488  vtctx->frame_ct_in++;
2489  } else if(!vtctx->flushing) {
2490  vtctx->flushing = true;
2491 
2492  status = VTCompressionSessionCompleteFrames(vtctx->session,
2493  kCMTimeIndefinite);
2494 
2495  if (status) {
2496  av_log(avctx, AV_LOG_ERROR, "Error flushing frames: %d\n", status);
2498  goto end_nopkt;
2499  }
2500  }
2501 
2502  *got_packet = 0;
2503  get_frame = vtctx->dts_delta >= 0 || !frame;
2504  if (!get_frame) {
2505  status = 0;
2506  goto end_nopkt;
2507  }
2508 
2509  status = vtenc_q_pop(vtctx, !frame, &buf, &sei);
2510  if (status) goto end_nopkt;
2511  if (!buf) goto end_nopkt;
2512 
2513  status = vtenc_cm_to_avpacket(avctx, buf, pkt, sei);
2514  if (sei) {
2515  if (sei->data) av_free(sei->data);
2516  av_free(sei);
2517  }
2518  CFRelease(buf);
2519  if (status) goto end_nopkt;
2520 
2521  *got_packet = 1;
2522  return 0;
2523 
2524 end_nopkt:
2526  return status;
2527 }
2528 
2530  CMVideoCodecType codec_type,
2531  CFStringRef profile_level,
2532  CFNumberRef gamma_level,
2533  CFDictionaryRef enc_info,
2534  CFDictionaryRef pixel_buffer_info)
2535 {
2536  VTEncContext *vtctx = avctx->priv_data;
2537  int status;
2538  CVPixelBufferPoolRef pool = NULL;
2539  CVPixelBufferRef pix_buf = NULL;
2540  CMTime time;
2541  CMSampleBufferRef buf = NULL;
2542 
2543  status = vtenc_create_encoder(avctx,
2544  codec_type,
2545  profile_level,
2546  gamma_level,
2547  enc_info,
2548  pixel_buffer_info,
2549  vtctx->constant_bit_rate,
2550  &vtctx->session);
2551  if (status)
2552  goto pe_cleanup;
2553 
2554  pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
2555  if(!pool){
2556  av_log(avctx, AV_LOG_ERROR, "Error getting pixel buffer pool.\n");
2557  goto pe_cleanup;
2558  }
2559 
2560  status = CVPixelBufferPoolCreatePixelBuffer(NULL,
2561  pool,
2562  &pix_buf);
2563 
2564  if(status != kCVReturnSuccess){
2565  av_log(avctx, AV_LOG_ERROR, "Error creating frame from pool: %d\n", status);
2566  goto pe_cleanup;
2567  }
2568 
2569  time = CMTimeMake(0, avctx->time_base.den);
2570  status = VTCompressionSessionEncodeFrame(vtctx->session,
2571  pix_buf,
2572  time,
2573  kCMTimeInvalid,
2574  NULL,
2575  NULL,
2576  NULL);
2577 
2578  if (status) {
2579  av_log(avctx,
2580  AV_LOG_ERROR,
2581  "Error sending frame for extradata: %d\n",
2582  status);
2583 
2584  goto pe_cleanup;
2585  }
2586 
2587  //Populates extradata - output frames are flushed and param sets are available.
2588  status = VTCompressionSessionCompleteFrames(vtctx->session,
2589  kCMTimeIndefinite);
2590 
2591  if (status)
2592  goto pe_cleanup;
2593 
2594  status = vtenc_q_pop(vtctx, 0, &buf, NULL);
2595  if (status) {
2596  av_log(avctx, AV_LOG_ERROR, "popping: %d\n", status);
2597  goto pe_cleanup;
2598  }
2599 
2600  CFRelease(buf);
2601 
2602 
2603 
2604 pe_cleanup:
2605  CVPixelBufferRelease(pix_buf);
2606  if(vtctx->session)
2607  CFRelease(vtctx->session);
2608 
2609  vtctx->session = NULL;
2610  vtctx->frame_ct_out = 0;
2611 
2612  av_assert0(status != 0 || (avctx->extradata && avctx->extradata_size > 0));
2613 
2614  return status;
2615 }
2616 
2618 {
2619  VTEncContext *vtctx = avctx->priv_data;
2620 
2621  if(!vtctx->session) {
2623  pthread_mutex_destroy(&vtctx->lock);
2624  return 0;
2625  }
2626 
2627  VTCompressionSessionCompleteFrames(vtctx->session,
2628  kCMTimeIndefinite);
2629  clear_frame_queue(vtctx);
2631  pthread_mutex_destroy(&vtctx->lock);
2632  CFRelease(vtctx->session);
2633  vtctx->session = NULL;
2634 
2635  if (vtctx->color_primaries) {
2636  CFRelease(vtctx->color_primaries);
2637  vtctx->color_primaries = NULL;
2638  }
2639 
2640  if (vtctx->transfer_function) {
2641  CFRelease(vtctx->transfer_function);
2642  vtctx->transfer_function = NULL;
2643  }
2644 
2645  if (vtctx->ycbcr_matrix) {
2646  CFRelease(vtctx->ycbcr_matrix);
2647  vtctx->ycbcr_matrix = NULL;
2648  }
2649 
2650  return 0;
2651 }
2652 
2653 static const enum AVPixelFormat avc_pix_fmts[] = {
2658 };
2659 
2660 static const enum AVPixelFormat hevc_pix_fmts[] = {
2667 };
2668 
2669 static const enum AVPixelFormat prores_pix_fmts[] = {
2672 #ifdef kCFCoreFoundationVersionNumber10_7
2675 #endif
2677 #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
2679 #endif
2680 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE
2682 #endif
2683 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE
2685 #endif
2686 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE
2688 #endif
2689 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE
2691 #endif
2692 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE
2694 #endif
2695 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE
2697 #endif
2700 };
2701 
2702 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
2703 #define COMMON_OPTIONS \
2704  { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \
2705  { .i64 = 0 }, 0, 1, VE }, \
2706  { "require_sw", "Require software encoding", OFFSET(require_sw), AV_OPT_TYPE_BOOL, \
2707  { .i64 = 0 }, 0, 1, VE }, \
2708  { "realtime", "Hint that encoding should happen in real-time if not faster (e.g. capturing from camera).", \
2709  OFFSET(realtime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, -1, 1, VE }, \
2710  { "frames_before", "Other frames will come before the frames in this session. This helps smooth concatenation issues.", \
2711  OFFSET(frames_before), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \
2712  { "frames_after", "Other frames will come after the frames in this session. This helps smooth concatenation issues.", \
2713  OFFSET(frames_after), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \
2714  { "prio_speed", "prioritize encoding speed", OFFSET(prio_speed), AV_OPT_TYPE_BOOL, \
2715  { .i64 = -1 }, -1, 1, VE }, \
2716 
2717 #define OFFSET(x) offsetof(VTEncContext, x)
2718 static const AVOption h264_options[] = {
2719  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = H264_PROF_AUTO }, H264_PROF_AUTO, H264_PROF_COUNT, VE, "profile" },
2720  { "baseline", "Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_BASELINE }, INT_MIN, INT_MAX, VE, "profile" },
2721  { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
2722  { "high", "High Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_HIGH }, INT_MIN, INT_MAX, VE, "profile" },
2723  { "extended", "Extend Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_EXTENDED }, INT_MIN, INT_MAX, VE, "profile" },
2724 
2725  { "level", "Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, VE, "level" },
2726  { "1.3", "Level 1.3, only available with Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = 13 }, INT_MIN, INT_MAX, VE, "level" },
2727  { "3.0", "Level 3.0", 0, AV_OPT_TYPE_CONST, { .i64 = 30 }, INT_MIN, INT_MAX, VE, "level" },
2728  { "3.1", "Level 3.1", 0, AV_OPT_TYPE_CONST, { .i64 = 31 }, INT_MIN, INT_MAX, VE, "level" },
2729  { "3.2", "Level 3.2", 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, INT_MIN, INT_MAX, VE, "level" },
2730  { "4.0", "Level 4.0", 0, AV_OPT_TYPE_CONST, { .i64 = 40 }, INT_MIN, INT_MAX, VE, "level" },
2731  { "4.1", "Level 4.1", 0, AV_OPT_TYPE_CONST, { .i64 = 41 }, INT_MIN, INT_MAX, VE, "level" },
2732  { "4.2", "Level 4.2", 0, AV_OPT_TYPE_CONST, { .i64 = 42 }, INT_MIN, INT_MAX, VE, "level" },
2733  { "5.0", "Level 5.0", 0, AV_OPT_TYPE_CONST, { .i64 = 50 }, INT_MIN, INT_MAX, VE, "level" },
2734  { "5.1", "Level 5.1", 0, AV_OPT_TYPE_CONST, { .i64 = 51 }, INT_MIN, INT_MAX, VE, "level" },
2735  { "5.2", "Level 5.2", 0, AV_OPT_TYPE_CONST, { .i64 = 52 }, INT_MIN, INT_MAX, VE, "level" },
2736 
2737  { "coder", "Entropy coding", OFFSET(entropy), AV_OPT_TYPE_INT, { .i64 = VT_ENTROPY_NOT_SET }, VT_ENTROPY_NOT_SET, VT_CABAC, VE, "coder" },
2738  { "cavlc", "CAVLC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CAVLC }, INT_MIN, INT_MAX, VE, "coder" },
2739  { "vlc", "CAVLC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CAVLC }, INT_MIN, INT_MAX, VE, "coder" },
2740  { "cabac", "CABAC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CABAC }, INT_MIN, INT_MAX, VE, "coder" },
2741  { "ac", "CABAC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CABAC }, INT_MIN, INT_MAX, VE, "coder" },
2742 
2743  { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, VE },
2744 
2745  { "constant_bit_rate", "Require constant bit rate (macOS 13 or newer)", OFFSET(constant_bit_rate), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
2746 
2748  { NULL },
2749 };
2750 
2752  .class_name = "h264_videotoolbox",
2753  .item_name = av_default_item_name,
2754  .option = h264_options,
2755  .version = LIBAVUTIL_VERSION_INT,
2756 };
2757 
2759  .p.name = "h264_videotoolbox",
2760  CODEC_LONG_NAME("VideoToolbox H.264 Encoder"),
2761  .p.type = AVMEDIA_TYPE_VIDEO,
2762  .p.id = AV_CODEC_ID_H264,
2763  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
2764  .priv_data_size = sizeof(VTEncContext),
2765  .p.pix_fmts = avc_pix_fmts,
2766  .init = vtenc_init,
2768  .close = vtenc_close,
2769  .p.priv_class = &h264_videotoolbox_class,
2770  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
2771 };
2772 
2773 static const AVOption hevc_options[] = {
2774  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = HEVC_PROF_AUTO }, HEVC_PROF_AUTO, HEVC_PROF_COUNT, VE, "profile" },
2775  { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 = HEVC_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
2776  { "main10", "Main10 Profile", 0, AV_OPT_TYPE_CONST, { .i64 = HEVC_PROF_MAIN10 }, INT_MIN, INT_MAX, VE, "profile" },
2777 
2778  { "alpha_quality", "Compression quality for the alpha channel", OFFSET(alpha_quality), AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0.0, 1.0, VE },
2779 
2780  { "constant_bit_rate", "Require constant bit rate (macOS 13 or newer)", OFFSET(constant_bit_rate), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
2781 
2783  { NULL },
2784 };
2785 
2787  .class_name = "hevc_videotoolbox",
2788  .item_name = av_default_item_name,
2789  .option = hevc_options,
2790  .version = LIBAVUTIL_VERSION_INT,
2791 };
2792 
2794  .p.name = "hevc_videotoolbox",
2795  CODEC_LONG_NAME("VideoToolbox H.265 Encoder"),
2796  .p.type = AVMEDIA_TYPE_VIDEO,
2797  .p.id = AV_CODEC_ID_HEVC,
2798  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2800  .priv_data_size = sizeof(VTEncContext),
2801  .p.pix_fmts = hevc_pix_fmts,
2802  .init = vtenc_init,
2804  .close = vtenc_close,
2805  .p.priv_class = &hevc_videotoolbox_class,
2806  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
2807  .p.wrapper_name = "videotoolbox",
2808 };
2809 
2810 static const AVOption prores_options[] = {
2811  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_PRORES_XQ, VE, "profile" },
2812  { "auto", "Automatically determine based on input format", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, VE, "profile" },
2813  { "proxy", "ProRes 422 Proxy", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_PROXY }, INT_MIN, INT_MAX, VE, "profile" },
2814  { "lt", "ProRes 422 LT", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_LT }, INT_MIN, INT_MAX, VE, "profile" },
2815  { "standard", "ProRes 422", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_STANDARD }, INT_MIN, INT_MAX, VE, "profile" },
2816  { "hq", "ProRes 422 HQ", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_HQ }, INT_MIN, INT_MAX, VE, "profile" },
2817  { "4444", "ProRes 4444", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_4444 }, INT_MIN, INT_MAX, VE, "profile" },
2818  { "xq", "ProRes 4444 XQ", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_XQ }, INT_MIN, INT_MAX, VE, "profile" },
2819 
2821  { NULL },
2822 };
2823 
2825  .class_name = "prores_videotoolbox",
2826  .item_name = av_default_item_name,
2827  .option = prores_options,
2828  .version = LIBAVUTIL_VERSION_INT,
2829 };
2830 
2832  .p.name = "prores_videotoolbox",
2833  CODEC_LONG_NAME("VideoToolbox ProRes Encoder"),
2834  .p.type = AVMEDIA_TYPE_VIDEO,
2835  .p.id = AV_CODEC_ID_PRORES,
2836  .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2838  .priv_data_size = sizeof(VTEncContext),
2839  .p.pix_fmts = prores_pix_fmts,
2840  .init = vtenc_init,
2842  .close = vtenc_close,
2843  .p.priv_class = &prores_videotoolbox_class,
2844  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
2845  .p.wrapper_name = "videotoolbox",
2846 };
get_vt_hevc_profile_level
static bool get_vt_hevc_profile_level(AVCodecContext *avctx, CFStringRef *profile_level_val)
Definition: videotoolboxenc.c:811
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:2758
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:2793
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:2660
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:527
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:2529
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:1995
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2860
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:536
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
H264_NAL_AUD
@ H264_NAL_AUD
Definition: h264.h:43
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:2199
vtenc_output_callback
static void vtenc_output_callback(void *ctx, void *sourceFrameCtx, OSStatus status, VTEncodeInfoFlags flags, CMSampleBufferRef sample_buffer)
Definition: videotoolboxenc.c:633
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:706
write_sei
static int write_sei(const ExtraSEI *sei, int sei_type, uint8_t *dst, size_t dst_size)
Definition: videotoolboxenc.c:1748
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:630
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:374
compat_keys
static struct @171 compat_keys
AVOption
AVOption.
Definition: opt.h:251
encode.h
AVCOL_TRC_UNSPECIFIED
@ AVCOL_TRC_UNSPECIFIED
Definition: pixfmt.h:530
kVTProfileLevel_H264_High_4_0
CFStringRef kVTProfileLevel_H264_High_4_0
Definition: videotoolboxenc.c:89
data
const char data[16]
Definition: mxf.c:146
FFCodec
Definition: codec_internal.h:119
VTEncContext::lock
pthread_mutex_t lock
Definition: videotoolboxenc.c:221
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:557
AVCOL_TRC_BT2020_12
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:543
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:502
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:1079
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
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
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:1821
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2900
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:562
vtenc_get_frame_info
static void vtenc_get_frame_info(CMSampleBufferRef buffer, bool *is_key_frame)
Definition: videotoolboxenc.c:1595
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:840
av_color_space_name
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:3277
vtenc_close
static av_cold int vtenc_close(AVCodecContext *avctx)
Definition: videotoolboxenc.c:2617
SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
@ SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
Definition: sei.h:34
kCVPixelFormatType_420YpCbCr10BiPlanarFullRange
@ kCVPixelFormatType_420YpCbCr10BiPlanarFullRange
Definition: videotoolboxenc.c:51
AVCOL_RANGE_NB
@ AVCOL_RANGE_NB
Not part of ABI.
Definition: pixfmt.h:631
AVCOL_TRC_GAMMA28
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
Definition: pixfmt.h:533
add_color_attr
static void add_color_attr(AVCodecContext *avctx, CFMutableDictionaryRef dict)
Definition: videotoolboxenc.c:855
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:288
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:2388
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:532
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:2718
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:466
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:2653
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:2773
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:2669
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:2810
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:563
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:227
kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
@ kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange
Definition: videotoolboxenc.c:52
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
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:505
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:509
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:584
AVCOL_PRI_SMPTE170M
@ AVCOL_PRI_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:510
av_color_range_name
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:3217
kCMVideoCodecType_HEVCWithAlpha
@ kCMVideoCodecType_HEVCWithAlpha
Definition: videotoolboxenc.c:47
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:2824
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:2751
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:504
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:492
create_cv_pixel_buffer_info
static int create_cv_pixel_buffer_info(AVCodecContext *avctx, CFMutableDictionaryRef *dict)
Definition: videotoolboxenc.c:877
av_color_primaries_name
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:3235
AVCOL_TRC_BT2020_10
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:542
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:1074
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:596
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:77
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:513
get_cv_transfer_function
static int get_cv_transfer_function(AVCodecContext *avctx, CFStringRef *transfer_fnc, CFNumberRef *gamma_level)
Definition: videotoolboxenc.c:978
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:544
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
kCMVideoCodecType_HEVC
@ kCMVideoCodecType_HEVC
Definition: videotoolboxenc.c:43
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:535
FF_PROFILE_PRORES_HQ
#define FF_PROFILE_PRORES_HQ
Definition: avcodec.h:1661
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:2291
H264_NAL_PPS
@ H264_NAL_PPS
Definition: h264.h:42
AV_PIX_FMT_AYUV64
#define AV_PIX_FMT_AYUV64
Definition: pixfmt.h:479
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:2786
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:493
AV_PIX_FMT_P210
#define AV_PIX_FMT_P210
Definition: pixfmt.h:491
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:529
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:564
AV_PIX_FMT_VIDEOTOOLBOX
@ AV_PIX_FMT_VIDEOTOOLBOX
hardware decoding through Videotoolbox
Definition: pixfmt.h:274
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:2703
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
AVCOL_SPC_BT2020_NCL
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:567
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:340
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:1697
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:1622
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
H264_NAL_SEI
@ H264_NAL_SEI
Definition: h264.h:40
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:559
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:613
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
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:1440
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
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:548
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:2125
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:520
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:480
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:1041
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
OFFSET
#define OFFSET(x)
Definition: videotoolboxenc.c:2717
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:2404
VE
#define VE
Definition: videotoolboxenc.c:2702
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:276
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:2831
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:494
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:1978
vtenc_frame
static av_cold int vtenc_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: videotoolboxenc.c:2462
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:1633
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:558
H264_PROF_HIGH
@ H264_PROF_HIGH
Definition: videotoolboxenc.c:180
AVColorRange
AVColorRange
Visual content value range.
Definition: pixfmt.h:595
get_cm_codec_type
static CMVideoCodecType get_cm_codec_type(AVCodecContext *avctx, int64_t profile, double alpha_quality)
Definition: videotoolboxenc.c:417
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
av_color_transfer_name
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:3256
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:669
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:2780
vtenc_init
static av_cold int vtenc_init(AVCodecContext *avctx)
Definition: videotoolboxenc.c:1561
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:944
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:73
kVTCompressionPropertyKey_TargetQualityForAlpha
CFStringRef kVTCompressionPropertyKey_TargetQualityForAlpha
Definition: videotoolboxenc.c:102