📄 bitstream.cpp
字号:
for(i = 1; i < 256; i++){
tmp[i] = (bs->ShowBits(16) & 0xFF);
if(tmp[i] == 0)
break;
bs->Skip(8);
}
//DPRINTF(XVID_DEBUG_STARTCODE, "<user_data>: %s\n", tmp);
/* read xvid bitstream version */
#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);
}
/* divx detection */
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');
//DPRINTF(XVID_DEBUG_HEADER, "divx version=%i, build=%i packed=%i\n", version, build, packed_mode);
}
}
#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);
//video_object_start_code
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); //video_object_layer_start_code
bs->Skip(1); //random_accessible_vol
bs->Skip(8); //video_object_type_indication
if(bs->GetBit()){
//is_object_layer_identifier
DPRINTF(XVID_DEBUG_HEADER, "+ is_object_layer_identifier\n");
vol_ver_id = bs->GetBits(4); /* video_object_layer_verid */
DPRINTF(XVID_DEBUG_HEADER,"ver_id %i\n", vol_ver_id);
bs->Skip(3); /* video_object_layer_priority */
}else{
vol_ver_id = 1;
}
aspect_ratio = bs->GetBits(4);
if(aspect_ratio == VIDOBJLAY_AR_EXTPAR){
//aspect_ratio_info
DPRINTF(XVID_DEBUG_HEADER, "+ aspect_ratio_info\n");
par_width = bs->GetBits(8); /* par_width */
par_height = bs->GetBits(8); /* par_height */
}
if(bs->GetBit()){
//vol_control_parameters
DPRINTF(XVID_DEBUG_HEADER, "+ vol_control_parameters\n");
bs->Skip(2); /* chroma_format */
low_delay = (bs->GetBit()!=0);
DPRINTF(XVID_DEBUG_HEADER, "low_delay %i\n", (int)low_delay);
if (bs->GetBit()) /* vbv_parameters */
{
unsigned int bitrate;
unsigned int buffer_size;
unsigned int occupancy;
DPRINTF(XVID_DEBUG_HEADER,"+ vbv_parameters\n");
bitrate = bs->GetBits(15) << 15; /* first_half_bit_rate */
READ_MARKER();
bitrate |= bs->GetBits(15); /* latter_half_bit_rate */
READ_MARKER();
buffer_size = bs->GetBits(15) << 3; /* first_half_vbv_buffer_size */
READ_MARKER();
buffer_size |= bs->GetBits(3); /* latter_half_vbv_buffer_size */
occupancy = bs->GetBits(11) << 15; /* first_half_vbv_occupancy */
READ_MARKER();
occupancy |= bs->GetBits(15); /* latter_half_vbv_occupancy */
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;
}
//video_object_layer_shape
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){
//video_object_layer_shape_extension
bs->Skip(4);
}
READ_MARKER();
/********************** for decode B-frame time ***********************/
time_inc_resolution = bs->GetBits(16); /* vop_time_increment_resolution */
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
/* for "old" xvid compatibility, set time_inc_bits = 1 */
time_inc_bits = 1;
}
READ_MARKER();
if(bs->GetBit()){
//fixed_vop_rate
DPRINTF(XVID_DEBUG_HEADER, "+ fixed_vop_rate\n");
bs->Skip(time_inc_bits); //fixed_vop_time_increment
}
if(shape != VIDOBJLAY_SHAPE_BINARY_ONLY){
if(shape == VIDOBJLAY_SHAPE_RECTANGULAR){
dword _width, _height;
READ_MARKER();
_width = bs->GetBits(13); //video_object_layer_width
READ_MARKER();
_height = bs->GetBits(13); //video_object_layer_height
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()){
//obmc_disable
DPRINTF(XVID_DEBUG_ERROR, "obmc_disabled==false not supported\n");
/* TODO */
/* fucking divx4.02 has this enabled */
}
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); /* sprite_width */
READ_MARKER();
sprite_height = bs->GetBits(13); /* sprite_height */
READ_MARKER();
sprite_left_coord = bs->GetBits(13); /* sprite_left_coordinate */
READ_MARKER();
sprite_top_coord = bs->GetBits(13); /* sprite_top_coordinate */
READ_MARKER();
}
sprite_warping_points = bs->GetBits(6); /* no_of_sprite_warping_points */
sprite_warping_accuracy = bs->GetBits(2); /* sprite_warping_accuracy */
sprite_brightness_change = bs->GetBits(1); /* brightness_change */
if (sprite_enable != SPRITE_GMC)
{
low_latency_sprite_enable = bs->GetBits(1); /* low_latency_sprite_enable */
}
}
if(vol_ver_id != 1 && shape != VIDOBJLAY_SHAPE_RECTANGULAR){
//sadct_disable
bs->Skip(1);
}
if(bs->GetBit()){
//not_8_bit
DPRINTF(XVID_DEBUG_HEADER, "not_8_bit==true (ignored)\n");
quant_bits = bs->GetBits(4); /* quant_precision */
bs->Skip(4); /* bits_per_pixel */
}else{
quant_bits = 5;
}
if(shape == VIDOBJLAY_SHAPE_GRAYSCALE){
bs->Skip(1); /* no_gray_quant_update */
bs->Skip(1); /* composition_method */
bs->Skip(1); /* linear_composition */
}
quant_type = bs->GetBit();
DPRINTF(XVID_DEBUG_HEADER, "quant_type %i\n", quant_type);
if(quant_type){
if (bs->GetBit()) //load_intra_quant_mat
{
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()) /* load_inter_quant_mat */
{
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); //resync_marker_disable
if(bs->GetBit()){
//data_partitioned
DPRINTF(XVID_DEBUG_ERROR, "data_partitioned not supported\n");
bs->Skip(1); /* reversible_vlc */
}
if(vol_ver_id != 1){
newpred_enable = !!bs->GetBit();
if (newpred_enable) /* newpred_enable */
{
DPRINTF(XVID_DEBUG_HEADER, "+ newpred_enable\n");
bs->Skip(2); /* requested_upstream_message_type */
bs->Skip(1); /* newpred_segment_type */
}
reduced_resolution_enable = !!bs->GetBit(); //reduced_resolution_vop_enable
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); /* hierarchy_type */
bs->Skip(4); /* ref_layer_id */
bs->Skip(1); /* ref_layer_sampling_direc */
bs->Skip(5); /* hor_sampling_factor_n */
bs->Skip(5); /* hor_sampling_factor_m */
bs->Skip(5); /* vert_sampling_factor_n */
bs->Skip(5); /* vert_sampling_factor_m */
bs->Skip(1); /* enhancement_type */
if(shape == VIDOBJLAY_SHAPE_BINARY /* && hierarchy_type==0 */) {
bs->Skip(1); /* use_ref_shape */
bs->Skip(1); /* use_ref_texture */
bs->Skip(5); /* shape_hor_sampling_factor_n */
bs->Skip(5); /* shape_hor_sampling_factor_m */
bs->Skip(5); /* shape_vert_sampling_factor_n */
bs->Skip(5); /* shape_vert_sampling_factor_m */
}
return -1;
}
}else{
//shape == BINARY_ONLY
if(vol_ver_id != 1){
scalability = (bs->GetBit()!=0);
if(scalability){
DPRINTF(XVID_DEBUG_ERROR, "scalability not supported\n");
bs->Skip(4); /* ref_layer_id */
bs->Skip(5); /* hor_sampling_factor_n */
bs->Skip(5); /* hor_sampling_factor_m */
bs->Skip(5); /* vert_sampling_factor_n */
bs->Skip(5); /* vert_sampling_factor_m */
return -1;
}
}
bs->Skip(1); /* resync_marker_disable */
}
return (resize ? -3 : -2); //VOL
}
break;
default:
{
//start_code == ?
//if(bs->ShowBits(24) == 0x000001)
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; //ignore it
}
//----------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -