mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-17 22:10:21 +01:00
g3dvl: Rewrite the mpeg 1&2 bitstream parser
Based on work of Maarten Lankhorst this time. Signed-off-by: Christian König <deathsimple@vodafone.de> Reviewed-by: Younes Manton <younes.m@gmail.com>
This commit is contained in:
parent
31096e13f8
commit
9765dede75
5 changed files with 1034 additions and 1851 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -30,32 +30,25 @@
|
|||
|
||||
#include "vl_defines.h"
|
||||
#include "vl_vlc.h"
|
||||
#include "vl_vertex_buffers.h"
|
||||
|
||||
struct vl_mpg12_bs
|
||||
{
|
||||
unsigned width, height;
|
||||
struct pipe_video_decoder *decoder;
|
||||
|
||||
struct pipe_mpeg12_picture_desc desc;
|
||||
struct dct_coeff *intra_dct_tbl;
|
||||
|
||||
struct vl_vlc vlc;
|
||||
|
||||
unsigned block_num;
|
||||
unsigned *num_ycbcr_blocks;
|
||||
|
||||
struct vl_ycbcr_block *ycbcr_stream[VL_MAX_PLANES];
|
||||
short *ycbcr_buffer;
|
||||
|
||||
struct vl_motionvector *mv_stream[VL_MAX_REF_FRAMES];
|
||||
short pred_dc[3];
|
||||
};
|
||||
|
||||
void
|
||||
vl_mpg12_bs_init(struct vl_mpg12_bs *bs, unsigned width, unsigned height);
|
||||
vl_mpg12_bs_init(struct vl_mpg12_bs *bs, struct pipe_video_decoder *decoder);
|
||||
|
||||
void
|
||||
vl_mpg12_bs_set_buffers(struct vl_mpg12_bs *bs, struct vl_ycbcr_block *ycbcr_stream[VL_MAX_PLANES],
|
||||
short *ycbcr_buffer, struct vl_motionvector *mv_stream[VL_MAX_REF_FRAMES]);
|
||||
vl_mpg12_bs_set_picture_desc(struct vl_mpg12_bs *bs, struct pipe_mpeg12_picture_desc *picture);
|
||||
|
||||
void
|
||||
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]);
|
||||
vl_mpg12_bs_decode(struct vl_mpg12_bs *bs, unsigned num_bytes, const uint8_t *buffer);
|
||||
|
||||
#endif /* vl_mpeg12_bitstream_h */
|
||||
|
|
|
|||
|
|
@ -450,9 +450,7 @@ vl_mpeg12_create_buffer(struct pipe_video_decoder *decoder)
|
|||
goto error_zscan;
|
||||
|
||||
if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
|
||||
vl_mpg12_bs_init(&buffer->bs,
|
||||
dec->base.width / MACROBLOCK_WIDTH,
|
||||
dec->base.height / MACROBLOCK_HEIGHT);
|
||||
vl_mpg12_bs_init(&buffer->bs, decoder);
|
||||
|
||||
return buffer;
|
||||
|
||||
|
|
@ -614,7 +612,7 @@ vl_mpeg12_begin_frame(struct pipe_video_decoder *decoder)
|
|||
buf->mv_stream[i] = vl_vb_get_mv_stream(&buf->vertex_stream, i);
|
||||
|
||||
if (dec->base.entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
|
||||
vl_mpg12_bs_set_buffers(&buf->bs, buf->ycbcr_stream, buf->texels, buf->mv_stream);
|
||||
vl_mpg12_bs_set_picture_desc(&buf->bs, &dec->picture_desc);
|
||||
|
||||
} else {
|
||||
|
||||
|
|
@ -708,7 +706,7 @@ vl_mpeg12_decode_bitstream(struct pipe_video_decoder *decoder,
|
|||
vl_zscan_set_layout(&buf->zscan[i], dec->picture_desc.alternate_scan ?
|
||||
dec->zscan_alternate : dec->zscan_normal);
|
||||
|
||||
vl_mpg12_bs_decode(&buf->bs, num_bytes, data, &dec->picture_desc, buf->num_ycbcr_blocks);
|
||||
vl_mpg12_bs_decode(&buf->bs, num_bytes, data);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -25,116 +25,147 @@
|
|||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* This file is based uppon slice_xvmc.c and vlc.h from the xine project,
|
||||
* which in turn is based on mpeg2dec. The following is the original copyright:
|
||||
*
|
||||
* Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
|
||||
* Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
|
||||
*
|
||||
* This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
|
||||
* See http://libmpeg2.sourceforge.net/ for updates.
|
||||
*
|
||||
* mpeg2dec is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpeg2dec is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef vl_vlc_h
|
||||
#define vl_vlc_h
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include <pipe/p_compiler.h>
|
||||
|
||||
#include <util/u_math.h>
|
||||
|
||||
struct vl_vlc
|
||||
{
|
||||
uint32_t buf; /* current 32 bit working set of buffer */
|
||||
int bits; /* used bits in working set */
|
||||
const uint8_t *ptr; /* buffer with stream data */
|
||||
const uint8_t *max; /* ptr+len of buffer */
|
||||
uint64_t buffer;
|
||||
unsigned valid_bits;
|
||||
uint32_t *data;
|
||||
uint32_t *end;
|
||||
};
|
||||
|
||||
struct vl_vlc_entry
|
||||
{
|
||||
int8_t length;
|
||||
int8_t value;
|
||||
};
|
||||
|
||||
struct vl_vlc_compressed
|
||||
{
|
||||
uint16_t bitcode;
|
||||
struct vl_vlc_entry entry;
|
||||
};
|
||||
|
||||
static INLINE void
|
||||
vl_vlc_restart(struct vl_vlc *vlc)
|
||||
vl_vlc_init_table(struct vl_vlc_entry *dst, unsigned dst_size, const struct vl_vlc_compressed *src, unsigned src_size)
|
||||
{
|
||||
vlc->buf = (vlc->ptr[0] << 24) | (vlc->ptr[1] << 16) | (vlc->ptr[2] << 8) | vlc->ptr[3];
|
||||
vlc->bits = -16;
|
||||
vlc->ptr += 4;
|
||||
unsigned i, bits = util_logbase2(dst_size);
|
||||
|
||||
for (i=0;i<dst_size;++i) {
|
||||
dst[i].length = 0;
|
||||
dst[i].value = 0;
|
||||
}
|
||||
|
||||
for(; src_size > 0; --src_size, ++src) {
|
||||
for(i=0; i<(1 << (bits - src->entry.length)); ++i)
|
||||
dst[src->bitcode >> (16 - bits) | i] = src->entry;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
vl_vlc_fillbits(struct vl_vlc *vlc)
|
||||
{
|
||||
if (vlc->valid_bits < 32) {
|
||||
uint32_t value = *vlc->data;
|
||||
|
||||
//assert(vlc->data <= vlc->end);
|
||||
|
||||
#ifndef PIPE_ARCH_BIG_ENDIAN
|
||||
value = util_bswap32(value);
|
||||
#endif
|
||||
|
||||
vlc->buffer |= (uint64_t)value << (32 - vlc->valid_bits);
|
||||
++vlc->data;
|
||||
vlc->valid_bits += 32;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
vl_vlc_init(struct vl_vlc *vlc, const uint8_t *data, unsigned len)
|
||||
{
|
||||
vlc->ptr = data;
|
||||
vlc->max = data + len;
|
||||
vl_vlc_restart(vlc);
|
||||
assert(vlc);
|
||||
assert(data && len);
|
||||
|
||||
vlc->buffer = 0;
|
||||
vlc->valid_bits = 0;
|
||||
|
||||
/* align the data pointer */
|
||||
while((uint64_t)data & 3) {
|
||||
vlc->buffer |= (uint64_t)*data << (56 - vlc->valid_bits);
|
||||
++data;
|
||||
--len;
|
||||
vlc->valid_bits += 8;
|
||||
}
|
||||
vlc->data = (uint32_t*)data;
|
||||
vlc->end = (uint32_t*)(data + len);
|
||||
|
||||
vl_vlc_fillbits(vlc);
|
||||
vl_vlc_fillbits(vlc);
|
||||
}
|
||||
|
||||
static INLINE bool
|
||||
vl_vlc_getbyte(struct vl_vlc *vlc)
|
||||
static INLINE unsigned
|
||||
vl_vlc_bytes_left(struct vl_vlc *vlc)
|
||||
{
|
||||
vlc->buf <<= 8;
|
||||
vlc->buf |= vlc->ptr[0];
|
||||
vlc->ptr++;
|
||||
return vlc->ptr < vlc->max;
|
||||
return ((uint8_t*)vlc->end)-((uint8_t*)vlc->data);
|
||||
}
|
||||
|
||||
#define vl_vlc_getword(vlc, shift) \
|
||||
do { \
|
||||
(vlc)->buf |= (((vlc)->ptr[0] << 8) | (vlc)->ptr[1]) << (shift); \
|
||||
(vlc)->ptr += 2; \
|
||||
} while (0)
|
||||
static INLINE unsigned
|
||||
vl_vlc_peekbits(struct vl_vlc *vlc, unsigned num_bits)
|
||||
{
|
||||
//assert(vlc->valid_bits >= num_bits);
|
||||
|
||||
/* make sure that there are at least 16 valid bits in bit_buf */
|
||||
#define vl_vlc_needbits(vlc) \
|
||||
do { \
|
||||
if ((vlc)->bits >= 0) { \
|
||||
vl_vlc_getword(vlc, (vlc)->bits); \
|
||||
(vlc)->bits -= 16; \
|
||||
} \
|
||||
} while (0)
|
||||
return vlc->buffer >> (64 - num_bits);
|
||||
}
|
||||
|
||||
/* make sure that the full 32 bit of the buffer are valid */
|
||||
static INLINE void
|
||||
vl_vlc_need32bits(struct vl_vlc *vlc)
|
||||
vl_vlc_eatbits(struct vl_vlc *vlc, unsigned num_bits)
|
||||
{
|
||||
vl_vlc_needbits(vlc);
|
||||
if (vlc->bits > -8) {
|
||||
unsigned n = -vlc->bits;
|
||||
vlc->buf <<= n;
|
||||
vlc->buf |= *vlc->ptr << 8;
|
||||
vlc->bits = -8;
|
||||
vlc->ptr++;
|
||||
}
|
||||
if (vlc->bits > -16) {
|
||||
unsigned n = -vlc->bits - 8;
|
||||
vlc->buf <<= n;
|
||||
vlc->buf |= *vlc->ptr;
|
||||
vlc->bits = -16;
|
||||
vlc->ptr++;
|
||||
}
|
||||
//assert(vlc->valid_bits > num_bits);
|
||||
|
||||
vlc->buffer <<= num_bits;
|
||||
vlc->valid_bits -= num_bits;
|
||||
}
|
||||
|
||||
/* remove num valid bits from bit_buf */
|
||||
#define vl_vlc_dumpbits(vlc, num) \
|
||||
do { \
|
||||
(vlc)->buf <<= (num); \
|
||||
(vlc)->bits += (num); \
|
||||
} while (0)
|
||||
static INLINE unsigned
|
||||
vl_vlc_get_uimsbf(struct vl_vlc *vlc, unsigned num_bits)
|
||||
{
|
||||
unsigned value;
|
||||
|
||||
/* take num bits from the high part of bit_buf and zero extend them */
|
||||
#define vl_vlc_ubits(vlc, num) (((uint32_t)((vlc)->buf)) >> (32 - (num)))
|
||||
//assert(vlc->valid_bits >= num_bits);
|
||||
|
||||
/* take num bits from the high part of bit_buf and sign extend them */
|
||||
#define vl_vlc_sbits(vlc, num) (((int32_t)((vlc)->buf)) >> (32 - (num)))
|
||||
value = vlc->buffer >> (64 - num_bits);
|
||||
vl_vlc_eatbits(vlc, num_bits);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static INLINE signed
|
||||
vl_vlc_get_simsbf(struct vl_vlc *vlc, unsigned num_bits)
|
||||
{
|
||||
signed value;
|
||||
|
||||
//assert(vlc->valid_bits >= num_bits);
|
||||
|
||||
value = ((int64_t)vlc->buffer) >> (64 - num_bits);
|
||||
vl_vlc_eatbits(vlc, num_bits);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static INLINE int8_t
|
||||
vl_vlc_get_vlclbf(struct vl_vlc *vlc, const struct vl_vlc_entry *tbl, unsigned num_bits)
|
||||
{
|
||||
tbl += vl_vlc_peekbits(vlc, num_bits);
|
||||
vl_vlc_eatbits(vlc, tbl->length);
|
||||
return tbl->value;
|
||||
}
|
||||
|
||||
#endif /* vl_vlc_h */
|
||||
|
|
|
|||
|
|
@ -43,6 +43,17 @@ struct pipe_video_rect
|
|||
unsigned x, y, w, h;
|
||||
};
|
||||
|
||||
/*
|
||||
* see table 6-12 in the spec
|
||||
*/
|
||||
enum pipe_mpeg12_picture_coding_type
|
||||
{
|
||||
PIPE_MPEG12_PICTURE_CODING_TYPE_I = 0x01,
|
||||
PIPE_MPEG12_PICTURE_CODING_TYPE_P = 0x02,
|
||||
PIPE_MPEG12_PICTURE_CODING_TYPE_B = 0x03,
|
||||
PIPE_MPEG12_PICTURE_CODING_TYPE_D = 0x04
|
||||
};
|
||||
|
||||
/*
|
||||
* see table 6-14 in the spec
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue