📄 bitstream.c
字号:
}
if (!BitstreamGetBit(bs)) // resync_marker_disable
{
DEBUG("IGNORED/TODO: !resync_marker_disable");
// TODO
}
if (BitstreamGetBit(bs)) // data_partitioned
{
DEBUG("+ data_partitioned");
BitstreamSkip(bs, 1); // reversible_vlc
}
if (vol_ver_id != 1)
{
if (BitstreamGetBit(bs)) // newpred_enable
{
DEBUG("+ newpred_enable");
BitstreamSkip(bs, 2); // requested_upstream_message_type
BitstreamSkip(bs, 1); // newpred_segment_type
}
if (BitstreamGetBit(bs)) // reduced_resolution_vop_enable
{
DEBUG("TODO: reduced_resolution_vop_enable");
// TODO
return -1;
}
}
if (BitstreamGetBit(bs)) // scalability
{
// TODO
DEBUG("TODO: scalability");
return -1;
}
}
else // dec->shape == BINARY_ONLY
{
if (vol_ver_id != 1)
{
if (BitstreamGetBit(bs)) // scalability
{
// TODO
DEBUG("TODO: scalability");
return -1;
}
}
BitstreamSkip(bs, 1); // resync_marker_disable
}
if (findvol != 0) return 1;
}
else if (start_code == GRPOFVOP_START_CODE)
{
// DEBUG("group_of_vop");
BitstreamSkip(bs, 32);
{
int hours, minutes, seconds;
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 (dec->time_inc_bits)
{
BitstreamSkip(bs, dec->time_inc_bits); // vop_time_increment
}
READ_MARKER();
if (!BitstreamGetBit(bs)) // vop_coded
{
return N_VOP;
}
/* if (newpred_enable)
{
}
*/
if (coding_type != I_VOP)
{
*rounding = BitstreamGetBit(bs); // rounding_type
//DEBUG1("rounding", *rounding);
}
/* if (reduced_resolution_enable)
{
}
*/
if (dec->shape != VIDOBJLAY_SHAPE_RECTANGULAR)
{
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();
// 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 (dec->shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
{
// intra_dc_vlc_threshold
*intra_dc_threshold = intra_dc_threshold_table[ BitstreamGetBits(bs,3) ];
if (dec->interlacing)
{
if ((dec->top_field_first = BitstreamGetBit(bs)))
{
DEBUG("vop: top_field_first");
}
if ((dec->alternate_vertical_scan = BitstreamGetBit(bs)))
{
DEBUG("vop: alternate_vertical_scan");
}
}
}
*quant = BitstreamGetBits(bs, dec->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 // start_code == ?
{
if (BitstreamShowBits(bs, 24) == 0x000001)
{
DEBUG1("*** WARNING: unknown start_code", BitstreamShowBits(bs, 32));
}
BitstreamSkip(bs, 8);
}
}
while ((BitstreamPos(bs) >> 3) < bs->length);
DEBUG("*** WARNING: no vop_start_code found");
if (findvol != 0) return 0;
return -1; /* ignore it */
}
/* write custom quant matrix */
static void bs_put_matrix(Bitstream * bs, const int16_t *matrix)
{
int i, j;
const int last = matrix[scan_tables[0][63]];
for (j = 63; j >= 0 && matrix[scan_tables[0][j - 1]] == last; j--) ;
for (i = 0; i <= j; i++)
{
BitstreamPutBits(bs, matrix[scan_tables[0][i]], 8);
}
if (j < 63)
{
BitstreamPutBits(bs, 0, 8);
}
}
#ifdef MPEG4IP
/*
write vosh header
*/
void BitstreamWriteVoshHeader(Bitstream * const bs)
{
BitstreamPad(bs);
BitstreamPutBits(bs, VISOBJSEQ_START_CODE, 32);
BitstreamPutBits(bs, 3, 8); // Simple Profile @ L3
// video object_start_code
BitstreamPutBits(bs, VISOBJ_START_CODE, 32);
// no verid, priority, or signal type
BitstreamPutBits(bs, 0x08, 8);
// video object_start_code & vo_id
BitstreamPutBits(bs, VO_START_CODE, 27);
BitstreamPutBits(bs, 0, 5);
}
#endif
/*
write vol header
*/
void BitstreamWriteVolHeader(Bitstream * const bs,
const MBParam * pParam)
{
BitstreamPad(bs);
#ifndef MPEG4IP
// video object_start_code & vo_id
BitstreamPutBits(bs, VO_START_CODE, 27);
BitstreamPutBits(bs, 0, 5);
#endif
// video_object_layer_start_code & vol_id
BitstreamPutBits(bs, VOL_START_CODE, 28);
BitstreamPutBits(bs, 0, 4);
BitstreamPutBit(bs, 0); // random_accessible_vol
#ifdef MPEG4IP
BitstreamPutBits(bs, 1, 8); // video_object_type_indication
// 1 == simple profile
BitstreamPutBit(bs, 1); // is_object_layer_identified
BitstreamPutBits(bs, 2, 4); // visual object layer ver id = 2
BitstreamPutBits(bs, 1, 3); // visual object layer priority = 1
#else
BitstreamPutBits(bs, 0, 8); // video_object_type_indication
BitstreamPutBit(bs, 0); // is_object_layer_identified (0=not given)
#endif
BitstreamPutBits(bs, 1, 4); // aspect_ratio_info (1=1:1)
BitstreamPutBit(bs, 0); // vol_control_parameters (0=not given)
BitstreamPutBits(bs, 0, 2); // video_object_layer_shape (0=rectangular)
WRITE_MARKER();
/* time_increment_resolution; ignored by current decore versions
eg. 2fps res=2 inc=1
25fps res=25 inc=1
29.97fps res=30000 inc=1001
*/
#ifdef MPEG4IP
BitstreamPutBits(bs, pParam->fbase, 16);
#else
BitstreamPutBits(bs, 2, 16);
#endif
WRITE_MARKER();
// fixed_vop_rate
// MPEG4IP - above comment is incorrect, 0 signals variable rate
BitstreamPutBit(bs, 0);
// fixed_time_increment: value=nth_of_sec, nbits = log2(resolution)
// BitstreamPutBits(bs, 0, 15);
WRITE_MARKER();
BitstreamPutBits(bs, pParam->width, 13); // width
WRITE_MARKER();
BitstreamPutBits(bs, pParam->height, 13); // height
WRITE_MARKER();
BitstreamPutBit(bs, pParam->global_flags & XVID_INTERLACING); // interlace
BitstreamPutBit(bs, 1); // obmc_disable (overlapped block motion compensation)
#ifdef MPEG4IP
BitstreamPutBits(bs, 0, 2); // sprite_usage
#else
BitstreamPutBit(bs, 0); // sprite_enable
#endif
BitstreamPutBit(bs, 0); // not_in_bit
// quant_type 0=h.263 1=mpeg4(quantizer tables)
BitstreamPutBit(bs, pParam->quant_type);
if (pParam->quant_type)
{
BitstreamPutBit(bs, get_intra_matrix_status()); // load_intra_quant_mat
if (get_intra_matrix_status())
{
bs_put_matrix(bs, get_intra_matrix());
}
BitstreamPutBit(bs, get_inter_matrix_status()); // load_inter_quant_mat
if (get_inter_matrix_status())
{
bs_put_matrix(bs, get_inter_matrix());
}
}
#ifdef MPEG4IP
BitstreamPutBit(bs, 0); // quarter pixel
#endif
BitstreamPutBit(bs, 1); // complexity_estimation_disable
BitstreamPutBit(bs, 1); // resync_marker_disable
BitstreamPutBit(bs, 0); // data_partitioned
#ifdef MPEG4IP
BitstreamPutBit(bs, 0); // newpred
BitstreamPutBit(bs, 0); // reduced resolution vop
#endif
BitstreamPutBit(bs, 0); // scalability
}
/*
write vop header
NOTE: doesnt handle bother with time_base & time_inc
time_base = n seconds since last resync (eg. last iframe)
time_inc = nth of a second since last resync
(decoder uses these values to determine precise time since last resync)
*/
void BitstreamWriteVopHeader(Bitstream * const bs,
const MBParam * pParam)
{
BitstreamPad(bs);
BitstreamPutBits(bs, VOP_START_CODE, 32);
BitstreamPutBits(bs, pParam->coding_type, 2);
// time_base = 0 write n x PutBit(1), PutBit(0)
BitstreamPutBits(bs, 0, 1);
WRITE_MARKER();
// time_increment: value=nth_of_sec, nbits = log2(resolution)
#ifdef MPEG4IP
BitstreamPutBits(bs, pParam->fincr, pParam->time_inc_bits);
#else
BitstreamPutBits(bs, 1, 1);
#endif
WRITE_MARKER();
BitstreamPutBits(bs, 1, 1); // vop_coded
if (pParam->coding_type != I_VOP)
BitstreamPutBits(bs, pParam->rounding_type, 1);
BitstreamPutBits(bs, 0, 3); // intra_dc_vlc_threshold
if (pParam->global_flags & XVID_INTERLACING)
{
BitstreamPutBit(bs, 1); // top field first
BitstreamPutBit(bs, 0); // alternate vertical scan
}
BitstreamPutBits(bs, pParam->quant, 5); // quantizer
if (pParam->coding_type != I_VOP)
BitstreamPutBits(bs, pParam->fixed_code, 3); // fixed_code = [1,4]
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -