#include <pipe/p_video_state.h>
#include "vl_vlc.h"
+#include "vl_zscan.h"
#include "vl_mpeg12_bitstream.h"
/* take num bits from the high part of bit_buf and zero extend them */
{ 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}
};
-/* original (non-patched) scan tables */
-static const uint8_t mpeg2_scan_norm_orig[64] =
-{
- /* Zig-Zag scan pattern */
- 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
-};
-
-static const uint8_t mpeg2_scan_alt_orig[64] =
-{
- /* Alternate scan pattern */
- 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 const int non_linear_quantizer_scale[] = {
0, 1, 2, 3, 4, 5, 6, 7,
8, 10, 12, 14, 16, 18, 20, 22,
static inline void
get_intra_block_B14(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture,
- int quantizer_scale, short *dest)
+ const int scan[64], int quantizer_scale, short *dest)
{
int i, j, val;
- const uint8_t *scan;
uint8_t *quant_matrix = picture->intra_quantizer_matrix;
int mismatch;
const DCTtab *tab;
- if (!picture->alternate_scan) {
- scan = mpeg2_scan_norm_orig;
- } else {
- scan = mpeg2_scan_alt_orig;
- }
-
i = 0;
mismatch = ~dest[0];
val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
mismatch ^= val;
bs->vlc.buf <<= 1;
val = (vl_vlc_sbits(&bs->vlc, 12) * quantizer_scale * quant_matrix[j]) / 16;
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
mismatch ^= val;
vl_vlc_dumpbits(&bs->vlc, 12);
static inline void
get_intra_block_B15(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture,
- int quantizer_scale, short *dest)
+ const int scan[64], int quantizer_scale, short *dest)
{
int i, j, val;
- const uint8_t *scan;
uint8_t *quant_matrix = picture->intra_quantizer_matrix;
int mismatch;
const DCTtab * tab;
- if (!picture->alternate_scan) {
- scan = mpeg2_scan_norm_orig;
- } else {
- scan = mpeg2_scan_alt_orig;
- }
-
i = 0;
mismatch = ~dest[0];
val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
mismatch ^= val;
bs->vlc.buf <<= 1;
val = (vl_vlc_sbits(&bs->vlc, 12) * quantizer_scale * quant_matrix[j]) / 16;
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
mismatch ^= val;
vl_vlc_dumpbits(&bs->vlc, 12);
static inline void
get_non_intra_block(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture,
- int quantizer_scale, short *dest)
+ const int scan[64], int quantizer_scale, short *dest)
{
int i, j, val;
- const uint8_t *scan;
uint8_t *quant_matrix = picture->non_intra_quantizer_matrix;
int mismatch;
const DCTtab *tab;
i = -1;
mismatch = 1;
- if (!picture->alternate_scan) {
- scan = mpeg2_scan_norm_orig;
- } else {
- scan = mpeg2_scan_alt_orig;
- }
-
vl_vlc_needbits(&bs->vlc);
if (bs->vlc.buf >= 0x28000000) {
tab = DCT_B14DC_5 + (vl_vlc_ubits(&bs->vlc, 5) - 5);
val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
mismatch ^= val;
bs->vlc.buf <<= 1;
val = (val * quantizer_scale * quant_matrix[j]) / 32;
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
mismatch ^= val;
vl_vlc_dumpbits(&bs->vlc, 12);
static inline void
get_mpeg1_intra_block(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture,
- int quantizer_scale, short *dest)
+ const int scan[64], int quantizer_scale, short *dest)
{
int i, j, val;
- const uint8_t *scan;
uint8_t *quant_matrix = picture->intra_quantizer_matrix;
const DCTtab * tab;
i = 0;
- if (!picture->alternate_scan) {
- scan = mpeg2_scan_norm_orig;
- } else {
- scan = mpeg2_scan_alt_orig;
- }
-
vl_vlc_needbits(&bs->vlc);
while (1) {
val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
bs->vlc.buf <<= 1;
vl_vlc_needbits(&bs->vlc);
val = (val + ~SBITS (val, 1)) | 1;
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
vl_vlc_dumpbits(&bs->vlc, 8);
vl_vlc_needbits(&bs->vlc);
static inline void
get_mpeg1_non_intra_block(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture,
- int quantizer_scale, short *dest)
+ const int scan[64], int quantizer_scale, short *dest)
{
int i, j, val;
- const uint8_t * scan;
uint8_t *quant_matrix = picture->non_intra_quantizer_matrix;
const DCTtab * tab;
i = -1;
- if (!picture->alternate_scan) {
- scan = mpeg2_scan_norm_orig;
- } else {
- scan = mpeg2_scan_alt_orig;
- }
-
vl_vlc_needbits(&bs->vlc);
if (bs->vlc.buf >= 0x28000000) {
tab = DCT_B14DC_5 + (vl_vlc_ubits(&bs->vlc, 5) - 5);
val = (val ^ vl_vlc_sbits(&bs->vlc, 1)) - vl_vlc_sbits(&bs->vlc, 1);
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
bs->vlc.buf <<= 1;
vl_vlc_needbits(&bs->vlc);
val = (val + ~SBITS (val, 1)) | 1;
SATURATE (val);
- dest[j] = val;
+ dest[i] = val;
vl_vlc_dumpbits(&bs->vlc, 8);
vl_vlc_needbits(&bs->vlc);
}
static inline void
-slice_intra_DCT(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture, int cc, unsigned x, unsigned y,
- enum pipe_mpeg12_dct_type coding, int quantizer_scale, int dc_dct_pred[3])
+slice_intra_DCT(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture, const int scan[64], int cc,
+ unsigned x, unsigned y, enum pipe_mpeg12_dct_type coding, int quantizer_scale, int dc_dct_pred[3])
{
short *dest = bs->ycbcr_buffer[cc];
dest[0] = dc_dct_pred[cc] << (3 - picture->intra_dc_precision);
if (picture->mpeg1) {
if (picture->picture_coding_type != D_TYPE)
- get_mpeg1_intra_block(bs, picture, quantizer_scale, dest);
+ get_mpeg1_intra_block(bs, picture, scan, quantizer_scale, dest);
} else if (picture->intra_vlc_format)
- get_intra_block_B15(bs, picture, quantizer_scale, dest);
+ get_intra_block_B15(bs, picture, scan, quantizer_scale, dest);
else
- get_intra_block_B14(bs, picture, quantizer_scale, dest);
+ get_intra_block_B14(bs, picture, scan, quantizer_scale, dest);
bs->num_ycbcr_blocks[cc]++;
bs->ycbcr_stream[cc]++;
}
static inline void
-slice_non_intra_DCT(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture, int cc,
+slice_non_intra_DCT(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc * picture, const int scan[64], int cc,
unsigned x, unsigned y, int quantizer_scale, enum pipe_mpeg12_dct_type coding)
{
short *dest = bs->ycbcr_buffer[cc];
memset(dest, 0, sizeof(int16_t) * 64);
if (picture->mpeg1)
- get_mpeg1_non_intra_block(bs, picture, quantizer_scale, dest);
+ get_mpeg1_non_intra_block(bs, picture, scan, quantizer_scale, dest);
else
- get_non_intra_block(bs, picture, quantizer_scale, dest);
+ get_non_intra_block(bs, picture, scan, quantizer_scale, dest);
bs->num_ycbcr_blocks[cc]++;
bs->ycbcr_stream[cc]++;
}
static inline bool
-decode_slice(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc *picture)
+decode_slice(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc *picture, const int scan[64])
{
struct pipe_motionvector mv_fwd, mv_bwd;
enum pipe_mpeg12_dct_type dct_type;
mv_bwd.top.weight = mv_bwd.bottom.weight = PIPE_VIDEO_MV_WEIGHT_MIN;
// unravaled loop of 6 block(i) calls in macroblock()
- slice_intra_DCT(bs, picture, 0, x*2+0, y*2+0, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 0, x*2+1, y*2+0, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 0, x*2+0, y*2+1, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 0, x*2+1, y*2+1, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 1, x, y, dct_type, quantizer_scale, dc_dct_pred);
- slice_intra_DCT(bs, picture, 2, x, y, dct_type, quantizer_scale, dc_dct_pred);
+ slice_intra_DCT(bs, picture, scan, 0, x*2+0, y*2+0, dct_type, quantizer_scale, dc_dct_pred);
+ slice_intra_DCT(bs, picture, scan, 0, x*2+1, y*2+0, dct_type, quantizer_scale, dc_dct_pred);
+ slice_intra_DCT(bs, picture, scan, 0, x*2+0, y*2+1, dct_type, quantizer_scale, dc_dct_pred);
+ slice_intra_DCT(bs, picture, scan, 0, x*2+1, y*2+1, dct_type, quantizer_scale, dc_dct_pred);
+ slice_intra_DCT(bs, picture, scan, 1, x, y, dct_type, quantizer_scale, dc_dct_pred);
+ slice_intra_DCT(bs, picture, scan, 2, x, y, dct_type, quantizer_scale, dc_dct_pred);
if (picture->picture_coding_type == D_TYPE) {
vl_vlc_needbits(&bs->vlc);
// TODO optimize not fully used for idct accel only mc.
if (coded_block_pattern & 0x20)
- slice_non_intra_DCT(bs, picture, 0, x*2+0, y*2+0, quantizer_scale, dct_type); // cc0 luma 0
+ slice_non_intra_DCT(bs, picture, scan, 0, x*2+0, y*2+0, quantizer_scale, dct_type); // cc0 luma 0
if (coded_block_pattern & 0x10)
- slice_non_intra_DCT(bs, picture, 0, x*2+1, y*2+0, quantizer_scale, dct_type); // cc0 luma 1
+ slice_non_intra_DCT(bs, picture, scan, 0, x*2+1, y*2+0, quantizer_scale, dct_type); // cc0 luma 1
if (coded_block_pattern & 0x08)
- slice_non_intra_DCT(bs, picture, 0, x*2+0, y*2+1, quantizer_scale, dct_type); // cc0 luma 2
+ slice_non_intra_DCT(bs, picture, scan, 0, x*2+0, y*2+1, quantizer_scale, dct_type); // cc0 luma 2
if (coded_block_pattern & 0x04)
- slice_non_intra_DCT(bs, picture, 0, x*2+1, y*2+1, quantizer_scale, dct_type); // cc0 luma 3
+ slice_non_intra_DCT(bs, picture, scan, 0, x*2+1, y*2+1, quantizer_scale, dct_type); // cc0 luma 3
if (coded_block_pattern & 0x2)
- slice_non_intra_DCT(bs, picture, 1, x, y, quantizer_scale, dct_type); // cc1 croma
+ slice_non_intra_DCT(bs, picture, scan, 1, x, y, quantizer_scale, dct_type); // cc1 croma
if (coded_block_pattern & 0x1)
- slice_non_intra_DCT(bs, picture, 2, x, y, quantizer_scale, dct_type); // cc2 croma
+ slice_non_intra_DCT(bs, picture, scan, 2, x, y, quantizer_scale, dct_type); // cc2 croma
}
dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const void *buffer,
struct pipe_mpeg12_picture_desc *picture, unsigned num_ycbcr_blocks[3])
{
+ const int *scan;
+
assert(bs);
assert(num_ycbcr_blocks);
assert(buffer && num_bytes);
vl_vlc_init(&bs->vlc, buffer, num_bytes);
- while(decode_slice(bs, picture));
+ scan = picture->alternate_scan ? vl_zscan_alternate : vl_zscan_normal;
+
+ while(decode_slice(bs, picture, scan));
}
VS_O_VTEX
};
+const int vl_zscan_linear[] =
+{
+ /* Linear scan pattern */
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9,10,11,12,13,14,15,
+ 16,17,18,19,20,21,22,23,
+ 24,25,26,27,28,29,30,31,
+ 32,33,34,35,36,37,38,39,
+ 40,41,42,43,44,45,46,47,
+ 48,49,50,51,52,53,54,55,
+ 56,57,58,59,60,61,62,63
+};
+
+const int vl_zscan_normal[] =
+{
+ /* Zig-Zag scan pattern */
+ 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
+};
+
+const int vl_zscan_alternate[] =
+{
+ /* Alternate scan pattern */
+ 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 void *
create_vert_shader(struct vl_zscan *zscan)
{
}
struct pipe_sampler_view *
-vl_zscan_linear(struct pipe_context *pipe, unsigned blocks_per_line)
+vl_zscan_layout(struct pipe_context *pipe, const int layout[64], unsigned blocks_per_line)
{
const unsigned total_size = blocks_per_line * BLOCK_WIDTH * BLOCK_HEIGHT;
+ int patched_layout[64];
+
struct pipe_resource res_tmpl, *res;
struct pipe_sampler_view sv_tmpl, *sv;
struct pipe_transfer *buf_transfer;
1
};
- assert(pipe && blocks_per_line);
+ assert(pipe && layout && blocks_per_line);
+
+ for (i = 0; i < 64; ++i)
+ patched_layout[layout[i]] = i;
memset(&res_tmpl, 0, sizeof(res_tmpl));
res_tmpl.target = PIPE_TEXTURE_2D;
for (i = 0; i < blocks_per_line; ++i)
for (y = 0; y < BLOCK_HEIGHT; ++y)
for (x = 0; x < BLOCK_WIDTH; ++x) {
- float addr = x + y * BLOCK_WIDTH +
+ float addr = patched_layout[x + y * BLOCK_WIDTH] +
i * BLOCK_WIDTH * BLOCK_HEIGHT;
addr /= total_size;
cleanup_state(zscan);
}
-void
-vl_zscan_set_layout(struct vl_zscan *zscan, struct pipe_sampler_view *layout)
-{
- assert(zscan);
- assert(layout);
-
- pipe_sampler_view_reference(&zscan->scan, layout);
-}
-
#if 0
// TODO
void
buffer->zscan = zscan;
pipe_sampler_view_reference(&buffer->src, src);
- pipe_sampler_view_reference(&buffer->scan, zscan->scan);
- pipe_sampler_view_reference(&buffer->quant, zscan->quant);
buffer->viewport.scale[0] = dst->width;
buffer->viewport.scale[1] = dst->height;
assert(buffer);
pipe_sampler_view_reference(&buffer->src, NULL);
- pipe_sampler_view_reference(&buffer->scan, NULL);
+ pipe_sampler_view_reference(&buffer->layout, NULL);
pipe_sampler_view_reference(&buffer->quant, NULL);
pipe_surface_reference(&buffer->fb_state.cbufs[0], NULL);
}
+void
+vl_zscan_set_layout(struct vl_zscan_buffer *buffer, struct pipe_sampler_view *layout)
+{
+ assert(buffer);
+ assert(layout);
+
+ pipe_sampler_view_reference(&buffer->layout, layout);
+}
+
void
vl_zscan_render(struct vl_zscan_buffer *buffer, unsigned num_instances)
{