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

Reply via email to