Setting AVFrame.pic_type to AV_PICTURE_TYPE_I will force an I-frame. Signed-off-by: Rick Kern <ker...@gmail.com> --- libavcodec/videotoolboxenc.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index c630825..5935d09 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -1434,27 +1434,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) { -- 2.7.4 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel