Skip to content

Commit

Permalink
implement intensity compensation for VC-1 decoding
Browse files Browse the repository at this point in the history
Intensity compensation was not present for B-frames, but only for P-frames. When a P-frame flags intensity compensation for its forward reference frame, all subsequent B-frames that use this reference frame as well, need to do intensity compensation as well.
  • Loading branch information
carpalis authored and xhaihao committed Jul 28, 2017
1 parent f536934 commit 6702b01
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 18 deletions.
44 changes: 38 additions & 6 deletions src/gen75_mfd.c
Expand Up @@ -1518,6 +1518,9 @@ gen75_mfd_init_vc1_surface(VADriverContextP ctx,
}

gen7_vc1_surface->picture_type = pic_param->picture_fields.bits.picture_type;
gen7_vc1_surface->intensity_compensation = 0;
gen7_vc1_surface->luma_scale = 0;
gen7_vc1_surface->luma_shift = 0;

if (gen7_vc1_surface->dmv == NULL) {
gen7_vc1_surface->dmv = dri_bo_alloc(i965->intel.bufmgr,
Expand All @@ -1538,17 +1541,33 @@ gen75_mfd_vc1_decode_init(VADriverContextP ctx,
dri_bo *bo;
int width_in_mbs;
int picture_type;
int intensity_compensation;

assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
width_in_mbs = ALIGN(pic_param->coded_width, 16) / 16;
picture_type = pic_param->picture_fields.bits.picture_type;
intensity_compensation = (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation);

intel_update_vc1_frame_store_index(ctx,
decode_state,
pic_param,
gen7_mfd_context->reference_surface);

/* Forward reference picture */
obj_surface = decode_state->reference_objects[0];
if (pic_param->forward_reference_picture != VA_INVALID_ID &&
obj_surface &&
obj_surface->private_data) {
if (picture_type == 1 && intensity_compensation) { /* P picture */
struct gen7_vc1_surface *gen7_vc1_surface = obj_surface->private_data;

gen7_vc1_surface->intensity_compensation = intensity_compensation;
gen7_vc1_surface->luma_scale = pic_param->luma_scale;
gen7_vc1_surface->luma_shift = pic_param->luma_shift;
}
}

/* Current decoded picture */
obj_surface = decode_state->render_object;
i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
Expand Down Expand Up @@ -1915,24 +1934,37 @@ gen75_mfd_vc1_pred_pipe_state(VADriverContextP ctx,
{
struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
VAPictureParameterBufferVC1 *pic_param;
int intensitycomp_single;
int picture_type;
int intensitycomp_single_fwd = 0;
int luma_scale1 = 0;
int luma_shift1 = 0;

assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
intensitycomp_single = (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation);
picture_type = pic_param->picture_fields.bits.picture_type;

if (gen7_mfd_context->reference_surface[0].surface_id != VA_INVALID_ID) {
if (picture_type == 1 || picture_type == 2) { /* P/B picture */
struct gen7_vc1_surface *gen7_vc1_surface = gen7_mfd_context->reference_surface[0].obj_surface->private_data;

This comment has been minimized.

Copy link
@fritsch

fritsch Aug 26, 2017

Contributor

and here


intensitycomp_single_fwd = gen7_vc1_surface->intensity_compensation;
luma_scale1 = gen7_vc1_surface->luma_scale;
luma_shift1 = gen7_vc1_surface->luma_shift;
}
}

BEGIN_BCS_BATCH(batch, 6);
OUT_BCS_BATCH(batch, MFX_VC1_PRED_PIPE_STATE | (6 - 2));
OUT_BCS_BATCH(batch,
0 << 14 | /* FIXME: double ??? */
0 << 12 |
intensitycomp_single << 10 |
intensitycomp_single << 8 |
intensitycomp_single_fwd << 10 |
0 << 8 |
0 << 4 | /* FIXME: interlace mode */
0);
OUT_BCS_BATCH(batch,
pic_param->luma_shift << 16 |
pic_param->luma_scale << 0); /* FIXME: Luma Scaling */
luma_shift1 << 16 |
luma_scale1 << 0);
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, 0);
Expand Down
44 changes: 38 additions & 6 deletions src/gen7_mfd.c
Expand Up @@ -1253,6 +1253,9 @@ gen7_mfd_init_vc1_surface(VADriverContextP ctx,
}

gen7_vc1_surface->picture_type = pic_param->picture_fields.bits.picture_type;
gen7_vc1_surface->intensity_compensation = 0;
gen7_vc1_surface->luma_scale = 0;
gen7_vc1_surface->luma_shift = 0;

if (gen7_vc1_surface->dmv == NULL) {
gen7_vc1_surface->dmv = dri_bo_alloc(i965->intel.bufmgr,
Expand All @@ -1273,17 +1276,33 @@ gen7_mfd_vc1_decode_init(VADriverContextP ctx,
dri_bo *bo;
int width_in_mbs;
int picture_type;
int intensity_compensation;

assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
width_in_mbs = ALIGN(pic_param->coded_width, 16) / 16;
picture_type = pic_param->picture_fields.bits.picture_type;
intensity_compensation = (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation);

intel_update_vc1_frame_store_index(ctx,
decode_state,
pic_param,
gen7_mfd_context->reference_surface);

/* Forward reference picture */
obj_surface = decode_state->reference_objects[0];
if (pic_param->forward_reference_picture != VA_INVALID_ID &&
obj_surface &&
obj_surface->private_data) {
if (picture_type == 1 && intensity_compensation) { /* P picture */
struct gen7_vc1_surface *gen7_vc1_surface = obj_surface->private_data;

gen7_vc1_surface->intensity_compensation = intensity_compensation;
gen7_vc1_surface->luma_scale = pic_param->luma_scale;
gen7_vc1_surface->luma_shift = pic_param->luma_shift;
}
}

/* Current decoded picture */
obj_surface = decode_state->render_object;
i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
Expand Down Expand Up @@ -1650,24 +1669,37 @@ gen7_mfd_vc1_pred_pipe_state(VADriverContextP ctx,
{
struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
VAPictureParameterBufferVC1 *pic_param;
int intensitycomp_single;
int picture_type;
int intensitycomp_single_fwd = 0;
int luma_scale1 = 0;
int luma_shift1 = 0;

assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
intensitycomp_single = (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation);
picture_type = pic_param->picture_fields.bits.picture_type;

if (gen7_mfd_context->reference_surface[0].surface_id != VA_INVALID_ID) {
if (picture_type == 1 || picture_type == 2) { /* P/B picture */
struct gen7_vc1_surface *gen7_vc1_surface = gen7_mfd_context->reference_surface[0].obj_surface->private_data;

This comment has been minimized.

Copy link
@fritsch

fritsch Aug 26, 2017

Contributor

same here, please check gen7_vc1_surface for not being null


intensitycomp_single_fwd = gen7_vc1_surface->intensity_compensation;
luma_scale1 = gen7_vc1_surface->luma_scale;
luma_shift1 = gen7_vc1_surface->luma_shift;
}
}

BEGIN_BCS_BATCH(batch, 6);
OUT_BCS_BATCH(batch, MFX_VC1_PRED_PIPE_STATE | (6 - 2));
OUT_BCS_BATCH(batch,
0 << 14 | /* FIXME: double ??? */
0 << 12 |
intensitycomp_single << 10 |
intensitycomp_single << 8 |
intensitycomp_single_fwd << 10 |
0 << 8 |
0 << 4 | /* FIXME: interlace mode */
0);
OUT_BCS_BATCH(batch,
pic_param->luma_shift << 16 |
pic_param->luma_scale << 0); /* FIXME: Luma Scaling */
luma_shift1 << 16 |
luma_scale1 << 0);
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, 0);
Expand Down
3 changes: 3 additions & 0 deletions src/gen7_mfd.h
Expand Up @@ -63,6 +63,9 @@
struct gen7_vc1_surface {
dri_bo *dmv;
int picture_type;
int intensity_compensation;
int luma_scale;
int luma_shift;
};

struct hw_context;
Expand Down
44 changes: 38 additions & 6 deletions src/gen8_mfd.c
Expand Up @@ -1297,6 +1297,9 @@ gen8_mfd_init_vc1_surface(VADriverContextP ctx,
}

gen7_vc1_surface->picture_type = pic_param->picture_fields.bits.picture_type;
gen7_vc1_surface->intensity_compensation = 0;
gen7_vc1_surface->luma_scale = 0;
gen7_vc1_surface->luma_shift = 0;

if (gen7_vc1_surface->dmv == NULL) {
gen7_vc1_surface->dmv = dri_bo_alloc(i965->intel.bufmgr,
Expand All @@ -1317,17 +1320,33 @@ gen8_mfd_vc1_decode_init(VADriverContextP ctx,
dri_bo *bo;
int width_in_mbs;
int picture_type;
int intensity_compensation;

assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
width_in_mbs = ALIGN(pic_param->coded_width, 16) / 16;
picture_type = pic_param->picture_fields.bits.picture_type;
intensity_compensation = (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation);

intel_update_vc1_frame_store_index(ctx,
decode_state,
pic_param,
gen7_mfd_context->reference_surface);

/* Forward reference picture */
obj_surface = decode_state->reference_objects[0];
if (pic_param->forward_reference_picture != VA_INVALID_ID &&
obj_surface &&
obj_surface->private_data) {
if (picture_type == 1 && intensity_compensation) { /* P picture */
struct gen7_vc1_surface *gen7_vc1_surface = obj_surface->private_data;

gen7_vc1_surface->intensity_compensation = intensity_compensation;
gen7_vc1_surface->luma_scale = pic_param->luma_scale;
gen7_vc1_surface->luma_shift = pic_param->luma_shift;
}
}

/* Current decoded picture */
obj_surface = decode_state->render_object;
i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
Expand Down Expand Up @@ -1694,24 +1713,37 @@ gen8_mfd_vc1_pred_pipe_state(VADriverContextP ctx,
{
struct intel_batchbuffer *batch = gen7_mfd_context->base.batch;
VAPictureParameterBufferVC1 *pic_param;
int intensitycomp_single;
int picture_type;
int intensitycomp_single_fwd = 0;
int luma_scale1 = 0;
int luma_shift1 = 0;

assert(decode_state->pic_param && decode_state->pic_param->buffer);
pic_param = (VAPictureParameterBufferVC1 *)decode_state->pic_param->buffer;
intensitycomp_single = (pic_param->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation);
picture_type = pic_param->picture_fields.bits.picture_type;

if (gen7_mfd_context->reference_surface[0].surface_id != VA_INVALID_ID) {
if (picture_type == 1 || picture_type == 2) { /* P/B picture */
struct gen7_vc1_surface *gen7_vc1_surface = gen7_mfd_context->reference_surface[0].obj_surface->private_data;

This comment has been minimized.

Copy link
@fritsch

fritsch Aug 26, 2017

Contributor

We get a crash when using kodi, when resuming - it seems the gen7_vc1_surface is null, here is a crashlog: http://sprunge.us/HHbE

This comment has been minimized.

Copy link
@xhaihao

xhaihao Aug 30, 2017

Contributor

It is weird because the private_data is assigned when decoding a frame to the corresponding surface, so the gen7_vc1_surface shouldn't be null here. Did you see any artifact after applying #260?

This comment has been minimized.

Copy link
@MilhouseVH

MilhouseVH Aug 30, 2017

Hi @xhaihao. I'm the person that found the crashes when testing a LibreELEC (Kodi) build I created with #234 on top of intel-vaapi-driver 1.8.3.

Unfortunately I was only testing on behalf of a user that complained of the artifacts (see forum thread), and I don't see the artifacts myself (or I've simply not noticed them), nor do I see them with #260. The only difference with #260, of course, is that the driver no longer crashes..

This comment has been minimized.

Copy link
@xhaihao

xhaihao Sep 1, 2017

Contributor

@MilhouseVH Thanks for the info.


intensitycomp_single_fwd = gen7_vc1_surface->intensity_compensation;
luma_scale1 = gen7_vc1_surface->luma_scale;
luma_shift1 = gen7_vc1_surface->luma_shift;
}
}

BEGIN_BCS_BATCH(batch, 6);
OUT_BCS_BATCH(batch, MFX_VC1_PRED_PIPE_STATE | (6 - 2));
OUT_BCS_BATCH(batch,
0 << 14 | /* FIXME: double ??? */
0 << 12 |
intensitycomp_single << 10 |
intensitycomp_single << 8 |
intensitycomp_single_fwd << 10 |
0 << 8 |
0 << 4 | /* FIXME: interlace mode */
0);
OUT_BCS_BATCH(batch,
pic_param->luma_shift << 16 |
pic_param->luma_scale << 0); /* FIXME: Luma Scaling */
luma_shift1 << 16 |
luma_scale1 << 0);
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, 0);
OUT_BCS_BATCH(batch, 0);
Expand Down

0 comments on commit 6702b01

Please sign in to comment.