OSDN Git Service

implement intensity compensation for VC-1 decoding
authorcarpalis <30320745+carpalis@users.noreply.github.com>
Mon, 24 Jul 2017 11:21:16 +0000 (13:21 +0200)
committerXiang, Haihao <haihao.xiang@intel.com>
Fri, 28 Jul 2017 04:52:07 +0000 (12:52 +0800)
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.

src/gen75_mfd.c
src/gen7_mfd.c
src/gen7_mfd.h
src/gen8_mfd.c

index 926d3df..08855a0 100644 (file)
@@ -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,
@@ -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);
@@ -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;
+
+            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);
index 7c836a2..fe4d66d 100644 (file)
@@ -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,
@@ -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);
@@ -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;
+
+            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);
index aede374..d8938ab 100644 (file)
@@ -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;
index 5c70ff0..c93c26d 100644 (file)
@@ -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,
@@ -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);
@@ -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;
+
+            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);