www.pudn.com > rm52h.rar > bitstream.c
/* *********************************************************************** * COPYRIGHT AND WARRANTY INFORMATION * * Copyright 2003, Advanced Audio Video Coding Standard, Part II * * DISCLAIMER OF WARRANTY * * These software programs are available to the users without any * license fee or royalty on an "as is" basis. The AVS disclaims * any and all warranties, whether express, implied, or statutory, * including any implied warranties of merchantability or of fitness * for a particular purpose. In no event shall the contributors or * the AVS be liable for any incidental, punitive, or consequential * damages of any kind whatsoever arising from the use of this program. * * This disclaimer of warranty extends to the user of this program * and user's customers, employees, agents, transferees, successors, * and assigns. * * The AVS does not represent or warrant that the program furnished * hereunder are free of infringement of any third-party patents. * Commercial implementations of AVS, including shareware, may be * subject to royalty fees to patent holders. Information regarding * the AVS patent policy is available from the AVS Web site at * http://www.avs.org.cn * * THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. ************************************************************************ */ /* ************************************************************************************* * File name: bitstream.c * Function: decode bitstream * ************************************************************************************* */ #include#include #include #include "global.h" #include "annexb.h" #include "memalloc.h" #define SVA_STREAM_BUF_SIZE 1024 FILE *bitsfile = NULL; //!< the bit stream file unsigned char bit[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; typedef struct { FILE *f; unsigned char buf[SVA_STREAM_BUF_SIZE]; //流缓冲区,size must be large than 3 bytes unsigned int uClearBits;//不含填充位的位缓冲,32位,初始值是0xFFFFFFFF unsigned int uPre3Bytes;// 含填充位的位缓冲,32位,初始值是0x00000000 int iBytePosition; //当前字节位置 int iBufBytesNum; //最近一次读入缓冲区的字节数 int iClearBitsNum; //不含填充位的位的个数 int iStuffBitsNum; //已剔除的填充位的个数,遇到开始码时置0 int iBitsCount; //码流总位数 } InputStream; InputStream IRABS; InputStream *pIRABS = &IRABS; void OpenIRABS(InputStream *p, char *fname) { p->f = fopen(fname,"rb"); if(p->f==NULL){printf ("\nCan't open file %s",fname);exit(-1);} p->uClearBits = 0xffffffff; p->iBytePosition = 0; p->iBufBytesNum = 0; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount = 0; p->uPre3Bytes = 0; } void CloseIRABS(InputStream *p) { fclose(p->f); } //------------------------------------------------------------------------ // move iBytePosition to the next byte of start code prefix //return // 0 : OK // -1 : arrive at stream end and start code is not found // -2 : p->iBytePosition error //------------------------------------------------------------------------- int NextStartCode(InputStream *p) { int i, m; unsigned char a,b; // a b 0 1 2 3 4 ... M-3 M-2 M-1 m=0; // cjw 20060323 for linux envi while(1) { if(p->iBytePosition >= p->iBufBytesNum - 2) //if all bytes in buffer has been searched { m = p->iBufBytesNum - p->iBytePosition; if(m <0) return -2; // p->iBytePosition error if(m==1) b=p->buf[p->iBytePosition+1]; if(m==2){ b=p->buf[p->iBytePosition+1]; a=p->buf[p->iBytePosition];} p->iBufBytesNum = fread(p->buf,1,SVA_STREAM_BUF_SIZE,p->f); p->iBytePosition = 0; } if(p->iBufBytesNum + m < 3) return -1; //arrive at stream end and start code is not found if(m==1 && b==0 && p->buf[0]==0 && p->buf[1]==1) { p->iBytePosition = 2; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount += 24; p->uPre3Bytes = 1; return 0; } if(m==2 && b==0 && a==0 && p->buf[0]==1) { p->iBytePosition = 1; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount += 24; p->uPre3Bytes = 1; return 0; } if(m==2 && b==0 && p->buf[0]==0 && p->buf[1]==1) { p->iBytePosition = 2; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount += 24; p->uPre3Bytes = 1; return 0; } for(i = p->iBytePosition; i < p->iBufBytesNum - 2; i++) { if(p->buf[i]==0 && p->buf[i+1]==0 && p->buf[i+2]==1) { p->iBytePosition = i+3; p->iClearBitsNum = 0; p->iStuffBitsNum = 0; p->iBitsCount += 24; p->uPre3Bytes = 1; return 0; } p->iBitsCount += 8; } p->iBytePosition = i; } } //---------------------------------------------------------------------- //return // 0 : OK // -1 : arrive at stream end // -2 : meet another start code //---------------------------------------------------------------------- int ClearNextByte(InputStream *p) { int i,k,j; unsigned char temp[3]; i = p->iBytePosition; k = p->iBufBytesNum - i; if(k < 3) { for(j=0;j buf[i+j]; p->iBufBytesNum = fread(p->buf+k,1,SVA_STREAM_BUF_SIZE-k,p->f); if(p->iBufBytesNum == 0) { if(k>0) { p->uPre3Bytes = ((p->uPre3Bytes<<8) | p->buf[i]) & 0x00ffffff; if(p->uPre3Bytes < 4) { p->uClearBits = (p->uClearBits << 6) | (p->buf[i] >> 2); p->iClearBitsNum += 6; } else { p->uClearBits = (p->uClearBits << 8) | p->buf[i]; p->iClearBitsNum += 8; } p->iBytePosition++; return 0; } else { return -1;//arrive at stream end } } else { for(j=0;j buf[j] = temp[j]; p->iBufBytesNum += k; i = p->iBytePosition = 0; } } if(p->buf[i]==0 && p->buf[i+1]==0 && p->buf[i+2]==1) return -2;// meet another start code p->uPre3Bytes = ((p->uPre3Bytes<<8) | p->buf[i]) & 0x00ffffff; if(p->uPre3Bytes < 4) { p->uClearBits = (p->uClearBits << 6) | (p->buf[i] >> 2); p->iClearBitsNum += 6; } else { p->uClearBits = (p->uClearBits << 8) | p->buf[i]; p->iClearBitsNum += 8; } p->iBytePosition++; return 0; } //---------------------------------------------------------- //return // 0 : OK // -1 : arrive at stream end // -2 : meet another start code //---------------------------------------------------------- int read_n_bit(InputStream *p,int n,int *v) { int r; unsigned int t; while(n > p->iClearBitsNum) { r = ClearNextByte( p ); if(r) { if(r==-1) { if(p->iBufBytesNum - p->iBytePosition > 0) break; } return r; } } t = p->uClearBits; r = 32 - p->iClearBitsNum; *v = (t << r) >> (32 - n); p->iClearBitsNum -= n; return 0; } //================================================================================== void OpenBitstreamFile (char *fn) { OpenIRABS(pIRABS, fn); } void CloseBitstreamFile() { CloseIRABS(pIRABS); } static int FindStartCode (unsigned char *Buf, int i) { if(Buf[i]==0 && Buf[i+1]==0 && Buf[i+2]==1) return 1; else return 0; } //////////////////////////////////////////////////////////////////////////// //check slice start code jlzheng 6.30 //////////////////////////////////////////////////////////////////////////// int checkstartcode() //check slice start code jlzheng 6.30 { int temp_i, temp_val; if (currStream->bitstream_length*8 - currStream->frame_bitoffset == 0) return 1; if(img->current_mb_nr == 0) { //--- added by Yulj 2004.07.15 if ( currStream->bitstream_length*8 - currStream->frame_bitoffset <=8 && currStream->bitstream_length*8 - currStream->frame_bitoffset > 0 ){ temp_i = currStream->bitstream_length*8 - currStream->frame_bitoffset; assert( temp_i > 0 ); temp_val = get_uv(temp_i, "filling data") ; } } if(img->current_mb_nr == 0) { if(StartCodePosition>6 && StartCodePosition<20) return 1; else { currStream->frame_bitoffset = currentbitoffset; return 0; } } if(img->current_mb_nr != 0) { //--- added by Yulj 2004.07.15 if (currStream->bitstream_length*8 - currStream->frame_bitoffset <= 8 && currStream->bitstream_length*8 - currStream->frame_bitoffset >0){ temp_i = currStream->bitstream_length*8 - currStream->frame_bitoffset; assert( temp_i > 0 ); temp_val = get_uv(temp_i, "filling data") ; if ( temp_val == (1 << (temp_i -1)) && img->cod_counter <= 0 ) return 1; // last MB in current slice } return 0; // not last MB in current slice //---end } return 1; } //------------------------------------------------------------ // buf : buffer // startcodepos : // length : int GetOneUnit (char *buf,int *startcodepos,int *length) { int i,j,k; i = NextStartCode(pIRABS); if(i!=0) { if(i==-1) printf("\narrive at stream end and start code is not found!"); if(i==-2) printf("\np->iBytePosition error!"); exit(i); } buf[0] = 0; buf[1] = 0; buf[2] = 1; *startcodepos = 3; i = read_n_bit(pIRABS,8,&j); buf[3] = (char)j; if(buf[3]==SEQUENCE_END_CODE) { *length = 4; return -1; } k = 4; while(1) { i = read_n_bit(pIRABS,8,&j); if(i<0) break; buf[k++] = (char)j; } if(pIRABS->iClearBitsNum>0) { int shift; shift = 8 - pIRABS->iClearBitsNum; i = read_n_bit(pIRABS,pIRABS->iClearBitsNum,&j); if(j!=0) //qhg 20060327 for de-emulation. buf[k++] = (char)(j<