From 9d8a38d20b4057a140e132284def9263d8ca80a8 Mon Sep 17 00:00:00 2001 From: Rick Kern Date: Wed, 27 Apr 2016 10:53:13 -0400 Subject: lavc/videotoolboxenc: Support for forced I-frames Setting AVFrame.pic_type to AV_PICTURE_TYPE_I will force an I-frame. Signed-off-by: Rick Kern --- libavcodec/videotoolboxenc.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index e1553839b4..5f027560cd 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -1414,27 +1414,51 @@ static int create_cv_pixel_buffer(AVCodecContext *avctx, return 0; } +static int create_encoder_dict_h264(const AVFrame *frame, + CFDictionaryRef* dict_out) +{ + CFDictionaryRef dict = NULL; + if (frame->pict_type == AV_PICTURE_TYPE_I) { + const void *keys[] = { kVTEncodeFrameOptionKey_ForceKeyFrame }; + const void *vals[] = { kCFBooleanTrue }; + + dict = CFDictionaryCreate(NULL, keys, vals, 1, NULL, NULL); + if(!dict) return AVERROR(ENOMEM); + } + + *dict_out = dict; + return 0; +} + static int vtenc_send_frame(AVCodecContext *avctx, VTEncContext *vtctx, const AVFrame *frame) { CMTime time; + CFDictionaryRef frame_dict; CVPixelBufferRef cv_img = NULL; int status = create_cv_pixel_buffer(avctx, frame, &cv_img); if (status) return status; + status = create_encoder_dict_h264(frame, &frame_dict); + if (status) { + CFRelease(cv_img); + return status; + } + time = CMTimeMake(frame->pts * avctx->time_base.num, avctx->time_base.den); status = VTCompressionSessionEncodeFrame( vtctx->session, cv_img, time, kCMTimeInvalid, - NULL, + frame_dict, NULL, NULL ); + if (frame_dict) CFRelease(frame_dict); CFRelease(cv_img); if (status) { -- cgit v1.2.3