📄 bitstream.c
字号:
BitstreamSkip(bs, 1); // sadct_disable
}
if (BitstreamGetBit(bs)) // not_8_bit
{
//DEBUG("+ not_8_bit [IGNORED/TODO]");
quant_bits = BitstreamGetBits(bs, 4); // quant_precision
BitstreamSkip(bs, 4); // bits_per_pixel
}
else
{
quant_bits = 5;
}
if (shape == VIDOBJLAY_SHAPE_GRAYSCALE)
{
BitstreamSkip(bs, 1); // no_gray_quant_update
BitstreamSkip(bs, 1); // composition_method
BitstreamSkip(bs, 1); // linear_composition
}
quant_type = BitstreamGetBit(bs); // quant_type
// DEBUG1("**** quant_type", dec->quant_type);
if (quant_type)
{
if (BitstreamGetBit(bs)) // load_intra_quant_mat
{
}
else
//set_intra_matrix(get_default_intra_matrix());
if (BitstreamGetBit(bs)) // load_inter_quant_mat
{
}
else
//set_inter_matrix(get_default_inter_matrix());
if (shape == VIDOBJLAY_SHAPE_GRAYSCALE)
{
// TODO
fprintf(stderr,"TODO: grayscale matrix stuff\n");
return -1;
}
}
if (vol_ver_id != 1)
{
quarterpel = BitstreamGetBit(bs); // quarter_sampe
if (quarterpel)
{
fprintf(stderr,"IGNORED/TODO: quarter_sample\n");
}
}
else
{
quarterpel = 0;
}
if (!BitstreamGetBit(bs)) // complexity_estimation_disable
{
fprintf(stderr,"TODO: complexity_estimation header\n");
// TODO
return -1;
}
if (!BitstreamGetBit(bs)) // resync_marker_disable
{
fprintf(stderr,"IGNORED/TODO: !resync_marker_disable\n");
// TODO
}
if (BitstreamGetBit(bs)) // data_partitioned
{
fprintf(stderr,"+ data_partitioned\n");
BitstreamSkip(bs, 1); // reversible_vlc
}
if (vol_ver_id != 1)
{
if (BitstreamGetBit(bs)) // newpred_enable
{
fprintf(stderr,"+ newpred_enable\n");
BitstreamSkip(bs, 2); // requested_upstream_message_type
BitstreamSkip(bs, 1); // newpred_segment_type
}
if (BitstreamGetBit(bs)) // reduced_resolution_vop_enable
{
fprintf(stderr,"TODO: reduced_resolution_vop_enable\n");
// TODO
return -1;
}
}
if (BitstreamGetBit(bs)) // scalability
{
// TODO
fprintf(stderr,"TODO: scalability\n");
return -1;
}
}
else // dec->shape == BINARY_ONLY
{
if (vol_ver_id != 1)
{
if (BitstreamGetBit(bs)) // scalability
{
// TODO
fprintf(stderr,"TODO: scalability\n");
return -1;
}
}
BitstreamSkip(bs, 1); // resync_marker_disable
}
param->width = width;
param->height = height;
param->time_inc_bits = time_inc_bits;
param->framerate = (time_inc_resolution+1)*1000/1001;
return 1;
}
else if (start_code == GRPOFVOP_START_CODE)
{
// DEBUG("group_of_vop");
BitstreamSkip(bs, 32);
{
hours = BitstreamGetBits(bs, 5);
minutes = BitstreamGetBits(bs, 6);
READ_MARKER();
seconds = BitstreamGetBits(bs, 6);
// DEBUG3("hms", hours, minutes, seconds);
}
BitstreamSkip(bs, 1); // closed_gov
BitstreamSkip(bs, 1); // broken_link
}
else if (start_code == VOP_START_CODE)
{
if (findvol != 0) return -1;
// DEBUG("vop_start_code");
BitstreamSkip(bs, 32); // vop_start_code
coding_type = BitstreamGetBits(bs, 2); // vop_coding_type
//DEBUG1("coding_type", coding_type);
while (BitstreamGetBit(bs) != 0) ; // time_base
READ_MARKER();
//DEBUG1("time_inc_bits", dec->time_inc_bits);
//DEBUG1("vop_time_incr", BitstreamShowBits(bs, dec->time_inc_bits));
if (time_inc_bits)
{
BitstreamSkip(bs, time_inc_bits); // vop_time_increment
}
READ_MARKER();
if (!BitstreamGetBit(bs)) // vop_coded
{
return N_VOP;
}
if (coding_type != I_VOP)
{
rounding = BitstreamGetBit(bs); // rounding_type
//DEBUG1("rounding", *rounding);
}
if (shape != VIDOBJLAY_SHAPE_RECTANGULAR)
{
temp_width = BitstreamGetBits(bs, 13);
READ_MARKER();
temp_height = BitstreamGetBits(bs, 13);
READ_MARKER();
horiz_mc_ref = BitstreamGetBits(bs, 13);
READ_MARKER();
vert_mc_ref = BitstreamGetBits(bs, 13);
READ_MARKER();
// DEBUG2("vop_width/height", width, height);
// DEBUG2("ref ", horiz_mc_ref, vert_mc_ref);
BitstreamSkip(bs, 1); // change_conv_ratio_disable
if (BitstreamGetBit(bs)) // vop_constant_alpha
{
BitstreamSkip(bs, 8); // vop_constant_alpha_value
}
}
if (shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
{
// intra_dc_vlc_threshold
intra_dc_threshold = intra_dc_threshold_table[ BitstreamGetBits(bs,3) ];
if (interlacing)
{
if ((top_field_first = BitstreamGetBit(bs)))
{
fprintf(stderr,"vop: top_field_first\n");
}
if ((alternate_vertical_scan = BitstreamGetBit(bs)))
{
fprintf(stderr,"vop: alternate_vertical_scan");
}
}
}
quant = BitstreamGetBits(bs, quant_bits); // vop_quant
//DEBUG1("quant", *quant);
if (coding_type != I_VOP)
{
fcode = BitstreamGetBits(bs, 3); // fcode_forward
}
if (coding_type == B_VOP)
{
// *fcode_backward = BitstreamGetBits(bs, 3); // fcode_backward
}
return coding_type;
}
else if (start_code == USERDATA_START_CODE)
{
// DEBUG("user_data");
BitstreamSkip(bs, 32); // user_data_start_code
}
else if ((start_code & 0xfffffc03) == 0x00008002)
{
// Short video header. Skip short_video_start_marker,
// temporal reference, marker and zero bit
have_short_header = 1;
shape = VIDOBJLAY_SHAPE_RECTANGULAR;
interlacing = 0;
quant_bits = 5;
quant_type = 0;
quarterpel = 0;
intra_dc_threshold = intra_dc_threshold_table[0];
rounding = 0;
fcode = 1;
BitstreamSkip(bs, 22);
BitstreamSkip(bs, 8 + 5);
source_format = BitstreamGetBits(bs, 3);
switch (source_format) {
case 1: // sub-QCIF
width = 128;
height = 96;
break;
case 2: // QCIF
width = 176;
height = 144;
break;
case 3: // CIF
width = 352;
height = 288;
break;
case 4: // 4CIF
width = 704;
height = 576;
break;
case 5:
width = 1408;
height = 1152;
break;
default:
fprintf(stderr,"FATAL: illegal code in short video header %u\n", source_format);
return -1;
}
if (findvol == 0) {
if (temp_width != width || temp_height != height)
{
fprintf(stderr,"FATAL: video dimension discrepancy ***");
fprintf(stderr,"bitstream width %u /height %u \n", width, height);
fprintf(stderr,"param width %u /height %u \n", width, height);
return -1;
}
}
else
{
width = temp_width;
height = temp_height;
param->width = width;
param->height = height;
return 1;
}
if (BitstreamGetBit(bs))
{
// P frame
coding_type = P_VOP;
}
else
{
coding_type = I_VOP;
}
BitstreamSkip(bs, 4); // skip 4 reserved 0 bits
quant = BitstreamGetBits(bs, 5);
BitstreamSkip(bs, 1);
while (BitstreamGetBit(bs) == 1) BitstreamSkip(bs, 8); // pei and psupp
return coding_type;
}
else // start_code == ?
{
if (BitstreamShowBits(bs, 24) == 0x000001)
{
fprintf(stderr,"*** WARNING: unknown start_code%u\n", BitstreamShowBits(bs, 32));
}
BitstreamSkip(bs, 8);
}
}
while ((BitstreamPos(bs) >> 3) < bs->length);
fprintf(stderr,"*** WARNING: no vop_start_code found");
if (findvol != 0) return 0;
return -1; /* ignore it */
}
////////////////////////////////////
/* initialise bitstream structure */
void BitstreamInit(Bitstream * bs,/*const uint32_t * bitstream,*/uint32_t length)
{
uint32_t tmp;
bs->start = bs->tail = (uint32_t*)bitstream;
tmp = *(uint32_t *)bitstream;
bs->bufa = tmp;
tmp = *((uint32_t *)bitstream+1);
bs->bufb = tmp;
bs->buf = 0;
bs->pos = 0;
bs->length = length;
}
//////////////////////////////
// entire function added for mpeg4ip
int decoder_find_vol( uint32_t length,XVID_DEC_PARAM * param)
{
Bitstream bs;
int ret;
BitstreamInit(&bs,length);
ret = BitstreamReadHeaders(&bs,param,1);
return ret;
}
int parse_vovod(unsigned char *ConfigHex,unsigned int HexLen,unsigned *FrameRate,unsigned *TimeIncBits,unsigned *Width,unsigned *Height)
{
int ret = -1;
int size_int = 0;
int i = 0,j = 0;
XVID_DEC_PARAM param;
// Get the VO/VOL header. If we fail, set the bytestream back
size_int = HexLen/sizeof(uint32_t)+1;
bitstream = (uint32_t *)malloc(size_int*sizeof(uint32_t));
if(bitstream == NULL)
{
fprintf(stderr,"bitstream alloc failed \n");
return ret;
}
for(i=0;i<size_int;i++)
{
bitstream[i] = ((ConfigHex[j]&0xff)<<24)|((ConfigHex[j+1]&0xff)<<16)|((ConfigHex[j+2]&0xff)<<8)|(ConfigHex[j+3]&0xff);
j = j+sizeof(uint32_t);
fprintf(stderr,"bitstream i %d,%x\n",i,*(bitstream+i));
}
ret = 0;
ret = decoder_find_vol(HexLen, ¶m);
*Width = param.width;
*Height = param.height;
*TimeIncBits = param.time_inc_bits;
*FrameRate = param.framerate;
free(bitstream);
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -