[FFmpeg-devel] [PATCH] lavc/vaapi_encode: enable "force_key_frames" option in vaapi_encode

Jun Zhao mypopydev at gmail.com
Mon Jan 9 08:19:07 EET 2017


From 40804a849556e1303f6351f5560d5552e2588b12 Mon Sep 17 00:00:00 2001
From: Jun Zhao <jun.zhao at intel.com>
Date: Mon, 9 Jan 2017 14:05:59 +0800
Subject: [PATCH] lavc/vaapi_encode: enable "force_key_frames" option in
 vaapi_encode

enable the opt "force_key_frame" to force IDR output in vaapi_encode,
and this option can take a expression as an argument, allowing
functionality such as forcing a key frame(IDR frame) every 5 seconds
like:

-force_key_frames 'expr:gte(t,n_forced*5)'

Signed-off-by: Wang, Yi A <yi.a.wang at intel.com>
Signed-off-by: Jun Zhao <jun.zhao at intel.com>
---
 libavcodec/vaapi_encode.c | 24 +++++++++++++++---------
 libavcodec/vaapi_encode.h |  1 +
 2 files changed, 16 insertions(+), 9 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index a3c9991..26694aa 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -28,7 +28,7 @@
 #include "avcodec.h"
 
 static const char *picture_type_name[] = { "IDR", "I", "P", "B" };
-
+static int vaapi_encode_mangle_end(AVCodecContext *avctx);
 static int vaapi_encode_make_packed_header(AVCodecContext *avctx,
                                            VAAPIEncodePicture *pic,
                                            int type, char *data, size_t bit_len)
@@ -626,12 +626,16 @@ static int vaapi_encode_get_next(AVCodecContext *avctx,
     VAAPIEncodePicture *start, *end, *pic;
     int i;
 
-    for (pic = ctx->pic_start; pic; pic = pic->next) {
-        if (pic->next)
-            av_assert0(pic->display_order + 1 == pic->next->display_order);
-        if (pic->display_order == ctx->input_order) {
-            *pic_out = pic;
-            return 0;
+    if (ctx->force_idr_frame) {
+        vaapi_encode_mangle_end(avctx);
+    } else {
+        for (pic = ctx->pic_start; pic; pic = pic->next) {
+            if (pic->next)
+                av_assert0(pic->display_order + 1 == pic->next->display_order);
+            if (pic->display_order == ctx->input_order) {
+                *pic_out = pic;
+                return 0;
+            }
         }
     }
 
@@ -657,14 +661,15 @@ static int vaapi_encode_get_next(AVCodecContext *avctx,
     if (!pic)
         return AVERROR(ENOMEM);
 
-    if (ctx->p_per_i == 0 || ctx->p_counter == ctx->p_per_i) {
-        if (ctx->i_per_idr == 0 || ctx->i_counter == ctx->i_per_idr) {
+    if (ctx->force_idr_frame == 1 || ctx->p_per_i == 0 || ctx->p_counter == ctx->p_per_i) {
+        if (ctx->force_idr_frame == 1 || ctx->i_per_idr == 0 || ctx->i_counter == ctx->i_per_idr) {
             pic->type = PICTURE_TYPE_IDR;
             ctx->i_counter = 0;
         } else {
             pic->type = PICTURE_TYPE_I;
             ++ctx->i_counter;
         }
+        ctx->force_idr_frame = 0;
         ctx->p_counter = 0;
     } else {
         pic->type = PICTURE_TYPE_P;
@@ -834,6 +839,7 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
         av_log(avctx, AV_LOG_DEBUG, "Encode frame: %ux%u (%"PRId64").\n",
                input_image->width, input_image->height, input_image->pts);
 
+        ctx->force_idr_frame = (input_image->pict_type == AV_PICTURE_TYPE_I ? 1 : 0) ;
         err = vaapi_encode_get_next(avctx, &pic);
         if (err) {
             av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err);
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index cc05ac8..63b3e51 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -197,6 +197,7 @@ typedef struct VAAPIEncodeContext {
     int i_counter;
     int p_counter;
     int end_of_stream;
+    int force_idr_frame;
 
     // Codec-local options are allocated to follow this structure in
     // memory (in the AVCodec definition, set priv_data_size to
-- 
2.9.3



More information about the ffmpeg-devel mailing list