summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRick Kern <kernrj@gmail.com>2016-04-27 10:53:13 -0400
committerwm4 <nfxjfg@googlemail.com>2016-05-04 18:40:40 +0200
commit9d8a38d20b4057a140e132284def9263d8ca80a8 (patch)
treed3f0050d05a95e2a92833b4ba64a403ae6c32a1c
parent4b806081b25ffa15e174a8c7a86343ea63f51670 (diff)
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 <kernrj@gmail.com>
-rw-r--r--libavcodec/videotoolboxenc.c26
1 files changed, 25 insertions, 1 deletions
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) {