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