[Libva] [PATCH] Add phantom slice support on IVB+

Li, Zhong zhong.li at intel.com
Wed Aug 6 07:10:26 PDT 2014


Thanks for your verification.  We'll check this patch into master branch, instead of the first patch attached on https://bugs.freedesktop.org/show_bug.cgi?id=81447 .

-----Original Message-----
From: Stephan Raue [mailto:mailinglists at openelec.tv] 
Sent: Wednesday, August 6, 2014 6:11 PM
To: Li, Zhong; libva at lists.freedesktop.org
Subject: Re: [Libva] [PATCH] Add phantom slice support on IVB+

Hi Zhong Li,

just tested this patch (on OpenELEC with XBMC) and it works great. We can visually see the video is faulty, but it looks visually better then with the patch from https://bugs.freedesktop.org/show_bug.cgi?id=81447 .

many thanks for your help

Stephan

Am 06.08.2014 10:56, schrieb Zhong Li:
> HW requires driver to add a phantom slice when FirstMbX and FirstMbY 
> are not 0, in order to avc decoding error concealment. Otherwise, GPU may hang.
> This patch is a workround for 
> bug:https://bugs.freedesktop.org/show_bug.cgi?id=81447
>
> Signed-off-by: Zhong Li<zhong.li at intel.com>
> ---
>   src/gen75_mfd.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   src/gen7_mfd.c  |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   src/gen8_mfd.c  |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>   3 files changed, 240 insertions(+)
>
> diff --git a/src/gen75_mfd.c b/src/gen75_mfd.c index b14db61..27ecbd9 
> 100644
> --- a/src/gen75_mfd.c
> +++ b/src/gen75_mfd.c
> @@ -812,6 +812,83 @@ gen75_mfd_avc_directmode_state(VADriverContextP ctx,
>   }
>   
>   static void
> +gen75_mfd_avc_phantom_slice_state(VADriverContextP ctx,
> +                                 VAPictureParameterBufferH264 *pic_param,
> +                                 VASliceParameterBufferH264 *next_slice_param,
> +                                 struct gen7_mfd_context 
> +*gen7_mfd_context) {
> +    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
> +    int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
> +    int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
> +    int slice_hor_pos, slice_ver_pos, slice_start_mb_num, next_slice_hor_pos, next_slice_ver_pos;
> +    int mbaff_picture = (!pic_param->pic_fields.bits.field_pic_flag &&
> +                         
> +pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
> +
> +    if (next_slice_param) {
> +        int first_mb_in_next_slice;
> +
> +        slice_hor_pos = 0;
> +        slice_ver_pos = 0;
> +        slice_start_mb_num = 0;
> +        first_mb_in_next_slice = next_slice_param->first_mb_in_slice << mbaff_picture;
> +        next_slice_hor_pos = first_mb_in_next_slice % width_in_mbs;
> +        next_slice_ver_pos = first_mb_in_next_slice / width_in_mbs;
> +    } else {
> +        slice_hor_pos = 0;
> +        slice_ver_pos = height_in_mbs;
> +        slice_start_mb_num = width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag);
> +        next_slice_hor_pos = 0;
> +        next_slice_ver_pos = 0;
> +    }
> +
> +    BEGIN_BCS_BATCH(batch, 11); /* FIXME: is it 10??? */
> +    OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2));
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch,
> +                  slice_ver_pos << 24 |
> +                  slice_hor_pos << 16 |
> +                  slice_start_mb_num << 0);
> +    OUT_BCS_BATCH(batch,
> +                  next_slice_ver_pos << 16 |
> +                  next_slice_hor_pos << 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen75_mfd_avc_phantom_slice_bsd_object(VADriverContextP ctx,
> +                                      VAPictureParameterBufferH264 *pic_param,
> +                                      struct gen7_mfd_context 
> +*gen7_mfd_context) {
> +    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
> +
> +    BEGIN_BCS_BATCH(batch, 6);
> +    OUT_BCS_BATCH(batch, MFD_AVC_BSD_OBJECT | (6 - 2));
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen75_mfd_avc_phantom_slice_first(VADriverContextP ctx,
> +                           VAPictureParameterBufferH264 *pic_param,
> +                           VASliceParameterBufferH264 *next_slice_param,
> +                           struct gen7_mfd_context *gen7_mfd_context) 
> +{
> +    gen75_mfd_avc_phantom_slice_state(ctx, pic_param, next_slice_param, gen7_mfd_context);
> +    gen75_mfd_avc_phantom_slice_bsd_object(ctx, pic_param, 
> +gen7_mfd_context); }
> +
> +static void
>   gen75_mfd_avc_slice_state(VADriverContextP ctx,
>                            VAPictureParameterBufferH264 *pic_param,
>                            VASliceParameterBufferH264 *slice_param, @@ 
> -1145,6 +1222,9 @@ gen75_mfd_avc_decode_picture(VADriverContextP ctx,
>           else
>               next_slice_group_param = (VASliceParameterBufferH264 
> *)decode_state->slice_params[j + 1]->buffer;
>   
> +        if (j == 0 && slice_param->first_mb_in_slice)
> +            gen75_mfd_avc_phantom_slice_first(ctx, pic_param, 
> + slice_param, gen7_mfd_context);
> +
>           for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
>               assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
>               assert((slice_param->slice_type == SLICE_TYPE_I) || diff 
> --git a/src/gen7_mfd.c b/src/gen7_mfd.c index 46a07a0..e50c83b 100755
> --- a/src/gen7_mfd.c
> +++ b/src/gen7_mfd.c
> @@ -506,6 +506,83 @@ gen7_mfd_avc_directmode_state(VADriverContextP ctx,
>   }
>   
>   static void
> +gen7_mfd_avc_phantom_slice_state(VADriverContextP ctx,
> +                                 VAPictureParameterBufferH264 *pic_param,
> +                                 VASliceParameterBufferH264 *next_slice_param,
> +                                 struct gen7_mfd_context 
> +*gen7_mfd_context) {
> +    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
> +    int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
> +    int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
> +    int slice_hor_pos, slice_ver_pos, slice_start_mb_num, next_slice_hor_pos, next_slice_ver_pos;
> +    int mbaff_picture = (!pic_param->pic_fields.bits.field_pic_flag &&
> +                         
> +pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
> +
> +    if (next_slice_param) {
> +        int first_mb_in_next_slice;
> +
> +        slice_hor_pos = 0;
> +        slice_ver_pos = 0;
> +        slice_start_mb_num = 0;
> +        first_mb_in_next_slice = next_slice_param->first_mb_in_slice << mbaff_picture;
> +        next_slice_hor_pos = first_mb_in_next_slice % width_in_mbs;
> +        next_slice_ver_pos = first_mb_in_next_slice / width_in_mbs;
> +    } else {
> +        slice_hor_pos = 0;
> +        slice_ver_pos = height_in_mbs;
> +        slice_start_mb_num = width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag);
> +        next_slice_hor_pos = 0;
> +        next_slice_ver_pos = 0;
> +    }
> +
> +    BEGIN_BCS_BATCH(batch, 11); /* FIXME: is it 10??? */
> +    OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2));
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch,
> +                  slice_ver_pos << 24 |
> +                  slice_hor_pos << 16 |
> +                  slice_start_mb_num << 0);
> +    OUT_BCS_BATCH(batch,
> +                  next_slice_ver_pos << 16 |
> +                  next_slice_hor_pos << 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen7_mfd_avc_phantom_slice_bsd_object(VADriverContextP ctx,
> +                                      VAPictureParameterBufferH264 *pic_param,
> +                                      struct gen7_mfd_context 
> +*gen7_mfd_context) {
> +    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
> +
> +    BEGIN_BCS_BATCH(batch, 6);
> +    OUT_BCS_BATCH(batch, MFD_AVC_BSD_OBJECT | (6 - 2));
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen7_mfd_avc_phantom_slice_first(VADriverContextP ctx,
> +                           VAPictureParameterBufferH264 *pic_param,
> +                           VASliceParameterBufferH264 *next_slice_param,
> +                           struct gen7_mfd_context *gen7_mfd_context) 
> +{
> +    gen7_mfd_avc_phantom_slice_state(ctx, pic_param, next_slice_param, gen7_mfd_context);
> +    gen7_mfd_avc_phantom_slice_bsd_object(ctx, pic_param, 
> +gen7_mfd_context); }
> +
> +static void
>   gen7_mfd_avc_slice_state(VADriverContextP ctx,
>                            VAPictureParameterBufferH264 *pic_param,
>                            VASliceParameterBufferH264 *slice_param, @@ 
> -842,6 +919,9 @@ gen7_mfd_avc_decode_picture(VADriverContextP ctx,
>           else
>               next_slice_group_param = (VASliceParameterBufferH264 
> *)decode_state->slice_params[j + 1]->buffer;
>   
> +        if (j == 0 && slice_param->first_mb_in_slice)
> +            gen7_mfd_avc_phantom_slice_first(ctx, pic_param, 
> + slice_param, gen7_mfd_context);
> +
>           for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
>               assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
>               assert((slice_param->slice_type == SLICE_TYPE_I) || diff 
> --git a/src/gen8_mfd.c b/src/gen8_mfd.c index d08dd43..b8e7af4 100644
> --- a/src/gen8_mfd.c
> +++ b/src/gen8_mfd.c
> @@ -575,6 +575,83 @@ gen8_mfd_avc_directmode_state(VADriverContextP ctx,
>   }
>   
>   static void
> +gen8_mfd_avc_phantom_slice_state(VADriverContextP ctx,
> +                                 VAPictureParameterBufferH264 *pic_param,
> +                                 VASliceParameterBufferH264 *next_slice_param,
> +                                 struct gen7_mfd_context 
> +*gen7_mfd_context) {
> +    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
> +    int width_in_mbs = pic_param->picture_width_in_mbs_minus1 + 1;
> +    int height_in_mbs = pic_param->picture_height_in_mbs_minus1 + 1; /* frame height */
> +    int slice_hor_pos, slice_ver_pos, slice_start_mb_num, next_slice_hor_pos, next_slice_ver_pos;
> +    int mbaff_picture = (!pic_param->pic_fields.bits.field_pic_flag &&
> +                         
> +pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
> +
> +    if (next_slice_param) {
> +        int first_mb_in_next_slice;
> +
> +        slice_hor_pos = 0;
> +        slice_ver_pos = 0;
> +        slice_start_mb_num = 0;
> +        first_mb_in_next_slice = next_slice_param->first_mb_in_slice << mbaff_picture;
> +        next_slice_hor_pos = first_mb_in_next_slice % width_in_mbs;
> +        next_slice_ver_pos = first_mb_in_next_slice / width_in_mbs;
> +    } else {
> +        slice_hor_pos = 0;
> +        slice_ver_pos = height_in_mbs;
> +        slice_start_mb_num = width_in_mbs * height_in_mbs / (1 + !!pic_param->pic_fields.bits.field_pic_flag);
> +        next_slice_hor_pos = 0;
> +        next_slice_ver_pos = 0;
> +    }
> +
> +    BEGIN_BCS_BATCH(batch, 11); /* FIXME: is it 10??? */
> +    OUT_BCS_BATCH(batch, MFX_AVC_SLICE_STATE | (11 - 2));
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch,
> +                  slice_ver_pos << 24 |
> +                  slice_hor_pos << 16 |
> +                  slice_start_mb_num << 0);
> +    OUT_BCS_BATCH(batch,
> +                  next_slice_ver_pos << 16 |
> +                  next_slice_hor_pos << 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen8_mfd_avc_phantom_slice_bsd_object(VADriverContextP ctx,
> +                                      VAPictureParameterBufferH264 *pic_param,
> +                                      struct gen7_mfd_context 
> +*gen7_mfd_context) {
> +    struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
> +
> +    BEGIN_BCS_BATCH(batch, 6);
> +    OUT_BCS_BATCH(batch, MFD_AVC_BSD_OBJECT | (6 - 2));
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    OUT_BCS_BATCH(batch, 0);
> +    ADVANCE_BCS_BATCH(batch);
> +}
> +
> +static void
> +gen8_mfd_avc_phantom_slice_first(VADriverContextP ctx,
> +                           VAPictureParameterBufferH264 *pic_param,
> +                           VASliceParameterBufferH264 *next_slice_param,
> +                           struct gen7_mfd_context *gen7_mfd_context) 
> +{
> +    gen8_mfd_avc_phantom_slice_state(ctx, pic_param, next_slice_param, gen7_mfd_context);
> +    gen8_mfd_avc_phantom_slice_bsd_object(ctx, pic_param, 
> +gen7_mfd_context); }
> +
> +static void
>   gen8_mfd_avc_slice_state(VADriverContextP ctx,
>                            VAPictureParameterBufferH264 *pic_param,
>                            VASliceParameterBufferH264 *slice_param, @@ 
> -908,6 +985,9 @@ gen8_mfd_avc_decode_picture(VADriverContextP ctx,
>           else
>               next_slice_group_param = (VASliceParameterBufferH264 
> *)decode_state->slice_params[j + 1]->buffer;
>   
> +        if (j == 0 && slice_param->first_mb_in_slice)
> +            gen8_mfd_avc_phantom_slice_first(ctx, pic_param, 
> + slice_param, gen7_mfd_context);
> +
>           for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) {
>               assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL);
>               assert((slice_param->slice_type == SLICE_TYPE_I) ||
> -- 1.7.9.5



More information about the Libva mailing list