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

📄 decoder.c

📁 This document aims to provide instructions on how to configure the H.264/AVC encoder and decoder usi
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * readBytesFromFile: * * Parameters: *      str                   Bitbuffer object * * Function: *      Read bytes from the bistream file * * Returns: *      Number of bytes read * */static int readBytesFromFile(byteStream_s *str){  int n;  if (str->bitbufLen - str->bitbufDataLen < NALBUF_BLOCK_SIZE) {    /* Buffer is too small -> allocate bigger buffer */    str->bitbuf = realloc(str->bitbuf, str->bitbufLen+NALBUF_BLOCK_SIZE);    if (str->bitbuf == NULL) {      fprintf(stderr, "Cannot resize bitbuffer\n");      exit(1);    }    str->bitbufLen += NALBUF_BLOCK_SIZE;  }  /* Read block of data */  n = (int)fread(str->bitbuf + str->bitbufDataLen, 1, NALBUF_BLOCK_SIZE, str->fn);  str->bytesRead     += n;  str->bitbufDataLen += n;  return n;}/* * * findStartCode: * * Parameters: *      str                   Bitbuffer object * * Function: *      First next start code in AVC byte stream * * Returns: *      Length of start code * *      str->bitbufDataPos will point to first byte that follows start code */static int findStartCode(byteStream_s *str){  int numZeros;  int startCodeFound;  int i;  int currByte;  numZeros       = 0;  startCodeFound = 0;  i = str->bitbufDataPos;  while (!startCodeFound) {    if (i == str->bitbufDataLen) {      /* We are at the end of data -> read more from the bitstream file */      int n = readBytesFromFile(str);      if (n == 0)        /* End of bitstream -> stop search */        break;    }    /* Find sequence of 0x00 ... 0x00 0x01 */    while (i < str->bitbufDataLen) {      currByte = str->bitbuf[i];      i++;      if (currByte > 1) /* If current byte is > 1, it cannot be part of a start code */        numZeros = 0;      else if (currByte == 0)  /* If current byte is 0, it could be part of a start code */        numZeros++;      else {                    /* currByte == 1 */        if (numZeros > 1) {  /* currByte == 1. If numZeros > 1, we found a start code */          startCodeFound = 1;          break;        }        numZeros = 0;      }    }  }  str->bitbufDataPos = i;  if (startCodeFound)    return (numZeros + 1);  else    return 0;}/* * * getNalunitBits_ByteStream: * * Parameters: *      strIn                 Bytestream pointer * * Function: *      Read one NAL unit from bitstream file. * * Returns: *      1: No errors *      0: Could not read bytes (end of file) */int getNalunitBits_ByteStream(void *strIn){  byteStream_s *str;  int numRemainingBytes;  int startCodeLen;  int nalUnitStartPos;  str = (byteStream_s *)strIn;  /*   * Copy valid data to the beginning of the buffer   */  numRemainingBytes = str->bitbufDataLen - str->bitbufDataPos;  if (numRemainingBytes > 0) {    memcpy(str->bitbuf, str->bitbuf + str->bitbufDataPos, numRemainingBytes);  }  /* Update bitbuffer variables */  str->bitbufDataLen = numRemainingBytes;  str->bitbufDataPos = 0;  /*   * Find NAL unit boundaries   */  /* Find first start code */  startCodeLen = findStartCode(str);  if (startCodeLen == 0)    return 0;  /* Start address of the NAL unit */  nalUnitStartPos = str->bitbufDataPos - startCodeLen;  /* Find second start code */  startCodeLen = findStartCode(str);  /* Set data pointer to the beginning of the second start code */  /* (i.e. to the end of the NAL unit)                          */  if (startCodeLen != 0)    str->bitbufDataPos -= startCodeLen;  str->bitbufNalunit    = str->bitbuf + nalUnitStartPos;  str->bitbufNalunitLen = str->bitbufDataPos;  return 1;}/* * * postProcessFrame: * * Parameters: *      recoBuf               Decoded picture *      recoFile              Reconstruction file *      globalStat            Statistics *      cropFlag              True if cropping enabled * * Function: *      Note that it can be called only after a whole frame is decoded * * Returns: *      - */static void postProcessFrame(avcdYUVbuffer_s *recoBuf, videoFile_s *recoFile,                             statOverall_s *globalStat,  userParam_s *param){  /* Write reconstruction to file */  if (recoFile->enabled)    writeFrame(recoBuf, recoFile, param->cropFlag);  /* update statistics */  if (recoBuf->picType == 1) { /* An Intra picture */    globalStat->numBitsI += recoBuf->numDecodedBits;    globalStat->numIframes += 1;  }  else {    globalStat->numBitsP += recoBuf->numDecodedBits;    globalStat->numPframes += 1;  }  /* Output statistics for the picture */  printf("%d\tbits = %d, \tPSNR Y = %5.2f, \tU = %5.2f, \tV = %5.2f\n",    globalStat->numIframes + globalStat->numPframes - 1,    recoBuf->numDecodedBits, 0.0, 0.0, 0.0);}#ifndef DECODE_ACCESS_UNITS/* * * main: * * Parameters: *      argc                  Number of parameters *      argv                  Parameter strings * * Function: *      Decoder main function * * Returns: *         0 ok *      <> 0 error * */int main(int argc, char **argv){  userParam_s param;  avcdDecoder_t *decoder;  byteStream_s strByte;  videoFile_s recoFile;  avcdYUVbuffer_s recoBuf;  FILE *cumuFp;  statOverall_s globalStat;  int result, seqEndFlag;  /* Parse command line arguments  */  if (!parseArg(argc, argv, &param)) {    usage();    exit(1);  }  /* Open video & bitstream files */  openFiles(&param, &recoFile, &strByte);  /* Zero out statistics */  memset(&globalStat, 0, sizeof(statOverall_s));  /* Open sequence */   decoder = avcdOpen(param.ecAlg);  if (decoder == NULL) {    fprintf(stderr, "Could not open sequence\n");    exit(1);  }  /*   * Main decoder loop. Frames are decoded until there are no more frames.   */  seqEndFlag = 0;  result     = AVCD_OK;  while (!seqEndFlag) {    /* result == AVCD_OK_STREAM_NOT_DECODED -> don't update bitbuffer */    if (result != AVCD_OK_STREAM_NOT_DECODED) {      if (!getNalunitBits_ByteStream(&strByte)) {        strByte.bitbufNalunit    = 0;        strByte.bitbufNalunitLen = 0;      }    }    /* Decode one NAL unit */    result = avcdDecodeOneNal(decoder, strByte.bitbufNalunit,                              strByte.bitbufNalunitLen, &recoBuf);    switch (result) {      case AVCD_OK:      case AVCD_OK_STREAM_NOT_DECODED:        postProcessFrame(&recoBuf, &recoFile, &globalStat, &param);        break;      case AVCD_OK_FRAME_NOT_AVAILABLE:        if (strByte.bitbufNalunit == 0 && strByte.bitbufNalunitLen == 0)          seqEndFlag = 1;        break;      case AVCD_ERROR:      default:        fprintf(stderr, "Error occured in AVC decoder\n");        seqEndFlag = 1;        break;    }  }  /* Close sequence */  avcdClose(decoder);  /* Close video & bitstream files */  closeFiles(&recoFile, &strByte);  /* Print decoding time */  printf("took %3.3f seconds\n", (double)clock()/CLOCKS_PER_SEC);  /* Append short sequence statistics to -cumul file if file present */  if (param.cumuFile != NULL) {    if ((cumuFp = fopen(param.cumuFile, "a")) != NULL) {      printSeqStat(&globalStat, 0, 0, cumuFp);      fclose(cumuFp);    }  }  /* print a brief report */  printf("Total frames being decoded: %d\nI: %d, P: %d\n",         globalStat.numIframes + globalStat.numPframes, globalStat.numIframes, globalStat.numPframes);  printf("Total bits: %d\nI: %d, P: %d\n",         globalStat.numBitsI + globalStat.numBitsP, globalStat.numBitsI, globalStat.numBitsP);  return 0;}#else#define NUM_SLICES_PER_PICTURE  1/* * * main: * * Parameters: *      argc                  Number of parameters *      argv                  Parameter strings * * Function: *      This main function calls avcdDecodeOneFrame() instead of avcdDecodeOneNal() * * Returns: *         0 ok *      <> 0 error * */int main(int argc, char **argv){  userParam_s param;  avcdDecoder_t *decoder;  byteStream_s strByte;  videoFile_s recoFile;  avcdYUVbuffer_s recoBuf;  int firstSliceFlag;  FILE *cumuFp;  statOverall_s globalStat;  int result, seqEndFlag;  char tmpBuf[30000];  char *tmpPtr;  int tmpBufLen;  int frameNum = 0;  int numSlices;  /* Parse command line arguments  */  if (!parseArg(argc, argv, &param)) {    usage();    exit(1);  }  /* Open video & bitstream files */  openFiles(&param, &recoFile, &strByte);  /* Zero out statistics */  memset(&globalStat, 0, sizeof(statOverall_s));  /* Open sequence */  decoder = avcdOpen();  if (decoder == NULL) {    fprintf(stderr, "Could not open sequence\n");    exit(1);  }  /*   * Main decoder loop. Frames are decoded until there are no more frames.   */  firstSliceFlag = 1;  seqEndFlag = 0;  result = AVCD_OK;  tmpPtr = 0;  tmpBufLen = 0;  while (!seqEndFlag) {    /*     * Get one frame NAL units.     */    /* result == AVCD_OK_STREAM_NOT_DECODED -> don't update bitbuffer */    if (result != AVCD_OK_STREAM_NOT_DECODED) {      tmpPtr = tmpBuf;      tmpBufLen = 0;      numSlices = 0;      do {        if (!getNalunitBits_ByteStream(&strByte)) {          if (tmpBufLen == 0)            tmpPtr = 0;          break;        }        memcpy(tmpPtr+tmpBufLen, strByte.bitbufNalunit, strByte.bitbufNalunitLen);        tmpBufLen += strByte.bitbufNalunitLen;        if (!((strByte.bitbufNalunit[4]&31) == 7 || (strByte.bitbufNalunit[4]&31) == 8))          numSlices++;      } while (numSlices < NUM_SLICES_PER_PICTURE);    }    /*     * Decode NAL units.     */    result = avcdDecodeOneFrame(decoder, tmpPtr, tmpBufLen, &recoBuf);    switch (result) {      case AVCD_OK:      case AVCD_OK_STREAM_NOT_DECODED:        postProcessFrame(&recoBuf, &recoFile, &globalStat, &param);        break;      case AVCD_OK_FRAME_NOT_AVAILABLE:        if (tmpPtr == 0 && tmpBufLen == 0)          seqEndFlag = 1;        break;      case AVCD_ERROR:      default:        fprintf(stderr, "Error occured in AVC decoder\n");        seqEndFlag = 1;        break;    }        frameNum++;  }  /* Close sequence */  avcdClose(decoder);  /* Close video & bitstream files */  closeFiles(&recoFile, &strByte);  /* Print decoding time */  printf("took %3.3f seconds\n", (double)clock()/CLOCKS_PER_SEC);  /* Append short sequence statistics to -cumul file if file present */  if (param.cumuFile != NULL) {    if ((cumuFp = fopen(param.cumuFile, "a")) != NULL) {      printSeqStat(&globalStat, 0, 0, cumuFp);      fclose(cumuFp);    }  }  /* print a brief report */  printf("Total frames being decoded: %d\nI: %d, P: %d\n",         globalStat.numIframes + globalStat.numPframes, globalStat.numIframes, globalStat.numPframes);  printf("Total bits: %d\nI: %d, P: %d\n",         globalStat.numBitsI + globalStat.numBitsP, globalStat.numBitsI, globalStat.numBitsP);  return 0;}#endif

⌨️ 快捷键说明

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