#include "nal_encap.h"
#include "svc_enc_golomb.h"
#include "ls_defines.h"
namespace WelsEnc {
void WelsLoadNal (SWelsEncoderOutput* pEncoderOuput, const int32_t kiType,
const int32_t kiNalRefIdc) {
SWelsEncoderOutput* pWelsEncoderOuput = pEncoderOuput;
SWelsNalRaw* pRawNal = &pWelsEncoderOuput->sNalList[ pWelsEncoderOuput->iNalIndex ];
SNalUnitHeader* sNalUnitHeader = &pRawNal->sNalExt.sNalUnitHeader;
const int32_t kiStartPos = (BsGetBitsPos (&pWelsEncoderOuput->sBsWrite) >> 3);
sNalUnitHeader->eNalUnitType = (EWelsNalUnitType)kiType;
sNalUnitHeader->uiNalRefIdc = (EWelsNalRefIdc)kiNalRefIdc;
sNalUnitHeader->uiForbiddenZeroBit = 0;
pRawNal->pRawData = &pWelsEncoderOuput->pBsBuffer[kiStartPos];
pRawNal->iStartPos = kiStartPos;
pRawNal->iPayloadSize = 0;
}
void WelsUnloadNal (SWelsEncoderOutput* pEncoderOuput) {
SWelsEncoderOutput* pWelsEncoderOuput = pEncoderOuput;
int32_t* pIdx = &pWelsEncoderOuput->iNalIndex;
SWelsNalRaw* pRawNal = &pWelsEncoderOuput->sNalList[ *pIdx ];
const int32_t kiEndPos = (BsGetBitsPos (&pWelsEncoderOuput->sBsWrite) >> 3);
pRawNal->iPayloadSize = kiEndPos - pRawNal->iStartPos;
++ (*pIdx);
}
void WelsLoadNalForSlice (SWelsSliceBs* pSliceBs, const int32_t kiType,
const int32_t kiNalRefIdc) {
SWelsNalRaw* pRawNal = &pSliceBs->sNalList[ pSliceBs->iNalIndex ];
SNalUnitHeader* sNalUnitHeader = &pRawNal->sNalExt.sNalUnitHeader;
SBitStringAux* pBitStringAux = &pSliceBs->sBsWrite;
const int32_t kiStartPos = (BsGetBitsPos (pBitStringAux) >> 3);
sNalUnitHeader->eNalUnitType = (EWelsNalUnitType)kiType;
sNalUnitHeader->uiNalRefIdc = (EWelsNalRefIdc)kiNalRefIdc;
sNalUnitHeader->uiForbiddenZeroBit = 0;
pRawNal->pRawData = &pSliceBs->pBsBuffer[kiStartPos];
pRawNal->iStartPos = kiStartPos;
pRawNal->iPayloadSize = 0;
}
void WelsUnloadNalForSlice (SWelsSliceBs* pSliceBs) {
int32_t* pIdx = &pSliceBs->iNalIndex;
SWelsNalRaw* pRawNal = &pSliceBs->sNalList[ *pIdx ];
SBitStringAux* pBitStringAux = &pSliceBs->sBsWrite;
const int32_t kiEndPos = (BsGetBitsPos (pBitStringAux) >> 3);
pRawNal->iPayloadSize = kiEndPos - pRawNal->iStartPos;
++ (*pIdx);
}
int32_t WelsEncodeNal (SWelsNalRaw* pRawNal, void* pNalHeaderExt, const int32_t kiDstBufferLen, void* pDst,
int32_t* pDstLen) {
const bool kbNALExt = pRawNal->sNalExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_PREFIX
|| pRawNal->sNalExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_EXT;
int32_t iAssumedNeededLength = NAL_HEADER_SIZE + (kbNALExt ? 3 : 0) + pRawNal->iPayloadSize + 1;
WELS_VERIFY_RETURN_IF (ENC_RETURN_UNEXPECTED, (iAssumedNeededLength <= 0))
if (kiDstBufferLen < (iAssumedNeededLength + (iAssumedNeededLength >> 1))) {
return ENC_RETURN_MEMALLOCERR;
}
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;
*pDstLen = 0;
static const uint8_t kuiStartCodePrefix[NAL_HEADER_SIZE] = { 0, 0, 0, 1 };
ST32 (pDstPointer, LD32 (&kuiStartCodePrefix[0]));
pDstPointer += 4;
*pDstPointer++ = (pRawNal->sNalExt.sNalUnitHeader.uiNalRefIdc << 5) | (pRawNal->sNalExt.sNalUnitHeader.eNalUnitType &
0x1f);
if (kbNALExt) {
SNalUnitHeaderExt* sNalExt = (SNalUnitHeaderExt*)pNalHeaderExt;
*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++;
}
iNalLength = (int32_t) (pDstPointer - pDstStart);
if (NULL != pDstLen)
*pDstLen = iNalLength;
return ENC_RETURN_SUCCESS;
}
int32_t WelsWriteSVCPrefixNal (SBitStringAux* pBitStringAux, const int32_t kiNalRefIdc,
const bool kbIdrFlag) {
if (0 < kiNalRefIdc) {
BsWriteOneBit (pBitStringAux, false);
BsWriteOneBit (pBitStringAux, false);
BsRbspTrailingBits (pBitStringAux);
}
return 0;
}
}