This source file includes following definitions.
- ByteSwap
- Init
- ShowBits
- Skip
- ShowBitsFromByteAlign
- GetBits
- get_matrix
- read_video_packet_header
- read_vol_complexity_estimation_header
- read_vop_complexity_estimation_header
- BitstreamReadHeaders
#include "bitstream.h"
#include "quant_matrix.h"
#ifdef WIN32
#include <stdio.h>
#endif
inline dword ByteSwap(dword a) {
return (a<<24) | ((a&0xff00) << 8) | ((a&0xff0000) >> 8) | (a>>24);
}
void Bitstream::Init(const void *bitstream, dword _length) {
dword adjbitstream = (dword)bitstream;
long bitpos = ((sizeof(dword)-1) & (long)bitstream);
adjbitstream = adjbitstream - bitpos;
start = tail = (dword *) adjbitstream;
if(_length) {
dword tmp = *start;
#ifndef ARCH_IS_BIG_ENDIAN
tmp = ByteSwap(tmp);
#endif
bufa = tmp;
if(_length>4) {
tmp = *(start + 1);
#ifndef ARCH_IS_BIG_ENDIAN
tmp = ByteSwap(tmp);
#endif
bufb = tmp;
} else
bufb = 0;
} else
bufa = bufb = 0;
buf = 0;
pos = initpos = bitpos*8;
length = _length;
}
dword Bitstream::ShowBits(dword bits) {
int nbit = (bits + pos) - 32;
if(nbit > 0)
return ((bufa & (0xffffffff >> pos)) << nbit) | (bufb >> (32 - nbit));
return (bufa & (0xffffffff >> pos)) >> (32 - pos - bits);
}
void Bitstream::Skip(dword bits) {
pos += bits;
if(pos >= 32) {
dword tmp;
bufa = bufb;
tmp = *((dword *) tail + 2);
#ifndef ARCH_IS_BIG_ENDIAN
tmp = ByteSwap(tmp);
#endif
bufb = tmp;
tail++;
pos -= 32;
}
}
dword Bitstream::ShowBitsFromByteAlign(int bits) {
int bspos = pos + NumBitsToByteAlign();
int nbit = (bits + bspos) - 32;
if (bspos >= 32) {
return bufb >> (32 - nbit);
} else if (nbit > 0) {
return ((bufa & (0xffffffff >> bspos)) << nbit) | (bufb >> (32 - nbit));
} else {
return (bufa & (0xffffffff >> bspos)) >> (32 - bspos - bits);
}
}
dword Bitstream::GetBits(dword n) {
dword ret = ShowBits(n);
Skip(n);
return ret;
}
static const dword intra_dc_threshold_table[] = {
32,
13,
15,
17,
19,
21,
23,
1,
};
void Bitstream::get_matrix(byte * matrix) {
int i = 0;
int last, value = 0;
do {
last = value;
value = GetBits(8);
matrix[scan_tables[0][i++]] = value;
}
while (value != 0 && i < 64);
i--;
while (i < 64) {
matrix[scan_tables[0][i++]] = last;
}
}
int S_decoder::read_video_packet_header(Bitstream *bs, const int addbits, int *quant, int *fcode_forward, int *fcode_backward, int *intra_dc_threshold) {
int startcode_bits = NUMBITS_VP_RESYNC_MARKER + addbits;
int mbnum_bits = log2bin(mb_width * mb_height - 1);
int mbnum;
int hec = 0;
bs->Skip(bs->NumBitsToByteAlign());
bs->Skip(startcode_bits);
DPRINTF(XVID_DEBUG_STARTCODE, "<video_packet_header>\n");
if (shape != VIDOBJLAY_SHAPE_RECTANGULAR)
{
hec = bs->GetBit();
if (hec && !(sprite_enable == SPRITE_STATIC ))
{
bs->Skip(13);
READ_MARKER();
bs->Skip(13);
READ_MARKER();
bs->Skip(13);
READ_MARKER();
bs->Skip(13);
READ_MARKER();
}
}
mbnum = bs->GetBits(mbnum_bits);
DPRINTF(XVID_DEBUG_HEADER, "mbnum %i\n", mbnum);
if (shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
{
*quant = bs->GetBits(quant_bits);
DPRINTF(XVID_DEBUG_HEADER, "quant %i\n", *quant);
}
if (shape == VIDOBJLAY_SHAPE_RECTANGULAR)
hec = bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "header_extension_code %i\n", hec);
if (hec)
{
int time_base;
int time_increment = 0;
int coding_type;
for (time_base=0; bs->GetBit()!=0; time_base++);
READ_MARKER();
if (time_inc_bits)
time_increment = (bs->GetBits(time_inc_bits));
READ_MARKER();
coding_type = bs->GetBits(2);
DPRINTF(XVID_DEBUG_HEADER,"coding_type %i\n", coding_type);
if (shape != VIDOBJLAY_SHAPE_RECTANGULAR)
{
bs->Skip(1);
if (coding_type != I_VOP)
bs->Skip(1);
}
if (shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
{
*intra_dc_threshold = intra_dc_threshold_table[bs->GetBits(3)];
if (sprite_enable == SPRITE_GMC && coding_type == S_VOP &&
sprite_warping_points > 0)
{
}
if(reduced_resolution_enable && shape == VIDOBJLAY_SHAPE_RECTANGULAR && (coding_type == P_VOP || coding_type == I_VOP)) {
bs->Skip(1);
}
if (coding_type != I_VOP && fcode_forward)
{
*fcode_forward = bs->GetBits(3);
DPRINTF(XVID_DEBUG_HEADER,"fcode_forward %i\n", *fcode_forward);
}
if (coding_type == B_VOP && fcode_backward)
{
*fcode_backward = bs->GetBits(3);
DPRINTF(XVID_DEBUG_HEADER,"fcode_backward %i\n", *fcode_backward);
}
}
}
if (newpred_enable) {
int vop_id;
int vop_id_for_prediction;
vop_id = bs->GetBits(MIN(time_inc_bits + 3, 15));
DPRINTF(XVID_DEBUG_HEADER, "vop_id %i\n", vop_id);
if (bs->GetBit())
{
vop_id_for_prediction = bs->GetBits(MIN(time_inc_bits + 3, 15));
DPRINTF(XVID_DEBUG_HEADER, "vop_id_for_prediction %i\n", vop_id_for_prediction);
}
READ_MARKER();
}
return mbnum;
}
void S_decoder::read_vol_complexity_estimation_header(Bitstream * bs) {
ESTIMATION * e = &estimation;
e->method = bs->GetBits(2);
DPRINTF(XVID_DEBUG_HEADER,"+ complexity_estimation_header; method=%i\n", e->method);
if (e->method == 0 || e->method == 1) {
if(!bs->GetBit()) {
e->opaque = bs->GetBit();
e->transparent = bs->GetBit();
e->intra_cae = bs->GetBit();
e->inter_cae = bs->GetBit();
e->no_update = bs->GetBit();
e->upsampling = bs->GetBit();
}
if (!bs->GetBit())
{
e->intra_blocks = bs->GetBit();
e->inter_blocks = bs->GetBit();
e->inter4v_blocks = bs->GetBit();
e->not_coded_blocks = bs->GetBit();
}
}
READ_MARKER();
if (!bs->GetBit()) {
e->dct_coefs = bs->GetBit();
e->dct_lines = bs->GetBit();
e->vlc_symbols = bs->GetBit();
e->vlc_bits = bs->GetBit();
}
if (!bs->GetBit()) {
e->apm = bs->GetBit();
e->npm = bs->GetBit();
e->interpolate_mc_q = bs->GetBit();
e->forw_back_mc_q = bs->GetBit();
e->halfpel2 = bs->GetBit();
e->halfpel4 = bs->GetBit();
}
READ_MARKER();
if (e->method == 1) {
if (!bs->GetBit()) {
e->sadct = bs->GetBit();
e->quarterpel = bs->GetBit();
}
}
}
void S_decoder::read_vop_complexity_estimation_header(Bitstream * bs, int coding_type) {
ESTIMATION * e = &estimation;
if (e->method == 0 || e->method == 1)
{
if (coding_type == I_VOP) {
if (e->opaque) bs->Skip(8);
if (e->transparent) bs->Skip(8);
if (e->intra_cae) bs->Skip(8);
if (e->inter_cae) bs->Skip(8);
if (e->no_update) bs->Skip(8);
if (e->upsampling) bs->Skip(8);
if (e->intra_blocks) bs->Skip(8);
if (e->not_coded_blocks) bs->Skip(8);
if (e->dct_coefs) bs->Skip(8);
if (e->dct_lines) bs->Skip(8);
if (e->vlc_symbols) bs->Skip(8);
if (e->vlc_bits) bs->Skip(8);
if (e->sadct) bs->Skip(8);
}
if (coding_type == P_VOP) {
if (e->opaque) bs->Skip(8);
if (e->transparent) bs->Skip(8);
if (e->intra_cae) bs->Skip(8);
if (e->inter_cae) bs->Skip(8);
if (e->no_update) bs->Skip(8);
if (e->upsampling) bs->Skip(8);
if (e->intra_blocks) bs->Skip(8);
if (e->not_coded_blocks) bs->Skip(8);
if (e->dct_coefs) bs->Skip(8);
if (e->dct_lines) bs->Skip(8);
if (e->vlc_symbols) bs->Skip(8);
if (e->vlc_bits) bs->Skip(8);
if (e->inter_blocks) bs->Skip(8);
if (e->inter4v_blocks) bs->Skip(8);
if (e->apm) bs->Skip(8);
if (e->npm) bs->Skip(8);
if (e->forw_back_mc_q) bs->Skip(8);
if (e->halfpel2) bs->Skip(8);
if (e->halfpel4) bs->Skip(8);
if (e->sadct) bs->Skip(8);
if (e->quarterpel) bs->Skip(8);
}
if (coding_type == B_VOP) {
if (e->opaque) bs->Skip(8);
if (e->transparent) bs->Skip(8);
if (e->intra_cae) bs->Skip(8);
if (e->inter_cae) bs->Skip(8);
if (e->no_update) bs->Skip(8);
if (e->upsampling) bs->Skip(8);
if (e->intra_blocks) bs->Skip(8);
if (e->not_coded_blocks) bs->Skip(8);
if (e->dct_coefs) bs->Skip(8);
if (e->dct_lines) bs->Skip(8);
if (e->vlc_symbols) bs->Skip(8);
if (e->vlc_bits) bs->Skip(8);
if (e->inter_blocks) bs->Skip(8);
if (e->inter4v_blocks) bs->Skip(8);
if (e->apm) bs->Skip(8);
if (e->npm) bs->Skip(8);
if (e->forw_back_mc_q) bs->Skip(8);
if (e->halfpel2) bs->Skip(8);
if (e->halfpel4) bs->Skip(8);
if (e->interpolate_mc_q) bs->Skip(8);
if (e->sadct) bs->Skip(8);
if (e->quarterpel) bs->Skip(8);
}
if (coding_type == S_VOP && sprite_enable == SPRITE_STATIC) {
if (e->intra_blocks) bs->Skip(8);
if (e->not_coded_blocks) bs->Skip(8);
if (e->dct_coefs) bs->Skip(8);
if (e->dct_lines) bs->Skip(8);
if (e->vlc_symbols) bs->Skip(8);
if (e->vlc_bits) bs->Skip(8);
if (e->inter_blocks) bs->Skip(8);
if (e->inter4v_blocks) bs->Skip(8);
if (e->apm) bs->Skip(8);
if (e->npm) bs->Skip(8);
if (e->forw_back_mc_q) bs->Skip(8);
if (e->halfpel2) bs->Skip(8);
if (e->halfpel4) bs->Skip(8);
if (e->interpolate_mc_q) bs->Skip(8);
}
}
}
#define VIDOBJ_START_CODE_MASK 0x0000001f
#define VIDOBJLAY_START_CODE_MASK 0x0000000f
int S_decoder::BitstreamReadHeaders(Bitstream * bs, bool &rounding, bool *reduced_resolution, dword *quant, dword *fcode_forward,
dword *fcode_backward, dword *intra_dc_threshold, WARPPOINTS *gmc_warp) {
dword vol_ver_id;
dword coding_type;
dword start_code;
dword time_incr = 0;
int time_increment = 0;
int resize = 0;
while((bs->Pos() >> 3) < bs->length) {
bs->ByteAlign();
start_code = bs->ShowBits(32);
switch(start_code) {
case VISOBJSEQ_START_CODE:
{
DPRINTF(XVID_DEBUG_STARTCODE, "<visual_object_sequence>\n");
bs->Skip(32);
int profile = bs->GetBits(8);
DPRINTF(XVID_DEBUG_HEADER, "profile_and_level_indication %i\n", profile);
}
break;
case VISOBJSEQ_STOP_CODE:
{
bs->Skip(32);
DPRINTF(XVID_DEBUG_STARTCODE, "</visual_object_sequence>\n");
}
break;
case VISOBJ_START_CODE:
{
DPRINTF(XVID_DEBUG_STARTCODE, "<visual_object>\n");
bs->Skip(32);
int visobj_ver_id;
if(bs->GetBit()) {
visobj_ver_id = bs->GetBits(4);
DPRINTF(XVID_DEBUG_HEADER,"visobj_ver_id %i\n", visobj_ver_id);
bs->Skip(3);
} else {
visobj_ver_id = 1;
}
if(bs->ShowBits(4) != VISOBJ_TYPE_VIDEO) {
DPRINTF(XVID_DEBUG_ERROR, "visual_object_type != video\n");
return -1;
}
bs->Skip(4);
if(bs->GetBit()) {
DPRINTF(XVID_DEBUG_HEADER,"+ video_signal_type\n");
bs->Skip(3);
bs->Skip(1);
if (bs->GetBit())
{
DPRINTF(XVID_DEBUG_HEADER,"+ color_description");
bs->Skip(8);
bs->Skip(8);
bs->Skip(8);
}
}
}
break;
case GRPOFVOP_START_CODE:
{
DPRINTF(XVID_DEBUG_STARTCODE, "<group_of_vop>\n");
bs->Skip(32);
{
int hours, minutes, seconds;
hours = bs->GetBits(5);
minutes = bs->GetBits(6);
READ_MARKER();
seconds = bs->GetBits(6);
}
bs->Skip(1);
bs->Skip(1);
}
break;
case VOP_START_CODE:
{
DPRINTF(XVID_DEBUG_STARTCODE, "<vop>\n");
bs->Skip(32);
coding_type = bs->GetBits(2);
DPRINTF(XVID_DEBUG_HEADER, "coding_type %i\n", coding_type);
while (bs->GetBit() != 0)
time_incr++;
READ_MARKER();
if (time_inc_bits) {
time_increment = (bs->GetBits(time_inc_bits));
}
DPRINTF(XVID_DEBUG_HEADER, "time_base %i\n", time_incr);
DPRINTF(XVID_DEBUG_HEADER, "time_increment %i\n", time_increment);
if (coding_type != B_VOP) {
last_time_base = time_base;
time_base += time_incr;
time = time_increment;
#if 0
time_base * time_inc_resolution +
time_increment;
#endif
time_pp = (dword)
(time_inc_resolution + time - last_non_b_time)%time_inc_resolution;
last_non_b_time = time;
} else {
time = time_increment;
#if 0
(last_time_base +
time_incr) * time_inc_resolution + time_increment;
#endif
time_bp = (dword)
(time_inc_resolution + last_non_b_time - time)%time_inc_resolution;
}
DPRINTF(XVID_DEBUG_HEADER,"time_pp=%i\n", time_pp);
DPRINTF(XVID_DEBUG_HEADER,"time_bp=%i\n", time_bp);
READ_MARKER();
if (!bs->GetBit())
{
DPRINTF(XVID_DEBUG_HEADER, "vop_coded==false\n");
return N_VOP;
}
if (newpred_enable) {
int vop_id;
int vop_id_for_prediction;
vop_id = bs->GetBits(MIN(time_inc_bits + 3, 15));
DPRINTF(XVID_DEBUG_HEADER, "vop_id %i\n", vop_id);
if (bs->GetBit())
{
vop_id_for_prediction = bs->GetBits(MIN(time_inc_bits + 3, 15));
DPRINTF(XVID_DEBUG_HEADER, "vop_id_for_prediction %i\n", vop_id_for_prediction);
}
READ_MARKER();
}
if((shape != VIDOBJLAY_SHAPE_BINARY_ONLY) &&
((coding_type == P_VOP) || (coding_type == S_VOP && sprite_enable == SPRITE_GMC))) {
rounding = !!bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "rounding %i\n", rounding);
}
if(reduced_resolution_enable && shape == VIDOBJLAY_SHAPE_RECTANGULAR && (coding_type == P_VOP || coding_type == I_VOP)) {
*reduced_resolution = !!bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "reduced_resolution %i\n", *reduced_resolution);
} else {
*reduced_resolution = false;
}
if (shape != VIDOBJLAY_SHAPE_RECTANGULAR) {
if(!(sprite_enable == SPRITE_STATIC && coding_type == I_VOP)) {
dword width, height;
dword horiz_mc_ref, vert_mc_ref;
width = bs->GetBits(13);
READ_MARKER();
height = bs->GetBits(13);
READ_MARKER();
horiz_mc_ref = bs->GetBits(13);
READ_MARKER();
vert_mc_ref = bs->GetBits(13);
READ_MARKER();
DPRINTF(XVID_DEBUG_HEADER, "width %i\n", width);
DPRINTF(XVID_DEBUG_HEADER, "height %i\n", height);
DPRINTF(XVID_DEBUG_HEADER, "horiz_mc_ref %i\n", horiz_mc_ref);
DPRINTF(XVID_DEBUG_HEADER, "vert_mc_ref %i\n", vert_mc_ref);
}
bs->Skip(1);
if (bs->GetBit())
{
bs->Skip(8);
}
}
if (shape != VIDOBJLAY_SHAPE_BINARY_ONLY) {
if (!complexity_estimation_disable)
{
read_vop_complexity_estimation_header(bs, coding_type);
}
*intra_dc_threshold =
intra_dc_threshold_table[bs->GetBits(3)];
top_field_first = 0;
alternate_vertical_scan = 0;
if(interlacing) {
top_field_first = bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "interlace top_field_first %i\n", top_field_first);
alternate_vertical_scan = bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "interlace alternate_vertical_scan %i\n", alternate_vertical_scan);
}
}
if ((sprite_enable == SPRITE_STATIC || sprite_enable== SPRITE_GMC) && coding_type == S_VOP) {
int i;
for (i = 0 ; i < sprite_warping_points; i++)
{
int length;
int x = 0, y = 0;
length = bs->bs_get_spritetrajectory();
if(length) {
x= bs->GetBits(length);
if ((x >> (length - 1)) == 0)
x = - (x ^ ((1 << length) - 1));
}
READ_MARKER();
length = bs->bs_get_spritetrajectory();
if(length) {
y = bs->GetBits(length);
if ((y >> (length - 1)) == 0)
y = - (y ^ ((1 << length) - 1));
}
READ_MARKER();
gmc_warp->duv[i].x = x;
gmc_warp->duv[i].y = y;
}
if (sprite_brightness_change)
{
}
if (sprite_enable == SPRITE_STATIC)
{
}
}
if ((*quant = bs->GetBits(quant_bits)) < 1)
*quant = 1;
DPRINTF(XVID_DEBUG_HEADER, "quant %i\n", *quant);
if (coding_type != I_VOP) {
*fcode_forward = bs->GetBits(3);
DPRINTF(XVID_DEBUG_HEADER, "fcode_forward %i\n", *fcode_forward);
}
if (coding_type == B_VOP) {
*fcode_backward = bs->GetBits(3);
DPRINTF(XVID_DEBUG_HEADER, "fcode_backward %i\n", *fcode_backward);
}
if(!scalability) {
if ((shape != VIDOBJLAY_SHAPE_RECTANGULAR) &&
(coding_type != I_VOP)) {
bs->Skip(1);
}
}
return coding_type;
}
break;
case USERDATA_START_CODE:
{
char tmp[256];
int i;
bs->Skip(32);
tmp[0] = bs->ShowBits(8);
for(i = 1; i < 256; i++) {
tmp[i] = (bs->ShowBits(16) & 0xFF);
if(tmp[i] == 0)
break;
bs->Skip(8);
}
#ifdef WIN32
{
char packed;
int version, build;
if(MemCmp(tmp, "XviD", 4) == 0) {
sscanf(tmp, "XviD%d", &bs_version);
DPRINTF(XVID_DEBUG_HEADER, "xvid bitstream version=%i", bs_version);
}
i = sscanf(tmp, "DivX%dBuild%d%c", &version, &build, &packed);
if (i < 2)
i = sscanf(tmp, "DivX%db%d%c", &version, &build, &packed);
if (i >= 2) {
packed_mode = (i == 3 && packed == 'p');
}
}
#endif
}
break;
default:
switch(start_code & ~VIDOBJ_START_CODE_MASK) {
case VIDOBJ_START_CODE:
{
DPRINTF(XVID_DEBUG_STARTCODE, "<video_object>\n");
DPRINTF(XVID_DEBUG_HEADER, "vo id %i\n", start_code & VIDOBJ_START_CODE_MASK);
bs->Skip(32);
}
break;
case VIDOBJLAY_START_CODE:
{
DPRINTF(XVID_DEBUG_STARTCODE, "<video_object_layer>\n");
DPRINTF(XVID_DEBUG_HEADER, "vol id %i\n", start_code & VIDOBJLAY_START_CODE_MASK);
bs->Skip(32);
bs->Skip(1);
bs->Skip(8);
if(bs->GetBit()) {
DPRINTF(XVID_DEBUG_HEADER, "+ is_object_layer_identifier\n");
vol_ver_id = bs->GetBits(4);
DPRINTF(XVID_DEBUG_HEADER,"ver_id %i\n", vol_ver_id);
bs->Skip(3);
} else {
vol_ver_id = 1;
}
aspect_ratio = bs->GetBits(4);
if(aspect_ratio == VIDOBJLAY_AR_EXTPAR) {
DPRINTF(XVID_DEBUG_HEADER, "+ aspect_ratio_info\n");
par_width = bs->GetBits(8);
par_height = bs->GetBits(8);
}
if(bs->GetBit()) {
DPRINTF(XVID_DEBUG_HEADER, "+ vol_control_parameters\n");
bs->Skip(2);
low_delay = (bs->GetBit()!=0);
DPRINTF(XVID_DEBUG_HEADER, "low_delay %i\n", (int)low_delay);
if (bs->GetBit())
{
unsigned int bitrate;
unsigned int buffer_size;
unsigned int occupancy;
DPRINTF(XVID_DEBUG_HEADER,"+ vbv_parameters\n");
bitrate = bs->GetBits(15) << 15;
READ_MARKER();
bitrate |= bs->GetBits(15);
READ_MARKER();
buffer_size = bs->GetBits(15) << 3;
READ_MARKER();
buffer_size |= bs->GetBits(3);
occupancy = bs->GetBits(11) << 15;
READ_MARKER();
occupancy |= bs->GetBits(15);
READ_MARKER();
DPRINTF(XVID_DEBUG_HEADER,"bitrate %d (unit=400 bps)\n", bitrate);
DPRINTF(XVID_DEBUG_HEADER,"buffer_size %d (unit=16384 bits)\n", buffer_size);
DPRINTF(XVID_DEBUG_HEADER,"occupancy %d (unit=64 bits)\n", occupancy);
}
} else {
low_delay = low_delay_default;
}
shape = bs->GetBits(2);
DPRINTF(XVID_DEBUG_HEADER, "shape %i\n", shape);
if(shape != VIDOBJLAY_SHAPE_RECTANGULAR) {
DPRINTF(XVID_DEBUG_ERROR,"non-rectangular shapes are not supported\n");
}
if(shape == VIDOBJLAY_SHAPE_GRAYSCALE && vol_ver_id != 1) {
bs->Skip(4);
}
READ_MARKER();
time_inc_resolution = bs->GetBits(16);
DPRINTF(XVID_DEBUG_HEADER,"vop_time_increment_resolution %i\n", time_inc_resolution);
#if 0
time_inc_resolution--;
#endif
if(time_inc_resolution > 0) {
time_inc_bits = log2bin(time_inc_resolution-1);
} else {
#if 0
time_inc_bits = 0;
#endif
time_inc_bits = 1;
}
READ_MARKER();
if(bs->GetBit()) {
DPRINTF(XVID_DEBUG_HEADER, "+ fixed_vop_rate\n");
bs->Skip(time_inc_bits);
}
if(shape != VIDOBJLAY_SHAPE_BINARY_ONLY) {
if(shape == VIDOBJLAY_SHAPE_RECTANGULAR) {
dword _width, _height;
READ_MARKER();
_width = bs->GetBits(13);
READ_MARKER();
_height = bs->GetBits(13);
READ_MARKER();
DPRINTF(XVID_DEBUG_HEADER, "width %i\n", _width);
DPRINTF(XVID_DEBUG_HEADER, "height %i\n", _height);
if(width != _width || height != _height) {
if(fixed_dimensions) {
DPRINTF(XVID_DEBUG_ERROR, "decoder width/height does not match bitstream\n");
return -1;
}
resize = 1;
width = _width;
height = _height;
}
}
interlacing = !!bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "interlacing %i\n", interlacing);
if(!bs->GetBit()) {
DPRINTF(XVID_DEBUG_ERROR, "obmc_disabled==false not supported\n");
}
sprite_enable = bs->GetBits((vol_ver_id == 1 ? 1 : 2));
if(sprite_enable == SPRITE_STATIC || sprite_enable == SPRITE_GMC) {
int low_latency_sprite_enable;
if(sprite_enable != SPRITE_GMC) {
int sprite_width;
int sprite_height;
int sprite_left_coord;
int sprite_top_coord;
sprite_width = bs->GetBits(13);
READ_MARKER();
sprite_height = bs->GetBits(13);
READ_MARKER();
sprite_left_coord = bs->GetBits(13);
READ_MARKER();
sprite_top_coord = bs->GetBits(13);
READ_MARKER();
}
sprite_warping_points = bs->GetBits(6);
sprite_warping_accuracy = bs->GetBits(2);
sprite_brightness_change = bs->GetBits(1);
if (sprite_enable != SPRITE_GMC)
{
low_latency_sprite_enable = bs->GetBits(1);
}
}
if(vol_ver_id != 1 && shape != VIDOBJLAY_SHAPE_RECTANGULAR) {
bs->Skip(1);
}
if(bs->GetBit()) {
DPRINTF(XVID_DEBUG_HEADER, "not_8_bit==true (ignored)\n");
quant_bits = bs->GetBits(4);
bs->Skip(4);
} else {
quant_bits = 5;
}
if(shape == VIDOBJLAY_SHAPE_GRAYSCALE) {
bs->Skip(1);
bs->Skip(1);
bs->Skip(1);
}
quant_type = bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "quant_type %i\n", quant_type);
if(quant_type) {
if (bs->GetBit())
{
byte matrix[64];
DPRINTF(XVID_DEBUG_HEADER, "load_intra_quant_mat\n");
bs->get_matrix(matrix);
set_intra_matrix(mpeg_quant_matrices, matrix);
} else
set_intra_matrix(mpeg_quant_matrices, get_default_intra_matrix());
if (bs->GetBit())
{
byte matrix[64];
DPRINTF(XVID_DEBUG_HEADER, "load_inter_quant_mat\n");
bs->get_matrix(matrix);
set_inter_matrix(mpeg_quant_matrices, matrix);
} else
set_inter_matrix(mpeg_quant_matrices, get_default_inter_matrix());
if (shape == VIDOBJLAY_SHAPE_GRAYSCALE) {
DPRINTF(XVID_DEBUG_ERROR, "greyscale matrix not supported\n");
return -1;
}
}
if(vol_ver_id != 1) {
quarterpel = bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER,"quarterpel %i\n", quarterpel);
} else
quarterpel = 0;
complexity_estimation_disable = bs->GetBit();
if(!complexity_estimation_disable) {
read_vol_complexity_estimation_header(bs);
}
bs->Skip(1);
if(bs->GetBit()) {
DPRINTF(XVID_DEBUG_ERROR, "data_partitioned not supported\n");
bs->Skip(1);
}
if(vol_ver_id != 1) {
newpred_enable = !!bs->GetBit();
if (newpred_enable)
{
DPRINTF(XVID_DEBUG_HEADER, "+ newpred_enable\n");
bs->Skip(2);
bs->Skip(1);
}
reduced_resolution_enable = !!bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "reduced_resolution_enable %i\n", reduced_resolution_enable);
} else {
newpred_enable = false;
reduced_resolution_enable = false;
}
scalability = (bs->GetBit()!=0);
if(scalability) {
DPRINTF(XVID_DEBUG_ERROR, "scalability not supported\n");
bs->Skip(1);
bs->Skip(4);
bs->Skip(1);
bs->Skip(5);
bs->Skip(5);
bs->Skip(5);
bs->Skip(5);
bs->Skip(1);
if(shape == VIDOBJLAY_SHAPE_BINARY ) {
bs->Skip(1);
bs->Skip(1);
bs->Skip(5);
bs->Skip(5);
bs->Skip(5);
bs->Skip(5);
}
return -1;
}
} else {
if(vol_ver_id != 1) {
scalability = (bs->GetBit()!=0);
if(scalability) {
DPRINTF(XVID_DEBUG_ERROR, "scalability not supported\n");
bs->Skip(4);
bs->Skip(5);
bs->Skip(5);
bs->Skip(5);
bs->Skip(5);
return -1;
}
}
bs->Skip(1);
}
return (resize ? -3 : -2);
}
break;
default:
{
if((start_code&0x00ffffff) == 0x000001) {
DPRINTF(XVID_DEBUG_STARTCODE, "<unknown: %x>\n", bs->ShowBits(32));
}
bs->Skip(8);
}
}
}
}
#if 0
DPRINTF("*** WARNING: no vop_start_code found");
#endif
return -1;
}