📄 bitpack.cpp
字号:
/* modified by Jie Liang (Texas Instruments)
to return the last bits left in the last byte */
Int CVTCDecoder::align_byte1()
{
Int i;
if((i=(bit_num+1)%8)==0)
return 0;
return(get_X_bits(i)<<(8-i));
}
Int CVTCDecoder::align_byte ()
{
Int i;
if((i=(bit_num+1)%8)==0)
i=8; /* for stuffing as defined in CD 6.2.1 */
junkCount += i;
//Added by Sarnoff for error resilience, 3/5/99
if(!mzte_codec.m_usErrResiDisable)
packet_size -= i;
else
//End: Added by Sarnoff for error resilience, 3/5/99
count -= i;
return(get_X_bits(i)<<(8-i));
}
/* added by Jie Liang (Texas Instruments) */
/* the data needs to by byte aligned first */
Int CVTCDecoder::get_allbits (Char *buffer)
{
Int n,len;
Int loc=0;
/* read until end of file */
do {
buffer[loc]=get_X_bits(8);
loc++;
}while (!feof(bitfile));
/* read until the data in buffer is finished */
len = buffer_length-byte_ptr+2;
for (n=0;n<len;n++)
{
buffer[loc]=get_X_bits(8);
loc++;
}
return loc;
}
/* added by Jie Liang (Texas Instruments) */
/* check the next four bytes for start code */
Int CVTCDecoder::Is_startcode (long startcode)
{
long next_4bytes=0;
Int i;
Int offset;
if (bit_num>=7)
offset=1;
else
offset=0;
next_4bytes = output_buffer[byte_ptr-offset];
for(i=0;i<3;i++)
next_4bytes = (next_4bytes<<8)+output_buffer[byte_ptr-offset+1+i];
if(next_4bytes == startcode)
return 1;
return 0;
}
#define MAXRUNZERO 22 // hjlee
Void CVTCEncoder::emit_bits_checksc(UInt code, Int size)
{
Int m;
Int bit;
for(m=size-1;m>=0;m--){
bit = (code>>m) & (0x01);
emit_bits (bit, 1);
/* update zero bit count */
if (bit)
zerocount=0;
else
zerocount++;
if (zerocount>=MAXRUNZERO)
{ /* exceeding maximum runs, add 1 */
emit_bits (1, 1);
zerocount=0;
}
} /* end of m - bits */
return;
}
Void CVTCEncoder::emit_bits_checksc_init()
{
zerocount=0;
}
Int CVTCDecoder::get_X_bits_checksc(Int nbits)
{
Int v=0;
Int bit;
while (nbits--){
if(zerocount==MAXRUNZERO) /*skip next bit */
{
// if(!nextinputbit()) ; deleted by swinder
nextinputbit(); // added by swinder
// noteProgress("Possible start code emulation error: should be 1 after MAXZERORUN 0's");
zerocount = 0;
}
bit = nextinputbit();
if(!bit)
zerocount++;
else
zerocount =0;
v = (v << 1) + bit;
}
return v;
}
Void CVTCDecoder::get_X_bits_checksc_init()
{
zerocount=0;
}
Int CVTCDecoder::get_allbits_checksc (unsigned char *buffer)
{
Int n,len;
Int loc=0;
/* read until end of file */
do {
buffer[loc]=get_X_bits_checksc(8);
loc++;
}while (!feof(bitfile));
/* read until the data in buffer is finished */
len = buffer_length-byte_ptr+2;
for (n=0;n<len;n++)
{
buffer[loc]=get_X_bits_checksc(8);
loc++;
}
return loc;
}
Int CVTCDecoder::align_byte_checksc ()
{
Int bit;
Int i;
Int m;
Int out=0;
Int n=0;
if((i=(bit_num+1)%8)==0)
return 0;
for(m=0;m<i;m++){
if(zerocount==MAXRUNZERO){
get_X_bits(1);
zerocount=0;
}
else{
bit = get_X_bits(1);
out = (out<<1) | bit;
if (bit)
zerocount=0;
else
zerocount++;
n++;
}
}
return(out<<(8-n));
}
/* This program combine the stuff in bitbuffer Into the actual bitstream */
Void CVTCEncoder::write_to_bitstream(UChar *bitbuffer,Int total_bits)
{
Int i,bit_stream_length=total_bits>>3, resid=total_bits%8;
/* write to file assume file has been opened by control program*/
for(i=0;i<bit_stream_length;i++)
emit_bits(bitbuffer[i],8);
if(resid != 0)
emit_bits(bitbuffer[bit_stream_length]>>(8-resid),resid);
}
/* get the number of bytes already decoded */
int CVTCDecoder::decoded_bytes_from_bitstream ()
{
long n;
n = ftell(bitfile);
return (n+byte_ptr);
}
// begin: added by Sharp (99/2/16)
Void CVTCDecoder::search_tile(int target_tile_id)
{
Int still_tile_start_code, tile_id;
long pos=prev_start_code;
fseek(bitfile, pos, SEEK_SET);
init_bit_packing_fp(bitfile, 1);
while (1){
do {
fseek(bitfile, pos+1, SEEK_SET);
init_bit_packing_fp(bitfile, 1);
pos = ftell(bitfile);
/* printf("%d\n", pos);*/
still_tile_start_code = get_X_bits(32);
} while ( still_tile_start_code != 0x000001c1);
prev_start_code = pos;
tile_id = get_X_bits(16);
if ( tile_id == target_tile_id ){
fseek(bitfile, pos, SEEK_SET);
init_bit_packing_fp(bitfile, 1);
break;
}
}
}
Void CVTCDecoder::relative_jump(long size)
{
long current;
current = ftell(bitfile);
fseek(bitfile, size-current, SEEK_CUR);
init_bit_packing_fp(bitfile,1);
/* printf("Jump to %ld\n", size);*/
/* fseek(bitfile, size, SEEK_SET);*/
/* Int i;*/
/* for ( i=0; i<size; i++ )*/
/* get_X_bits(8);*/
}
long CVTCEncoder::current_fp()
{
return ftell(bitfile);
}
Int CVTCEncoder::current_put_bits()
{
return huff_put_bits;
}
// end: added by Sharp (99/2/16)
//Added by Sarnoff for error resilience, 3/5/99
/* -------------------------------------------------------- */
/* -------------- Error Resilience Routines --------------- */
/* -------------------------------------------------------- */
/****************************************************/
/* count the number of erroneous bits, bbc, 8/24/98 */
/****************************************************/
static Int error_bits=0, count_marker=0;
Void CVTCDecoder::error_bits_stat(int error_mode)
{
if(error_mode ==1 ) /* have error, accumulate error count */
error_bits +=count-count_marker;
/* reset count marker */
count_marker=count;
/* fp=fopen("count.txt","a");
fprintf(fp, "[TU_%d,TU_%d] error_mode=%d, count=%d, err_count=%d\n",
TU_first, TU_last,error_mode, count,error_bits);
fclose(fp); */
}
/* get 17 bit resynch marker etc for error resilience, bbc, 6/12/98 */
Int CVTCDecoder::get_err_resilience_header()
{
static int first_get=0;
packet_size=0;
/* check end of file */
if(feof(bitfile) && buffer_length==0){
TU_first=TU_last=TU_max+1;
return TU_first;
}
/* skip error packets,bbc, 6/29/98 */
if(RESYNCH_MARKER != get_X_bits(17)){
noteWarning("Incorrect resynch marker.");
errSignal=-10;
return(TU_max);
}
if(prev_TU_err != -1){ /* not the first time, bbc, 9/8/98 */
prev_TU_err=0;
prev_TU_first=TU_first;
prev_TU_last=TU_last;
}
if(first_get==0){ /* first time in the function, reset */
first_get=1;
prev_TU_err=0;
}
error_bits_stat(0); /* bbc, 8/25/98 */
TU_first=get_param(7);
if(TU_first>TU_max){
errSignal=-13;
return TU_first;
}
else if(prev_TU_err==0){
if(TU_first != prev_TU_last+1){ /* compare with previous packet */
errSignal=-12;
return (TU_first);
}
}
/* compare with older packets */
else if(TU_first <=prev_TU_last && TU_first !=0){
errSignal=-12;
return (TU_first);
}
TU_last=get_param(7);
if(TU_last>TU_max && TU_first !=0){
errSignal=-13;
return TU_first;
}
else if(TU_last < TU_first){
errSignal=-12;
return (TU_first);
}
packet_size=-1; /* account for the HEC to be read in next */
return(TU_first); /* return the next TU_no to be decoded, bbc, 6/29/98 */
}
/*********************************************************/
/* put TU numbera into TU_buf, refer to VTC syntax */
/* for algorithm, modified from put_param. Always assume */
/* using 7 bit format */
/*********************************************************/
static Int put_param_TU(Int value)
{
Int extension;
Int module = 128;
Int mask = 127;
while (value/module > 0) {
extension = 1;
TU_buf[TU_buf_len++]=((value%module) | (extension << 7));
value = value >> 7;
}
extension = 0;
TU_buf[TU_buf_len++]=((value & mask) | (extension << 7));
return (TU_buf_len<<3);
}
/******************************************************/
/* New routine to write packet header to the right */
/* place in the bitstream. This routine assumes that */
/* the output_buffer contains only the information */
/* on current packet with the first bit left as dummy */
/* for this fn to fill in. bbc, 6/27/98 */
/******************************************************/
Void CVTCEncoder::write_packet_header_to_file()
{
Int i,k;
UChar temp[12];
TU_buf_len=0;
put_param_TU(TU_first); /* first TU_number */
put_param_TU(TU_last); /* number of TU's in the packet */
/* Resynch marker */
temp[0]=temp[1]=0;
/* Add TU's */
temp[2]=128|(TU_buf[0]>>1);
for(i=1,k=3;i<TU_buf_len;i++,k++)
temp[k]=(TU_buf[i-1]<<7)|(TU_buf[i]>>1);
fwrite(temp,sizeof(UChar),k,bitfile); /* write header part to file before
data */
/* count overheads, 17 resynch, 16 TU, 1 HEC, bbc, 7/9/98 */
totalBitRate +=k<<3;
/* overwrite the first bit in output_buffer */
output_buffer[0]=(TU_buf[i-1]<<7)|(output_buffer[0]&0x7f);
}
Void CVTCDecoder::rewind_bits(Int nbits)
{
bit_num+=nbits;
count -=nbits;
/* if(nbits>16) */
/* errorHandler("Cannot rewind more than 16 bits yet."); */
if(bit_num>64)
errorHandler("Cannot rewind %d bits. Rewinded bit_num=%d.",nbits,bit_num);
}
/* check if at the end of bitstream, bbc, 7/30/98 */
int CVTCDecoder::end_of_stream()
{
return (out_src>=2);
}
//End: Added by Sarnoff for error resilience, 3/5/99
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -