[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