www.pudn.com > wm2.5.zip > bitstream.c
/*! ************************************************************************************* * \file bitstream.c * * \brief * * * \date: updating* * \author * ************************************************************************************* */ #include #include #include #include "global.h" #include "bitstream.h" #include "memalloc.h" #include "nalu.h"//WJP FOR NAL //////////////////////////////////////////////////////////////////////////////// FILE *bits = NULL; //!< the bit stream file //WJP FOR SLICE //extern int Position_of_Slice_in_Picbuff[176]; //extern int Slice_Enable; #define SVA_STREAM_BUF_SIZE 1024 //unsigned char bit[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; typedef struct { 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 IRABS , *pIRABS = &IRABS; /* ************************************************************************* * Function:get the current nalu_header. * Input: * Output: * Return: code : OK -1 : arrive at stream end and start code is not found -2 : Pop->iBytesition error * Author: Jianpeng Wang ************************************************************************* */ int GetNaluHeader(InputStream *p) { int i, m; 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; } } /* ************************************************************************* * Function:read one byte of the nalu payload * Input: * Output: * Return: code : meet the nalu header -1 : arrive at stream end -2 : OK * Author: Jianpeng Wang ************************************************************************* */ 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; } /* ************************************************************************* * Function:get the a unit start with a start code. * Input: * Output: * Return: * Attention: Modified by Jianpeng Wang ************************************************************************* */ 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; //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; }