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; }
/*! * \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; }