[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