[Libva] [PATCH] Make MPEG-2 QM state live until the next change from application.
Xiang, Haihao
haihao.xiang at intel.com
Tue Sep 13 19:02:17 PDT 2011
It is ok for me.
Thanks
Haihao
> 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
>
> _______________________________________________
> Libva mailing list
> Libva at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/libva
More information about the Libva
mailing list