⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitstream.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (info!=NULL) {
      /* write info string */
      if (fputs(info,stream->file) == EOF) {
	CommonWarning("BsOpenFileWrite: "
		      "error writing bit stream file (header)");
	BsClose(stream);
	return NULL;
      }
      if (fputc('\0',stream->file) == EOF) {
	CommonWarning("BsOpenFileWrite: "
		      "error writing bit stream file (header)");
	BsClose(stream);
	return NULL;
      }
    }
  }

  stream->currentBit = 0;
  stream->numByte = 0;

  return stream;
}


/* BsOpenBufferRead() */
/* Open bit stream buffer for reading. */

BsBitStream *BsOpenBufferRead (
  BsBitBuffer *buffer)		/* in: bit buffer */
				/* returns: */
				/*  bit stream (handle) */
{
  BsBitStream *stream;

  if (BSdebugLevel >= 2)
    printf("BsOpenBufferRead: id=%ld  bufNumBit=%ld  bufSize=%ld  "
	   "bufAddr=0x%lx\n",
	   BSstreamId,buffer->numBit,buffer->size,(unsigned long)buffer);

  if ((stream=(BsBitStream*)malloc(sizeof(BsBitStream))) == NULL)
    CommonExit(1,"BsOpenBufferRead: memory allocation error");

  stream->file = NULL;
  stream->write = 0;
  stream->streamId = BSstreamId++;
  stream->info = NULL;

  stream->buffer[0] = buffer;
  stream->currentBit = 0;
  
  return stream;
}


/* BsOpenBufferWrite() */
/* Open bit stream buffer for writing. */
/* (Buffer is cleared first - previous data in buffer is lost !!!) */

BsBitStream *BsOpenBufferWrite (
  BsBitBuffer *buffer)		/* in: bit buffer */
				/* returns: */
				/*  bit stream (handle) */
{
  BsBitStream *stream;

  if (BSdebugLevel >= 2)
    printf("BsOpenBufferWrite: id=%ld  bufNumBit=%ld  bufSize=%ld  "
	   "bufAddr=0x%lx\n",
	   BSstreamId,buffer->numBit,buffer->size,(unsigned long)buffer);

  if ((stream=(BsBitStream*)malloc(sizeof(BsBitStream))) == NULL)
    CommonExit(1,"BsOpenBufferWrite: memory allocation error");

  stream->file = NULL;
  stream->write = 1;
  stream->streamId = BSstreamId++;
  stream->info = NULL;

  stream->buffer[0] = buffer;
  BsClearBuffer(buffer);
  stream->currentBit = 0;
  
  return stream;
}


/* BsCurrentBit() */
/* Get number of bits read/written from/to stream. */

long BsCurrentBit (
  BsBitStream *stream)		/* in: bit stream */
				/* returns: */
				/*  number of bits read/written */
{
  return stream->currentBit;
}


/* BsEof() */
/* Test if end of bit stream file occurs within the next numBit bits. */

int BsEof (
  BsBitStream *stream,		/* in: bit stream */
  long numBit)			/* in: number of bits ahead scanned for EOF */
				/* returns: */
				/*  0=not EOF  1=EOF */
{
  int eof;

  if (BSdebugLevel >= 2)
    printf("BsEof: %s  id=%ld  curBit=%ld  numBit=%ld\n",
	   (stream->file!=NULL)?"file":"buffer",
	   stream->streamId,stream->currentBit,numBit);

  if (stream->file != NULL && numBit > stream->buffer[0]->size)
    CommonExit(1,"BsEof: "
	       "number of bits to look ahead too high (%ld)",numBit);

  if (BsReadAhead(stream,numBit+1)) {
    CommonWarning("BsEof: error reading bit stream");
    eof = 0;
  }
  else
    eof = BsCheckRead(stream,numBit+1);

  if (BSdebugLevel >= 2)
    printf("BsEof: eof=%d\n",eof);

  return eof;
}


static void BsRemoveBufferOffset (BsBitBuffer *buffer, long startPosBit)
{
  int           bitsToCopy;
  BsBitStream*  offset_stream;
  BsBitBuffer*  helpBuffer;

  /* open bit stream buffer for reading */
  offset_stream = BsOpenBufferRead(buffer);

  /* create help buffer */
  helpBuffer = BsAllocBuffer(buffer->size);
  

  /* read bits from bit stream to help buffer */
  offset_stream->currentBit =  startPosBit;
  bitsToCopy = buffer->numBit - startPosBit;
  if (BsGetBuffer(offset_stream, helpBuffer, bitsToCopy))
    CommonExit(1, "BsRemoveBufferOffset: error reading bit stream");

  /* close bit stream (no remove) */
  BsCloseRemove(offset_stream, 0);

  /* memcpy the offset free data from help buffer to buffer */
  memcpy(buffer->data, helpBuffer->data, bit2byte(buffer->size));

  /*FREE help buffer */
  BsFreeBuffer(helpBuffer);

  buffer->numBit = bitsToCopy;
}


/* BsCloseRemove() */
/* Close bit stream. */

int BsCloseRemove (
  BsBitStream *stream,		/* in: bit stream */
  int remove)			/* in: if opened with BsOpenBufferRead(): */
				/*       0 = keep buffer unchanged */
				/*       1 = remove bits read from buffer */
				/* returns: */
				/*  0=OK  1=error */
{
  int returnFlag = 0;
  int tmp,i;
  long startPosBit;

  if ((stream->file != NULL) && (BSdebugLevel >= 1) )
    printf("BsClose: %s  %s  id=%ld  curBit=%ld\n",
	   (stream->write)?"write":"read",
	   (stream->file!=NULL)?"file":"buffer",
	   stream->streamId,stream->currentBit);

  if (stream->file != NULL) {
    if (stream->write == 1)
      /* flush buffer to file */
      if (BsWriteFile(stream)) {
	CommonWarning("BsClose: error writing bit stream");
	returnFlag = 1;
      }

    BsFreeBuffer(stream->buffer[0]);
    if (stream->write == 0)
      BsFreeBuffer(stream->buffer[1]);
    
    if (stream->file!=stdin && stream->file!=stdout)
      if (fclose(stream->file)) {
	CommonWarning("BsClose: error closing bit stream file");
	returnFlag = 1;
      }
  }
  else if (stream->write == 0 && remove){    
    /* remove all completely read bytes from buffer */
    tmp = stream->currentBit/8;
    for (i=0; i<((stream->buffer[0]->size+7)>>3)-tmp; i++)
      stream->buffer[0]->data[i] = stream->buffer[0]->data[i+tmp];
    startPosBit = stream->currentBit - tmp*8;
    if ((startPosBit>7) || (startPosBit<0)){
      CommonExit(1,"BsClose: Error removing bit in buffer");        
    }
    stream->buffer[0]->numBit -= tmp*8;      

    /* better located here ???   HP/BT 990520 */
    if (stream->buffer[0]->numBit <= startPosBit) {
      stream->buffer[0]->numBit=0;
      startPosBit=0;
    }

    /* remove remaining read bits from buffer          */
    /* usually we do not have remaining bits in buffer 
     reply: that not really true, eg. HVXC frames are not byte aligned, thereofore you have remaining bits after every second frame, 
    BT*/
    if (startPosBit != 0)
      {
      /* printf("Remove buffer offset: %li\n", startPosBit); */
      BsRemoveBufferOffset(stream->buffer[0], startPosBit);
      if ((stream->currentBit - startPosBit) < 0)
        CommonExit(1,"BsClose: Error decreasing currentBit");
      else
        stream->currentBit -= startPosBit;
      }
  }

  if (stream->info != NULL)
   FREE(stream->info);
 FREE(stream);
  return returnFlag;
}


/* BsClose() */
/* Close bit stream. */

int BsClose (
  BsBitStream *stream)		/* in: bit stream */
				/* returns: */
				/*  0=OK  1=error */
{
 return BsCloseRemove(stream,0);
}


/* BsGetBit() */
/* Read bits from bit stream. */
/* (Current position in bit stream is advanced !!!) */

int BsGetBit (
  BsBitStream *stream,		/* in: bit stream */
  unsigned long *data,		/* out: bits read */
				/*      (may be NULL if numBit==0) */
  int numBit)			/* in: num bits to read */
				/*     [0..32] */
				/* returns: */
				/*  0=OK  1=error */
{
  int		num;
  int		maxNum;
  int		curNum;
  unsigned long bits;

  if (BSdebugLevel >= 3)
    printf("BsGetBit: %s  id=%ld  numBit=%d  curBit=%ld\n",
	   (stream->file!=NULL)?"file":"buffer",
	   stream->streamId,numBit,stream->currentBit);

  if (stream->write != 0)
    CommonExit(1,"BsGetBit: stream not in read mode");
  if (numBit<0 || numBit>LONG_NUMBIT)
    CommonExit(1,"BsGetBit: number of bits out of range (%d)",numBit);

  if (data != NULL)
    *data = 0;
  if (numBit == 0)
    return 0;

  /* read bits in packets according to buffer byte boundaries */
  num = 0;
  maxNum = BYTE_NUMBIT - stream->currentBit % BYTE_NUMBIT;
  while (num < numBit) {
    curNum = min(numBit-num,maxNum);
    if (BsReadByte(stream,&bits,curNum) != curNum) {
      if ( ! BSaacEOF || BSdebugLevel > 0  ) 
        CommonWarning("BsGetBit: error reading bit stream");

      if ( BSaacEOF  ) {        
        return -1;/* end of stream */
      } else {
        return 1; 
      }
    }
    *data |= bits<<(numBit-num-curNum);
    num += curNum;
    maxNum = BYTE_NUMBIT;
  }

  if (BSdebugLevel >= 3)
    printf("BsGetBit: data=0x%lx\n",*data);

  return 0;
}


/* this function is mainly for debugging purpose, */
/* you can call it from the debugger */
long int BsGetBitBack (
  BsBitStream *stream,		/* in: bit stream */
  int numBit)			/* in: num bits to read */
				/*     [0..32] */
				/* returns: */
				/*  if numBit is positive
				      return the last numBits bit from stream
				    else
				      return the next -numBits from stream 
				    stream->currentBit is always unchanged */
{
  int		num;
  int		maxNum;
  int		curNum;
  unsigned long bits;
  long int	data;
  int		rewind = 0;

  if (BSdebugLevel >= 3)
    printf("BsGetBitBack: %s  id=%ld  numBit=%d  curBit=%ld\n",
	   (stream->file!=NULL)?"file":"buffer",
	   stream->streamId,numBit,stream->currentBit);

  /*   if (stream->write != 0) */
  /*	 CommonWarning("BsGetBitBack: stream not in read mode"); */
  if (numBit<-32 || numBit>LONG_NUMBIT)
    CommonExit(1,"BsGetBitBack: number of bits out of range (%d)",numBit);

  data = 0;
  if (numBit == 0)
    return 0;
  if (numBit > 0)
    stream->currentBit-=numBit;
  else {
    rewind = 1;
    numBit = -numBit;
  }
    
  if (stream->currentBit<0){
    stream->currentBit+=numBit;
    CommonWarning("BsGetBitBack: stream enough bits in stream ");
    return 0;
  }

  /* read bits in packets according to buffer byte boundaries */
  num = 0;
  maxNum = BYTE_NUMBIT - stream->currentBit % BYTE_NUMBIT;
  while (num < numBit) {
    curNum = min(numBit-num,maxNum);
    if (BsReadByte(stream,&bits,curNum) != curNum) {
      CommonWarning("BsGetBitBack: error reading bit stream");
      return 0;
    }
    data |= bits<<(numBit-num-curNum);
    num += curNum;
    maxNum = BYTE_NUMBIT;
  }
  if (rewind) /* rewind */
    stream->currentBit-=numBit;

  if (BSdebugLevel >= 3)
    printf("BsGetBitBack: data=0x%lx\n",data);

  return data;
}


/* BsGetBitChar() */
/* Read bits from bit stream (char). */
/* (Current position in bit stream is advanced !!!) */

int BsGetBitChar (
  BsBitStream *stream,		/* in: bit stream */
  unsigned char *data,		/* out: bits read */
				/*      (may be NULL if numBit==0) */
  int numBit)			/* in: num bits to read */
				/*     [0..8] */
				/* returns: */
				/*  0=OK  1=error */
{
  unsigned long ultmp;
  int result;

  if (numBit > 8)
    CommonExit(1,"BsGetBitChar: number of bits out of range (%d)",numBit);
  if (data != NULL)
    *data = 0;
  if (numBit == 0)
    return 0;
  result = BsGetBit(stream,&ultmp,numBit);
  *data = ultmp;
  return result;
}


/* BsGetBitShort() */
/* Read bits from bit stream (short). */
/* (Current position in bit stream is advanced !!!) */

int BsGetBitShort (
  BsBitStream *stream,		/* in: bit stream */
  unsigned short *data,		/* out: bits read */
				/*      (may be NULL if numBit==0) */
  int numBit)			/* in: num bits to read */
				/*     [0..16] */
				/* returns: */
				/*  0=OK  1=error */
{
  unsigned long ultmp;
  int result;

  if (numBit > 16)
    CommonExit(1,"BsGetBitShort: number of bits out of range (%d)",numBit);
  if (data != NULL)
    *data = 0;
  if (numBit == 0)
    return 0;
  result = BsGetBit(stream,&ultmp,numBit);
  *data = ultmp;
  return result;
}


/* BsGetBitInt() */
/* Read bits from bit stream (int). */
/* (Current position in bit stream is advanced !!!) */

int BsGetBitInt (
  BsBitStream *stream,		/* in: bit stream */
  unsigned int *data,		/* out: bits read */
				/*      (may be NULL if numBit==0) */
  int numBit)			/* in: num bits to read */
				/*     [0..16] */
				/* returns: */
				/*  0=OK  1=error */
{
  unsigned long ultmp;
  int result;

  if (numBit > 16)
    CommonExit(1,"BsGetBitInt: number of bits out of range (%d)",numBit);
  if (data != NULL)
    *data = 0;
  if (numBit == 0)
    return 0;
  result = BsGetBit(stream,&ultmp,numBit);
  *data = ultmp;
  return result;
}


/* BsGetBitAhead() */
/* Read bits from bit stream. */
/* (Current position in bit stream is NOT advanced !!!) */

int BsGetBitAhead (
  BsBitStream *stream,		/* in: bit stream */
  unsigned long *data,		/* out: bits read */
				/*      (may be NULL if numBit==0) */
  int numBit)			/* in: num bits to read */
				/*     [0..32] */
				/* returns: */
				/*  0=OK  1=error */
{
  long oldCurrentBit;
  int  result;

  if (BSdebugLevel >= 3)
    printf("BsGetBitAhead: %s  id=%ld  numBit=%d\n",
	   (stream->file!=NULL)?"file":"buffer",stream->streamId,numBit);

  oldCurrentBit = stream->currentBit;
  result = BsGetBit(stream,data,numBit);
  stream->currentBit = oldCurrentBit;
  if (result)
    CommonWarning("BsGetBitAhead: error reading bit stream");

  return result;
}


/* BsGetBitAheadChar() */
/* Read bits from bit stream (char). */
/* (Current position in bit stream is NOT advanced !!!) */

int BsGetBitAheadChar (
  BsBitStream *stream,		/* in: bit stream */
  unsigned char *data,		/* out: bits read */
				/*      (may be NULL if numBit==0) */
  int numBit)			/* in: num bits to read */
				/*     [0..8] */
				/* returns: */
				/*  0=OK  1=error */
{
  long oldCurrentBit;
  int result;

  if (BSdebugLevel >= 3)
    printf("BsGetBitAheadChar: %s  id=%ld  numBit=%d\n",
	   (stream->file!=NULL)?"file":"buffer",stream->streamId,numBit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -