📄 bitstream.c
字号:
}
dec->aspect_ratio = BitstreamGetBits(bs, 4);
if (dec->aspect_ratio == VIDOBJLAY_AR_EXTPAR) /* aspect_ratio_info */
{
DPRINTF(XVID_DEBUG_HEADER, "+ aspect_ratio_info\n");
dec->par_width = BitstreamGetBits(bs, 8); /* par_width */
dec->par_height = BitstreamGetBits(bs, 8); /* par_height */
}
if (BitstreamGetBit(bs)) /* vol_control_parameters */
{
DPRINTF(XVID_DEBUG_HEADER, "+ vol_control_parameters\n");
BitstreamSkip(bs, 2); /* chroma_format */
dec->low_delay = BitstreamGetBit(bs); /* low_delay */
DPRINTF(XVID_DEBUG_HEADER, "low_delay %i\n", dec->low_delay);
if (BitstreamGetBit(bs)) /* vbv_parameters */
{
unsigned int bitrate;
unsigned int buffer_size;
unsigned int occupancy;
DPRINTF(XVID_DEBUG_HEADER,"+ vbv_parameters\n");
bitrate = BitstreamGetBits(bs,15) << 15; /* first_half_bit_rate */
READ_MARKER();
bitrate |= BitstreamGetBits(bs,15); /* latter_half_bit_rate */
READ_MARKER();
buffer_size = BitstreamGetBits(bs, 15) << 3; /* first_half_vbv_buffer_size */
READ_MARKER();
buffer_size |= BitstreamGetBits(bs, 3); /* latter_half_vbv_buffer_size */
occupancy = BitstreamGetBits(bs, 11) << 15; /* first_half_vbv_occupancy */
READ_MARKER();
occupancy |= BitstreamGetBits(bs, 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{
dec->low_delay = dec->low_delay_default;
}
dec->shape = BitstreamGetBits(bs, 2); /* video_object_layer_shape */
DPRINTF(XVID_DEBUG_HEADER, "shape %i\n", dec->shape);
if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR)
{
DPRINTF(XVID_DEBUG_ERROR,"non-rectangular shapes are not supported\n");
}
if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE && vol_ver_id != 1) {
BitstreamSkip(bs, 4); /* video_object_layer_shape_extension */
}
READ_MARKER();
/********************** for decode B-frame time ***********************/
dec->time_inc_resolution = BitstreamGetBits(bs, 16); /* vop_time_increment_resolution */
DPRINTF(XVID_DEBUG_HEADER,"vop_time_increment_resolution %i\n", dec->time_inc_resolution);
if (dec->time_inc_resolution > 0) {
dec->time_inc_bits = MAX(log2bin(dec->time_inc_resolution-1), 1);
} else {
/* for "old" xvid compatibility, set time_inc_bits = 1 */
dec->time_inc_bits = 1;
}
READ_MARKER();
if (BitstreamGetBit(bs)) /* fixed_vop_rate */
{
DPRINTF(XVID_DEBUG_HEADER, "+ fixed_vop_rate\n");
BitstreamSkip(bs, dec->time_inc_bits); /* fixed_vop_time_increment */
}
if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) {
if (dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR) {
uint32_t width, height;
READ_MARKER();
width = BitstreamGetBits(bs, 13); /* video_object_layer_width */
READ_MARKER();
height = BitstreamGetBits(bs, 13); /* video_object_layer_height */
READ_MARKER();
DPRINTF(XVID_DEBUG_HEADER, "width %i\n", width);
DPRINTF(XVID_DEBUG_HEADER, "height %i\n", height);
if (dec->width != width || dec->height != height)
{
if (dec->fixed_dimensions)
{
DPRINTF(XVID_DEBUG_ERROR, "decoder width/height does not match bitstream\n");
return -1;
}
resize = 1;
dec->width = width;
dec->height = height;
}
}
dec->interlacing = BitstreamGetBit(bs);
DPRINTF(XVID_DEBUG_HEADER, "interlacing %i\n", dec->interlacing);
if (!BitstreamGetBit(bs)) /* obmc_disable */
{
DPRINTF(XVID_DEBUG_ERROR, "obmc_disabled==false not supported\n");
/* TODO */
/* fucking divx4.02 has this enabled */
}
dec->sprite_enable = BitstreamGetBits(bs, (vol_ver_id == 1 ? 1 : 2)); /* sprite_enable */
if (dec->sprite_enable == SPRITE_STATIC || dec->sprite_enable == SPRITE_GMC)
{
int low_latency_sprite_enable;
if (dec->sprite_enable != SPRITE_GMC)
{
int sprite_width;
int sprite_height;
int sprite_left_coord;
int sprite_top_coord;
sprite_width = BitstreamGetBits(bs, 13); /* sprite_width */
READ_MARKER();
sprite_height = BitstreamGetBits(bs, 13); /* sprite_height */
READ_MARKER();
sprite_left_coord = BitstreamGetBits(bs, 13); /* sprite_left_coordinate */
READ_MARKER();
sprite_top_coord = BitstreamGetBits(bs, 13); /* sprite_top_coordinate */
READ_MARKER();
}
dec->sprite_warping_points = BitstreamGetBits(bs, 6); /* no_of_sprite_warping_points */
dec->sprite_warping_accuracy = BitstreamGetBits(bs, 2); /* sprite_warping_accuracy */
dec->sprite_brightness_change = BitstreamGetBits(bs, 1); /* brightness_change */
if (dec->sprite_enable != SPRITE_GMC)
{
low_latency_sprite_enable = BitstreamGetBits(bs, 1); /* low_latency_sprite_enable */
}
}
if (vol_ver_id != 1 &&
dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) {
BitstreamSkip(bs, 1); /* sadct_disable */
}
if (BitstreamGetBit(bs)) /* not_8_bit */
{
DPRINTF(XVID_DEBUG_HEADER, "not_8_bit==true (ignored)\n");
dec->quant_bits = BitstreamGetBits(bs, 4); /* quant_precision */
BitstreamSkip(bs, 4); /* bits_per_pixel */
} else {
dec->quant_bits = 5;
}
if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE) {
BitstreamSkip(bs, 1); /* no_gray_quant_update */
BitstreamSkip(bs, 1); /* composition_method */
BitstreamSkip(bs, 1); /* linear_composition */
}
dec->quant_type = BitstreamGetBit(bs); /* quant_type */
DPRINTF(XVID_DEBUG_HEADER, "quant_type %i\n", dec->quant_type);
if (dec->quant_type) {
if (BitstreamGetBit(bs)) /* load_intra_quant_mat */
{
uint8_t matrix[64];
DPRINTF(XVID_DEBUG_HEADER, "load_intra_quant_mat\n");
bs_get_matrix(bs, matrix);
set_intra_matrix(dec->mpeg_quant_matrices, matrix);
} else
set_intra_matrix(dec->mpeg_quant_matrices, get_default_intra_matrix());
if (BitstreamGetBit(bs)) /* load_inter_quant_mat */
{
uint8_t matrix[64];
DPRINTF(XVID_DEBUG_HEADER, "load_inter_quant_mat\n");
bs_get_matrix(bs, matrix);
set_inter_matrix(dec->mpeg_quant_matrices, matrix);
} else
set_inter_matrix(dec->mpeg_quant_matrices, get_default_inter_matrix());
if (dec->shape == VIDOBJLAY_SHAPE_GRAYSCALE) {
DPRINTF(XVID_DEBUG_ERROR, "greyscale matrix not supported\n");
return -1;
}
}
if (vol_ver_id != 1) {
dec->quarterpel = BitstreamGetBit(bs); /* quarter_sample */
DPRINTF(XVID_DEBUG_HEADER,"quarterpel %i\n", dec->quarterpel);
}
else
dec->quarterpel = 0;
dec->complexity_estimation_disable = BitstreamGetBit(bs); /* complexity estimation disable */
if (!dec->complexity_estimation_disable)
{
read_vol_complexity_estimation_header(bs, dec);
}
BitstreamSkip(bs, 1); /* resync_marker_disable */
if (BitstreamGetBit(bs)) /* data_partitioned */
{
DPRINTF(XVID_DEBUG_ERROR, "data_partitioned not supported\n");
BitstreamSkip(bs, 1); /* reversible_vlc */
}
if (vol_ver_id != 1) {
dec->newpred_enable = BitstreamGetBit(bs);
if (dec->newpred_enable) /* newpred_enable */
{
DPRINTF(XVID_DEBUG_HEADER, "+ newpred_enable\n");
BitstreamSkip(bs, 2); /* requested_upstream_message_type */
BitstreamSkip(bs, 1); /* newpred_segment_type */
}
dec->reduced_resolution_enable = BitstreamGetBit(bs); /* reduced_resolution_vop_enable */
DPRINTF(XVID_DEBUG_HEADER, "reduced_resolution_enable %i\n", dec->reduced_resolution_enable);
}
else
{
dec->newpred_enable = 0;
dec->reduced_resolution_enable = 0;
}
dec->scalability = BitstreamGetBit(bs); /* scalability */
if (dec->scalability)
{
DPRINTF(XVID_DEBUG_ERROR, "scalability not supported\n");
BitstreamSkip(bs, 1); /* hierarchy_type */
BitstreamSkip(bs, 4); /* ref_layer_id */
BitstreamSkip(bs, 1); /* ref_layer_sampling_direc */
BitstreamSkip(bs, 5); /* hor_sampling_factor_n */
BitstreamSkip(bs, 5); /* hor_sampling_factor_m */
BitstreamSkip(bs, 5); /* vert_sampling_factor_n */
BitstreamSkip(bs, 5); /* vert_sampling_factor_m */
BitstreamSkip(bs, 1); /* enhancement_type */
if(dec->shape == VIDOBJLAY_SHAPE_BINARY /* && hierarchy_type==0 */) {
BitstreamSkip(bs, 1); /* use_ref_shape */
BitstreamSkip(bs, 1); /* use_ref_texture */
BitstreamSkip(bs, 5); /* shape_hor_sampling_factor_n */
BitstreamSkip(bs, 5); /* shape_hor_sampling_factor_m */
BitstreamSkip(bs, 5); /* shape_vert_sampling_factor_n */
BitstreamSkip(bs, 5); /* shape_vert_sampling_factor_m */
}
return -1;
}
} else /* dec->shape == BINARY_ONLY */
{
if (vol_ver_id != 1) {
dec->scalability = BitstreamGetBit(bs); /* scalability */
if (dec->scalability)
{
DPRINTF(XVID_DEBUG_ERROR, "scalability not supported\n");
BitstreamSkip(bs, 4); /* ref_layer_id */
BitstreamSkip(bs, 5); /* hor_sampling_factor_n */
BitstreamSkip(bs, 5); /* hor_sampling_factor_m */
BitstreamSkip(bs, 5); /* vert_sampling_factor_n */
BitstreamSkip(bs, 5); /* vert_sampling_factor_m */
return -1;
}
}
BitstreamSkip(bs, 1); /* resync_marker_disable */
}
return (resize ? -3 : -2 ); /* VOL */
} else if (start_code == GRPOFVOP_START_CODE) {
DPRINTF(XVID_DEBUG_STARTCODE, "<group_of_vop>\n");
BitstreamSkip(bs, 32);
{
int hours, minutes, seconds;
hours = BitstreamGetBits(bs, 5);
minutes = BitstreamGetBits(bs, 6);
READ_MARKER();
seconds = BitstreamGetBits(bs, 6);
DPRINTF(XVID_DEBUG_HEADER, "time %ih%im%is\n", hours,minutes,seconds);
}
BitstreamSkip(bs, 1); /* closed_gov */
BitstreamSkip(bs, 1); /* broken_link */
} else if (start_code == VOP_START_CODE) {
DPRINTF(XVID_DEBUG_STARTCODE, "<vop>\n");
BitstreamSkip(bs, 32); /* vop_start_code */
coding_type = BitstreamGetBits(bs, 2); /* vop_coding_type */
DPRINTF(XVID_DEBUG_HEADER, "coding_type %i\n", coding_type);
/*********************** for decode B-frame time ***********************/
while (BitstreamGetBit(bs) != 0) /* time_base */
time_incr++;
READ_MARKER();
if (dec->time_inc_bits) {
time_increment = (BitstreamGetBits(bs, dec->time_inc_bits)); /* vop_time_increment */
}
DPRINTF(XVID_DEBUG_HEADER, "time_base %i\n", time_incr);
DPRINTF(XVID_DEBUG_HEADER, "time_increment %i\n", time_increment);
DPRINTF(XVID_DEBUG_TIMECODE, "%c %i:%i\n",
coding_type == I_VOP ? 'I' : coding_type == P_VOP ? 'P' : coding_type == B_VOP ? 'B' : 'S',
time_incr, time_increment);
if (coding_type != B_VOP) {
dec->last_time_base = dec->time_base;
dec->time_base += time_incr;
dec->time = dec->time_base*dec->time_inc_resolution + time_increment;
dec->time_pp = (int32_t)(dec->time - dec->last_non_b_time);
dec->last_non_b_time = dec->time;
} else {
dec->time = (dec->last_time_base + time_incr)*dec->time_inc_resolution + time_increment;
dec->time_bp = dec->time_pp - (int32_t)(dec->last_non_b_time - dec->time);
}
DPRINTF(XVID_DEBUG_HEADER,"time_pp=%i\n", dec->time_pp);
DPRINTF(XVID_DEBUG_HEADER,"time_bp=%i\n", dec->time_bp);
READ_MARKER();
if (!BitstreamGetBit(bs)) /* vop_coded */
{
DPRINTF(XVID_DEBUG_HEADER, "vop_coded==false\n");
return N_VOP;
}
if (dec->newpred_enable)
{
int vop_id;
int vop_id_for_prediction;
vop_id = BitstreamGetBits(bs, MIN(dec->time_inc_bits + 3, 15));
DPRINTF(XVID_DEBUG_HEADER, "vop_id %i\n", vop_id);
if (BitstreamGetBit(bs)) /* vop_id_for_prediction_indication */
{
vop_id_for_prediction = BitstreamGetBits(bs, MIN(dec->time_inc_bits + 3, 15));
DPRINTF(XVID_DEBUG_HEADER, "vop_id_for_prediction %i\n", vop_id_for_prediction);
}
READ_MARKER();
}
/* fix a little bug by MinChen <chenm002@163.com> */
if ((dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) &&
( (coding_type == P_VOP) || (coding_type == S_VOP && dec->sprite_enable == SPRITE_GMC) ) ) {
*rounding = BitstreamGetBit(bs); /* rounding_type */
DPRINTF(XVID_DEBUG_HEADER, "rounding %i\n", *rounding);
}
if (dec->reduced_resolution_enable &&
dec->shape == VIDOBJLAY_SHAPE_RECTANGULAR &&
(coding_type == P_VOP || coding_type == I_VOP)) {
if (BitstreamGetBit(bs));
DPRINTF(XVID_DEBUG_ERROR, "RRV not supported (anymore)\n");
}
if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR) {
if(!(dec->sprite_enable == SPRITE_STATIC && coding_type == I_VOP)) {
uint32_t width, height;
uint32_t horiz_mc_ref, vert_mc_ref;
width = BitstreamGetBits(bs, 13);
READ_MARKER();
height = BitstreamGetBits(bs, 13);
READ_MARKER();
horiz_mc_ref = BitstreamGetBits(bs, 13);
READ_MARKER();
vert_mc_ref = BitstreamGetBits(bs, 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);
}
BitstreamSkip(bs, 1); /* change_conv_ratio_disable */
if (BitstreamGetBit(bs)) /* vop_constant_alpha */
{
BitstreamSkip(bs, 8); /* vop_constant_alpha_value */
}
}
if (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY) {
if (!dec->complexity_estimation_disable)
{
read_vop_complexity_estimation_header(bs, dec, coding_type);
}
/* intra_dc_vlc_threshold */
*intra_dc_threshold =
intra_dc_threshold_table[BitstreamGetBits(bs, 3)];
dec->top_field_first = 0;
dec->alternate_vertical_scan = 0;
if (dec->interlacing) {
dec->top_field_first = BitstreamGetBit(bs);
DPRINTF(XVID_DEBUG_HEADER, "interlace top_field_first %i\n", dec->top_field_first);
dec->alternate_vertical_scan = BitstreamGetBit(bs);
DPRINTF(XVID_DEBUG_HEADER, "interlace alternate_vertical_scan %i\n", dec->alternate_vertical_scan);
}
}
if ((dec->sprite_enable == SPRITE_STATIC || dec->sprite_enable== SPRITE_GMC) && coding_type == S_VOP) {
int i;
for (i = 0 ; i < dec->sprite_warping_points; i++)
{
int length;
int x = 0, y = 0;
/* sprite code borowed from ffmpeg; thx Michael Niedermayer <michaelni@gmx.at> */
length = bs_get_spritetrajectory(bs);
if(length){
x= BitstreamGetBits(bs, length);
if ((x >> (length - 1)) == 0) /* if MSB not set it is negative*/
x = - (x ^ ((1 << length) - 1));
}
READ_MARKER();
length = bs_get_spritetrajectory(bs);
if(length){
y = BitstreamGetBits(bs, length);
if ((y >> (length - 1)) == 0) /* if MSB not set it is negative*/
y = - (y ^ ((1 << length) - 1));
}
READ_MARKER();
gmc_warp->duv[i].x = x;
gmc_warp->duv[i].y = y;
DPRINTF(XVID_DEBUG_HEADER,"sprite_warping_point[%i] xy=(%i,%i)\n", i, x, y);
}
if (dec->sprite_brightness_change)
{
/* XXX: brightness_change_factor() */
}
if (dec->sprite_enable == SPRITE_STATIC)
{
/* XXX: todo */
}
}
if ((*quant = BitstreamGetBits(bs, dec->quant_bits)) < 1) /* vop_quant */
*quant = 1;
DPRINTF(XVID_DEBUG_HEADER, "quant %i\n", *quant);
if (coding_type != I_VOP) {
*fcode_forward = BitstreamGetBits(bs, 3); /* fcode_forward */
DPRINTF(XVID_DEBUG_HEADER, "fcode_forward %i\n", *fcode_forward);
}
if (coding_type == B_VOP) {
*fcode_backward = BitstreamGetBits(bs, 3); /* fcode_backward */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -