[FFmpeg-devel] [PATCH] lavc/vaapi_encode_h265: add low_delay_b option for HEVC

Linjie Fu linjie.fu at intel.com
Mon Apr 13 07:32:32 EEST 2020


Low delay B-frame is supported on ICL+ platform.

For low power encoding, low_delay_b should be enabled by default.

Low delay B:
<http://what-when-how.com/Tutorial/topic-397pct9eq3/High-Efficiency-Video-Coding-HEVC-288.html>

There is an on-going work in libva and media-driver to add querys
support for low delay b, would add it once it's ready:
https://github.com/intel/libva/pull/220
https://github.com/intel/libva/pull/364
https://github.com/intel/media-driver/issues/721

Signed-off-by: Linjie Fu <linjie.fu at intel.com>
---
 doc/encoders.texi              |  8 ++++++++
 libavcodec/vaapi_encode_h265.c | 19 +++++++++++++++++--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/doc/encoders.texi b/doc/encoders.texi
index e23b6b3..b0812be 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3089,6 +3089,14 @@ Some combination of the following values:
 Include HDR metadata if the input frames have it
 (@emph{mastering_display_colour_volume} and @emph{content_light_level}
 messages).
+
+ at item low_delay_b
+Use low delay B-frames instead of P frames. Reordering of pictures is
+not allowed. The first picture is encoded as an I picture and subsequent
+pictures are encoded as B pictures. Moreover, since past B pictures are
+used for prediction, a low coding delay but with higher coding efficiency
+(because of bi-prediction) is achieved.
+
 @end table
 
 @end table
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 97dc5a7..cd48545 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -62,6 +62,7 @@ typedef struct VAAPIEncodeH265Context {
     int tier;
     int level;
     int sei;
+    int low_delay_b;
 
     // Derived settings.
     int fixed_qp_idr;
@@ -894,6 +895,9 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
 
     sh->slice_type = hpic->slice_type;
 
+    if (sh->slice_type == HEVC_SLICE_P && priv->low_delay_b)
+        sh->slice_type = HEVC_SLICE_B;
+
     sh->slice_pic_order_cnt_lsb = hpic->pic_order_cnt &
         (1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4)) - 1;
 
@@ -1054,9 +1058,13 @@ static int vaapi_encode_h265_init_slice_params(AVCodecContext *avctx,
         vslice->ref_pic_list0[0] = vpic->reference_frames[0];
     }
     if (pic->nb_refs >= 2) {
-        // Forward reference for B-frame.
         av_assert0(pic->type == PICTURE_TYPE_B);
-        vslice->ref_pic_list1[0] = vpic->reference_frames[1];
+        if (priv->low_delay_b)
+            // Reference for low delay B-frame
+            vslice->ref_pic_list1[0] = vpic->reference_frames[0];
+        else
+            // Forward reference for B-frame.
+            vslice->ref_pic_list1[0] = vpic->reference_frames[1];
     }
 
     return 0;
@@ -1181,6 +1189,11 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
     if (priv->qp > 0)
         ctx->explicit_qp = priv->qp;
 
+    /* low_delay_b is required for low power encoding */
+    priv->low_delay_b = ctx->low_power ? 1 : priv->low_delay_b;
+    if (priv->low_delay_b)
+        av_log(avctx, AV_LOG_VERBOSE, "Low delay B-frame enabled.\n");
+
     return ff_vaapi_encode_init(avctx);
 }
 
@@ -1256,6 +1269,8 @@ static const AVOption vaapi_encode_h265_options[] = {
       0, AV_OPT_TYPE_CONST,
       { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL },
       INT_MIN, INT_MAX, FLAGS, "sei" },
+    { "low_delay_b", "Use low delay B frames instead of P frames",
+      OFFSET(low_delay_b), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS },
 
     { NULL },
 };
-- 
2.7.4



More information about the ffmpeg-devel mailing list