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