int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pDst,
                      int32_t* pNalLen,
                      int32_t iTotalLeftLength,
                      const int32_t iSliceIdx,
                      int32_t& iSliceSize) {
  SWelsSliceBs* pSliceBs        = &pCtx->pSliceBs[iSliceIdx];
  SNalUnitHeaderExt* pNalHdrExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;

  const int32_t kiNalCnt        = pSliceBs->iNalIndex;
  int32_t iNalIdx               = 0;
  int32_t iNalSize              = 0;
  int32_t iReturn = ENC_RETURN_SUCCESS;
  iSliceSize = 0;
  assert (kiNalCnt <= 2);
  if (kiNalCnt > 2)
    return 0;

  while (iNalIdx < kiNalCnt) {
    iNalSize = 0;
    iReturn = WelsEncodeNal (&pSliceBs->sNalList[iNalIdx], pNalHdrExt, iTotalLeftLength - iSliceSize,
                             pDst, &iNalSize);
    WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
    pNalLen[iNalIdx] = iNalSize;
    iSliceSize += iNalSize;
    pDst += iNalSize;
    ++ iNalIdx;
  }
  pSliceBs->uiBsPos = iSliceSize;

  return iReturn;
}
Example #2
0
/*!
 * \brief	encode a nal into a pBuffer for any type of NAL, involved WelsEncodeNal introduced in AVC
 *
 * \param	pDst			pDst NAL pData
 * \param	pDstLen		length of pDst NAL output
 * \param	annexeb		annexeb flag
 * \param	pRawNal			pRawNal NAL pData
 * \param	pNalHeaderExt	pointer of SNalUnitHeaderExt
 *
 * \return	length of pDst NAL
 */
int32_t WelsEncodeNalExt (SWelsNalRaw* pRawNal, void* pNalHeaderExt, void* pDst, int32_t* pDstLen) {
  SNalUnitHeaderExt* sNalExt	= (SNalUnitHeaderExt*)pNalHeaderExt;
  uint8_t* pDstStart				    = (uint8_t*)pDst;
  uint8_t* pDstPointer				= pDstStart;
  uint8_t* pSrcPointer				= pRawNal->pRawData;
  uint8_t* pSrcEnd					= pRawNal->pRawData + pRawNal->iPayloadSize;
  int32_t iZeroCount					= 0;
  int32_t iNalLength					= 0;

  if (pRawNal->sNalExt.sNalHeader.eNalUnitType != NAL_UNIT_PREFIX
      && pRawNal->sNalExt.sNalHeader.eNalUnitType != NAL_UNIT_CODED_SLICE_EXT) {
    return WelsEncodeNal (pRawNal, pDst, pDstLen);
  }

  /* FIXME this code doesn't check overflow */

  static const uint8_t kuiStartCodePrefixExt[4] = { 0, 0, 0, 1 };
  ST32 (pDstPointer, LD32 (&kuiStartCodePrefixExt[0]));
  pDstPointer += 4;

  /* NAL Unit Header */
  *pDstPointer++	= (pRawNal->sNalExt.sNalHeader.uiNalRefIdc << 5) | (pRawNal->sNalExt.sNalHeader.eNalUnitType & 0x1f);

  /* NAL UNIT Extension Header */
  *pDstPointer++ =	(0x80) |
                    (sNalExt->bIdrFlag << 6);

  *pDstPointer++ =	(0x80) |
                    (sNalExt->uiDependencyId << 4);

  *pDstPointer++ =	(sNalExt->uiTemporalId << 5) |
                    (sNalExt->bDiscardableFlag << 3) |
                    (0x07);

  while (pSrcPointer < pSrcEnd) {
    if (iZeroCount == 2 && *pSrcPointer <= 3) {
      *pDstPointer++	= 3;
      iZeroCount		= 0;
    }
    if (*pSrcPointer == 0) {
      ++ iZeroCount;
    } else {
      iZeroCount		= 0;
    }
    *pDstPointer++ = *pSrcPointer++;
  }

  /* count length of NAL Unit */
  iNalLength	= pDstPointer - pDstStart;
  if (NULL != pDstLen)
    *pDstLen	= iNalLength;

  return iNalLength;
}