[Mesa-dev] [PATCH] vl/mpeg12: implement inverse scan/quantization steps
Christian König
deathsimple at vodafone.de
Mon Jun 24 01:48:23 PDT 2013
Am 23.06.2013 18:59, schrieb Ilia Mirkin:
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
>
> These changes make MPEG2 I-frames generate the correct macroblock data (as
> compared to mplayer via xvmc). Other MPEG2 frames are still misparsed, and
> MPEG1 I-frames have some errors (but largely match up).
NAK, zscan and mismatch handling are handled in vl/vl_zscan.c.
Please use/fix that one instead of adding another implementation.
Christian.
> src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c | 84 ++++++++++++++++++++++----
> 1 file changed, 73 insertions(+), 11 deletions(-)
>
> diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
> index b0fb1bb..cd3647d 100644
> --- a/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
> +++ b/src/gallium/auxiliary/vl/vl_mpeg12_bitstream.c
> @@ -520,6 +520,30 @@ static const unsigned quant_scale[2][32] = {
> 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, 104, 112 }
> };
>
> +/* Inverses of Figures 7-2 and 7-3 */
> +static const uint8_t scans[2][64] = {
> + {
> + 0, 1, 8,16, 9, 2, 3,10,
> + 17,24,32,25,18,11, 4, 5,
> + 12,19,26,33,40,48,41,34,
> + 27,20,13, 6, 7,14,21,28,
> + 35,42,49,56,57,50,43,36,
> + 29,22,15,23,30,37,44,51,
> + 58,59,52,45,38,31,39,46,
> + 53,60,61,54,47,55,62,63
> + },
> + {
> + 0, 8,16,24, 1, 9, 2,10,
> + 17,25,32,40,48,56,57,49,
> + 41,33,26,18, 3,11, 4,12,
> + 19,27,34,42,50,58,35,43,
> + 51,59,20,28, 5,13, 6,14,
> + 21,29,36,44,52,60,37,45,
> + 53,61,22,30, 7,15,23,31,
> + 38,46,54,62,39,47,55,63
> + }
> +};
> +
> static struct vl_vlc_entry tbl_B1[1 << 11];
> static struct vl_vlc_entry tbl_B2[1 << 2];
> static struct vl_vlc_entry tbl_B3[1 << 6];
> @@ -706,6 +730,13 @@ reset_predictor(struct vl_mpg12_bs *bs) {
> bs->pred_dc[0] = bs->pred_dc[1] = bs->pred_dc[2] = 0;
> }
>
> +static INLINE int16_t
> +sign(int16_t val)
> +{
> + if (!val) return 0;
> + return (val < 0) ? -1 : 1;
> +}
> +
> static INLINE void
> decode_dct(struct vl_mpg12_bs *bs, struct pipe_mpeg12_macroblock *mb, int scale)
> {
> @@ -717,8 +748,11 @@ decode_dct(struct vl_mpg12_bs *bs, struct pipe_mpeg12_macroblock *mb, int scale)
> bool intra = mb->macroblock_type & PIPE_MPEG12_MB_TYPE_INTRA;
> const struct dct_coeff *table = intra ? bs->intra_dct_tbl : tbl_B14_AC;
> const struct dct_coeff *entry;
> - int i, cbp, blk = 0;
> + int i, j, cbp, blk = 0;
> short *dst = mb->blocks;
> + const uint8_t *scan = &scans[bs->desc->alternate_scan][0];
> + const uint8_t *quant_matrix = intra ? bs->desc->intra_matrix : bs->desc->non_intra_matrix;
> + int sums[6] = {0};
>
> vl_vlc_fillbits(&bs->vlc);
> mb->coded_block_pattern = cbp = intra ? 0x3F : vl_vlc_get_vlclbf(&bs->vlc, tbl_B9, 9);
> @@ -757,8 +791,9 @@ entry:
> bs->pred_dc[cc] += dct_diff;
> }
>
> - dst[0] = bs->pred_dc[cc];
> i = 0;
> + j = scan[i];
> + dst[j] = bs->pred_dc[cc];
>
> } else {
> entry = tbl_B14_DC + vl_vlc_peekbits(&bs->vlc, 17);
> @@ -771,32 +806,59 @@ entry:
> i += vl_vlc_get_uimsbf(&bs->vlc, 6) + 1;
> if (i > 64)
> break;
> + j = scan[i];
>
> - dst[i] = vl_vlc_get_simsbf(&bs->vlc, 8);
> - if (dst[i] == -128)
> - dst[i] = vl_vlc_get_uimsbf(&bs->vlc, 8) - 256;
> - else if (dst[i] == 0)
> - dst[i] = vl_vlc_get_uimsbf(&bs->vlc, 8);
> -
> - dst[i] *= scale;
> + dst[j] = vl_vlc_get_simsbf(&bs->vlc, 8);
> + if (dst[j] == -128)
> + dst[j] = vl_vlc_get_uimsbf(&bs->vlc, 8) - 256;
> + else if (dst[j] == 0)
> + dst[j] = vl_vlc_get_uimsbf(&bs->vlc, 8);
> } else if (entry->run == dct_Escape) {
> i += vl_vlc_get_uimsbf(&bs->vlc, 6) + 1;
> if (i > 64)
> break;
>
> - dst[i] = vl_vlc_get_simsbf(&bs->vlc, 12) * scale;
> + j = scan[i];
> + dst[j] = vl_vlc_get_simsbf(&bs->vlc, 12);
>
> } else {
> i += entry->run;
> if (i > 64)
> break;
>
> - dst[i] = entry->level * scale;
> + j = scan[i];
> + dst[j] = entry->level;
> + }
> +
> + if (intra && !j) {
> + dst[j] = dst[j] << (3 - bs->desc->intra_dc_precision);
> + } else {
> + dst[j] = (2 * dst[j] + (intra ? 0 : sign(dst[j]))) * quant_matrix[j] * scale / 32;
> + if (bs->decoder->profile == PIPE_VIDEO_PROFILE_MPEG1 && dst[j])
> + dst[j] = (dst[j] - 1) | 1;
> }
> + if (dst[j] > 2047)
> + dst[j] = 2047;
> + else if (dst[j] < -2048)
> + dst[j] = -2048;
> +
> + sums[blk] += dst[j];
>
> vl_vlc_fillbits(&bs->vlc);
> entry = table + vl_vlc_peekbits(&bs->vlc, 17);
> }
> +
> + if (bs->decoder->profile != PIPE_VIDEO_PROFILE_MPEG1) {
> + dst = mb->blocks;
> + for (i = 0; i < blk; i++, dst += 64) {
> + if ((sums[i] & 1) == 0) {
> + if (dst[63] & 1)
> + dst[63] -= 1;
> + else
> + dst[63] += 1;
> + }
> + }
> + }
> }
>
> static INLINE void
More information about the mesa-dev
mailing list