]> git.sesse.net Git - ffmpeg/blob - libavcodec/videotoolboxenc.c
lavf/utils: Fix DTS for short H264 streams.
[ffmpeg] / libavcodec / videotoolboxenc.c
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 "internal.h"
33 #include <pthread.h>
34
35 typedef enum VT_H264Profile {
36     H264_PROF_AUTO,
37     H264_PROF_BASELINE,
38     H264_PROF_MAIN,
39     H264_PROF_HIGH,
40     H264_PROF_COUNT
41 } VT_H264Profile;
42
43 static const uint8_t start_code[] = { 0, 0, 0, 1 };
44
45 typedef struct BufNode {
46     CMSampleBufferRef cm_buffer;
47     struct BufNode* next;
48     int error;
49 } BufNode;
50
51 typedef struct VTEncContext {
52     AVClass *class;
53     VTCompressionSessionRef session;
54
55     pthread_mutex_t lock;
56     pthread_cond_t  cv_sample_sent;
57
58     int async_error;
59
60     BufNode *q_head;
61     BufNode *q_tail;
62
63     int64_t frame_ct_out;
64     int64_t frame_ct_in;
65
66     int64_t first_pts;
67     int64_t dts_delta;
68
69     int64_t profile;
70     int64_t level;
71
72     bool flushing;
73     bool has_b_frames;
74     bool warned_color_range;
75 } VTEncContext;
76
77 static void set_async_error(VTEncContext *vtctx, int err)
78 {
79     BufNode *info;
80
81     pthread_mutex_lock(&vtctx->lock);
82
83     vtctx->async_error = err;
84
85     info = vtctx->q_head;
86     vtctx->q_head = vtctx->q_tail = NULL;
87
88     while (info) {
89         BufNode *next = info->next;
90         CFRelease(info->cm_buffer);
91         av_free(info);
92         info = next;
93     }
94
95     pthread_mutex_unlock(&vtctx->lock);
96 }
97
98 static int vtenc_q_pop(VTEncContext *vtctx, bool wait, CMSampleBufferRef *buf)
99 {
100     BufNode *info;
101
102     pthread_mutex_lock(&vtctx->lock);
103
104     if (vtctx->async_error) {
105         pthread_mutex_unlock(&vtctx->lock);
106         return vtctx->async_error;
107     }
108
109     if (vtctx->flushing && vtctx->frame_ct_in == vtctx->frame_ct_out) {
110         *buf = NULL;
111
112         pthread_mutex_unlock(&vtctx->lock);
113         return 0;
114     }
115
116     while (!vtctx->q_head && !vtctx->async_error && wait) {
117         pthread_cond_wait(&vtctx->cv_sample_sent, &vtctx->lock);
118     }
119
120     if (!vtctx->q_head) {
121         pthread_mutex_unlock(&vtctx->lock);
122         *buf = NULL;
123         return 0;
124     }
125
126     info = vtctx->q_head;
127     vtctx->q_head = vtctx->q_head->next;
128     if (!vtctx->q_head) {
129         vtctx->q_tail = NULL;
130     }
131
132     pthread_mutex_unlock(&vtctx->lock);
133
134     *buf = info->cm_buffer;
135     av_free(info);
136
137     vtctx->frame_ct_out++;
138
139     return 0;
140 }
141
142 static void vtenc_q_push(VTEncContext *vtctx, CMSampleBufferRef buffer)
143 {
144     BufNode *info = av_malloc(sizeof(BufNode));
145     if (!info) {
146         set_async_error(vtctx, AVERROR(ENOMEM));
147         return;
148     }
149
150     CFRetain(buffer);
151     info->cm_buffer = buffer;
152     info->next = NULL;
153
154     pthread_mutex_lock(&vtctx->lock);
155     pthread_cond_signal(&vtctx->cv_sample_sent);
156
157     if (!vtctx->q_head) {
158         vtctx->q_head = info;
159     } else {
160         vtctx->q_tail->next = info;
161     }
162
163     vtctx->q_tail = info;
164
165     pthread_mutex_unlock(&vtctx->lock);
166 }
167
168 static CMVideoCodecType get_cm_codec_type(enum AVCodecID id)
169 {
170     switch (id) {
171     case AV_CODEC_ID_H264: return kCMVideoCodecType_H264;
172     default:               return 0;
173     }
174 }
175
176 static void vtenc_free_block(void *opaque, uint8_t *data)
177 {
178     CMBlockBufferRef block = opaque;
179     CFRelease(block);
180 }
181
182 /**
183  * Get the parameter sets from a CMSampleBufferRef.
184  * @param dst If *dst isn't NULL, the parameters are copied into existing
185  *            memory. *dst_size must be set accordingly when *dst != NULL.
186  *            If *dst is NULL, it will be allocated.
187  *            In all cases, *dst_size is set to the number of bytes used starting
188  *            at *dst.
189  */
190 static int get_params_size(
191     AVCodecContext              *avctx,
192     CMVideoFormatDescriptionRef vid_fmt,
193     size_t                      *size)
194 {
195     size_t total_size = 0;
196     size_t ps_count;
197     size_t i;
198     int status;
199     status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
200                                                                 0,
201                                                                 NULL,
202                                                                 NULL,
203                                                                 &ps_count,
204                                                                 NULL);
205     if (status) {
206         av_log(avctx, AV_LOG_ERROR, "Error getting parameter set count: %d\n", status);
207         return AVERROR_EXTERNAL;
208     }
209
210     for(i = 0; i < ps_count; i++){
211         const uint8_t *ps;
212         size_t ps_size;
213         status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
214                                                                     i,
215                                                                     &ps,
216                                                                     &ps_size,
217                                                                     NULL,
218                                                                     NULL);
219         if(status){
220             av_log(avctx, AV_LOG_ERROR, "Error getting parameter set size for index %zd: %d\n", i, status);
221             return AVERROR_EXTERNAL;
222         }
223
224         total_size += ps_size + sizeof(start_code);
225     }
226
227     *size = total_size;
228     return 0;
229 }
230
231 static int copy_param_sets(
232     AVCodecContext              *avctx,
233     CMVideoFormatDescriptionRef vid_fmt,
234     uint8_t                     *dst,
235     size_t                      dst_size)
236 {
237     size_t ps_count;
238     int status;
239     size_t offset = 0;
240     size_t i;
241
242     status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
243                                                                 0,
244                                                                 NULL,
245                                                                 NULL,
246                                                                 &ps_count,
247                                                                 NULL);
248     if (status) {
249         av_log(avctx, AV_LOG_ERROR, "Error getting parameter set count for copying: %d\n", status);
250         return AVERROR_EXTERNAL;
251     }
252
253     for (i = 0; i < ps_count; i++) {
254         const uint8_t *ps;
255         size_t ps_size;
256         size_t next_offset;
257
258         status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
259                                                                     i,
260                                                                     &ps,
261                                                                     &ps_size,
262                                                                     NULL,
263                                                                     NULL);
264         if (status) {
265             av_log(avctx, AV_LOG_ERROR, "Error getting parameter set data for index %zd: %d\n", i, status);
266             return AVERROR_EXTERNAL;
267         }
268
269         next_offset = offset + sizeof(start_code) + ps_size;
270         if (dst_size < next_offset) {
271             av_log(avctx, AV_LOG_ERROR, "Error: buffer too small for parameter sets.\n");
272             return AVERROR_BUFFER_TOO_SMALL;
273         }
274
275         memcpy(dst + offset, start_code, sizeof(start_code));
276         offset += sizeof(start_code);
277
278         memcpy(dst + offset, ps, ps_size);
279         offset = next_offset;
280     }
281
282     return 0;
283 }
284
285 static int set_extradata(AVCodecContext *avctx, CMSampleBufferRef sample_buffer)
286 {
287     CMVideoFormatDescriptionRef vid_fmt;
288     size_t total_size;
289     int status;
290
291     vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
292     if (!vid_fmt) {
293         av_log(avctx, AV_LOG_ERROR, "No video format.\n");
294         return AVERROR_EXTERNAL;
295     }
296
297     status = get_params_size(avctx, vid_fmt, &total_size);
298     if (status) {
299         av_log(avctx, AV_LOG_ERROR, "Could not get parameter sets.\n");
300         return status;
301     }
302
303     avctx->extradata = av_malloc(total_size);
304     if (!avctx->extradata) {
305         return AVERROR(ENOMEM);
306     }
307     avctx->extradata_size = total_size;
308
309     status = copy_param_sets(avctx, vid_fmt, avctx->extradata, total_size);
310
311     if (status) {
312         av_log(avctx, AV_LOG_ERROR, "Could not copy param sets.\n");
313         return status;
314     }
315
316     return 0;
317 }
318
319 static void vtenc_output_callback(
320     void *ctx,
321     void *sourceFrameCtx,
322     OSStatus status,
323     VTEncodeInfoFlags flags,
324     CMSampleBufferRef sample_buffer)
325 {
326     AVCodecContext *avctx = ctx;
327     VTEncContext   *vtctx = avctx->priv_data;
328
329     if (vtctx->async_error) {
330         if(sample_buffer) CFRelease(sample_buffer);
331         return;
332     }
333
334     if (status || !sample_buffer) {
335         av_log(avctx, AV_LOG_ERROR, "Error encoding frame: %d\n", (int)status);
336         set_async_error(vtctx, AVERROR_EXTERNAL);
337         return;
338     }
339
340     if (!avctx->extradata && (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)) {
341         int set_status = set_extradata(avctx, sample_buffer);
342         if (set_status) {
343             set_async_error(vtctx, set_status);
344             return;
345         }
346     }
347
348     vtenc_q_push(vtctx, sample_buffer);
349 }
350
351 static int get_length_code_size(
352     AVCodecContext    *avctx,
353     CMSampleBufferRef sample_buffer,
354     size_t            *size)
355 {
356     CMVideoFormatDescriptionRef vid_fmt;
357     int isize;
358     int status;
359
360     vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
361     if (!vid_fmt) {
362         av_log(avctx, AV_LOG_ERROR, "Error getting buffer format description.\n");
363         return AVERROR_EXTERNAL;
364     }
365
366     status = CMVideoFormatDescriptionGetH264ParameterSetAtIndex(vid_fmt,
367                                                                 0,
368                                                                 NULL,
369                                                                 NULL,
370                                                                 NULL,
371                                                                 &isize);
372     if (status) {
373         av_log(avctx, AV_LOG_ERROR, "Error getting length code size: %d\n", status);
374         return AVERROR_EXTERNAL;
375     }
376
377     *size = isize;
378     return 0;
379 }
380
381 /*
382  * Returns true on success.
383  *
384  * If profile_level_val is NULL and this method returns true, don't specify the
385  * profile/level to the encoder.
386  */
387 static bool get_vt_profile_level(AVCodecContext *avctx,
388                                  CFStringRef    *profile_level_val)
389 {
390     VTEncContext *vtctx = avctx->priv_data;
391     int64_t profile = vtctx->profile;
392
393     if (profile == H264_PROF_AUTO && vtctx->level) {
394         //Need to pick a profile if level is not auto-selected.
395         profile = vtctx->has_b_frames ? H264_PROF_MAIN : H264_PROF_BASELINE;
396     }
397
398     *profile_level_val = NULL;
399
400     switch (profile) {
401         case H264_PROF_AUTO:
402             return true;
403
404         case H264_PROF_BASELINE:
405             switch (vtctx->level) {
406                 case  0: *profile_level_val = kVTProfileLevel_H264_Baseline_AutoLevel; break;
407                 case 13: *profile_level_val = kVTProfileLevel_H264_Baseline_1_3;       break;
408                 case 30: *profile_level_val = kVTProfileLevel_H264_Baseline_3_0;       break;
409                 case 31: *profile_level_val = kVTProfileLevel_H264_Baseline_3_1;       break;
410                 case 32: *profile_level_val = kVTProfileLevel_H264_Baseline_3_2;       break;
411                 case 40: *profile_level_val = kVTProfileLevel_H264_Baseline_4_0;       break;
412                 case 41: *profile_level_val = kVTProfileLevel_H264_Baseline_4_1;       break;
413                 case 42: *profile_level_val = kVTProfileLevel_H264_Baseline_4_2;       break;
414                 case 50: *profile_level_val = kVTProfileLevel_H264_Baseline_5_0;       break;
415                 case 51: *profile_level_val = kVTProfileLevel_H264_Baseline_5_1;       break;
416                 case 52: *profile_level_val = kVTProfileLevel_H264_Baseline_5_2;       break;
417             }
418             break;
419
420         case H264_PROF_MAIN:
421             switch (vtctx->level) {
422                 case  0: *profile_level_val = kVTProfileLevel_H264_Main_AutoLevel; break;
423                 case 30: *profile_level_val = kVTProfileLevel_H264_Main_3_0;       break;
424                 case 31: *profile_level_val = kVTProfileLevel_H264_Main_3_1;       break;
425                 case 32: *profile_level_val = kVTProfileLevel_H264_Main_3_2;       break;
426                 case 40: *profile_level_val = kVTProfileLevel_H264_Main_4_0;       break;
427                 case 41: *profile_level_val = kVTProfileLevel_H264_Main_4_1;       break;
428                 case 42: *profile_level_val = kVTProfileLevel_H264_Main_4_2;       break;
429                 case 50: *profile_level_val = kVTProfileLevel_H264_Main_5_0;       break;
430                 case 51: *profile_level_val = kVTProfileLevel_H264_Main_5_1;       break;
431                 case 52: *profile_level_val = kVTProfileLevel_H264_Main_5_2;       break;
432             }
433             break;
434
435         case H264_PROF_HIGH:
436             switch (vtctx->level) {
437                 case  0: *profile_level_val = kVTProfileLevel_H264_High_AutoLevel; break;
438                 case 30: *profile_level_val = kVTProfileLevel_H264_High_3_0;       break;
439                 case 31: *profile_level_val = kVTProfileLevel_H264_High_3_1;       break;
440                 case 32: *profile_level_val = kVTProfileLevel_H264_High_3_2;       break;
441                 case 40: *profile_level_val = kVTProfileLevel_H264_High_4_0;       break;
442                 case 41: *profile_level_val = kVTProfileLevel_H264_High_4_1;       break;
443                 case 42: *profile_level_val = kVTProfileLevel_H264_High_4_2;       break;
444                 case 50: *profile_level_val = kVTProfileLevel_H264_High_5_0;       break;
445                 case 51: *profile_level_val = kVTProfileLevel_H264_High_5_1;       break;
446                 case 52: *profile_level_val = kVTProfileLevel_H264_High_5_2;       break;
447             }
448             break;
449     }
450
451     if (!*profile_level_val) {
452         av_log(avctx, AV_LOG_ERROR, "Invalid Profile/Level.\n");
453         return false;
454     }
455
456     return true;
457 }
458
459 static av_cold int vtenc_init(AVCodecContext *avctx)
460 {
461     CFMutableDictionaryRef enc_info;
462     CMVideoCodecType       codec_type;
463     VTEncContext           *vtctx = avctx->priv_data;
464     CFStringRef            profile_level;
465     SInt32                 bit_rate = avctx->bit_rate;
466     CFNumberRef            bit_rate_num;
467     int                    status;
468
469     codec_type = get_cm_codec_type(avctx->codec_id);
470     if (!codec_type) {
471         av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id);
472         return AVERROR(EINVAL);
473     }
474
475     vtctx->has_b_frames = avctx->has_b_frames || avctx->max_b_frames > 0;
476     if(vtctx->has_b_frames && vtctx->profile == H264_PROF_BASELINE){
477         av_log(avctx, AV_LOG_WARNING, "Cannot use B-frames with baseline profile. Output will not contain B-frames.\n");
478         vtctx->has_b_frames = false;
479     }
480
481     if (!get_vt_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
482
483     vtctx->session = NULL;
484
485     enc_info = CFDictionaryCreateMutable(
486         kCFAllocatorDefault,
487         20,
488         &kCFCopyStringDictionaryKeyCallBacks,
489         &kCFTypeDictionaryValueCallBacks
490     );
491
492     if (!enc_info) return AVERROR(ENOMEM);
493
494 #if !TARGET_OS_IPHONE
495     CFDictionarySetValue(enc_info, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder, kCFBooleanTrue);
496     CFDictionarySetValue(enc_info, kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,  kCFBooleanTrue);
497 #endif
498
499     status = VTCompressionSessionCreate(
500         kCFAllocatorDefault,
501         avctx->width,
502         avctx->height,
503         codec_type,
504         enc_info,
505         NULL,
506         kCFAllocatorDefault,
507         vtenc_output_callback,
508         avctx,
509         &vtctx->session
510     );
511
512 #if !TARGET_OS_IPHONE
513     if (status != 0 || !vtctx->session) {
514         CFDictionaryRemoveValue(enc_info, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder);
515
516         status = VTCompressionSessionCreate(
517             kCFAllocatorDefault,
518             avctx->width,
519             avctx->height,
520             codec_type,
521             enc_info,
522             NULL,
523             kCFAllocatorDefault,
524             vtenc_output_callback,
525             avctx,
526             &vtctx->session
527         );
528     }
529 #endif
530
531     CFRelease(enc_info);
532
533     if (status || !vtctx->session) {
534         av_log(avctx, AV_LOG_ERROR, "Error: cannot create compression session: %d\n", status);
535         return AVERROR_EXTERNAL;
536     }
537
538     bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
539                                   kCFNumberSInt32Type,
540                                   &bit_rate);
541     if (!bit_rate_num) return AVERROR(ENOMEM);
542
543     status = VTSessionSetProperty(vtctx->session,
544                                   kVTCompressionPropertyKey_AverageBitRate,
545                                   bit_rate_num);
546     CFRelease(bit_rate_num);
547
548     if (status) {
549         av_log(avctx, AV_LOG_ERROR, "Error setting bitrate property: %d\n", status);
550         return AVERROR_EXTERNAL;
551     }
552
553     if (profile_level) {
554         status = VTSessionSetProperty(vtctx->session,
555                                       kVTCompressionPropertyKey_ProfileLevel,
556                                       profile_level);
557         if (status) {
558             av_log(avctx, AV_LOG_ERROR, "Error setting profile/level property: %d\n", status);
559             return AVERROR_EXTERNAL;
560         }
561     }
562
563     if (avctx->gop_size > 0) {
564         CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
565                                               kCFNumberIntType,
566                                               &avctx->gop_size);
567         status = VTSessionSetProperty(vtctx->session,
568                                       kVTCompressionPropertyKey_MaxKeyFrameInterval,
569                                       interval);
570
571         if (status) {
572             av_log(avctx, AV_LOG_ERROR, "Error setting 'max key-frame interval' property: %d\n", status);
573             return AVERROR_EXTERNAL;
574         }
575     }
576
577     if (!vtctx->has_b_frames) {
578         status = VTSessionSetProperty(vtctx->session,
579                                       kVTCompressionPropertyKey_AllowFrameReordering,
580                                       kCFBooleanFalse);
581
582         if (status) {
583             av_log(avctx, AV_LOG_ERROR, "Error setting 'allow frame reordering' property: %d\n", status);
584             return AVERROR_EXTERNAL;
585         }
586     }
587
588     status = VTCompressionSessionPrepareToEncodeFrames(vtctx->session);
589     if (status) {
590         av_log(avctx, AV_LOG_ERROR, "Error: cannot prepare encoder: %d\n", status);
591         return AVERROR_EXTERNAL;
592     }
593
594     pthread_mutex_init(&vtctx->lock, NULL);
595     pthread_cond_init(&vtctx->cv_sample_sent, NULL);
596     vtctx->dts_delta = vtctx->has_b_frames ? -1 : 0;
597
598     return 0;
599 }
600
601 static void vtenc_get_frame_info(CMSampleBufferRef buffer, bool *is_key_frame)
602 {
603     CFArrayRef      attachments;
604     CFDictionaryRef attachment;
605     CFBooleanRef    not_sync;
606     CFIndex         len;
607
608     attachments = CMSampleBufferGetSampleAttachmentsArray(buffer, false);
609     len = !attachments ? 0 : CFArrayGetCount(attachments);
610
611     if (!len) {
612         *is_key_frame = true;
613         return;
614     }
615
616     attachment = CFArrayGetValueAtIndex(attachments, 0);
617
618     if (CFDictionaryGetValueIfPresent(attachment,
619                                       kCMSampleAttachmentKey_NotSync,
620                                       (const void **)&not_sync))
621     {
622         *is_key_frame = !CFBooleanGetValue(not_sync);
623     } else {
624         *is_key_frame = true;
625     }
626 }
627
628 /**
629  * Replaces length codes with H.264 Annex B start codes.
630  * length_code_size must equal sizeof(start_code).
631  * On failure, the contents of data may have been modified.
632  *
633  * @param length_code_size Byte length of each length code
634  * @param data Call with NAL units prefixed with length codes.
635  *             On success, the length codes are replace with
636  *             start codes.
637  * @param size Length of data, excluding any padding.
638  * @return 0 on success
639  *         AVERROR_BUFFER_TOO_SMALL if length code size is smaller
640  *         than a start code or if a length_code in data specifies
641  *         data beyond the end of its buffer.
642  */
643 static int replace_length_codes(size_t  length_code_size,
644                                 uint8_t *data,
645                                 size_t  size)
646 {
647     size_t remaining_size = size;
648
649     if (length_code_size != sizeof(start_code)) {
650         av_log(NULL, AV_LOG_ERROR, "Start code size and length code size not equal.\n");
651         return AVERROR_BUFFER_TOO_SMALL;
652     }
653
654     while (remaining_size > 0) {
655         size_t box_len = 0;
656         size_t i;
657
658         for (i = 0; i < length_code_size; i++) {
659             box_len <<= 8;
660             box_len |= data[i];
661         }
662
663         if (remaining_size < box_len + sizeof(start_code)) {
664             av_log(NULL, AV_LOG_ERROR, "Length is out of range.\n");
665             AVERROR_BUFFER_TOO_SMALL;
666         }
667
668         memcpy(data, start_code, sizeof(start_code));
669         data += box_len + sizeof(start_code);
670         remaining_size -= box_len + sizeof(start_code);
671     }
672
673     return 0;
674 }
675
676 /**
677  * Copies NAL units and replaces length codes with
678  * H.264 Annex B start codes. On failure, the contents of
679  * dst_data may have been modified.
680  *
681  * @param length_code_size Byte length of each length code
682  * @param src_data NAL units prefixed with length codes.
683  * @param src_size Length of buffer, excluding any padding.
684  * @param dst_data Must be zeroed before calling this function.
685  *                 Contains the copied NAL units prefixed with
686  *                 start codes when the function returns
687  *                 successfully.
688  * @param dst_size Length of dst_data
689  * @return 0 on success
690  *         AVERROR_INVALIDDATA if length_code_size is invalid
691  *         AVERROR_BUFFER_TOO_SMALL if dst_data is too small
692  *         or if a length_code in src_data specifies data beyond
693  *         the end of its buffer.
694  */
695 static int copy_replace_length_codes(
696     size_t        length_code_size,
697     const uint8_t *src_data,
698     size_t        src_size,
699     uint8_t       *dst_data,
700     size_t        dst_size)
701 {
702     size_t remaining_src_size = src_size;
703     size_t remaining_dst_size = dst_size;
704
705     if (length_code_size > 4) {
706         return AVERROR_INVALIDDATA;
707     }
708
709     while (remaining_src_size > 0) {
710         size_t curr_src_len;
711         size_t curr_dst_len;
712         size_t box_len = 0;
713         size_t i;
714
715         uint8_t       *dst_box;
716         const uint8_t *src_box;
717
718         for (i = 0; i < length_code_size; i++) {
719             box_len <<= 8;
720             box_len |= src_data[i];
721         }
722
723         curr_src_len = box_len + length_code_size;
724         curr_dst_len = box_len + sizeof(start_code);
725
726         if (remaining_src_size < curr_src_len) {
727             return AVERROR_BUFFER_TOO_SMALL;
728         }
729
730         if (remaining_dst_size < curr_dst_len) {
731             return AVERROR_BUFFER_TOO_SMALL;
732         }
733
734         dst_box = dst_data + sizeof(start_code);
735         src_box = src_data + length_code_size;
736
737         memcpy(dst_data, start_code, sizeof(start_code));
738         memcpy(dst_box,  src_box,    box_len);
739
740         src_data += curr_src_len;
741         dst_data += curr_dst_len;
742
743         remaining_src_size -= curr_src_len;
744         remaining_dst_size -= curr_dst_len;
745     }
746
747     return 0;
748 }
749
750 static int vtenc_cm_to_avpacket(
751     AVCodecContext    *avctx,
752     CMSampleBufferRef sample_buffer,
753     AVPacket          *pkt)
754 {
755     VTEncContext *vtctx = avctx->priv_data;
756
757     int     status;
758     bool    is_key_frame;
759     bool    add_header;
760     char    *buf_data;
761     size_t  length_code_size;
762     size_t  header_size = 0;
763     size_t  in_buf_size;
764     int64_t dts_delta;
765     int64_t time_base_num;
766     CMTime  pts;
767     CMTime  dts;
768
769     CMBlockBufferRef            block;
770     CMVideoFormatDescriptionRef vid_fmt;
771
772
773     vtenc_get_frame_info(sample_buffer, &is_key_frame);
774     status = get_length_code_size(avctx, sample_buffer, &length_code_size);
775     if (status) return status;
776
777     add_header = is_key_frame && !(avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER);
778
779     if (add_header) {
780         vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
781         if (!vid_fmt) {
782             av_log(avctx, AV_LOG_ERROR, "Cannot get format description.\n");
783         }
784
785         int status = get_params_size(avctx, vid_fmt, &header_size);
786         if (status) return status;
787     }
788
789     block = CMSampleBufferGetDataBuffer(sample_buffer);
790     if (!block) {
791         av_log(avctx, AV_LOG_ERROR, "Could not get block buffer from sample buffer.\n");
792         return AVERROR_EXTERNAL;
793     }
794
795
796     status = CMBlockBufferGetDataPointer(block, 0, &in_buf_size, NULL, &buf_data);
797     if (status) {
798         av_log(avctx, AV_LOG_ERROR, "Error: cannot get data pointer: %d\n", status);
799         return AVERROR_EXTERNAL;
800     }
801
802     size_t out_buf_size = header_size + in_buf_size;
803     bool can_reuse_cmbuffer = !add_header &&
804                               !pkt->data  &&
805                               length_code_size == sizeof(start_code);
806
807     av_init_packet(pkt);
808
809     if (can_reuse_cmbuffer) {
810         AVBufferRef* buf_ref = av_buffer_create(
811             buf_data,
812             out_buf_size,
813             vtenc_free_block,
814             block,
815             0
816         );
817
818         if (!buf_ref) return AVERROR(ENOMEM);
819
820         CFRetain(block);
821
822         pkt->buf  = buf_ref;
823         pkt->data = buf_data;
824         pkt->size = in_buf_size;
825
826         status = replace_length_codes(length_code_size, pkt->data, pkt->size);
827         if (status) {
828             av_log(avctx, AV_LOG_ERROR, "Error replacing length codes: %d\n", status);
829             return status;
830         }
831     } else {
832         if (!pkt->data) {
833             status = av_new_packet(pkt, out_buf_size);
834             if(status) return status;
835         }
836
837         if (pkt->size < out_buf_size) {
838             av_log(avctx, AV_LOG_ERROR, "Error: packet's buffer is too small.\n");
839             return AVERROR_BUFFER_TOO_SMALL;
840         }
841
842         if (add_header) {
843             status = copy_param_sets(avctx, vid_fmt, pkt->data, out_buf_size);
844             if(status) return status;
845         }
846
847         status = copy_replace_length_codes(
848             length_code_size,
849             buf_data,
850             in_buf_size,
851             pkt->data + header_size,
852             pkt->size - header_size
853         );
854
855         if (status) {
856             av_log(avctx, AV_LOG_ERROR, "Error copying packet data: %d", status);
857             return status;
858         }
859     }
860
861     if (is_key_frame) {
862         pkt->flags |= AV_PKT_FLAG_KEY;
863     }
864
865     pts = CMSampleBufferGetPresentationTimeStamp(sample_buffer);
866     dts = CMSampleBufferGetDecodeTimeStamp      (sample_buffer);
867
868     dts_delta = vtctx->dts_delta >= 0 ? vtctx->dts_delta : 0;
869     time_base_num = avctx->time_base.num;
870     pkt->pts = pts.value / time_base_num;
871     pkt->dts = dts.value / time_base_num - dts_delta;
872
873     return 0;
874 }
875
876 /*
877  * contiguous_buf_size is 0 if not contiguous, and the size of the buffer
878  * containing all planes if so.
879  */
880 static int get_cv_pixel_info(
881     AVCodecContext *avctx,
882     const AVFrame  *frame,
883     int            *color,
884     int            *plane_count,
885     size_t         *widths,
886     size_t         *heights,
887     size_t         *strides,
888     size_t         *contiguous_buf_size)
889 {
890     VTEncContext *vtctx = avctx->priv_data;
891     int av_format       = frame->format;
892     int av_color_range  = av_frame_get_color_range(frame);
893     int i;
894
895     switch (av_format) {
896     case AV_PIX_FMT_NV12:
897         switch (av_color_range) {
898         case AVCOL_RANGE_MPEG:
899             *color = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
900             break;
901
902         case AVCOL_RANGE_JPEG:
903             *color = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
904             break;
905
906         default:
907             if (!vtctx->warned_color_range) {
908                 vtctx->warned_color_range = true;
909                 av_log(avctx, AV_LOG_WARNING, "Color range not set for NV12. Using MPEG range.\n");
910             }
911             *color = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
912         }
913
914         *plane_count = 2;
915
916         widths [0] = avctx->width;
917         heights[0] = avctx->height;
918         strides[0] = frame ? frame->linesize[0] : avctx->width;
919
920         widths [1] = (avctx->width  + 1) / 2;
921         heights[1] = (avctx->height + 1) / 2;
922         strides[1] = frame ? frame->linesize[1] : (avctx->width + 1) & -2;
923         break;
924
925     case AV_PIX_FMT_YUV420P:
926         switch (av_color_range) {
927         case AVCOL_RANGE_MPEG:
928             *color = kCVPixelFormatType_420YpCbCr8Planar;
929             break;
930
931         case AVCOL_RANGE_JPEG:
932             *color = kCVPixelFormatType_420YpCbCr8PlanarFullRange;
933             break;
934
935         default:
936             if (!vtctx->warned_color_range) {
937                 vtctx->warned_color_range = true;
938                 av_log(avctx, AV_LOG_WARNING, "Color range not set for YUV 4:2:0. Using MPEG range.\n");
939             }
940             *color = kCVPixelFormatType_420YpCbCr8Planar;
941         }
942
943         *plane_count = 3;
944
945         widths [0] = avctx->width;
946         heights[0] = avctx->height;
947         strides[0] = frame ? frame->linesize[0] : avctx->width;
948
949         widths [1] = (avctx->width  + 1) / 2;
950         heights[1] = (avctx->height + 1) / 2;
951         strides[1] = frame ? frame->linesize[1] : (avctx->width + 1) / 2;
952
953         widths [2] = (avctx->width  + 1) / 2;
954         heights[2] = (avctx->height + 1) / 2;
955         strides[2] = frame ? frame->linesize[2] : (avctx->width + 1) / 2;
956         break;
957
958     default: return AVERROR(EINVAL);
959     }
960
961     *contiguous_buf_size = 0;
962     for (i = 0; i < *plane_count; i++) {
963         if (i < *plane_count - 1 &&
964             frame->data[i] + strides[i] * heights[i] != frame->data[i + 1]) {
965             *contiguous_buf_size = 0;
966             break;
967         }
968
969         *contiguous_buf_size += strides[i] * heights[i];
970     }
971
972     return 0;
973 }
974
975 #if !TARGET_OS_IPHONE
976 //Not used on iOS - frame is always copied.
977 static void free_avframe(
978     void       *release_ctx,
979     const void *data,
980     size_t      size,
981     size_t      plane_count,
982     const void *plane_addresses[])
983 {
984     AVFrame *frame = release_ctx;
985     av_frame_free(&frame);
986 }
987 #else
988 //Not used on OSX - frame is never copied.
989 static int copy_avframe_to_pixel_buffer(AVCodecContext   *avctx,
990                                         const AVFrame    *frame,
991                                         CVPixelBufferRef cv_img,
992                                         const size_t     *plane_strides,
993                                         const size_t     *plane_rows)
994 {
995     int i, j;
996     size_t plane_count;
997     int status;
998     int rows;
999     int src_stride;
1000     int dst_stride;
1001     uint8_t *src_addr;
1002     uint8_t *dst_addr;
1003     size_t copy_bytes;
1004
1005     status = CVPixelBufferLockBaseAddress(cv_img, 0);
1006     if (status) {
1007         av_log(
1008             avctx,
1009             AV_LOG_ERROR,
1010             "Error: Could not lock base address of CVPixelBuffer: %d.\n",
1011             status
1012         );
1013     }
1014
1015     if (CVPixelBufferIsPlanar(cv_img)) {
1016         plane_count = CVPixelBufferGetPlaneCount(cv_img);
1017         for (i = 0; frame->data[i]; i++) {
1018             if (i == plane_count) {
1019                 CVPixelBufferUnlockBaseAddress(cv_img, 0);
1020                 av_log(avctx,
1021                     AV_LOG_ERROR,
1022                     "Error: different number of planes in AVFrame and CVPixelBuffer.\n"
1023                 );
1024
1025                 return AVERROR_EXTERNAL;
1026             }
1027
1028             dst_addr = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(cv_img, i);
1029             src_addr = (uint8_t*)frame->data[i];
1030             dst_stride = CVPixelBufferGetBytesPerRowOfPlane(cv_img, i);
1031             src_stride = plane_strides[i];
1032             rows = plane_rows[i];
1033
1034             if (dst_stride == src_stride) {
1035                 memcpy(dst_addr, src_addr, src_stride * rows);
1036             } else {
1037                 copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
1038
1039                 for (j = 0; j < rows; j++) {
1040                     memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
1041                 }
1042             }
1043         }
1044     } else {
1045         if (frame->data[1]) {
1046             CVPixelBufferUnlockBaseAddress(cv_img, 0);
1047             av_log(avctx,
1048                 AV_LOG_ERROR,
1049                 "Error: different number of planes in AVFrame and non-planar CVPixelBuffer.\n"
1050             );
1051
1052             return AVERROR_EXTERNAL;
1053         }
1054
1055         dst_addr = (uint8_t*)CVPixelBufferGetBaseAddress(cv_img);
1056         src_addr = (uint8_t*)frame->data[0];
1057         dst_stride = CVPixelBufferGetBytesPerRow(cv_img);
1058         src_stride = plane_strides[0];
1059         rows = plane_rows[0];
1060
1061         if (dst_stride == src_stride) {
1062             memcpy(dst_addr, src_addr, src_stride * rows);
1063         } else {
1064             copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
1065
1066             for (j = 0; j < rows; j++) {
1067                 memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
1068             }
1069         }
1070     }
1071
1072     status = CVPixelBufferUnlockBaseAddress(cv_img, 0);
1073     if (status) {
1074         av_log(avctx, AV_LOG_ERROR, "Error: Could not unlock CVPixelBuffer base address: %d.\n", status);
1075         return AVERROR_EXTERNAL;
1076     }
1077
1078     return 0;
1079 }
1080 #endif //!TARGET_OS_IPHONE
1081
1082 static int create_cv_pixel_buffer(AVCodecContext   *avctx,
1083                                   const AVFrame    *frame,
1084                                   CVPixelBufferRef *cv_img)
1085 {
1086     int plane_count;
1087     int color;
1088     size_t widths [AV_NUM_DATA_POINTERS];
1089     size_t heights[AV_NUM_DATA_POINTERS];
1090     size_t strides[AV_NUM_DATA_POINTERS];
1091     int status;
1092     size_t contiguous_buf_size;
1093
1094     memset(widths,  0, sizeof(widths));
1095     memset(heights, 0, sizeof(heights));
1096     memset(strides, 0, sizeof(strides));
1097
1098     status = get_cv_pixel_info(
1099         avctx,
1100         frame,
1101         &color,
1102         &plane_count,
1103         widths,
1104         heights,
1105         strides,
1106         &contiguous_buf_size
1107     );
1108
1109     if (status) {
1110         av_log(
1111             avctx,
1112             AV_LOG_ERROR,
1113             "Error: Cannot convert format %d color_range %d: %d\n",
1114             frame->format,
1115             av_frame_get_color_range(frame),
1116             status
1117         );
1118
1119         return AVERROR_EXTERNAL;
1120     }
1121
1122 #if TARGET_OS_IPHONE
1123     status = CVPixelBufferCreate(
1124         kCFAllocatorDefault,
1125         frame->width,
1126         frame->height,
1127         color,
1128         NULL,
1129         cv_img
1130     );
1131
1132     if (status) {
1133         return AVERROR_EXTERNAL;
1134     }
1135
1136     status = copy_avframe_to_pixel_buffer(avctx, frame, *cv_img, strides, heights);
1137     if (status) {
1138         CFRelease(*cv_img);
1139         *cv_img = NULL;
1140         return status;
1141     }
1142 #else
1143     AVFrame *enc_frame = av_frame_alloc();
1144     if (!enc_frame) return AVERROR(ENOMEM);
1145
1146     status = av_frame_ref(enc_frame, frame);
1147     if (status) {
1148         av_frame_free(&enc_frame);
1149         return status;
1150     }
1151
1152     status = CVPixelBufferCreateWithPlanarBytes(
1153         kCFAllocatorDefault,
1154         enc_frame->width,
1155         enc_frame->height,
1156         color,
1157         NULL,
1158         contiguous_buf_size,
1159         plane_count,
1160         (void **)enc_frame->data,
1161         widths,
1162         heights,
1163         strides,
1164         free_avframe,
1165         enc_frame,
1166         NULL,
1167         cv_img
1168     );
1169
1170     if (status) {
1171         av_log(avctx, AV_LOG_ERROR, "Error: Could not create CVPixelBuffer: %d\n", status);
1172         return AVERROR_EXTERNAL;
1173     }
1174 #endif
1175
1176     return 0;
1177 }
1178
1179 static int vtenc_send_frame(AVCodecContext *avctx,
1180                             VTEncContext   *vtctx,
1181                             const AVFrame  *frame)
1182 {
1183     CMTime time;
1184     CVPixelBufferRef cv_img = NULL;
1185     int status = create_cv_pixel_buffer(avctx, frame, &cv_img);
1186
1187     if (status) return status;
1188
1189     time = CMTimeMake(frame->pts * avctx->time_base.num, avctx->time_base.den);
1190     status = VTCompressionSessionEncodeFrame(
1191         vtctx->session,
1192         cv_img,
1193         time,
1194         kCMTimeInvalid,
1195         NULL,
1196         NULL,
1197         NULL
1198     );
1199
1200     CFRelease(cv_img);
1201
1202     if (status) {
1203         av_log(avctx, AV_LOG_ERROR, "Error: cannot encode frame: %d\n", status);
1204         return AVERROR_EXTERNAL;
1205     }
1206
1207     return 0;
1208 }
1209
1210 static av_cold int vtenc_frame(
1211     AVCodecContext *avctx,
1212     AVPacket       *pkt,
1213     const AVFrame  *frame,
1214     int            *got_packet)
1215 {
1216     VTEncContext *vtctx = avctx->priv_data;
1217     bool get_frame;
1218     int status;
1219     CMSampleBufferRef buf = NULL;
1220
1221     if (frame) {
1222         status = vtenc_send_frame(avctx, vtctx, frame);
1223
1224         if (status) {
1225             status = AVERROR_EXTERNAL;
1226             goto end_nopkt;
1227         }
1228
1229         if (vtctx->frame_ct_in == 0) {
1230             vtctx->first_pts = frame->pts;
1231         } else if(vtctx->frame_ct_in == 1 && vtctx->has_b_frames) {
1232             vtctx->dts_delta = frame->pts - vtctx->first_pts;
1233         }
1234
1235         vtctx->frame_ct_in++;
1236     } else if(!vtctx->flushing) {
1237         vtctx->flushing = true;
1238
1239         status = VTCompressionSessionCompleteFrames(vtctx->session,
1240                                                     kCMTimeIndefinite);
1241
1242         if (status) {
1243             av_log(avctx, AV_LOG_ERROR, "Error flushing frames: %d\n", status);
1244             status = AVERROR_EXTERNAL;
1245             goto end_nopkt;
1246         }
1247     }
1248
1249     *got_packet = 0;
1250     get_frame = vtctx->dts_delta >= 0 || !frame;
1251     if (!get_frame) {
1252         status = 0;
1253         goto end_nopkt;
1254     }
1255
1256     status = vtenc_q_pop(vtctx, !frame, &buf);
1257     if (status) goto end_nopkt;
1258     if (!buf)   goto end_nopkt;
1259
1260     status = vtenc_cm_to_avpacket(avctx, buf, pkt);
1261     CFRelease(buf);
1262     if (status) goto end_nopkt;
1263
1264     *got_packet = 1;
1265     return 0;
1266
1267 end_nopkt:
1268     av_packet_unref(pkt);
1269     return status;
1270 }
1271
1272 static av_cold int vtenc_close(AVCodecContext *avctx)
1273 {
1274     VTEncContext *vtctx = avctx->priv_data;
1275
1276     if(!vtctx->session) return 0;
1277
1278     VTCompressionSessionInvalidate(vtctx->session);
1279     pthread_cond_destroy(&vtctx->cv_sample_sent);
1280     pthread_mutex_destroy(&vtctx->lock);
1281     CFRelease(vtctx->session);
1282     vtctx->session = NULL;
1283
1284     return 0;
1285 }
1286
1287 static const enum AVPixelFormat pix_fmts[] = {
1288     AV_PIX_FMT_NV12,
1289 #if !TARGET_OS_IPHONE
1290     AV_PIX_FMT_YUV420P,
1291 #endif
1292     AV_PIX_FMT_NONE
1293 };
1294
1295 #define OFFSET(x) offsetof(VTEncContext, x)
1296 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1297 static const AVOption options[] = {
1298     { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = H264_PROF_AUTO }, H264_PROF_AUTO, H264_PROF_COUNT, VE, "profile" },
1299     { "baseline", "Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_BASELINE }, INT_MIN, INT_MAX, VE, "profile" },
1300     { "main",     "Main Profile",     0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_MAIN     }, INT_MIN, INT_MAX, VE, "profile" },
1301     { "high",     "High Profile",     0, AV_OPT_TYPE_CONST, { .i64 = H264_PROF_HIGH     }, INT_MIN, INT_MAX, VE, "profile" },
1302
1303     { "level", "Level", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 52, VE, "level" },
1304     { "1.3", "Level 1.3, only available with Baseline Profile", 0, AV_OPT_TYPE_CONST, { .i64 = 13 }, INT_MIN, INT_MAX, VE, "level" },
1305     { "3.0", "Level 3.0", 0, AV_OPT_TYPE_CONST, { .i64 = 30 }, INT_MIN, INT_MAX, VE, "level" },
1306     { "3.1", "Level 3.1", 0, AV_OPT_TYPE_CONST, { .i64 = 31 }, INT_MIN, INT_MAX, VE, "level" },
1307     { "3.2", "Level 3.2", 0, AV_OPT_TYPE_CONST, { .i64 = 32 }, INT_MIN, INT_MAX, VE, "level" },
1308     { "4.0", "Level 4.0", 0, AV_OPT_TYPE_CONST, { .i64 = 40 }, INT_MIN, INT_MAX, VE, "level" },
1309     { "4.1", "Level 4.1", 0, AV_OPT_TYPE_CONST, { .i64 = 41 }, INT_MIN, INT_MAX, VE, "level" },
1310     { "4.2", "Level 4.2", 0, AV_OPT_TYPE_CONST, { .i64 = 42 }, INT_MIN, INT_MAX, VE, "level" },
1311     { "5.0", "Level 5.0", 0, AV_OPT_TYPE_CONST, { .i64 = 50 }, INT_MIN, INT_MAX, VE, "level" },
1312     { "5.1", "Level 5.1", 0, AV_OPT_TYPE_CONST, { .i64 = 51 }, INT_MIN, INT_MAX, VE, "level" },
1313     { "5.2", "Level 5.2", 0, AV_OPT_TYPE_CONST, { .i64 = 52 }, INT_MIN, INT_MAX, VE, "level" },
1314
1315     { NULL },
1316 };
1317
1318 static const AVClass h264_videotoolbox_class = {
1319     .class_name = "h264_videotoolbox",
1320     .item_name  = av_default_item_name,
1321     .option     = options,
1322     .version    = LIBAVUTIL_VERSION_INT,
1323 };
1324
1325 AVCodec ff_h264_videotoolbox_encoder = {
1326     .name             = "h264_videotoolbox",
1327     .long_name        = NULL_IF_CONFIG_SMALL("VideoToolbox H.264 Encoder"),
1328     .type             = AVMEDIA_TYPE_VIDEO,
1329     .id               = AV_CODEC_ID_H264,
1330     .priv_data_size   = sizeof(VTEncContext),
1331     .pix_fmts         = pix_fmts,
1332     .init             = vtenc_init,
1333     .encode2          = vtenc_frame,
1334     .close            = vtenc_close,
1335     .capabilities     = AV_CODEC_CAP_DELAY,
1336     .priv_class       = &h264_videotoolbox_class,
1337     .caps_internal    = FF_CODEC_CAP_INIT_THREADSAFE |
1338                         FF_CODEC_CAP_INIT_CLEANUP,
1339 };