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 <[email protected]> --- 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 _______________________________________________ Libva mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libva
