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

lizhong zhong.li at intel.com
Wed Aug 6 22:46:20 PDT 2014


On 08/07/2014 01:17 PM, Xiang, Haihao wrote:
>> 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;
>> +    }
>
> next_slice_param is always non-NULL in this case, could you simplify the
> above if-else statement ?
>
> or could you factor out the code for phantom slice for SNB+ ?
Thanks for your suggestion. I'll add common functions used for SNB+.
>
>> +
>> +    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) ||
>
>
>



More information about the Libva mailing list