www.pudn.com > avs-m3.rar > annexb.c
/*! ************************************************************************************* * \file * bitstream.c * \brief * bitstream handling including high-level syntax parset and NAL de-compression etc. * \notes: * upadated @ June 14th 2005 according to the FCD ************************************************************************************* */ #include//#include #include "global.h" #include "annexb.h" #include "memalloc.h" #include "nalu.h" FILE *bits = NULL; //!< the bit stream file InputStream IRABS , *pIRABS = &IRABS; /*! ************************************************************************************* * \brief : * Open the Byte Stream ************************************************************************************* */ void OpenAnnexbFile(char *fn) { if ( NULL == (bits=fopen(fn, "rb")) ) //!< open bitstream file in bit format { snprintf (errortext, ET_SIZE, "Cannot open Annex B ByteStream file '%s'", input->infile); error(errortext,500); } } /*! ************************************************************************************* * \brief : * Close the Byte Stream ************************************************************************************* */ void CloseAnnexbFile() { fclose(bits); } /*! ************************************************************************************* * \brief : * get the current nalu_header * \notes : * code : OK * -1 : arrive at stream end and start code is not found * -2 : Pop->iBytesition error ************************************************************************************* */ int GetNaluHeader(InputStream *p) { int i, m=0;//change m=0 by stephen for debug unsigned char a,b,c; // a b c 0 1 2 3 4 ... M-3 M-2 M-1 while(1) { if(p->iBytePosition >= p->iBufBytesNum - 3) //if all bytes in buffer has been searched { m = p->iBufBytesNum - p->iBytePosition; if(m <0) return -2; // p->iBytePosition error if(m==1) c=p->buf[p->iBytePosition]; if(m==2){ c=p->buf[p->iBytePosition+1]; b=p->buf[p->iBytePosition];} if(m==3){ c=p->buf[p->iBytePosition+2]; b=p->buf[p->iBytePosition+1];a=p->buf[p->iBytePosition];} p->iBufBytesNum = fread(p->buf,1,SVA_STREAM_BUF_SIZE,bits); p->iBytePosition = 0; } if(p->iBufBytesNum + m < 4) return -1; //arrive at stream end and start code is not found if(m==1 && c==0 && p->buf[0]==0 && p->buf[1]==1) { p->iBytePosition = 3; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount += 32; p->uPre3Bytes = p->buf[2]+256; //printf("p->uPre3Bytes is %x n1\n",p->uPre3Bytes); return p->buf[2]; } if(m==2 && b==0 && c==0 && p->buf[0]==1) { p->iBytePosition = 2; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount += 32; p->uPre3Bytes = p->buf[1]+256; //printf("p->uPre3Bytes is %x n2\n",p->uPre3Bytes); return p->buf[1]; } if(m==3 && a==0 && b==0 && c==1) { p->iBytePosition = 1; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount += 32; p->uPre3Bytes = p->buf[0]+256; //printf("p->uPre3Bytes is %x n3\n",p->uPre3Bytes); return p->buf[0]; } for(i = p->iBytePosition; i < p->iBufBytesNum - 3; i++) { if(p->buf[i]==0 && p->buf[i+1]==0 && p->buf[i+2]==1) { p->iBytePosition = i+4; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount += 24; p->uPre3Bytes = p->buf[i+3]+256; //printf("p->uPre3Bytes is %x n0\n",p->uPre3Bytes); return p->buf[i+3]; } p->iBitsCount += 8; } p->iBytePosition = i; } } /*! ************************************************************************************* * \brief : * read one byte of the nalu payload * \notes : * code : meet the nalu header * -1 : arrive at stream end * -2 : OK ************************************************************************************* */ int read_1_byte(InputStream *p, int *value) { int i,k,j; unsigned char temp[4]; int read_len=0;//WJP FOR NAL ADD i = p->iBytePosition; k = p->iBufBytesNum - i; if(k < 4) { for(j=0;j buf[i+j]; read_len/*p->iBufBytesNum*/ = fread(p->buf+k,1,SVA_STREAM_BUF_SIZE-k,bits);//WJP FOR NAL ADD if(read_len == 0)//WJP FOR NAL ADD { if(k>0) { p->uClearBits = (p->uClearBits << 8) | p->buf[i]; p->iClearBitsNum += 8; p->iBytePosition++; *value = p->buf[i]; return -2; } else { return -1;//arrive at stream end } } else { for(j=0;j buf[j] = temp[j]; p->iBufBytesNum = read_len + k;//WJP FOR NAL ADD i = p->iBytePosition = 0; } } if(p->buf[i]==0 && p->buf[i+1]==0 && p->buf[i+2]==1) { //printf("The next code is %x c\n",p->buf[i+3]); return p->buf[i+3];// meet another start code } p->uPre3Bytes = ((p->uPre3Bytes<<8) | p->buf[i]) & 0x00ffffff; p->uClearBits = (p->uClearBits << 8) | p->buf[i]; p->iClearBitsNum += 8; p->iBytePosition++; *value = p->buf[i]; return -2; } /*! ************************************************************************************* * \brief : * get the a unit start with a start code. * \notes : * code : meet the nalu header * -1 : arrive at stream end * -2 : OK ************************************************************************************* */ int GetOneUnit (NALU_t *nalu, int *next_nalu_type) { int i,j,k; int nalu_over=0; i = GetNaluHeader(pIRABS); nalu->buf[0] = i; nalu->nal_unit_type = i & 31; i >>= 5; nalu->nal_reference_idc = i & 3; i >>= 2; nalu->forbidden_bit = i & 1; #if ERR_REPORT CheckNALUValid(nalu->buf[0],p_err); #endif //GET the nalu payload and find the next nalu type k=1; while(!nalu_over) { i = read_1_byte(pIRABS,&j); //code : meet the nalu header // -1 : arrive at stream end // -2 : OK if(i == -2) nalu->buf[k++] = (char)j; else if(i == -1) { *next_nalu_type = -1; break; } else { nalu_over = 1; *next_nalu_type = i & 31; } } nalu->len = k; return 1; } void DecodeTrailingBits(Bitstream *bitstream) { int ctr_bit, bitoffset, trailingbits; bitoffset = 0; //find trailing 1 ctr_bit = (bitstream->streamBuffer[currStream->bitstream_length-1] & (0x01< streamBuffer[currStream->bitstream_length-1] & (0x01<<(bitoffset)); } trailingbits = (0x01 << bitoffset); #if TRACE tracebits2("Byte Stream Trailing Bits",(bitoffset+1),trailingbits); #endif } void DecodeTrailingBits1(Bitstream *bitstream,int bitstream_length) { int ctr_bit, bitoffset, trailingbits; bitoffset = 0; //find trailing 1 ctr_bit = (bitstream->streamBuffer[bitstream_length-1] & (0x01< streamBuffer[bitstream_length-1] & (0x01<<(bitoffset)); } trailingbits = (0x01 << bitoffset); #if TRACE tracebits2("Byte Stream Trailing Bits",(bitoffset+1),trailingbits); #endif }