Am 23.06.2013 18:59, schrieb Ilia Mirkin:
Signed-off-by: Ilia Mirkin <imir...@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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to