FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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/atomic.h"
30 #include "libavutil/avstring.h"
31 #include "libavcodec/avcodec.h"
32 #include "libavutil/pixdesc.h"
33 #include "internal.h"
34 #include <pthread.h>
35 
36 #if !CONFIG_VT_BT2020
37 # define kCVImageBufferColorPrimaries_ITU_R_2020 CFSTR("ITU_R_2020")
38 # define kCVImageBufferTransferFunction_ITU_R_2020 CFSTR("ITU_R_2020")
39 # define kCVImageBufferYCbCrMatrix_ITU_R_2020 CFSTR("ITU_R_2020")
40 #endif
41 
42 typedef enum VT_H264Profile {
49 
50 typedef enum VTH264Entropy{
55 
56 static const uint8_t start_code[] = { 0, 0, 0, 1 };
57 
58 typedef struct BufNode {
59  CMSampleBufferRef cm_buffer;
60  struct BufNode* next;
61  int error;
62 } BufNode;
63 
64 typedef struct VTEncContext {
65  AVClass *class;
66  VTCompressionSessionRef session;
67  CFStringRef ycbcr_matrix;
68  CFStringRef color_primaries;
69  CFStringRef transfer_function;
70 
73 
75 
78 
79  int64_t frame_ct_out;
80  int64_t frame_ct_in;
81 
82  int64_t first_pts;
83  int64_t dts_delta;
84 
85  int64_t profile;
86  int64_t level;
87  int64_t entropy;
88  int64_t realtime;
89  int64_t frames_before;
90  int64_t frames_after;
91 
92  int64_t allow_sw;
93 
94  bool flushing;
97 } VTEncContext;
98 
100  CMVideoCodecType codec_type,
101  CFStringRef profile_level,
102  CFNumberRef gamma_level,
103  CFDictionaryRef enc_info,
104  CFDictionaryRef pixel_buffer_info);
105 
106 /**
107  * NULL-safe release of *refPtr, and sets value to NULL.
108  */
109 static void vt_release_num(CFNumberRef* refPtr){
110  if (!*refPtr) {
111  return;
112  }
113 
114  CFRelease(*refPtr);
115  *refPtr = NULL;
116 }
117 
118 static void set_async_error(VTEncContext *vtctx, int err)
119 {
120  BufNode *info;
121 
122  pthread_mutex_lock(&vtctx->lock);
123 
124  vtctx->async_error = err;
125 
126  info = vtctx->q_head;
127  vtctx->q_head = vtctx->q_tail = NULL;
128 
129  while (info) {
130  BufNode *next = info->next;
131  CFRelease(info->cm_buffer);
132  av_free(info);
133  info = next;
134  }
135 
136  pthread_mutex_unlock(&vtctx->lock);
137 }
138 
139 static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf)
140 {
141  BufNode *info;
142 
143  pthread_mutex_lock(&vtctx->lock);
144 
145  if (vtctx->async_error) {
146  pthread_mutex_unlock(&vtctx->lock);
147  return vtctx->async_error;
148  }
149 
150  if (vtctx->flushing && vtctx->frame_ct_in == vtctx->frame_ct_out) {
151  *buf = NULL;
152 
153  pthread_mutex_unlock(&vtctx->lock);
154  return 0;
155  }
156 
157  while (!vtctx->q_head && !vtctx->async_error && wait) {
158  pthread_cond_wait(&vtctx->cv_sample_sent, &vtctx->lock);
159  }
160 
161  if (!vtctx->q_head) {
162  pthread_mutex_unlock(&vtctx->lock);
163  *buf = NULL;
164  return 0;
165  }
166 
167  info = vtctx->q_head;
168  vtctx->q_head = vtctx->q_head->next;
169  if (!vtctx->q_head) {
170  vtctx->q_tail = NULL;
171  }
172 
173  pthread_mutex_unlock(&vtctx->lock);
174 
175  *buf = info->cm_buffer;
176  av_free(info);
177 
178  vtctx->frame_ct_out++;
179 
180  return 0;
181 }
182 
183 static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer)
184 {
185  BufNode *info = av_malloc(sizeof(BufNode));
186  if (!info) {
187  set_async_error(vtctx, AVERROR(ENOMEM));
188  return;
189  }
190 
191  CFRetain(buffer);
192  info->cm_buffer = buffer;
193  info->next = NULL;
194 
195  pthread_mutex_lock(&vtctx->lock);
197 
198  if (!vtctx->q_head) {
199  vtctx->q_head = info;
200  } else {
201  vtctx->q_tail->next = info;
202  }
203 
204  vtctx->q_tail = info;
205 
206  pthread_mutex_unlock(&vtctx->lock);
207 }
208 
209 static int count_nalus(size_t length_code_size,
210  CMSampleBufferRef sample_buffer,
211  int *count)
212 {
213  size_t offset = 0;
214  int status;
215  int nalu_ct = 0;
216  uint8_t size_buf[4];
217  size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
218  CMBlockBufferRef block = CMSampleBufferGetDataBuffer(sample_buffer);
219 
220  if (length_code_size > 4)
221  return AVERROR_INVALIDDATA;
222 
223  while (offset < src_size) {
224  size_t curr_src_len;
225  size_t box_len = 0;
226  size_t i;
227 
228  status = CMBlockBufferCopyDataBytes(block,
229  offset,
230  length_code_size,
231  size_buf);
232 
233  for (i = 0; i < length_code_size; i++) {
234  box_len <<= 8;
235  box_len |= size_buf[i];
236  }
237 
238  curr_src_len = box_len + length_code_size;
239  offset += curr_src_len;
240 
241  nalu_ct++;
242  }
243 
244  *count = nalu_ct;
245  return 0;
246 }
247 
248 static CMVideoCodecType get_cm_codec_type(enum AVCodecID id)
249 {
250  switch (id) {
251  case AV_CODEC_ID_H264: return kCMVideoCodecType_H264;
252  default: return 0;
253  }
254 }
255 
256 /**
257  * Get the parameter sets from a CMSampleBufferRef.
258  * @param dst If *dst isn't NULL, the parameters are copied into existing
259  * memory. *dst_size must be set accordingly when *dst != NULL.
260  * If *dst is NULL, it will be allocated.
261  * In all cases, *dst_size is set to the number of bytes used starting
262  * at *dst.
263  */
264 static int get_params_size(
265  AVCodecContext *avctx,
266  CMVideoFormatDescriptionRef vid_fmt,
267  size_t *size)
268 {
269  size_t total_size = 0;
270  size_t ps_count;
271  int is_count_bad = 0;
272  size_t i;
273  int status;
274  status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
275  0,
276  NULL,
277  NULL,
278  &ps_count,
279  NULL);
280  if (status) {
281  is_count_bad = 1;
282  ps_count = 0;
283  status = 0;
284  }
285 
286  for (i = 0; i < ps_count || is_count_bad; i++) {
287  const uint8_t *ps;
288  size_t ps_size;
289  status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
290  i,
291  &ps,
292  &ps_size,
293  NULL,
294  NULL);
295  if (status) {
296  /*
297  * When ps_count is invalid, status != 0 ends the loop normally
298  * unless we didn't get any parameter sets.
299  */
300  if (i > 0 && is_count_bad) status = 0;
301 
302  break;
303  }
304 
305  total_size += ps_size + sizeof(start_code);
306  }
307 
308  if (status) {
309  av_log(avctx, AV_LOG_ERROR, "Error getting parameter set sizes: %d\n", status);
310  return AVERROR_EXTERNAL;
311  }
312 
313  *size = total_size;
314  return 0;
315 }
316 
317 static int copy_param_sets(
318  AVCodecContext *avctx,
319  CMVideoFormatDescriptionRef vid_fmt,
320  uint8_t *dst,
321  size_t dst_size)
322 {
323  size_t ps_count;
324  int is_count_bad = 0;
325  int status;
326  size_t offset = 0;
327  size_t i;
328 
329  status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
330  0,
331  NULL,
332  NULL,
333  &ps_count,
334  NULL);
335  if (status) {
336  is_count_bad = 1;
337  ps_count = 0;
338  status = 0;
339  }
340 
341 
342  for (i = 0; i < ps_count || is_count_bad; i++) {
343  const uint8_t *ps;
344  size_t ps_size;
345  size_t next_offset;
346 
347  status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
348  i,
349  &ps,
350  &ps_size,
351  NULL,
352  NULL);
353  if (status) {
354  if (i > 0 && is_count_bad) status = 0;
355 
356  break;
357  }
358 
359  next_offset = offset + sizeof(start_code) + ps_size;
360  if (dst_size < next_offset) {
361  av_log(avctx, AV_LOG_ERROR, "Error: buffer too small for parameter sets.\n");
363  }
364 
365  memcpy(dst + offset, start_code, sizeof(start_code));
366  offset += sizeof(start_code);
367 
368  memcpy(dst + offset, ps, ps_size);
369  offset = next_offset;
370  }
371 
372  if (status) {
373  av_log(avctx, AV_LOG_ERROR, "Error getting parameter set data: %d\n", status);
374  return AVERROR_EXTERNAL;
375  }
376 
377  return 0;
378 }
379 
380 static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer)
381 {
382  CMVideoFormatDescriptionRef vid_fmt;
383  size_t total_size;
384  int status;
385 
386  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
387  if (!vid_fmt) {
388  av_log(avctx, AV_LOG_ERROR, "No video format.\n");
389  return AVERROR_EXTERNAL;
390  }
391 
392  status = get_params_size(avctx, vid_fmt, &total_size);
393  if (status) {
394  av_log(avctx, AV_LOG_ERROR, "Could not get parameter sets.\n");
395  return status;
396  }
397 
398  avctx->extradata = av_mallocz(total_size + AV_INPUT_BUFFER_PADDING_SIZE);
399  if (!avctx->extradata) {
400  return AVERROR(ENOMEM);
401  }
402  avctx->extradata_size = total_size;
403 
404  status = copy_param_sets(avctx, vid_fmt, avctx->extradata, total_size);
405 
406  if (status) {
407  av_log(avctx, AV_LOG_ERROR, "Could not copy param sets.\n");
408  return status;
409  }
410 
411  return 0;
412 }
413 
415  void *ctx,
416  void *sourceFrameCtx,
417  OSStatus status,
418  VTEncodeInfoFlags flags,
419  CMSampleBufferRef sample_buffer)
420 {
421  AVCodecContext *avctx = ctx;
422  VTEncContext *vtctx = avctx->priv_data;
423 
424  if (vtctx->async_error) {
425  if(sample_buffer) CFRelease(sample_buffer);
426  return;
427  }
428 
429  if (status || !sample_buffer) {
430  av_log(avctx, AV_LOG_ERROR, "Error encoding frame: %d\n", (int)status);
432  return;
433  }
434 
435  if (!avctx->extradata && (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
436  int set_status = set_extradata(avctx, sample_buffer);
437  if (set_status) {
438  set_async_error(vtctx, set_status);
439  return;
440  }
441  }
442 
443  vtenc_q_push(vtctx, sample_buffer);
444 }
445 
447  AVCodecContext *avctx,
448  CMSampleBufferRef sample_buffer,
449  size_t *size)
450 {
451  CMVideoFormatDescriptionRef vid_fmt;
452  int isize;
453  int status;
454 
455  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
456  if (!vid_fmt) {
457  av_log(avctx, AV_LOG_ERROR, "Error getting buffer format description.\n");
458  return AVERROR_EXTERNAL;
459  }
460 
461  status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
462  0,
463  NULL,
464  NULL,
465  NULL,
466  &isize);
467  if (status) {
468  av_log(avctx, AV_LOG_ERROR, "Error getting length code size: %d\n", status);
469  return AVERROR_EXTERNAL;
470  }
471 
472  *size = isize;
473  return 0;
474 }
475 
476 /*
477  * Returns true on success.
478  *
479  * If profile_level_val is NULL and this method returns true, don't specify the
480  * profile/level to the encoder.
481  */
483  CFStringRef *profile_level_val)
484 {
485  VTEncContext *vtctx = avctx->priv_data;
486  int64_t profile = vtctx->profile;
487 
488  if (profile == H264_PROF_AUTO && vtctx->level) {
489  //Need to pick a profile if level is not auto-selected.
490  profile = vtctx->has_b_frames ? H264_PROF_MAIN : H264_PROF_BASELINE;
491  }
492 
493  *profile_level_val = NULL;
494 
495  switch (profile) {
496  case H264_PROF_AUTO:
497  return true;
498 
499  case H264_PROF_BASELINE:
500  switch (vtctx->level) {
501  case 0: *profile_level_val = kVTProfileLevel_H264_Baseline_AutoLevel; break;
502  case 13: *profile_level_val = kVTProfileLevel_H264_Baseline_1_3; break;
503  case 30: *profile_level_val = kVTProfileLevel_H264_Baseline_3_0; break;
504  case 31: *profile_level_val = kVTProfileLevel_H264_Baseline_3_1; break;
505  case 32: *profile_level_val = kVTProfileLevel_H264_Baseline_3_2; break;
506  case 40: *profile_level_val = kVTProfileLevel_H264_Baseline_4_0; break;
507  case 41: *profile_level_val = kVTProfileLevel_H264_Baseline_4_1; break;
508  case 42: *profile_level_val = kVTProfileLevel_H264_Baseline_4_2; break;
509  case 50: *profile_level_val = kVTProfileLevel_H264_Baseline_5_0; break;
510  case 51: *profile_level_val = kVTProfileLevel_H264_Baseline_5_1; break;
511  case 52: *profile_level_val = kVTProfileLevel_H264_Baseline_5_2; break;
512  }
513  break;
514 
515  case H264_PROF_MAIN:
516  switch (vtctx->level) {
517  case 0: *profile_level_val = kVTProfileLevel_H264_Main_AutoLevel; break;
518  case 30: *profile_level_val = kVTProfileLevel_H264_Main_3_0; break;
519  case 31: *profile_level_val = kVTProfileLevel_H264_Main_3_1; break;
520  case 32: *profile_level_val = kVTProfileLevel_H264_Main_3_2; break;
521  case 40: *profile_level_val = kVTProfileLevel_H264_Main_4_0; break;
522  case 41: *profile_level_val = kVTProfileLevel_H264_Main_4_1; break;
523  case 42: *profile_level_val = kVTProfileLevel_H264_Main_4_2; break;
524  case 50: *profile_level_val = kVTProfileLevel_H264_Main_5_0; break;
525  case 51: *profile_level_val = kVTProfileLevel_H264_Main_5_1; break;
526  case 52: *profile_level_val = kVTProfileLevel_H264_Main_5_2; break;
527  }
528  break;
529 
530  case H264_PROF_HIGH:
531  switch (vtctx->level) {
532  case 0: *profile_level_val = kVTProfileLevel_H264_High_AutoLevel; break;
533  case 30: *profile_level_val = kVTProfileLevel_H264_High_3_0; break;
534  case 31: *profile_level_val = kVTProfileLevel_H264_High_3_1; break;
535  case 32: *profile_level_val = kVTProfileLevel_H264_High_3_2; break;
536  case 40: *profile_level_val = kVTProfileLevel_H264_High_4_0; break;
537  case 41: *profile_level_val = kVTProfileLevel_H264_High_4_1; break;
538  case 42: *profile_level_val = kVTProfileLevel_H264_High_4_2; break;
539  case 50: *profile_level_val = kVTProfileLevel_H264_High_5_0; break;
540  case 51: *profile_level_val = kVTProfileLevel_H264_High_5_1; break;
541  case 52: *profile_level_val = kVTProfileLevel_H264_High_5_2; break;
542  }
543  break;
544  }
545 
546  if (!*profile_level_val) {
547  av_log(avctx, AV_LOG_ERROR, "Invalid Profile/Level.\n");
548  return false;
549  }
550 
551  return true;
552 }
553 
555  enum AVPixelFormat fmt,
556  enum AVColorRange range,
557  int* av_pixel_format,
558  int* range_guessed)
559 {
560  if (range_guessed) *range_guessed = range != AVCOL_RANGE_MPEG &&
561  range != AVCOL_RANGE_JPEG;
562 
563  //MPEG range is used when no range is set
564  if (fmt == AV_PIX_FMT_NV12) {
565  *av_pixel_format = range == AVCOL_RANGE_JPEG ?
566  kCVPixelFormatType_420YpCbCr8BiPlanarFullRange :
567  kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
568  } else if (fmt == AV_PIX_FMT_YUV420P) {
569  *av_pixel_format = range == AVCOL_RANGE_JPEG ?
570  kCVPixelFormatType_420YpCbCr8PlanarFullRange :
571  kCVPixelFormatType_420YpCbCr8Planar;
572  } else {
573  return AVERROR(EINVAL);
574  }
575 
576  return 0;
577 }
578 
579 static void add_color_attr(AVCodecContext *avctx, CFMutableDictionaryRef dict) {
580  VTEncContext *vtctx = avctx->priv_data;
581 
582  if (vtctx->color_primaries) {
583  CFDictionarySetValue(dict,
584  kCVImageBufferColorPrimariesKey,
585  vtctx->color_primaries);
586  }
587 
588  if (vtctx->transfer_function) {
589  CFDictionarySetValue(dict,
590  kCVImageBufferTransferFunctionKey,
591  vtctx->transfer_function);
592  }
593 
594  if (vtctx->ycbcr_matrix) {
595  CFDictionarySetValue(dict,
596  kCVImageBufferYCbCrMatrixKey,
597  vtctx->ycbcr_matrix);
598  }
599 }
600 
602  CFMutableDictionaryRef* dict)
603 {
604  CFNumberRef cv_color_format_num = NULL;
605  CFNumberRef width_num = NULL;
606  CFNumberRef height_num = NULL;
607  CFMutableDictionaryRef pixel_buffer_info = NULL;
608  int cv_color_format;
609  int status = get_cv_pixel_format(avctx,
610  avctx->pix_fmt,
611  avctx->color_range,
612  &cv_color_format,
613  NULL);
614  if (status) return status;
615 
616  pixel_buffer_info = CFDictionaryCreateMutable(
617  kCFAllocatorDefault,
618  20,
619  &kCFCopyStringDictionaryKeyCallBacks,
620  &kCFTypeDictionaryValueCallBacks);
621 
622  if (!pixel_buffer_info) goto pbinfo_nomem;
623 
624  cv_color_format_num = CFNumberCreate(kCFAllocatorDefault,
625  kCFNumberSInt32Type,
626  &cv_color_format);
627  if (!cv_color_format_num) goto pbinfo_nomem;
628 
629  CFDictionarySetValue(pixel_buffer_info,
630  kCVPixelBufferPixelFormatTypeKey,
631  cv_color_format_num);
632  vt_release_num(&cv_color_format_num);
633 
634  width_num = CFNumberCreate(kCFAllocatorDefault,
635  kCFNumberSInt32Type,
636  &avctx->width);
637  if (!width_num) return AVERROR(ENOMEM);
638 
639  CFDictionarySetValue(pixel_buffer_info,
640  kCVPixelBufferWidthKey,
641  width_num);
642  vt_release_num(&width_num);
643 
644  height_num = CFNumberCreate(kCFAllocatorDefault,
645  kCFNumberSInt32Type,
646  &avctx->height);
647  if (!height_num) goto pbinfo_nomem;
648 
649  CFDictionarySetValue(pixel_buffer_info,
650  kCVPixelBufferHeightKey,
651  height_num);
652  vt_release_num(&height_num);
653 
654  add_color_attr(avctx, pixel_buffer_info);
655 
656  *dict = pixel_buffer_info;
657  return 0;
658 
659 pbinfo_nomem:
660  vt_release_num(&cv_color_format_num);
661  vt_release_num(&width_num);
662  vt_release_num(&height_num);
663  if (pixel_buffer_info) CFRelease(pixel_buffer_info);
664 
665  return AVERROR(ENOMEM);
666 }
667 
669  CFStringRef *primaries)
670 {
671  enum AVColorPrimaries pri = avctx->color_primaries;
672  switch (pri) {
674  *primaries = NULL;
675  break;
676 
677  case AVCOL_PRI_BT709:
678  *primaries = kCVImageBufferColorPrimaries_ITU_R_709_2;
679  break;
680 
681  case AVCOL_PRI_BT2020:
683  break;
684 
685  default:
686  av_log(avctx, AV_LOG_ERROR, "Color primaries %s is not supported.\n", av_color_primaries_name(pri));
687  *primaries = NULL;
688  return -1;
689  }
690 
691  return 0;
692 }
693 
695  CFStringRef *transfer_fnc,
696  CFNumberRef *gamma_level)
697 {
698  enum AVColorTransferCharacteristic trc = avctx->color_trc;
699  Float32 gamma;
700  *gamma_level = NULL;
701 
702  switch (trc) {
704  *transfer_fnc = NULL;
705  break;
706 
707  case AVCOL_TRC_BT709:
708  *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_709_2;
709  break;
710 
711  case AVCOL_TRC_SMPTE240M:
712  *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_240M_1995;
713  break;
714 
715  case AVCOL_TRC_GAMMA22:
716  gamma = 2.2;
717  *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
718  *gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
719  break;
720 
721  case AVCOL_TRC_GAMMA28:
722  gamma = 2.8;
723  *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
724  *gamma_level = CFNumberCreate(NULL, kCFNumberFloat32Type, &gamma);
725  break;
726 
727  case AVCOL_TRC_BT2020_10:
728  case AVCOL_TRC_BT2020_12:
730  break;
731 
732  default:
733  av_log(avctx, AV_LOG_ERROR, "Transfer function %s is not supported.\n", av_color_transfer_name(trc));
734  return -1;
735  }
736 
737  return 0;
738 }
739 
740 static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix) {
741  switch(avctx->colorspace) {
742  case AVCOL_SPC_BT709:
743  *matrix = kCVImageBufferYCbCrMatrix_ITU_R_709_2;
744  break;
745 
747  *matrix = NULL;
748  break;
749 
750  case AVCOL_SPC_BT470BG:
751  case AVCOL_SPC_SMPTE170M:
752  *matrix = kCVImageBufferYCbCrMatrix_ITU_R_601_4;
753  break;
754 
755  case AVCOL_SPC_SMPTE240M:
756  *matrix = kCVImageBufferYCbCrMatrix_SMPTE_240M_1995;
757  break;
758 
761  break;
762 
763  default:
764  av_log(avctx, AV_LOG_ERROR, "Color space %s is not supported.\n", av_color_space_name(avctx->colorspace));
765  return -1;
766  }
767 
768  return 0;
769 }
770 
772  CMVideoCodecType codec_type,
773  CFStringRef profile_level,
774  CFNumberRef gamma_level,
775  CFDictionaryRef enc_info,
776  CFDictionaryRef pixel_buffer_info,
777  VTCompressionSessionRef *session)
778 {
779  VTEncContext *vtctx = avctx->priv_data;
780  SInt32 bit_rate = avctx->bit_rate;
781  CFNumberRef bit_rate_num;
782 
783  int status = VTCompressionSessionCreate(kCFAllocatorDefault,
784  avctx->width,
785  avctx->height,
786  codec_type,
787  enc_info,
788  pixel_buffer_info,
789  kCFAllocatorDefault,
791  avctx,
792  session);
793 
794  if (status || !vtctx->session) {
795  av_log(avctx, AV_LOG_ERROR, "Error: cannot create compression session: %d\n", status);
796 
797 #if !TARGET_OS_IPHONE
798  if (!vtctx->allow_sw) {
799  av_log(avctx, AV_LOG_ERROR, "Try -allow_sw 1. The hardware encoder may be busy, or not supported.\n");
800  }
801 #endif
802 
803  return AVERROR_EXTERNAL;
804  }
805 
806  bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
807  kCFNumberSInt32Type,
808  &bit_rate);
809  if (!bit_rate_num) return AVERROR(ENOMEM);
810 
811  status = VTSessionSetProperty(vtctx->session,
812  kVTCompressionPropertyKey_AverageBitRate,
813  bit_rate_num);
814  CFRelease(bit_rate_num);
815 
816  if (status) {
817  av_log(avctx, AV_LOG_ERROR, "Error setting bitrate property: %d\n", status);
818  return AVERROR_EXTERNAL;
819  }
820 
821  if (profile_level) {
822  status = VTSessionSetProperty(vtctx->session,
823  kVTCompressionPropertyKey_ProfileLevel,
824  profile_level);
825  if (status) {
826  av_log(avctx, AV_LOG_ERROR, "Error setting profile/level property: %d\n", status);
827  return AVERROR_EXTERNAL;
828  }
829  }
830 
831  if (avctx->gop_size > 0) {
832  CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
833  kCFNumberIntType,
834  &avctx->gop_size);
835  if (!interval) {
836  return AVERROR(ENOMEM);
837  }
838 
839  status = VTSessionSetProperty(vtctx->session,
840  kVTCompressionPropertyKey_MaxKeyFrameInterval,
841  interval);
842  CFRelease(interval);
843 
844  if (status) {
845  av_log(avctx, AV_LOG_ERROR, "Error setting 'max key-frame interval' property: %d\n", status);
846  return AVERROR_EXTERNAL;
847  }
848  }
849 
850  if (vtctx->frames_before) {
851  status = VTSessionSetProperty(vtctx->session,
852  kVTCompressionPropertyKey_MoreFramesBeforeStart,
853  kCFBooleanTrue);
854 
855  if (status == kVTPropertyNotSupportedErr) {
856  av_log(avctx, AV_LOG_WARNING, "frames_before property is not supported on this device. Ignoring.\n");
857  } else if (status) {
858  av_log(avctx, AV_LOG_ERROR, "Error setting frames_before property: %d\n", status);
859  }
860  }
861 
862  if (vtctx->frames_after) {
863  status = VTSessionSetProperty(vtctx->session,
864  kVTCompressionPropertyKey_MoreFramesAfterEnd,
865  kCFBooleanTrue);
866 
867  if (status == kVTPropertyNotSupportedErr) {
868  av_log(avctx, AV_LOG_WARNING, "frames_after property is not supported on this device. Ignoring.\n");
869  } else if (status) {
870  av_log(avctx, AV_LOG_ERROR, "Error setting frames_after property: %d\n", status);
871  }
872  }
873 
874  if (avctx->sample_aspect_ratio.num != 0) {
875  CFNumberRef num;
876  CFNumberRef den;
877  CFMutableDictionaryRef par;
878  AVRational *avpar = &avctx->sample_aspect_ratio;
879 
880  av_reduce(&avpar->num, &avpar->den,
881  avpar->num, avpar->den,
882  0xFFFFFFFF);
883 
884  num = CFNumberCreate(kCFAllocatorDefault,
885  kCFNumberIntType,
886  &avpar->num);
887 
888  den = CFNumberCreate(kCFAllocatorDefault,
889  kCFNumberIntType,
890  &avpar->den);
891 
892 
893 
894  par = CFDictionaryCreateMutable(kCFAllocatorDefault,
895  2,
896  &kCFCopyStringDictionaryKeyCallBacks,
897  &kCFTypeDictionaryValueCallBacks);
898 
899  if (!par || !num || !den) {
900  if (par) CFRelease(par);
901  if (num) CFRelease(num);
902  if (den) CFRelease(den);
903 
904  return AVERROR(ENOMEM);
905  }
906 
907  CFDictionarySetValue(
908  par,
909  kCMFormatDescriptionKey_PixelAspectRatioHorizontalSpacing,
910  num);
911 
912  CFDictionarySetValue(
913  par,
914  kCMFormatDescriptionKey_PixelAspectRatioVerticalSpacing,
915  den);
916 
917  status = VTSessionSetProperty(vtctx->session,
918  kVTCompressionPropertyKey_PixelAspectRatio,
919  par);
920 
921  CFRelease(par);
922  CFRelease(num);
923  CFRelease(den);
924 
925  if (status) {
926  av_log(avctx,
927  AV_LOG_ERROR,
928  "Error setting pixel aspect ratio to %d:%d: %d.\n",
929  avctx->sample_aspect_ratio.num,
930  avctx->sample_aspect_ratio.den,
931  status);
932 
933  return AVERROR_EXTERNAL;
934  }
935  }
936 
937 
938  if (vtctx->transfer_function) {
939  status = VTSessionSetProperty(vtctx->session,
940  kVTCompressionPropertyKey_TransferFunction,
941  vtctx->transfer_function);
942 
943  if (status) {
944  av_log(avctx, AV_LOG_WARNING, "Could not set transfer function: %d\n", status);
945  }
946  }
947 
948 
949  if (vtctx->ycbcr_matrix) {
950  status = VTSessionSetProperty(vtctx->session,
951  kVTCompressionPropertyKey_YCbCrMatrix,
952  vtctx->ycbcr_matrix);
953 
954  if (status) {
955  av_log(avctx, AV_LOG_WARNING, "Could not set ycbcr matrix: %d\n", status);
956  }
957  }
958 
959 
960  if (vtctx->color_primaries) {
961  status = VTSessionSetProperty(vtctx->session,
962  kVTCompressionPropertyKey_ColorPrimaries,
963  vtctx->color_primaries);
964 
965  if (status) {
966  av_log(avctx, AV_LOG_WARNING, "Could not set color primaries: %d\n", status);
967  }
968  }
969 
970  if (gamma_level) {
971  status = VTSessionSetProperty(vtctx->session,
972  kCVImageBufferGammaLevelKey,
973  gamma_level);
974 
975  if (status) {
976  av_log(avctx, AV_LOG_WARNING, "Could not set gamma level: %d\n", status);
977  }
978  }
979 
980  if (!vtctx->has_b_frames) {
981  status = VTSessionSetProperty(vtctx->session,
982  kVTCompressionPropertyKey_AllowFrameReordering,
983  kCFBooleanFalse);
984 
985  if (status) {
986  av_log(avctx, AV_LOG_ERROR, "Error setting 'allow frame reordering' property: %d\n", status);
987  return AVERROR_EXTERNAL;
988  }
989  }
990 
991  if (vtctx->entropy != VT_ENTROPY_NOT_SET) {
992  CFStringRef entropy = vtctx->entropy == VT_CABAC ?
993  kVTH264EntropyMode_CABAC:
994  kVTH264EntropyMode_CAVLC;
995 
996  status = VTSessionSetProperty(vtctx->session,
997  kVTCompressionPropertyKey_H264EntropyMode,
998  entropy);
999 
1000  if (status) {
1001  av_log(avctx, AV_LOG_ERROR, "Error setting entropy property: %d\n", status);
1002  return AVERROR_EXTERNAL;
1003  }
1004  }
1005 
1006  if (vtctx->realtime) {
1007  status = VTSessionSetProperty(vtctx->session,
1008  kVTCompressionPropertyKey_RealTime,
1009  kCFBooleanTrue);
1010 
1011  if (status) {
1012  av_log(avctx, AV_LOG_ERROR, "Error setting realtime property: %d\n", status);
1013  }
1014  }
1015 
1016  status = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
1017  if (status) {
1018  av_log(avctx, AV_LOG_ERROR, "Error: cannot prepare encoder: %d\n", status);
1019  return AVERROR_EXTERNAL;
1020  }
1021 
1022  return 0;
1023 }
1024 
1026 {
1027  CFMutableDictionaryRef enc_info;
1028  CFMutableDictionaryRef pixel_buffer_info;
1029  CMVideoCodecType codec_type;
1030  VTEncContext *vtctx = avctx->priv_data;
1031  CFStringRef profile_level;
1032  CFBooleanRef has_b_frames_cfbool;
1033  CFNumberRef gamma_level = NULL;
1034  int status;
1035 
1036  codec_type = get_cm_codec_type(avctx->codec_id);
1037  if (!codec_type) {
1038  av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id);
1039  return AVERROR(EINVAL);
1040  }
1041 
1042  vtctx->has_b_frames = avctx->max_b_frames > 0;
1043  if(vtctx->has_b_frames && vtctx->profile == H264_PROF_BASELINE){
1044  av_log(avctx, AV_LOG_WARNING, "Cannot use B-frames with baseline profile. Output will not contain B-frames.\n");
1045  vtctx->has_b_frames = false;
1046  }
1047 
1048  if (vtctx->entropy == VT_CABAC && vtctx->profile == H264_PROF_BASELINE) {
1049  av_log(avctx, AV_LOG_WARNING, "CABAC entropy requires 'main' or 'high' profile, but baseline was requested. Encode will not use CABAC entropy.\n");
1050  vtctx->entropy = VT_ENTROPY_NOT_SET;
1051  }
1052 
1053  if (!get_vt_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1054 
1055  vtctx->session = NULL;
1056 
1057  enc_info = CFDictionaryCreateMutable(
1058  kCFAllocatorDefault,
1059  20,
1060  &kCFCopyStringDictionaryKeyCallBacks,
1061  &kCFTypeDictionaryValueCallBacks
1062  );
1063 
1064  if (!enc_info) return AVERROR(ENOMEM);
1065 
1066 #if !TARGET_OS_IPHONE
1067  if (!vtctx->allow_sw) {
1068  CFDictionarySetValue(enc_info, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder, kCFBooleanTrue);
1069  } else {
1070  CFDictionarySetValue(enc_info, kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder, kCFBooleanTrue);
1071  }
1072 #endif
1073 
1074  if (avctx->pix_fmt != AV_PIX_FMT_VIDEOTOOLBOX) {
1075  status = create_cv_pixel_buffer_info(avctx, &pixel_buffer_info);
1076  if (status)
1077  goto init_cleanup;
1078  } else {
1079  pixel_buffer_info = NULL;
1080  }
1081 
1082  pthread_mutex_init(&vtctx->lock, NULL);
1084  vtctx->dts_delta = vtctx->has_b_frames ? -1 : 0;
1085 
1086  get_cv_transfer_function(avctx, &vtctx->transfer_function, &gamma_level);
1087  get_cv_ycbcr_matrix(avctx, &vtctx->ycbcr_matrix);
1088  get_cv_color_primaries(avctx, &vtctx->color_primaries);
1089 
1090 
1091  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1092  status = vtenc_populate_extradata(avctx,
1093  codec_type,
1094  profile_level,
1095  gamma_level,
1096  enc_info,
1097  pixel_buffer_info);
1098  if (status)
1099  goto init_cleanup;
1100  }
1101 
1102  status = vtenc_create_encoder(avctx,
1103  codec_type,
1104  profile_level,
1105  gamma_level,
1106  enc_info,
1107  pixel_buffer_info,
1108  &vtctx->session);
1109 
1110  if (status < 0)
1111  goto init_cleanup;
1112 
1113  status = VTSessionCopyProperty(vtctx->session,
1114  kVTCompressionPropertyKey_AllowFrameReordering,
1115  kCFAllocatorDefault,
1116  &has_b_frames_cfbool);
1117 
1118  if (!status) {
1119  //Some devices don't output B-frames for main profile, even if requested.
1120  vtctx->has_b_frames = CFBooleanGetValue(has_b_frames_cfbool);
1121  CFRelease(has_b_frames_cfbool);
1122  }
1123  avctx->has_b_frames = vtctx->has_b_frames;
1124 
1125 init_cleanup:
1126  if (gamma_level)
1127  CFRelease(gamma_level);
1128 
1129  if (pixel_buffer_info)
1130  CFRelease(pixel_buffer_info);
1131 
1132  CFRelease(enc_info);
1133 
1134  return status;
1135 }
1136 
1137 static void vtenc_get_frame_info(CMSampleBufferRef buffer, bool *is_key_frame)
1138 {
1139  CFArrayRef attachments;
1140  CFDictionaryRef attachment;
1141  CFBooleanRef not_sync;
1142  CFIndex len;
1143 
1144  attachments = CMSampleBufferGetSampleAttachmentsArray(buffer, false);
1145  len = !attachments ? 0 : CFArrayGetCount(attachments);
1146 
1147  if (!len) {
1148  *is_key_frame = true;
1149  return;
1150  }
1151 
1152  attachment = CFArrayGetValueAtIndex(attachments, 0);
1153 
1154  if (CFDictionaryGetValueIfPresent(attachment,
1155  kCMSampleAttachmentKey_NotSync,
1156  (const void **)&not_sync))
1157  {
1158  *is_key_frame = !CFBooleanGetValue(not_sync);
1159  } else {
1160  *is_key_frame = true;
1161  }
1162 }
1163 
1164 /**
1165  * Copies NAL units and replaces length codes with
1166  * H.264 Annex B start codes. On failure, the contents of
1167  * dst_data may have been modified.
1168  *
1169  * @param length_code_size Byte length of each length code
1170  * @param src_data NAL units prefixed with length codes.
1171  * @param src_size Length of buffer, excluding any padding.
1172  * @param dst_data Must be zeroed before calling this function.
1173  * Contains the copied NAL units prefixed with
1174  * start codes when the function returns
1175  * successfully.
1176  * @param dst_size Length of dst_data
1177  * @return 0 on success
1178  * AVERROR_INVALIDDATA if length_code_size is invalid
1179  * AVERROR_BUFFER_TOO_SMALL if dst_data is too small
1180  * or if a length_code in src_data specifies data beyond
1181  * the end of its buffer.
1182  */
1184  AVCodecContext *avctx,
1185  size_t length_code_size,
1186  CMSampleBufferRef sample_buffer,
1187  uint8_t *dst_data,
1188  size_t dst_size)
1189 {
1190  size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
1191  size_t remaining_src_size = src_size;
1192  size_t remaining_dst_size = dst_size;
1193  size_t src_offset = 0;
1194  int status;
1195  uint8_t size_buf[4];
1196  CMBlockBufferRef block = CMSampleBufferGetDataBuffer(sample_buffer);
1197 
1198  if (length_code_size > 4) {
1199  return AVERROR_INVALIDDATA;
1200  }
1201 
1202  while (remaining_src_size > 0) {
1203  size_t curr_src_len;
1204  size_t curr_dst_len;
1205  size_t box_len = 0;
1206  size_t i;
1207 
1208  uint8_t *dst_box;
1209 
1210  status = CMBlockBufferCopyDataBytes(block,
1211  src_offset,
1212  length_code_size,
1213  size_buf);
1214  if (status) {
1215  av_log(avctx, AV_LOG_ERROR, "Cannot copy length: %d\n", status);
1216  return AVERROR_EXTERNAL;
1217  }
1218 
1219  for (i = 0; i < length_code_size; i++) {
1220  box_len <<= 8;
1221  box_len |= size_buf[i];
1222  }
1223 
1224  curr_src_len = box_len + length_code_size;
1225  curr_dst_len = box_len + sizeof(start_code);
1226 
1227  if (remaining_src_size < curr_src_len) {
1228  return AVERROR_BUFFER_TOO_SMALL;
1229  }
1230 
1231  if (remaining_dst_size < curr_dst_len) {
1232  return AVERROR_BUFFER_TOO_SMALL;
1233  }
1234 
1235  dst_box = dst_data + sizeof(start_code);
1236 
1237  memcpy(dst_data, start_code, sizeof(start_code));
1238  status = CMBlockBufferCopyDataBytes(block,
1239  src_offset + length_code_size,
1240  box_len,
1241  dst_box);
1242 
1243  if (status) {
1244  av_log(avctx, AV_LOG_ERROR, "Cannot copy data: %d\n", status);
1245  return AVERROR_EXTERNAL;
1246  }
1247 
1248  src_offset += curr_src_len;
1249  dst_data += curr_dst_len;
1250 
1251  remaining_src_size -= curr_src_len;
1252  remaining_dst_size -= curr_dst_len;
1253  }
1254 
1255  return 0;
1256 }
1257 
1259  AVCodecContext *avctx,
1260  CMSampleBufferRef sample_buffer,
1261  AVPacket *pkt)
1262 {
1263  VTEncContext *vtctx = avctx->priv_data;
1264 
1265  int status;
1266  bool is_key_frame;
1267  bool add_header;
1268  size_t length_code_size;
1269  size_t header_size = 0;
1270  size_t in_buf_size;
1271  size_t out_buf_size;
1272  int64_t dts_delta;
1273  int64_t time_base_num;
1274  int nalu_count;
1275  CMTime pts;
1276  CMTime dts;
1277  CMVideoFormatDescriptionRef vid_fmt;
1278 
1279 
1280  vtenc_get_frame_info(sample_buffer, &is_key_frame);
1281  status = get_length_code_size(avctx, sample_buffer, &length_code_size);
1282  if (status) return status;
1283 
1284  add_header = is_key_frame && !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER);
1285 
1286  if (add_header) {
1287  vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
1288  if (!vid_fmt) {
1289  av_log(avctx, AV_LOG_ERROR, "Cannot get format description.\n");
1290  return AVERROR_EXTERNAL;
1291  }
1292 
1293  int status = get_params_size(avctx, vid_fmt, &header_size);
1294  if (status) return status;
1295  }
1296 
1297  status = count_nalus(length_code_size, sample_buffer, &nalu_count);
1298  if(status)
1299  return status;
1300 
1301  in_buf_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
1302  out_buf_size = header_size +
1303  in_buf_size +
1304  nalu_count * ((int)sizeof(start_code) - (int)length_code_size);
1305 
1306  status = ff_alloc_packet2(avctx, pkt, out_buf_size, out_buf_size);
1307  if (status < 0)
1308  return status;
1309 
1310  if (add_header) {
1311  status = copy_param_sets(avctx, vid_fmt, pkt->data, out_buf_size);
1312  if(status) return status;
1313  }
1314 
1315  status = copy_replace_length_codes(
1316  avctx,
1317  length_code_size,
1318  sample_buffer,
1319  pkt->data + header_size,
1320  pkt->size - header_size
1321  );
1322 
1323  if (status) {
1324  av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d", status);
1325  return status;
1326  }
1327 
1328  if (is_key_frame) {
1329  pkt->flags |= AV_PKT_FLAG_KEY;
1330  }
1331 
1332  pts = CMSampleBufferGetPresentationTimeStamp(sample_buffer);
1333  dts = CMSampleBufferGetDecodeTimeStamp (sample_buffer);
1334 
1335  if (CMTIME_IS_INVALID(dts)) {
1336  if (!vtctx->has_b_frames) {
1337  dts = pts;
1338  } else {
1339  av_log(avctx, AV_LOG_ERROR, "DTS is invalid.\n");
1340  return AVERROR_EXTERNAL;
1341  }
1342  }
1343 
1344  dts_delta = vtctx->dts_delta >= 0 ? vtctx->dts_delta : 0;
1345  time_base_num = avctx->time_base.num;
1346  pkt->pts = pts.value / time_base_num;
1347  pkt->dts = dts.value / time_base_num - dts_delta;
1348  pkt->size = out_buf_size;
1349 
1350  return 0;
1351 }
1352 
1353 /*
1354  * contiguous_buf_size is 0 if not contiguous, and the size of the buffer
1355  * containing all planes if so.
1356  */
1358  AVCodecContext *avctx,
1359  const AVFrame *frame,
1360  int *color,
1361  int *plane_count,
1362  size_t *widths,
1363  size_t *heights,
1364  size_t *strides,
1365  size_t *contiguous_buf_size)
1366 {
1367  VTEncContext *vtctx = avctx->priv_data;
1368  int av_format = frame->format;
1369  int av_color_range = av_frame_get_color_range(frame);
1370  int i;
1371  int range_guessed;
1372  int status;
1373 
1374  status = get_cv_pixel_format(avctx, av_format, av_color_range, color, &range_guessed);
1375  if (status) {
1376  av_log(avctx,
1377  AV_LOG_ERROR,
1378  "Could not get pixel format for color format '%s' range '%s'.\n",
1379  av_get_pix_fmt_name(av_format),
1380  av_color_range > AVCOL_RANGE_UNSPECIFIED &&
1381  av_color_range < AVCOL_RANGE_NB ?
1382  av_color_range_name(av_color_range) :
1383  "Unknown");
1384 
1385  return AVERROR(EINVAL);
1386  }
1387 
1388  if (range_guessed) {
1389  if (!vtctx->warned_color_range) {
1390  vtctx->warned_color_range = true;
1391  av_log(avctx,
1393  "Color range not set for %s. Using MPEG range.\n",
1394  av_get_pix_fmt_name(av_format));
1395  }
1396 
1397  av_log(avctx, AV_LOG_WARNING, "");
1398  }
1399 
1400  switch (av_format) {
1401  case AV_PIX_FMT_NV12:
1402  *plane_count = 2;
1403 
1404  widths [0] = avctx->width;
1405  heights[0] = avctx->height;
1406  strides[0] = frame ? frame->linesize[0] : avctx->width;
1407 
1408  widths [1] = (avctx->width + 1) / 2;
1409  heights[1] = (avctx->height + 1) / 2;
1410  strides[1] = frame ? frame->linesize[1] : (avctx->width + 1) & -2;
1411  break;
1412 
1413  case AV_PIX_FMT_YUV420P:
1414  *plane_count = 3;
1415 
1416  widths [0] = avctx->width;
1417  heights[0] = avctx->height;
1418  strides[0] = frame ? frame->linesize[0] : avctx->width;
1419 
1420  widths [1] = (avctx->width + 1) / 2;
1421  heights[1] = (avctx->height + 1) / 2;
1422  strides[1] = frame ? frame->linesize[1] : (avctx->width + 1) / 2;
1423 
1424  widths [2] = (avctx->width + 1) / 2;
1425  heights[2] = (avctx->height + 1) / 2;
1426  strides[2] = frame ? frame->linesize[2] : (avctx->width + 1) / 2;
1427  break;
1428 
1429  default:
1430  av_log(
1431  avctx,
1432  AV_LOG_ERROR,
1433  "Could not get frame format info for color %d range %d.\n",
1434  av_format,
1435  av_color_range);
1436 
1437  return AVERROR(EINVAL);
1438  }
1439 
1440  *contiguous_buf_size = 0;
1441  for (i = 0; i < *plane_count; i++) {
1442  if (i < *plane_count - 1 &&
1443  frame->data[i] + strides[i] * heights[i] != frame->data[i + 1]) {
1444  *contiguous_buf_size = 0;
1445  break;
1446  }
1447 
1448  *contiguous_buf_size += strides[i] * heights[i];
1449  }
1450 
1451  return 0;
1452 }
1453 
1454 #if !TARGET_OS_IPHONE
1455 //Not used on iOS - frame is always copied.
1456 static void free_avframe(
1457  void *release_ctx,
1458  const void *data,
1459  size_t size,
1460  size_t plane_count,
1461  const void *plane_addresses[])
1462 {
1463  AVFrame *frame = release_ctx;
1464  av_frame_free(&frame);
1465 }
1466 #else
1467 //Not used on OSX - frame is never copied.
1468 static int copy_avframe_to_pixel_buffer(AVCodecContext *avctx,
1469  const AVFrame *frame,
1470  CVPixelBufferRef cv_img,
1471  const size_t *plane_strides,
1472  const size_t *plane_rows)
1473 {
1474  int i, j;
1475  size_t plane_count;
1476  int status;
1477  int rows;
1478  int src_stride;
1479  int dst_stride;
1480  uint8_t *src_addr;
1481  uint8_t *dst_addr;
1482  size_t copy_bytes;
1483 
1484  status = CVPixelBufferLockBaseAddress(cv_img, 0);
1485  if (status) {
1486  av_log(
1487  avctx,
1488  AV_LOG_ERROR,
1489  "Error: Could not lock base address of CVPixelBuffer: %d.\n",
1490  status
1491  );
1492  }
1493 
1494  if (CVPixelBufferIsPlanar(cv_img)) {
1495  plane_count = CVPixelBufferGetPlaneCount(cv_img);
1496  for (i = 0; frame->data[i]; i++) {
1497  if (i == plane_count) {
1498  CVPixelBufferUnlockBaseAddress(cv_img, 0);
1499  av_log(avctx,
1500  AV_LOG_ERROR,
1501  "Error: different number of planes in AVFrame and CVPixelBuffer.\n"
1502  );
1503 
1504  return AVERROR_EXTERNAL;
1505  }
1506 
1507  dst_addr = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(cv_img, i);
1508  src_addr = (uint8_t*)frame->data[i];
1509  dst_stride = CVPixelBufferGetBytesPerRowOfPlane(cv_img, i);
1510  src_stride = plane_strides[i];
1511  rows = plane_rows[i];
1512 
1513  if (dst_stride == src_stride) {
1514  memcpy(dst_addr, src_addr, src_stride * rows);
1515  } else {
1516  copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
1517 
1518  for (j = 0; j < rows; j++) {
1519  memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
1520  }
1521  }
1522  }
1523  } else {
1524  if (frame->data[1]) {
1525  CVPixelBufferUnlockBaseAddress(cv_img, 0);
1526  av_log(avctx,
1527  AV_LOG_ERROR,
1528  "Error: different number of planes in AVFrame and non-planar CVPixelBuffer.\n"
1529  );
1530 
1531  return AVERROR_EXTERNAL;
1532  }
1533 
1534  dst_addr = (uint8_t*)CVPixelBufferGetBaseAddress(cv_img);
1535  src_addr = (uint8_t*)frame->data[0];
1536  dst_stride = CVPixelBufferGetBytesPerRow(cv_img);
1537  src_stride = plane_strides[0];
1538  rows = plane_rows[0];
1539 
1540  if (dst_stride == src_stride) {
1541  memcpy(dst_addr, src_addr, src_stride * rows);
1542  } else {
1543  copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
1544 
1545  for (j = 0; j < rows; j++) {
1546  memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
1547  }
1548  }
1549  }
1550 
1551  status = CVPixelBufferUnlockBaseAddress(cv_img, 0);
1552  if (status) {
1553  av_log(avctx, AV_LOG_ERROR, "Error: Could not unlock CVPixelBuffer base address: %d.\n", status);
1554  return AVERROR_EXTERNAL;
1555  }
1556 
1557  return 0;
1558 }
1559 #endif //!TARGET_OS_IPHONE
1560 
1562  const AVFrame *frame,
1563  CVPixelBufferRef *cv_img)
1564 {
1565  int plane_count;
1566  int color;
1567  size_t widths [AV_NUM_DATA_POINTERS];
1568  size_t heights[AV_NUM_DATA_POINTERS];
1569  size_t strides[AV_NUM_DATA_POINTERS];
1570  int status;
1571  size_t contiguous_buf_size;
1572 #if TARGET_OS_IPHONE
1573  CVPixelBufferPoolRef pix_buf_pool;
1574  VTEncContext* vtctx = avctx->priv_data;
1575 #else
1576  CFMutableDictionaryRef pix_buf_attachments = CFDictionaryCreateMutable(
1577  kCFAllocatorDefault,
1578  10,
1579  &kCFCopyStringDictionaryKeyCallBacks,
1580  &kCFTypeDictionaryValueCallBacks);
1581 
1582  if (!pix_buf_attachments) return AVERROR(ENOMEM);
1583 #endif
1584 
1585  if (avctx->pix_fmt == AV_PIX_FMT_VIDEOTOOLBOX) {
1587 
1588  *cv_img = (CVPixelBufferRef)frame->data[3];
1589  av_assert0(*cv_img);
1590 
1591  CFRetain(*cv_img);
1592  return 0;
1593  }
1594 
1595  memset(widths, 0, sizeof(widths));
1596  memset(heights, 0, sizeof(heights));
1597  memset(strides, 0, sizeof(strides));
1598 
1599  status = get_cv_pixel_info(
1600  avctx,
1601  frame,
1602  &color,
1603  &plane_count,
1604  widths,
1605  heights,
1606  strides,
1607  &contiguous_buf_size
1608  );
1609 
1610  if (status) {
1611  av_log(
1612  avctx,
1613  AV_LOG_ERROR,
1614  "Error: Cannot convert format %d color_range %d: %d\n",
1615  frame->format,
1616  av_frame_get_color_range(frame),
1617  status
1618  );
1619 
1620  return AVERROR_EXTERNAL;
1621  }
1622 
1623 #if TARGET_OS_IPHONE
1624  pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->session);
1625  if (!pix_buf_pool) {
1626  av_log(avctx, AV_LOG_ERROR, "Could not get pixel buffer pool.\n");
1627  return AVERROR_EXTERNAL;
1628  }
1629 
1630  status = CVPixelBufferPoolCreatePixelBuffer(NULL,
1631  pix_buf_pool,
1632  cv_img);
1633 
1634 
1635  if (status) {
1636  av_log(avctx, AV_LOG_ERROR, "Could not create pixel buffer from pool: %d.\n", status);
1637  return AVERROR_EXTERNAL;
1638  }
1639 
1640  status = copy_avframe_to_pixel_buffer(avctx, frame, *cv_img, strides, heights);
1641  if (status) {
1642  CFRelease(*cv_img);
1643  *cv_img = NULL;
1644  return status;
1645  }
1646 #else
1647  AVFrame *enc_frame = av_frame_alloc();
1648  if (!enc_frame) return AVERROR(ENOMEM);
1649 
1650  status = av_frame_ref(enc_frame, frame);
1651  if (status) {
1652  av_frame_free(&enc_frame);
1653  return status;
1654  }
1655 
1656  status = CVPixelBufferCreateWithPlanarBytes(
1657  kCFAllocatorDefault,
1658  enc_frame->width,
1659  enc_frame->height,
1660  color,
1661  NULL,
1662  contiguous_buf_size,
1663  plane_count,
1664  (void **)enc_frame->data,
1665  widths,
1666  heights,
1667  strides,
1668  free_avframe,
1669  enc_frame,
1670  NULL,
1671  cv_img
1672  );
1673 
1674  add_color_attr(avctx, pix_buf_attachments);
1675  CVBufferSetAttachments(*cv_img, pix_buf_attachments, kCVAttachmentMode_ShouldPropagate);
1676  CFRelease(pix_buf_attachments);
1677 
1678  if (status) {
1679  av_log(avctx, AV_LOG_ERROR, "Error: Could not create CVPixelBuffer: %d\n", status);
1680  return AVERROR_EXTERNAL;
1681  }
1682 #endif
1683 
1684  return 0;
1685 }
1686 
1687 static int create_encoder_dict_h264(const AVFrame *frame,
1688  CFDictionaryRef* dict_out)
1689 {
1690  CFDictionaryRef dict = NULL;
1691  if (frame->pict_type == AV_PICTURE_TYPE_I) {
1692  const void *keys[] = { kVTEncodeFrameOptionKey_ForceKeyFrame };
1693  const void *vals[] = { kCFBooleanTrue };
1694 
1695  dict = CFDictionaryCreate(NULL, keys, vals, 1, NULL, NULL);
1696  if(!dict) return AVERROR(ENOMEM);
1697  }
1698 
1699  *dict_out = dict;
1700  return 0;
1701 }
1702 
1704  VTEncContext *vtctx,
1705  const AVFrame *frame)
1706 {
1707  CMTime time;
1708  CFDictionaryRef frame_dict;
1709  CVPixelBufferRef cv_img = NULL;
1710  int status = create_cv_pixel_buffer(avctx, frame, &cv_img);
1711 
1712  if (status) return status;
1713 
1714  status = create_encoder_dict_h264(frame, &frame_dict);
1715  if (status) {
1716  CFRelease(cv_img);
1717  return status;
1718  }
1719 
1720  time = CMTimeMake(frame->pts * avctx->time_base.num, avctx->time_base.den);
1721  status = VTCompressionSessionEncodeFrame(
1722  vtctx->session,
1723  cv_img,
1724  time,
1725  kCMTimeInvalid,
1726  frame_dict,
1727  NULL,
1728  NULL
1729  );
1730 
1731  if (frame_dict) CFRelease(frame_dict);
1732  CFRelease(cv_img);
1733 
1734  if (status) {
1735  av_log(avctx, AV_LOG_ERROR, "Error: cannot encode frame: %d\n", status);
1736  return AVERROR_EXTERNAL;
1737  }
1738 
1739  return 0;
1740 }
1741 
1743  AVCodecContext *avctx,
1744  AVPacket *pkt,
1745  const AVFrame *frame,
1746  int *got_packet)
1747 {
1748  VTEncContext *vtctx = avctx->priv_data;
1749  bool get_frame;
1750  int status;
1751  CMSampleBufferRef buf = NULL;
1752 
1753  if (frame) {
1754  status = vtenc_send_frame(avctx, vtctx, frame);
1755 
1756  if (status) {
1757  status = AVERROR_EXTERNAL;
1758  goto end_nopkt;
1759  }
1760 
1761  if (vtctx->frame_ct_in == 0) {
1762  vtctx->first_pts = frame->pts;
1763  } else if(vtctx->frame_ct_in == 1 && vtctx->has_b_frames) {
1764  vtctx->dts_delta = frame->pts - vtctx->first_pts;
1765  }
1766 
1767  vtctx->frame_ct_in++;
1768  } else if(!vtctx->flushing) {
1769  vtctx->flushing = true;
1770 
1771  status = VTCompressionSessionCompleteFrames(vtctx->session,
1772  kCMTimeIndefinite);
1773 
1774  if (status) {
1775  av_log(avctx, AV_LOG_ERROR, "Error flushing frames: %d\n", status);
1776  status = AVERROR_EXTERNAL;
1777  goto end_nopkt;
1778  }
1779  }
1780 
1781  *got_packet = 0;
1782  get_frame = vtctx->dts_delta >= 0 || !frame;
1783  if (!get_frame) {
1784  status = 0;
1785  goto end_nopkt;
1786  }
1787 
1788  status = vtenc_q_pop(vtctx, !frame, &buf);
1789  if (status) goto end_nopkt;
1790  if (!buf) goto end_nopkt;
1791 
1792  status = vtenc_cm_to_avpacket(avctx, buf, pkt);
1793  CFRelease(buf);
1794  if (status) goto end_nopkt;
1795 
1796  *got_packet = 1;
1797  return 0;
1798 
1799 end_nopkt:
1800  av_packet_unref(pkt);
1801  return status;
1802 }
1803 
1805  CMVideoCodecType codec_type,
1806  CFStringRef profile_level,
1807  CFNumberRef gamma_level,
1808  CFDictionaryRef enc_info,
1809  CFDictionaryRef pixel_buffer_info)
1810 {
1811  VTEncContext *vtctx = avctx->priv_data;
1812  AVFrame *frame = av_frame_alloc();
1813  int y_size = avctx->width * avctx->height;
1814  int chroma_size = (avctx->width / 2) * (avctx->height / 2);
1815  CMSampleBufferRef buf = NULL;
1816  int status;
1817 
1818  if (!frame)
1819  return AVERROR(ENOMEM);
1820 
1821  frame->buf[0] = av_buffer_alloc(y_size + 2 * chroma_size);
1822 
1823  if(!frame->buf[0]){
1824  status = AVERROR(ENOMEM);
1825  goto pe_cleanup;
1826  }
1827 
1828  status = vtenc_create_encoder(avctx,
1829  codec_type,
1830  profile_level,
1831  gamma_level,
1832  enc_info,
1833  pixel_buffer_info,
1834  &vtctx->session);
1835  if (status)
1836  goto pe_cleanup;
1837 
1838  frame->data[0] = frame->buf[0]->data;
1839  memset(frame->data[0], 0, y_size);
1840 
1841  frame->data[1] = frame->buf[0]->data + y_size;
1842  memset(frame->data[1], 128, chroma_size);
1843 
1844 
1845  if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
1846  frame->data[2] = frame->buf[0]->data + y_size + chroma_size;
1847  memset(frame->data[2], 128, chroma_size);
1848  }
1849 
1850  frame->linesize[0] = avctx->width;
1851 
1852  if (avctx->pix_fmt == AV_PIX_FMT_YUV420P) {
1853  frame->linesize[1] =
1854  frame->linesize[2] = (avctx->width + 1) / 2;
1855  } else {
1856  frame->linesize[1] = (avctx->width + 1) / 2;
1857  }
1858 
1859  frame->format = avctx->pix_fmt;
1860  frame->width = avctx->width;
1861  frame->height = avctx->height;
1862  av_frame_set_colorspace(frame, avctx->colorspace);
1863  av_frame_set_color_range(frame, avctx->color_range);
1864  frame->color_trc = avctx->color_trc;
1865  frame->color_primaries = avctx->color_primaries;
1866 
1867  frame->pts = 0;
1868  status = vtenc_send_frame(avctx, vtctx, frame);
1869  if (status) {
1870  av_log(avctx, AV_LOG_ERROR, "Error sending frame: %d\n", status);
1871  goto pe_cleanup;
1872  }
1873 
1874  //Populates extradata - output frames are flushed and param sets are available.
1875  status = VTCompressionSessionCompleteFrames(vtctx->session,
1876  kCMTimeIndefinite);
1877 
1878  if (status)
1879  goto pe_cleanup;
1880 
1881  status = vtenc_q_pop(vtctx, 0, &buf);
1882  if (status) {
1883  av_log(avctx, AV_LOG_ERROR, "popping: %d\n", status);
1884  goto pe_cleanup;
1885  }
1886 
1887  CFRelease(buf);
1888 
1889 
1890 
1891 pe_cleanup:
1892  if(vtctx->session)
1893  CFRelease(vtctx->session);
1894 
1895  vtctx->session = NULL;
1896  vtctx->frame_ct_out = 0;
1897 
1898  av_frame_unref(frame);
1899  av_frame_free(&frame);
1900 
1901  av_assert0(status != 0 || (avctx->extradata && avctx->extradata_size > 0));
1902 
1903  return status;
1904 }
1905 
1907 {
1908  VTEncContext *vtctx = avctx->priv_data;
1909 
1910  if(!vtctx->session) return 0;
1911 
1913  pthread_mutex_destroy(&vtctx->lock);
1914  CFRelease(vtctx->session);
1915  vtctx->session = NULL;
1916 
1917  if (vtctx->color_primaries) {
1918  CFRelease(vtctx->color_primaries);
1919  vtctx->color_primaries = NULL;
1920  }
1921 
1922  if (vtctx->transfer_function) {
1923  CFRelease(vtctx->transfer_function);
1924  vtctx->transfer_function = NULL;
1925  }
1926 
1927  if (vtctx->ycbcr_matrix) {
1928  CFRelease(vtctx->ycbcr_matrix);
1929  vtctx->ycbcr_matrix = NULL;
1930  }
1931 
1932  return 0;
1933 }
1934 
1935 static const enum AVPixelFormat pix_fmts[] = {
1940 };
1941 
1942 #define OFFSET(x) offsetof(VTEncContext, x)
1943 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1944 static const AVOption options[] = {
1945  { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = H264_PROF_AUTO }, H264_PROF_AUTO, H264_PROF_COUNT, VE, "profile" },
1946  { "baseline", "Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_BASELINE }, INT_MIN, INT_MAX, VE, "profile" },
1947  { "main", "Main Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_MAIN }, INT_MIN, INT_MAX, VE, "profile" },
1948  { "high", "High Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_HIGH }, INT_MIN, INT_MAX, VE, "profile" },
1949 
1950  { "level", "Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, VE, "level" },
1951  { "1.3", "Level 1.3, only available with Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = 13 }, INT_MIN, INT_MAX, VE, "level" },
1952  { "3.0", "Level 3.0", 0, AV_OPT_TYPE_CONST, { .i64 = 30 }, INT_MIN, INT_MAX, VE, "level" },
1953  { "3.1", "Level 3.1", 0, AV_OPT_TYPE_CONST, { .i64 = 31 }, INT_MIN, INT_MAX, VE, "level" },
1954  { "3.2", "Level 3.2", 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, INT_MIN, INT_MAX, VE, "level" },
1955  { "4.0", "Level 4.0", 0, AV_OPT_TYPE_CONST, { .i64 = 40 }, INT_MIN, INT_MAX, VE, "level" },
1956  { "4.1", "Level 4.1", 0, AV_OPT_TYPE_CONST, { .i64 = 41 }, INT_MIN, INT_MAX, VE, "level" },
1957  { "4.2", "Level 4.2", 0, AV_OPT_TYPE_CONST, { .i64 = 42 }, INT_MIN, INT_MAX, VE, "level" },
1958  { "5.0", "Level 5.0", 0, AV_OPT_TYPE_CONST, { .i64 = 50 }, INT_MIN, INT_MAX, VE, "level" },
1959  { "5.1", "Level 5.1", 0, AV_OPT_TYPE_CONST, { .i64 = 51 }, INT_MIN, INT_MAX, VE, "level" },
1960  { "5.2", "Level 5.2", 0, AV_OPT_TYPE_CONST, { .i64 = 52 }, INT_MIN, INT_MAX, VE, "level" },
1961 
1962  { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL,
1963  { .i64 = 0 }, 0, 1, VE },
1964 
1965  { "coder", "Entropy coding", OFFSET(entropy), AV_OPT_TYPE_INT, { .i64 = VT_ENTROPY_NOT_SET }, VT_ENTROPY_NOT_SET, VT_CABAC, VE, "coder" },
1966  { "cavlc", "CAVLC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CAVLC }, INT_MIN, INT_MAX, VE, "coder" },
1967  { "vlc", "CAVLC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CAVLC }, INT_MIN, INT_MAX, VE, "coder" },
1968  { "cabac", "CABAC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CABAC }, INT_MIN, INT_MAX, VE, "coder" },
1969  { "ac", "CABAC entropy coding", 0, AV_OPT_TYPE_CONST, { .i64 = VT_CABAC }, INT_MIN, INT_MAX, VE, "coder" },
1970 
1971  { "realtime", "Hint that encoding should happen in real-time if not faster (e.g. capturing from camera).",
1972  OFFSET(realtime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
1973 
1974  { "frames_before", "Other frames will come before the frames in this session. This helps smooth concatenation issues.",
1975  OFFSET(frames_before), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
1976  { "frames_after", "Other frames will come after the frames in this session. This helps smooth concatenation issues.",
1977  OFFSET(frames_after), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
1978 
1979  { NULL },
1980 };
1981 
1983  .class_name = "h264_videotoolbox",
1984  .item_name = av_default_item_name,
1985  .option = options,
1986  .version = LIBAVUTIL_VERSION_INT,
1987 };
1988 
1990  .name = "h264_videotoolbox",
1991  .long_name = NULL_IF_CONFIG_SMALL("VideoToolbox H.264 Encoder"),
1992  .type = AVMEDIA_TYPE_VIDEO,
1993  .id = AV_CODEC_ID_H264,
1994  .priv_data_size = sizeof(VTEncContext),
1995  .pix_fmts = pix_fmts,
1996  .init = vtenc_init,
1997  .encode2 = vtenc_frame,
1998  .close = vtenc_close,
1999  .capabilities = AV_CODEC_CAP_DELAY,
2000  .priv_class = &h264_videotoolbox_class,
2001  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
2003 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
ITU-R BT2020 for 12-bit system.
Definition: pixfmt.h:424
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
Definition: pixfmt.h:436
#define NULL
Definition: coverity.c:32
static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf)
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AV_NUM_DATA_POINTERS
Definition: frame.h:185
static CMVideoCodecType get_cm_codec_type(enum AVCodecID id)
static bool get_vt_profile_level(AVCodecContext *avctx, CFStringRef *profile_level_val)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:106
pthread_cond_t cv_sample_sent
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
static void free_avframe(void *release_ctx, const void *data, size_t size, size_t plane_count, const void *plane_addresses[])
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:164
AVOption.
Definition: opt.h:245
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
BufNode * q_head
const char * fmt
Definition: avisynth_c.h:632
struct BufNode * next
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1714
#define LIBAVUTIL_VERSION_INT
Definition: version.h:70
enum AVColorRange av_frame_get_color_range(const AVFrame *frame)
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:363
hardware decoding through Videotoolbox
Definition: pixfmt.h:295
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer)
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:1935
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 ...
Definition: pixfmt.h:440
static int copy_param_sets(AVCodecContext *avctx, CMVideoFormatDescriptionRef vid_fmt, uint8_t *dst, size_t dst_size)
int64_t allow_sw
static int create_cv_pixel_buffer_info(AVCodecContext *avctx, CFMutableDictionaryRef *dict)
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:2385
int num
numerator
Definition: rational.h:44
int size
Definition: avcodec.h:1581
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:2060
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
Definition: pixfmt.h:441
enum AVMediaType codec_type
Definition: rtp.c:37
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1877
static AVPacket pkt
AVCodec.
Definition: avcodec.h:3542
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition: os2threads.h:138
AVColorTransferCharacteristic
Color Transfer Characteristic.
Definition: pixfmt.h:408
functionally identical to above
Definition: pixfmt.h:442
const char * av_color_space_name(enum AVColorSpace space)
Definition: pixdesc.c:2553
static const AVOption options[]
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1786
static int16_t block[64]
Definition: dct.c:113
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:72
#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: avcodec.h:981
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:40
HMTX pthread_mutex_t
Definition: os2threads.h:49
uint8_t
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:140
AVOptions.
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:94
const char * av_color_range_name(enum AVColorRange range)
Definition: pixdesc.c:2535
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
Definition: pixfmt.h:413
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:374
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:268
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1764
bool warned_color_range
static AVFrame * frame
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)
uint8_t * data
Definition: avcodec.h:1580
int64_t frame_ct_in
Not part of ABI.
Definition: pixfmt.h:458
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
Definition: os2threads.h:146
static int get_length_code_size(AVCodecContext *avctx, CMSampleBufferRef sample_buffer, size_t *size)
AVColorRange
MPEG vs JPEG YUV range.
Definition: pixfmt.h:454
ptrdiff_t size
Definition: opengl_enc.c:101
AVColorPrimaries
Chromaticity coordinates of the source primaries.
Definition: pixfmt.h:389
static av_cold int vtenc_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
#define av_log(a,...)
#define kCVImageBufferYCbCrMatrix_ITU_R_2020
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1612
void av_frame_set_color_range(AVFrame *frame, enum AVColorRange val)
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:189
int width
width and height of the video frame
Definition: frame.h:236
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int has_b_frames
Size of the frame reordering buffer in the decoder.
Definition: avcodec.h:1971
static void vtenc_get_frame_info(CMSampleBufferRef buffer, bool *is_key_frame)
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:153
void av_frame_set_colorspace(AVFrame *frame, enum AVColorSpace val)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
BufNode * q_tail
static void add_color_attr(AVCodecContext *avctx, CFMutableDictionaryRef dict)
static int get_params_size(AVCodecContext *avctx, CMVideoFormatDescriptionRef vid_fmt, size_t *size)
Get the parameter sets from a CMSampleBufferRef.
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1744
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:90
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
Definition: pixfmt.h:391
simple assert() macros that are a bit more flexible than ISO C assert().
const char * name
Name of the codec implementation.
Definition: avcodec.h:3549
VTH264Entropy
static const uint8_t offset[127][2]
Definition: vf_spp.c:92
GLsizei count
Definition: opengl_enc.c:109
static int get_frame(AVFilterContext *ctx, int is_second)
Definition: vf_nnedi.c:689
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1586
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
Definition: pixdesc.c:2541
int64_t frames_before
static int vtenc_create_encoder(AVCodecContext *avctx, CMVideoCodecType codec_type, CFStringRef profile_level, CFNumberRef gamma_level, CFDictionaryRef enc_info, CFDictionaryRef pixel_buffer_info, VTCompressionSessionRef *session)
VTCompressionSessionRef session
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
CFStringRef color_primaries
static int get_cv_transfer_function(AVCodecContext *avctx, CFStringRef *transfer_fnc, CFNumberRef *gamma_level)
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:258
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:51
CMSampleBufferRef cm_buffer
int width
picture width / height.
Definition: avcodec.h:1836
ITU-R BT2020 non-constant luminance system.
Definition: pixfmt.h:444
AVFormatContext * ctx
Definition: movenc.c:48
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:2364
#define OFFSET(x)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:98
static enum AVPixelFormat pix_fmts[]
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:457
#define kCVImageBufferTransferFunction_ITU_R_2020
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:248
also ITU-R BT1361
Definition: pixfmt.h:410
static int vtenc_populate_extradata(AVCodecContext *avctx, CMVideoCodecType codec_type, CFStringRef profile_level, CFNumberRef gamma_level, CFDictionaryRef enc_info, CFDictionaryRef pixel_buffer_info)
static const AVClass h264_videotoolbox_class
Libavcodec external API header.
static int get_cv_pixel_format(AVCodecContext *avctx, enum AVPixelFormat fmt, enum AVColorRange range, int *av_pixel_format, int *range_guessed)
enum AVCodecID codec_id
Definition: avcodec.h:1666
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:66
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:215
int64_t first_pts
main external API structure.
Definition: avcodec.h:1649
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:563
uint8_t * data
The data buffer.
Definition: buffer.h:89
static int create_encoder_dict_h264(const AVFrame *frame, CFDictionaryRef *dict_out)
void * buf
Definition: avisynth_c.h:553
static av_cold int vtenc_close(AVCodecContext *avctx)
int extradata_size
Definition: avcodec.h:1765
Describe the class of an AVClass context structure.
Definition: log.h:67
CFStringRef transfer_function
static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix)
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:2378
rational number numerator/denominator
Definition: rational.h:43
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:2371
AVCodec ff_h264_videotoolbox_encoder
static int vtenc_send_frame(AVCodecContext *avctx, VTEncContext *vtctx, const AVFrame *frame)
VT_H264Profile
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: utils.c:1690
int64_t frames_after
mfxU16 profile
Definition: qsvenc.c:42
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:484
static int64_t pts
Global timestamp for the audio frames.
static int flags
Definition: cpu.c:47
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:198
uint8_t level
Definition: svq3.c:193
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:879
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:456
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1862
static int create_cv_pixel_buffer(AVCodecContext *avctx, const AVFrame *frame, CVPixelBufferRef *cv_img)
TARGET_OS_IPHONE.
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:62
common internal api header.
static int copy_replace_length_codes(AVCodecContext *avctx, size_t length_code_size, CMSampleBufferRef sample_buffer, uint8_t *dst_data, size_t dst_size)
Copies NAL units and replaces length codes with H.264 Annex B start codes.
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
Definition: pixdesc.c:2547
CFStringRef ycbcr_matrix
static void vtenc_output_callback(void *ctx, void *sourceFrameCtx, OSStatus status, VTEncodeInfoFlags flags, CMSampleBufferRef sample_buffer)
also ITU-R BT470BG
Definition: pixfmt.h:414
static void vt_release_num(CFNumberRef *refPtr)
NULL-safe release of *refPtr, and sets value to NULL.
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition: os2threads.h:127
pthread_mutex_t lock
int den
denominator
Definition: rational.h:45
#define kCVImageBufferColorPrimaries_ITU_R_2020
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:731
void * priv_data
Definition: avcodec.h:1691
#define av_free(p)
int64_t realtime
int len
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
Definition: os2threads.h:120
enum AVColorPrimaries color_primaries
Definition: frame.h:415
#define VE
int64_t frame_ct_out
ITU-R BT2020 for 10-bit system.
Definition: pixfmt.h:423
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1579
static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer)
ITU-R BT2020.
Definition: pixfmt.h:400
int height
Definition: frame.h:236
static int vtenc_cm_to_avpacket(AVCodecContext *avctx, CMSampleBufferRef sample_buffer, AVPacket *pkt)
static int count_nalus(size_t length_code_size, CMSampleBufferRef sample_buffer, int *count)
enum AVColorTransferCharacteristic color_trc
Definition: frame.h:417
static const uint8_t start_code[]
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
Definition: os2threads.h:113
static av_cold int vtenc_init(AVCodecContext *avctx)
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:2138
static int get_cv_color_primaries(AVCodecContext *avctx, CFStringRef *primaries)
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1557
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:252
static void set_async_error(VTEncContext *vtctx, int err)
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1573
GLuint buffer
Definition: opengl_enc.c:102
int64_t dts_delta