[FFmpeg-cvslog] vaapi_encode: Support forcing IDR frames via AVFrame.pict_type

Mark Thompson git at videolan.org
Fri May 5 14:31:31 EEST 2017


ffmpeg | branch: master | Mark Thompson <sw at jkqxz.net> | Mon Dec 12 21:25:28 2016 +0000| [a3c3a5eac20a51d402c332cdf5220fff40a7943f] | committer: Mark Thompson

vaapi_encode: Support forcing IDR frames via AVFrame.pict_type

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a3c3a5eac20a51d402c332cdf5220fff40a7943f
---

 libavcodec/vaapi_encode.c | 27 +++++++++++++++++++++++----
 libavcodec/vaapi_encode.h |  1 +
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c
index c670ae62df..c93bfcc0b1 100644
--- a/libavcodec/vaapi_encode.c
+++ b/libavcodec/vaapi_encode.c
@@ -590,6 +590,10 @@ static int vaapi_encode_step(AVCodecContext *avctx,
     } else if (ctx->issue_mode == ISSUE_MODE_MAXIMISE_THROUGHPUT) {
         int activity;
 
+        // Run through the list of all available pictures repeatedly
+        // and issue the first one found which has all dependencies
+        // available (including previously-issued but not necessarily
+        // completed pictures).
         do {
             activity = 0;
             for (pic = ctx->pic_start; pic; pic = pic->next) {
@@ -605,9 +609,15 @@ static int vaapi_encode_step(AVCodecContext *avctx,
                 if (err < 0)
                     return err;
                 activity = 1;
+                // Start again from the beginning of the list,
+                // because issuing this picture may have satisfied
+                // forward dependencies of earlier ones.
+                break;
             }
         } while(activity);
 
+        // If we had a defined target for this step then it will
+        // always have been issued by now.
         if (target) {
             av_assert0(target->encode_issued && "broken dependencies?");
         }
@@ -639,8 +649,10 @@ static int vaapi_encode_get_next(AVCodecContext *avctx,
     if (!pic)
         return AVERROR(ENOMEM);
 
-    if (ctx->input_order == 0 || ctx->gop_counter >= avctx->gop_size) {
+    if (ctx->input_order == 0 || ctx->force_idr ||
+        ctx->gop_counter >= avctx->gop_size) {
         pic->type = PICTURE_TYPE_IDR;
+        ctx->force_idr = 0;
         ctx->gop_counter = 1;
         ctx->p_counter = 0;
     } else if (ctx->p_counter >= ctx->p_per_i) {
@@ -722,7 +734,7 @@ fail:
     return AVERROR(ENOMEM);
 }
 
-static int vaapi_encode_mangle_end(AVCodecContext *avctx)
+static int vaapi_encode_truncate_gop(AVCodecContext *avctx)
 {
     VAAPIEncodeContext *ctx = avctx->priv_data;
     VAAPIEncodePicture *pic, *last_pic, *next;
@@ -772,7 +784,7 @@ static int vaapi_encode_mangle_end(AVCodecContext *avctx)
         // mangle anything.
     }
 
-    av_log(avctx, AV_LOG_DEBUG, "Pictures at end of stream:");
+    av_log(avctx, AV_LOG_DEBUG, "Pictures ending truncated GOP:");
     for (pic = ctx->pic_start; pic; pic = pic->next) {
         av_log(avctx, AV_LOG_DEBUG, " %s (%"PRId64"/%"PRId64")",
                picture_type_name[pic->type],
@@ -826,6 +838,13 @@ 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);
 
+        if (input_image->pict_type == AV_PICTURE_TYPE_I) {
+            err = vaapi_encode_truncate_gop(avctx);
+            if (err < 0)
+                goto fail;
+            ctx->force_idr = 1;
+        }
+
         err = vaapi_encode_get_next(avctx, &pic);
         if (err) {
             av_log(avctx, AV_LOG_ERROR, "Input setup failed: %d.\n", err);
@@ -854,7 +873,7 @@ int ff_vaapi_encode2(AVCodecContext *avctx, AVPacket *pkt,
 
     } else {
         if (!ctx->end_of_stream) {
-            err = vaapi_encode_mangle_end(avctx);
+            err = vaapi_encode_truncate_gop(avctx);
             if (err < 0)
                 goto fail;
             ctx->end_of_stream = 1;
diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h
index e8ed4fdb4e..2a72510b83 100644
--- a/libavcodec/vaapi_encode.h
+++ b/libavcodec/vaapi_encode.h
@@ -192,6 +192,7 @@ typedef struct VAAPIEncodeContext {
     // Frame type decision.
     int p_per_i;
     int b_per_p;
+    int force_idr;
     int gop_counter;
     int p_counter;
     int end_of_stream;



More information about the ffmpeg-cvslog mailing list