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

📄 sequence.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 4 页
字号:
        seq->unusedShortTermFrameNum = nextFrameNum;        seq->conceal                 = 1;        /* If dpb was not full we can recover lost frames */        if (numOutput == 0)           numOutput = concealFrames(seq);      }      else#endif      {        /*         * Start filling in gaps in frame numbers         */        seq->unusedShortTermFrameNum = nextFrameNum;#ifdef ERROR_CONCEALMENT        seq->conceal                 = 0;#endif        /* If dpb was not full (i.e. we did not have to output any pictures), */        /* we can generate non-existing frames.                               */        if (numOutput == 0)           numOutput = generateNonExistingFrames(seq);      }    }    if (numOutput == 0)      /* If there are no pictures in output queue we can decode next slice */      return decodeSliceData(seq);    else {      /* Don't decode slice since it belongs to next picture and */      /* we don't have space for new picture. */      seq->isSliceDataDecodePending = 1;      return SEQ_OK;    }  }}#ifdef ERROR_CONCEALMENT/* * * decodeSei: * * Parameters: *      seq                   Sequence object * * Function: *      Decode SEI message * * Returns: *      SEQ_OK for ok, negative value for error */static int decodeSei(sequence_s *seq){  int payloadType;  int payloadSize;  int byte;  int retCode;  bitbuffer_s *bitbuf;  sceneInfo_s *scene;  bitbuf = seq->bitbuf;  while (bibMoreRbspData(bitbuf)) {    payloadType = 0;    bibGetByte(bitbuf, &byte);    while (byte == 0xff) {      payloadType += byte;      bibGetByte(bitbuf, &byte);    }    payloadType += byte;    payloadSize = 0;    bibGetByte(bitbuf, &byte);    while (byte == 0xff) {      payloadSize += byte;      bibGetByte(bitbuf, &byte);    }    payloadSize += byte;    switch (payloadType) {    case SEI_TYPE_SCENE_INFO:      seq->hasSceneInfo = 1;      scene = seq->currSceneInfo;      seq->currSceneInfo = seq->prevSceneInfo;      seq->prevSceneInfo = scene;      if ((retCode = seiSceneInfo(seq->currSceneInfo, bitbuf)) < 0)         return retCode;      seq->sceneInfoDecoded = 1;      break;    default:      deb1f(stderr, "The decoder does not support the SEI message in type of %d\n", payloadType);      bitbuf->bytePos += payloadSize;   // skip the content of the SEI payload.      break;    }  }  return SEQ_OK;}#endif/* * * avcdDecodeOneNal: * * Parameters: *      seq                   Sequence object *      nalUnitBits           Bits for NAL unit to be decoded *      nalUnitLen            Number of bytes in NAL unit * * Function: *      Return output picture immediately if available. Otherwise finish any *      pending tasks from previous call such as storing of current frame to *      dpb, generation of non-existing frames (to fill in gaps in frame *      numbers) and decoding of current slice data. If any of the tasks *      did not exit the function, start decoding NAL unit. * * Returns: *      AVCD_OK:                     Nal unit decoded and frame available *      AVCD_OK_FRAME_NOT_AVAILABLE: Nal unit decoded, frame not available *      AVCD_OK_STREAM_NOT_DECODED:  Nal unit not decoded, frame available *      AVCD_ERROR:                  Error occured * */int avcdDecodeOneNal(avcdDecoder_t *dec, void *nalUnitBits, int nalUnitLen,                     avcdYUVbuffer_s *outBuf){  sequence_s *seq = (sequence_s *)dec;  int nalHeaderByte;  int nalType;  int nalRefIdc;  int ret;  /*   * The following conditions are tested to see what is the current decoder state   * and to act upon that state:   *   * - Check if picture can be output from output queue without further decoding.   * - Check if dpb store is pending (i.e current picture was not be   *   stored to dpb during previous call because dpb was full).   * - Check any non-existing frames should be generated (i.e there were gaps in   *   frame number). If non-existing frame(s) were generated, check output   *   queue again.   * - Check for end of stream. If end of stream was reached then current picture   *   is finished if not yet finished. Check again whether picture can be output   *   from either output queue or dpb (check is internal to getOutputPic(...)).   * - Check if slice decode is pending (i.e only header of the latest slice was   *   decoded during previous call and we now need to decode slice data) and if   *   so, decode slice data.   * - Check any lost frames being recovered (i.e there were ref frames lost)   *   If lost frames were rescued, check output queue again.   */  /* We can return immediately if there are queued output pics */  if (seq->numQueuedOutputPics > 0) {    getOutputPic(seq, outBuf);    return AVCD_OK_STREAM_NOT_DECODED;  }  /* Is current picture waiting to be moved to DPB? */  if (seq->isDpbStorePending) {    if (dpbStorePicture(seq->dpb, seq->recoBuf, seq->outputQueue) != 0) {      deb0f(stderr, "Error: dpb store failed\n");      return AVCD_ERROR;    }    seq->isDpbStorePending = 0;  }  /* Are there non-existing frames to be generated? */  /* Or are there any lost frames to be rescued?    */  if (seq->unusedShortTermFrameNum >= 0) {#ifdef ERROR_CONCEALMENT    if (seq->conceal) {      ret = concealFrames(seq);      if (ret < 0)        return AVCD_ERROR;      else if (ret != 0) {        getOutputPic(seq, outBuf);        return AVCD_OK_STREAM_NOT_DECODED;      }    }    else#endif    {      ret = generateNonExistingFrames(seq);      if (ret < 0)        return AVCD_ERROR;      else if (ret != 0) {        getOutputPic(seq, outBuf);        return AVCD_OK_STREAM_NOT_DECODED;      }    }  }  /* Check for end of stream */  if (nalUnitBits == 0 || nalUnitLen == 0) {    if (!seq->isSeqFinished && seq->recoBuf != NULL) {      if (finishCurrentPic(seq) < 0)        return AVCD_ERROR;      seq->isSeqFinished = 1;    }    /* Check for output */    if (getOutputPic(seq, outBuf))      return AVCD_OK;    else      return AVCD_OK_FRAME_NOT_AVAILABLE;  }  /* Decode slice data if slice decode is pending */  if (seq->isSliceDataDecodePending) {    decodeSliceData(seq);    return AVCD_OK_FRAME_NOT_AVAILABLE;  }  /*   * Decode new NAL unit   */  /* Initialize bitbuffer and get first byte containing NAL type and NAL ref idc */  if (bibInit(seq->bitbuf, (u_int8 *)nalUnitBits, nalUnitLen) < 0)    return AVCD_ERROR;  if (bibGetByte(seq->bitbuf, &nalHeaderByte))    return AVCD_ERROR;  /* Decode NAL unit type and reference indicator */  nalType   = nalHeaderByte & 0x1F;  nalRefIdc = (nalHeaderByte & 0x60) >> 5;  /* Decode NAL unit data */  switch (nalType)  {  case NAL_TYPE_CODED_SLICE:      // 1    decodeSlice(seq, nalType, nalRefIdc);    break;  case NAL_TYPE_CODED_SLICE_P_A:  // 2  case NAL_TYPE_CODED_SLICE_P_B:  // 3  case NAL_TYPE_CODED_SLICE_P_C:  // 4    deb1f(stderr, "Slice data partition NAL type (%i) not supported.\n", nalType);    return AVCD_ERROR;    break;  case NAL_TYPE_CODED_SLICE_IDR:  // 5    decodeSlice(seq, nalType, nalRefIdc);    break;  case NAL_TYPE_SEI:              // 6#ifdef ERROR_CONCEALMENT    decodeSei(seq);#else    deb0f(stderr, "SEI NAL unit (6) skipped.\n");#endif    break;  case NAL_TYPE_SPS:              // 7    if (psDecodeSPS(seq->bitbuf, seq->spsList) < 0)      return AVCD_ERROR;    break;  case NAL_TYPE_PPS:              // 8    if (psDecodePPS(seq->bitbuf, seq->ppsList) < 0)      return AVCD_ERROR;    break;  case NAL_TYPE_PIC_DELIMITER:    // 9    deb0f(stderr, "Picture Delimiter NAL unit (9) skipped.\n");    break;  case NAL_TYPE_END_SEQ:          // 10    deb0f(stderr, "End of Sequence NAL unit (10) skipped.\n");    break;  case NAL_TYPE_END_STREAM:       // 11    deb0f(stderr, "End of Stream NAL unit (11) skipped.\n");    break;  case NAL_TYPE_FILLER_DATA:      // 12    deb0f(stderr, "FIller Data NAL unit (12) skipped.\n");    break;  default:    /* Unspecied NAL types 0 and 24-31 */    if (nalType == 0 || (nalType >= 24 && nalType <= 31))      deb1f(stderr, "Unspecified NAL type: (%i)\n", nalType);    /* Reserved NAL types 13-23 */    else      deb1f(stderr, "Reserved NAL type (%i)\n", nalType);    break;  }  /*   * Check the output queue once again   */  if (getOutputPic(seq, outBuf)) {    if (seq->isSliceDataDecodePending)      /* We have output picture, but current slice has not been decoded */       return AVCD_OK_STREAM_NOT_DECODED;    else      return AVCD_OK;  }  else {    if (seq->isSliceDataDecodePending) {      /* If queue is empty, there should be no slice data left for current slice */      deb0f(stderr, "Something wrong here...\n");    }    return AVCD_OK_FRAME_NOT_AVAILABLE;  }}#ifdef DECODE_ACCESS_UNITS/* * * findStartCode: * * Parameters: *      ptr                   Pointer to byte stream *      len                   Length of byte stream *      offset                Search start position *      startCodeLen          Return pointer for start code langth * * Function: *      First next start code in byte stream * * Returns: *      Start code position if found or length of byte stream if *      start code was not found * */static int findStartCode(u_int8 *ptr, int len, int offset, int *startCodeLen){  int numZeros = 0;  while (offset < len) {    if (ptr[offset] == 0)      numZeros++;    else if (ptr[offset] == 1 && numZeros > 1) {      *startCodeLen = numZeros + 1;      return offset - numZeros;    }    else      numZeros = 0;    offset++;  }  return len;}/* * * avcdDecodeOneFrame: * * Parameters: *      dec                   Sequence object *      frameBitsPtr          Bits for frame *      frameBitsLen          Number of bytes in frame *      outBuf                Output buffer * * Function: *      Decode frame. * * Returns: *      AVCD_OK:                     Frame decoded and frame available *      AVCD_OK_FRAME_NOT_AVAILABLE: Frame decoded, frame not available *      AVCD_OK_STREAM_NOT_DECODED:  Frame not decoded, frame available *      AVCD_ERROR:                  Error occured * */int avcdDecodeOneFrame(avcdDecoder_t *dec, void *frameBitsPtr,                       int frameBitsLen, avcdYUVbuffer_s *outBuf){  sequence_s *seq = (sequence_s *)dec;  int isStreamEnd;  int isFrameEnd;  void *nalBitsPtr;  int nalBitsLen;  int numOutput;  /* If previous frame was completely decoded, start decoding */  /* this frame from the beginning.                           */  if (seq->decResult != AVCD_OK_STREAM_NOT_DECODED)    seq->streamPos = 0;  /* Check if end of stream (Empty NAL unit) */  if (frameBitsPtr == 0 || frameBitsLen == 0) {    seq->isSeqFinished = 1;    isStreamEnd = 1;  }  else    isStreamEnd = 0;  isFrameEnd = 0;  /*   * Decode all NAL units of the frame one NAL unit at a time.   * avcdDecodeOneNal() is called for each NAL unit.   */  do {    if (isStreamEnd) {      nalBitsPtr = 0;      nalBitsLen = 0;    }    else if (seq->decResult != AVCD_OK_STREAM_NOT_DECODED) {      int nalStart;      int nalStart2;      int startCodeLen;      int startCodeLen2;      /* Find first start code */      nalStart = findStartCode(frameBitsPtr, frameBitsLen, seq->streamPos, &startCodeLen);      if (nalStart != seq->streamPos) {        deb0f(stderr, "Error in byte stream\n");        return AVCD_ERROR;      }      /* Find second start code */      nalStart2 = findStartCode(frameBitsPtr, frameBitsLen, nalStart+startCodeLen, &startCodeLen2);      if (nalStart2-nalStart-startCodeLen < 1) {  // 1 is minimum NAL unit length        deb0f(stderr, "Error in byte stream\n");        return AVCD_ERROR;      }      /* Move stream pointer to next NAL unit */      seq->streamPos = nalStart2;      nalBitsPtr = (u_int8 *)frameBitsPtr + nalStart;      nalBitsLen = nalStart2-nalStart;    }    else {      /* Previous NAL unit was not decoded -> give some non-zero input   */      /* to avcdDecodeOneNal to finish decoding previous NAL unit.       */      /* There is no need to give exact bit pointer in this case because */      /* avcdDecodeOneNal has stored pointer for unfinished NAL unit.    */      nalBitsPtr = frameBitsPtr;      nalBitsLen = 1;    }    /* Decode NAL unit and check result */    seq->decResult = avcdDecodeOneNal(dec, nalBitsPtr, nalBitsLen, outBuf);    /* If there are no more bits in the stream and we got no frame, we */    /* know that all frames have been decoded and output.              */    if (isStreamEnd && seq->decResult == AVCD_OK_FRAME_NOT_AVAILABLE)      isFrameEnd = 1;    /* If we have decoded all NAL units of the frame, we can go */    if (!isStreamEnd && seq->streamPos >= frameBitsLen)      isFrameEnd = 1;    /* Decode until we are at the end of frame or ouput picture is available */  } while (!isFrameEnd && seq->decResult == AVCD_OK_FRAME_NOT_AVAILABLE);  /*   * If we are not at the end of stream and there is no frame available   * for output, we can finish current frame.   */  if (!isStreamEnd && seq->decResult == AVCD_OK_FRAME_NOT_AVAILABLE) {#ifdef ERROR_CONCEALMENT    pic_parameter_set_s *pps;    pps = seq->ppsList[seq->currSlice->pic_parameter_set_id];    /* Check if we need to coceal macroblocks */    ercCheckAndConceal(seq->errConcealment, seq->recoBuf, seq->mbData, seq->dpb, pps);#endif    /* Finish decoding of current picture */    numOutput = finishCurrentPic(seq);    /* numOutput is the number of pictures in output queue */    /* If numOutput < 0, error occured */    if (numOutput < 0)      return AVCD_ERROR;    /* Check if frame is available for output */    if (getOutputPic(seq, outBuf))      seq->decResult = AVCD_OK;    else      seq->decResult = AVCD_OK_FRAME_NOT_AVAILABLE;  }  return seq->decResult;}#endif

⌨️ 快捷键说明

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