[Libva] [PATCH] Make MPEG-2 QM state live until the next change from application.

Gwenole Beauchesne gb.devel at gmail.com
Tue Sep 13 05:14:52 PDT 2011


Hi,

This patch fixes MPEG-2 decoding when VAIQMatrixBufferMPEG2 is not submitted
for each frame. i.e. the quantization matrices shall be live until the next
change from the application.

Tested on CTG & SNB only with GStreamer.

I will push the patch to master if the IVB hunk is OK. It should since it's the
same as gen6 code. :)

Note: similar changes may be necessary for other codecs but I will submit them as
I test them on my system.

Regards,
Gwenole.
---
 src/gen6_mfd.c         |   48 ++++++++++++++++++++++++++++--------------------
 src/gen6_mfd.h         |    4 ++++
 src/gen7_mfd.c         |   48 ++++++++++++++++++++++++++++--------------------
 src/gen7_mfd.h         |    4 ++++
 src/i965_media_mpeg2.c |   44 +++++++++++++++++++++++++-------------------
 src/i965_media_mpeg2.h |    1 +
 6 files changed, 90 insertions(+), 59 deletions(-)

diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c
index 19368f1..c4c93f7 100644
--- a/src/gen6_mfd.c
+++ b/src/gen6_mfd.c
@@ -1253,42 +1253,50 @@ gen6_mfd_mpeg2_qm_state(VADriverContextP ctx,
                         struct gen6_mfd_context *gen6_mfd_context)
 {
     struct intel_batchbuffer *batch = gen6_mfd_context->base.batch;
-    VAIQMatrixBufferMPEG2 *iq_matrix;
-    int i;
+    VAIQMatrixBufferMPEG2 * const gen_iq_matrix = &gen6_mfd_context->iq_matrix.mpeg2;
+    int i, j;
 
-    if (!decode_state->iq_matrix || !decode_state->iq_matrix->buffer)
-        return;
+    /* Update internal QM state */
+    if (decode_state->iq_matrix && decode_state->iq_matrix->buffer) {
+        VAIQMatrixBufferMPEG2 * const iq_matrix =
+            (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
+
+        gen_iq_matrix->load_intra_quantiser_matrix =
+            iq_matrix->load_intra_quantiser_matrix;
+        if (iq_matrix->load_intra_quantiser_matrix) {
+            for (j = 0; j < 64; j++)
+                gen_iq_matrix->intra_quantiser_matrix[zigzag_direct[j]] =
+                    iq_matrix->intra_quantiser_matrix[j];
+        }
 
-    iq_matrix = (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
+        gen_iq_matrix->load_non_intra_quantiser_matrix =
+            iq_matrix->load_non_intra_quantiser_matrix;
+        if (iq_matrix->load_non_intra_quantiser_matrix) {
+            for (j = 0; j < 64; j++)
+                gen_iq_matrix->non_intra_quantiser_matrix[zigzag_direct[j]] =
+                    iq_matrix->non_intra_quantiser_matrix[j];
+        }
+    }
 
+    /* Commit QM state to HW */
     for (i = 0; i < 2; i++) {
-        int k, m;
         unsigned char *qm = NULL;
-        unsigned char qmx[64];
 
         if (i == 0) {
-            if (iq_matrix->load_intra_quantiser_matrix)
-                qm = iq_matrix->intra_quantiser_matrix;
+            if (gen_iq_matrix->load_intra_quantiser_matrix)
+                qm = gen_iq_matrix->intra_quantiser_matrix;
         } else {
-            if (iq_matrix->load_non_intra_quantiser_matrix)
-                qm = iq_matrix->non_intra_quantiser_matrix;
+            if (gen_iq_matrix->load_non_intra_quantiser_matrix)
+                qm = gen_iq_matrix->non_intra_quantiser_matrix;
         }
 
         if (!qm)
             continue;
 
-        /* Upload quantisation matrix in raster order. The mplayer vaapi
-         * patch passes quantisation matrix in zig-zag order to va library.
-         */
-        for (k = 0; k < 64; k++) {
-            m = zigzag_direct[k];
-            qmx[m] = qm[k];
-        }
-
         BEGIN_BCS_BATCH(batch, 18);
         OUT_BCS_BATCH(batch, MFX_MPEG2_QM_STATE | (18 - 2));
         OUT_BCS_BATCH(batch, i);
-        intel_batchbuffer_data(batch, qmx, 64);
+        intel_batchbuffer_data(batch, qm, 64);
         ADVANCE_BCS_BATCH(batch);
     }
 }
diff --git a/src/gen6_mfd.h b/src/gen6_mfd.h
index 31f7957..46bb0e4 100644
--- a/src/gen6_mfd.h
+++ b/src/gen6_mfd.h
@@ -65,6 +65,10 @@ struct gen6_mfd_context
 {
     struct hw_context base;
 
+    union {
+        VAIQMatrixBufferMPEG2 mpeg2;
+    } iq_matrix;
+
     struct {
         VASurfaceID surface_id;
         int frame_store_id;
diff --git a/src/gen7_mfd.c b/src/gen7_mfd.c
index 1188b84..0b6c55b 100644
--- a/src/gen7_mfd.c
+++ b/src/gen7_mfd.c
@@ -1207,28 +1207,44 @@ gen7_mfd_mpeg2_qm_state(VADriverContextP ctx,
                         struct decode_state *decode_state,
                         struct gen7_mfd_context *gen7_mfd_context)
 {
-    VAIQMatrixBufferMPEG2 *iq_matrix;
-    int i;
+    VAIQMatrixBufferMPEG2 * const gen_iq_matrix = &gen7_mfd_context->iq_matrix.mpeg2;
+    int i, j;
 
-    if (!decode_state->iq_matrix || !decode_state->iq_matrix->buffer)
-        return;
+    /* Update internal QM state */
+    if (decode_state->iq_matrix && decode_state->iq_matrix->buffer) {
+        VAIQMatrixBufferMPEG2 * const iq_matrix =
+            (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
+
+        gen_iq_matrix->load_intra_quantiser_matrix =
+            iq_matrix->load_intra_quantiser_matrix;
+        if (iq_matrix->load_intra_quantiser_matrix) {
+            for (j = 0; j < 64; j++)
+                gen_iq_matrix->intra_quantiser_matrix[zigzag_direct[j]] =
+                    iq_matrix->intra_quantiser_matrix[j];
+        }
 
-    iq_matrix = (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
+        gen_iq_matrix->load_non_intra_quantiser_matrix =
+            iq_matrix->load_non_intra_quantiser_matrix;
+        if (iq_matrix->load_non_intra_quantiser_matrix) {
+            for (j = 0; j < 64; j++)
+                gen_iq_matrix->non_intra_quantiser_matrix[zigzag_direct[j]] =
+                    iq_matrix->non_intra_quantiser_matrix[j];
+        }
+    }
 
+    /* Commit QM state to HW */
     for (i = 0; i < 2; i++) {
-        int k, m;
         unsigned char *qm = NULL;
-        unsigned char qmx[64];
         int qm_type;
 
         if (i == 0) {
-            if (iq_matrix->load_intra_quantiser_matrix) {
-                qm = iq_matrix->intra_quantiser_matrix;
+            if (gen_iq_matrix->load_intra_quantiser_matrix) {
+                qm = gen_iq_matrix->intra_quantiser_matrix;
                 qm_type = MFX_QM_MPEG_INTRA_QUANTIZER_MATRIX;
             }
         } else {
-            if (iq_matrix->load_non_intra_quantiser_matrix) {
-                qm = iq_matrix->non_intra_quantiser_matrix;
+            if (gen_iq_matrix->load_non_intra_quantiser_matrix) {
+                qm = gen_iq_matrix->non_intra_quantiser_matrix;
                 qm_type = MFX_QM_MPEG_NON_INTRA_QUANTIZER_MATRIX;
             }
         }
@@ -1236,15 +1252,7 @@ gen7_mfd_mpeg2_qm_state(VADriverContextP ctx,
         if (!qm)
             continue;
 
-        /* Upload quantisation matrix in raster order. The mplayer vaapi
-         * patch passes quantisation matrix in zig-zag order to va library.
-         */
-        for (k = 0; k < 64; k++) {
-            m = zigzag_direct[k];
-            qmx[m] = qm[k];
-        }
-
-        gen7_mfd_qm_state(ctx, qm_type, qmx, 64, gen7_mfd_context);
+        gen7_mfd_qm_state(ctx, qm_type, qm, 64, gen7_mfd_context);
     }
 }
 
diff --git a/src/gen7_mfd.h b/src/gen7_mfd.h
index af9cc54..088dbda 100644
--- a/src/gen7_mfd.h
+++ b/src/gen7_mfd.h
@@ -65,6 +65,10 @@ struct gen7_mfd_context
 {
     struct hw_context base;
 
+    union {
+        VAIQMatrixBufferMPEG2 mpeg2;
+    } iq_matrix;
+
     struct {
         VASurfaceID surface_id;
         int frame_store_id;
diff --git a/src/i965_media_mpeg2.c b/src/i965_media_mpeg2.c
index bc3e048..15edc5b 100644
--- a/src/i965_media_mpeg2.c
+++ b/src/i965_media_mpeg2.c
@@ -801,9 +801,9 @@ i965_media_mpeg2_upload_constants(VADriverContextP ctx,
                                   struct i965_media_context *media_context)
 {
     struct i965_mpeg2_context *i965_mpeg2_context = (struct i965_mpeg2_context *)media_context->private_context;
-    int i, j;
+    VAIQMatrixBufferMPEG2 * const gen_iq_matrix = &i965_mpeg2_context->iq_matrix;
+    int i;
     unsigned char *constant_buffer;
-    unsigned char *qmx;
     unsigned int *lib_reloc;
     int lib_reloc_offset = 0;
 
@@ -813,32 +813,38 @@ i965_media_mpeg2_upload_constants(VADriverContextP ctx,
 
     /* iq_matrix */
     if (decode_state->iq_matrix && decode_state->iq_matrix->buffer) {
-        VAIQMatrixBufferMPEG2 *iq_matrix = (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
-
-        /* Upload quantisation matrix in row-major order. The mplayer vaapi
-         * patch passes quantisation matrix in zig-zag order to va library.
-         * Do we need a flag in VAIQMatrixBufferMPEG2 to specify the order
-         * of the quantisation matrix?
-         */
-        qmx = constant_buffer;
+        VAIQMatrixBufferMPEG2 * const iq_matrix =
+            (VAIQMatrixBufferMPEG2 *)decode_state->iq_matrix->buffer;
+
+        gen_iq_matrix->load_intra_quantiser_matrix =
+            iq_matrix->load_intra_quantiser_matrix;
         if (iq_matrix->load_intra_quantiser_matrix) {
-            for (i = 0; i < 64; i++) {
-                j = zigzag_direct[i];
-                qmx[j] = iq_matrix->intra_quantiser_matrix[i];
-            }
+            for (i = 0; i < 64; i++)
+                gen_iq_matrix->intra_quantiser_matrix[zigzag_direct[i]] =
+                    iq_matrix->intra_quantiser_matrix[i];
         }
 
-        qmx = constant_buffer + 64;
+        gen_iq_matrix->load_non_intra_quantiser_matrix =
+            iq_matrix->load_non_intra_quantiser_matrix;
         if (iq_matrix->load_non_intra_quantiser_matrix) {
-            for (i = 0; i < 64; i++) {
-                j = zigzag_direct[i];
-                qmx[j] = iq_matrix->non_intra_quantiser_matrix[i];
-            }
+            for (i = 0; i < 64; i++)
+                gen_iq_matrix->non_intra_quantiser_matrix[zigzag_direct[i]] =
+                    iq_matrix->non_intra_quantiser_matrix[i];
         }
 
         /* no chroma quantisation matrices for 4:2:0 data */
     }
 
+    if (gen_iq_matrix->load_intra_quantiser_matrix) {
+        unsigned char * const qm = constant_buffer;
+        memcpy(qm, gen_iq_matrix->intra_quantiser_matrix, 64);
+    }
+
+    if (gen_iq_matrix->load_non_intra_quantiser_matrix) {
+        unsigned char * const qm = constant_buffer + 64;
+        memcpy(qm, gen_iq_matrix->non_intra_quantiser_matrix, 64);
+    }
+
     /* idct table */
     memcpy(constant_buffer + 128, idct_table, sizeof(idct_table));
 
diff --git a/src/i965_media_mpeg2.h b/src/i965_media_mpeg2.h
index 40d91f1..65e308c 100644
--- a/src/i965_media_mpeg2.h
+++ b/src/i965_media_mpeg2.h
@@ -43,6 +43,7 @@ struct i965_media_context;
 struct i965_mpeg2_context
 {
     struct i965_kernel vld_kernels[NUM_MPEG2_VLD_KERNELS];
+    VAIQMatrixBufferMPEG2 iq_matrix;
 };
 
 void i965_media_mpeg2_decode_init(VADriverContextP ctx, struct decode_state * decode_state, struct i965_media_context *media_context);
-- 
1.7.4.1



More information about the Libva mailing list