diff mbox

[FFmpeg-devel,v4,30/38] vaapi_encode_h264: Enable multiple-slice support

Message ID 20180918223116.14322-31-sw@jkqxz.net
State Accepted
Commit a769e72c750e113c75b1f106296ade94caa28748
Headers show

Commit Message

Mark Thompson Sept. 18, 2018, 10:31 p.m. UTC
---
 libavcodec/vaapi_encode_h264.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

Comments

mypopy@gmail.com Sept. 19, 2018, 3:20 a.m. UTC | #1
On Wed, Sep 19, 2018 at 6:35 AM Mark Thompson <sw@jkqxz.net> wrote:
>
> ---
>  libavcodec/vaapi_encode_h264.c | 13 +++++++------
>  1 file changed, 7 insertions(+), 6 deletions(-)
>
> diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
> index 8feae0d42f..7bb77cfba2 100644
> --- a/libavcodec/vaapi_encode_h264.c
> +++ b/libavcodec/vaapi_encode_h264.c
> @@ -733,8 +733,6 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
>      vpic->pic_fields.bits.idr_pic_flag       = (pic->type == PICTURE_TYPE_IDR);
>      vpic->pic_fields.bits.reference_pic_flag = (pic->type != PICTURE_TYPE_B);
>
> -    pic->nb_slices = 1;
> -
>      return 0;
>  }
>
> @@ -758,8 +756,7 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
>          sh->nal_unit_header.nal_ref_idc   = pic->type != PICTURE_TYPE_B;
>      }
>
> -    // Only one slice per frame.
> -    sh->first_mb_in_slice = 0;
> +    sh->first_mb_in_slice = slice->block_start;
>      sh->slice_type        = priv->slice_type;
>
>      sh->pic_parameter_set_id = pps->pic_parameter_set_id;
> @@ -780,8 +777,8 @@ static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
>          sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26);
>
>
> -    vslice->macroblock_address = sh->first_mb_in_slice;
> -    vslice->num_macroblocks    = priv->mb_width * priv->mb_height;
> +    vslice->macroblock_address = slice->block_start;
> +    vslice->num_macroblocks    = slice->block_size;
>
>      vslice->macroblock_info = VA_INVALID_ID;
>
> @@ -903,6 +900,8 @@ static const VAAPIEncodeProfile vaapi_encode_h264_profiles[] = {
>  static const VAAPIEncodeType vaapi_encode_type_h264 = {
>      .profiles              = vaapi_encode_h264_profiles,
>
> +    .flags                 = FLAG_SLICE_CONTROL,
> +
>      .configure             = &vaapi_encode_h264_configure,
>
>      .sequence_params_size  = sizeof(VAEncSequenceParameterBufferH264),
> @@ -978,6 +977,8 @@ static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
>      ctx->surface_width  = FFALIGN(avctx->width,  16);
>      ctx->surface_height = FFALIGN(avctx->height, 16);
>
> +    ctx->slice_block_height = ctx->slice_block_width = 16;
> +
>      return ff_vaapi_encode_init(avctx);
>  }
>
Missing “slices” option in doc/encoder VA-API part, I think. other part LGTM
Mark Thompson Sept. 23, 2018, 10:08 p.m. UTC | #2
On 19/09/18 02:33, mypopy@gmail.com wrote:> 
> VA-API encoder can support multiple-frame reference too.

That's loosely the intent, though it probably needs more information about similarities between frames for the feature to be of non-placebo use.

In terms of the common implementation it should be possible to make an alternative pick_next() function which creates the set of references in a different way and have it work for all codecs (or at least H.264/5, VP9 and in future AV1; MPEG-2 and VP8 have constraints making them less general), though the codec-specific parts do still contain some assumptions about structure which would need to be ironed out for that to actually work.

I think the information to make it useful could either come from somewhere external (e.g. a filter doing some sort of frame-similarity test and passing that information on), or it could be internal by running the encoder itself multiple times in different configurations and looking at the resulting output.  Any thoughts you have on how this should work are welcome.


On 19/09/18 04:20, mypopy@gmail.com wrote:
> On Wed, Sep 19, 2018 at 6:35 AM Mark Thompson <sw@jkqxz.net> wrote:
>>
>> ---
>>  libavcodec/vaapi_encode_h264.c | 13 +++++++------
>>  1 file changed, 7 insertions(+), 6 deletions(-)
>>
>> ...
> Missing “slices” option in doc/encoder VA-API part, I think. other part LGTM

Yep, added in new version.

Thanks,

- Mark
diff mbox

Patch

diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c
index 8feae0d42f..7bb77cfba2 100644
--- a/libavcodec/vaapi_encode_h264.c
+++ b/libavcodec/vaapi_encode_h264.c
@@ -733,8 +733,6 @@  static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx,
     vpic->pic_fields.bits.idr_pic_flag       = (pic->type == PICTURE_TYPE_IDR);
     vpic->pic_fields.bits.reference_pic_flag = (pic->type != PICTURE_TYPE_B);
 
-    pic->nb_slices = 1;
-
     return 0;
 }
 
@@ -758,8 +756,7 @@  static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
         sh->nal_unit_header.nal_ref_idc   = pic->type != PICTURE_TYPE_B;
     }
 
-    // Only one slice per frame.
-    sh->first_mb_in_slice = 0;
+    sh->first_mb_in_slice = slice->block_start;
     sh->slice_type        = priv->slice_type;
 
     sh->pic_parameter_set_id = pps->pic_parameter_set_id;
@@ -780,8 +777,8 @@  static int vaapi_encode_h264_init_slice_params(AVCodecContext *avctx,
         sh->slice_qp_delta = priv->fixed_qp_idr - (pps->pic_init_qp_minus26 + 26);
 
 
-    vslice->macroblock_address = sh->first_mb_in_slice;
-    vslice->num_macroblocks    = priv->mb_width * priv->mb_height;
+    vslice->macroblock_address = slice->block_start;
+    vslice->num_macroblocks    = slice->block_size;
 
     vslice->macroblock_info = VA_INVALID_ID;
 
@@ -903,6 +900,8 @@  static const VAAPIEncodeProfile vaapi_encode_h264_profiles[] = {
 static const VAAPIEncodeType vaapi_encode_type_h264 = {
     .profiles              = vaapi_encode_h264_profiles,
 
+    .flags                 = FLAG_SLICE_CONTROL,
+
     .configure             = &vaapi_encode_h264_configure,
 
     .sequence_params_size  = sizeof(VAEncSequenceParameterBufferH264),
@@ -978,6 +977,8 @@  static av_cold int vaapi_encode_h264_init(AVCodecContext *avctx)
     ctx->surface_width  = FFALIGN(avctx->width,  16);
     ctx->surface_height = FFALIGN(avctx->height, 16);
 
+    ctx->slice_block_height = ctx->slice_block_width = 16;
+
     return ff_vaapi_encode_init(avctx);
 }