//update iRefIndex and iMVs of both Mb and Mb_cache, only for P8x16 void_t UpdateP8x16MotionInfo(PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A], int8_t iRefIndex[LIST_A][30], int32_t iPartIdx, int8_t iRef, int16_t iMVs[2]) { const int16_t kiRef2 = (iRef << 8) | iRef; const int32_t kiMV32 = LD32(iMVs); int32_t i; int32_t iMbXy = pCurDqLayer->iMbXyIndex; for (i = 0; i < 2; i++, iPartIdx+=8) { const uint8_t kuiScan4Idx = g_kuiScan4[iPartIdx]; const uint8_t kuiCacheIdx = g_kuiCache30ScanIdx[iPartIdx]; const uint8_t kuiScan4IdxPlus4= 4 + kuiScan4Idx; const uint8_t kuiCacheIdxPlus6= 6 + kuiCacheIdx; //mb ST16( &pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4Idx ], kiRef2 ); ST16( &pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4IdxPlus4], kiRef2 ); ST32( pCurDqLayer->pMv[0][iMbXy][ kuiScan4Idx ], kiMV32 ); ST32( pCurDqLayer->pMv[0][iMbXy][1+kuiScan4Idx ], kiMV32 ); ST32( pCurDqLayer->pMv[0][iMbXy][ kuiScan4IdxPlus4], kiMV32 ); ST32( pCurDqLayer->pMv[0][iMbXy][1+kuiScan4IdxPlus4], kiMV32 ); //cache ST16( &iRefIndex[0][kuiCacheIdx ], kiRef2 ); ST16( &iRefIndex[0][kuiCacheIdxPlus6], kiRef2 ); ST32( iMotionVector[0][ kuiCacheIdx ], kiMV32 ); ST32( iMotionVector[0][1+kuiCacheIdx ], kiMV32 ); ST32( iMotionVector[0][ kuiCacheIdxPlus6], kiMV32 ); ST32( iMotionVector[0][1+kuiCacheIdxPlus6], kiMV32 ); } }
void_t WelsFillCacheNonZeroCount(PNeighAvail pNeighAvail, uint8_t* pNonZeroCount, PDqLayer pCurLayer) //no matter slice type, intra_pred_constrained_flag { int32_t iCurXy = pCurLayer->iMbXyIndex; int32_t iTopXy = 0; int32_t iLeftXy = 0; GetNeighborAvailMbType( pNeighAvail, pCurLayer ); if ( pNeighAvail->iTopAvail ) { iTopXy = iCurXy - pCurLayer->iMbWidth; } if ( pNeighAvail->iLeftAvail ) { iLeftXy = iCurXy - 1; } //stuff non_zero_coeff_count from pNeighAvail(left and top) if (pNeighAvail->iTopAvail) { ST32(&pNonZeroCount[1], LD32(&pCurLayer->pNzc[iTopXy][12])); pNonZeroCount[0] = pNonZeroCount[5] = pNonZeroCount[29] = 0; ST16(&pNonZeroCount[6], LD16(&pCurLayer->pNzc[iTopXy][20])); ST16(&pNonZeroCount[30], LD16(&pCurLayer->pNzc[iTopXy][22])); } else { ST32(&pNonZeroCount[1], 0xFFFFFFFFU); pNonZeroCount[0] = pNonZeroCount[5] = pNonZeroCount[29] = 0xFF; ST16(&pNonZeroCount[6], 0xFFFF); ST16(&pNonZeroCount[30], 0xFFFF); } if (pNeighAvail->iLeftAvail) { pNonZeroCount[8 * 1] = pCurLayer->pNzc[iLeftXy][3]; pNonZeroCount[8 * 2] = pCurLayer->pNzc[iLeftXy][7]; pNonZeroCount[8 * 3] = pCurLayer->pNzc[iLeftXy][11]; pNonZeroCount[8 * 4] = pCurLayer->pNzc[iLeftXy][15]; pNonZeroCount[5 + 8 * 1] = pCurLayer->pNzc[iLeftXy][17]; pNonZeroCount[5 + 8 * 2] = pCurLayer->pNzc[iLeftXy][21]; pNonZeroCount[5 + 8 * 4] = pCurLayer->pNzc[iLeftXy][19]; pNonZeroCount[5 + 8 * 5] = pCurLayer->pNzc[iLeftXy][23]; } else { pNonZeroCount[8 * 1] = pNonZeroCount[8 * 2] = pNonZeroCount[8 * 3] = pNonZeroCount[8 * 4] = -1;//unavailable pNonZeroCount[5 + 8 * 1] = pNonZeroCount[5 + 8 * 2] = -1;//unavailable pNonZeroCount[5 + 8 * 4] = pNonZeroCount[5 + 8 * 5] = -1;//unavailable } }
//update uiRefIndex and pMv of both SMB and Mb_cache, only for P8x16 void update_P8x16_motion_info(SMbCache* pMbCache, SMB* pCurMb, const int32_t kiPartIdx, const int8_t kiRef, SMVUnitXY* pMv) { // optimized 11/25/2011 SMVComponentUnit *pMvComp = &pMbCache->sMvComponents; const uint32_t kuiMv32 = LD32(pMv); const uint64_t kuiMv64 = BUTTERFLY4x8(kuiMv32); const int16_t kiScan4Idx = g_kuiMbCountScan4Idx[kiPartIdx]; const int16_t kiCacheIdx = g_kuiCache30ScanIdx[kiPartIdx]; const int16_t kiCacheIdx1 = 1+kiCacheIdx; const int16_t kiCacheIdx3 = 3+kiCacheIdx; const int16_t kiCacheIdx12 = 12+kiCacheIdx; const int16_t kiCacheIdx13 = 13+kiCacheIdx; const int16_t kiCacheIdx15 = 15+kiCacheIdx; const int16_t kiBlkIdx = kiPartIdx>>2; const uint16_t kuiRef16 = BUTTERFLY1x2(kiRef); pCurMb->pRefIndex[kiBlkIdx] = kiRef; pCurMb->pRefIndex[2+kiBlkIdx]= kiRef; ST64( &pCurMb->sMv[kiScan4Idx], kuiMv64 ); ST64( &pCurMb->sMv[4+kiScan4Idx], kuiMv64 ); ST64( &pCurMb->sMv[8+kiScan4Idx], kuiMv64 ); ST64( &pCurMb->sMv[12+kiScan4Idx], kuiMv64 ); /* * blocks 0: g_kuiCache30ScanIdx[iPartIdx]~g_kuiCache30ScanIdx[iPartIdx]+3, 1: g_kuiCache30ScanIdx[iPartIdx]+6~g_kuiCache30ScanIdx[iPartIdx]+9 */ pMvComp->iRefIndexCache[kiCacheIdx] = kiRef; ST16(&pMvComp->iRefIndexCache[kiCacheIdx1], kuiRef16); pMvComp->iRefIndexCache[kiCacheIdx3] = kiRef; pMvComp->iRefIndexCache[kiCacheIdx12] = kiRef; ST16(&pMvComp->iRefIndexCache[kiCacheIdx13], kuiRef16); pMvComp->iRefIndexCache[kiCacheIdx15] = kiRef; /* * blocks 0: g_kuiCache30ScanIdx[iPartIdx]~g_kuiCache30ScanIdx[iPartIdx]+3, 1: g_kuiCache30ScanIdx[iPartIdx]+6~g_kuiCache30ScanIdx[iPartIdx]+9 */ pMvComp->sMotionVectorCache[kiCacheIdx] = *pMv; ST64( &pMvComp->sMotionVectorCache[kiCacheIdx1], kuiMv64 ); pMvComp->sMotionVectorCache[kiCacheIdx3] = *pMv; pMvComp->sMotionVectorCache[kiCacheIdx12] = *pMv; ST64( &pMvComp->sMotionVectorCache[kiCacheIdx13], kuiMv64 ); pMvComp->sMotionVectorCache[kiCacheIdx15] = *pMv; }
/* can be further optimized */ void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int8_t iRef, int16_t iMVs[2]) { const int16_t kiRef2 = (iRef << 8) | iRef; const int32_t kiMV32 = LD32 (iMVs); int32_t i; int32_t iMbXy = pCurDqLayer->iMbXyIndex; for (i = 0; i < 16; i += 4) { //mb const uint8_t kuiScan4Idx = g_kuiScan4[i]; const uint8_t kuiScan4IdxPlus4 = 4 + kuiScan4Idx; ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4Idx ], kiRef2); ST16 (&pCurDqLayer->pRefIndex[0][iMbXy][kuiScan4IdxPlus4], kiRef2); ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4Idx ], kiMV32); ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4Idx ], kiMV32); ST32 (pCurDqLayer->pMv[0][iMbXy][ kuiScan4IdxPlus4], kiMV32); ST32 (pCurDqLayer->pMv[0][iMbXy][1 + kuiScan4IdxPlus4], kiMV32); } }
//update uiRefIndex and pMv of both SMB and Mb_cache, only for P16x8 void UpdateP16x8MotionInfo(SMbCache* pMbCache, SMB* pCurMb, const int32_t kiPartIdx, const int8_t kiRef, SMVUnitXY* pMv) { // optimized 11/25/2011 SMVComponentUnit *pMvComp = &pMbCache->sMvComponents; const uint32_t kuiMv32 = LD32(pMv); const uint64_t kuiMv64 = BUTTERFLY4x8(kuiMv32); uint64_t uiMvBuf[4] = { kuiMv64, kuiMv64, kuiMv64, kuiMv64 }; const int16_t kiScan4Idx = g_kuiMbCountScan4Idx[kiPartIdx]; const int16_t kiCacheIdx = g_kuiCache30ScanIdx[kiPartIdx]; const int16_t kiCacheIdx1 = 1+kiCacheIdx; const int16_t kiCacheIdx3 = 3+kiCacheIdx; const int16_t kiCacheIdx6 = 6+kiCacheIdx; const int16_t kiCacheIdx7 = 7+kiCacheIdx; const int16_t kiCacheIdx9 = 9+kiCacheIdx; const uint16_t kuiRef16 = BUTTERFLY1x2(kiRef); ST16( &pCurMb->pRefIndex[(kiPartIdx>>2)], kuiRef16 ); memcpy( &pCurMb->sMv[kiScan4Idx], uiMvBuf, sizeof(uiMvBuf) ); // confirmed_safe_unsafe_usage /* * blocks 0: g_kuiCache30ScanIdx[iPartIdx]~g_kuiCache30ScanIdx[iPartIdx]+3, 1: g_kuiCache30ScanIdx[iPartIdx]+6~g_kuiCache30ScanIdx[iPartIdx]+9 */ pMvComp->iRefIndexCache[kiCacheIdx] = kiRef; ST16(&pMvComp->iRefIndexCache[kiCacheIdx1], kuiRef16); pMvComp->iRefIndexCache[kiCacheIdx3] = kiRef; pMvComp->iRefIndexCache[kiCacheIdx6] = kiRef; ST16(&pMvComp->iRefIndexCache[kiCacheIdx7], kuiRef16); pMvComp->iRefIndexCache[kiCacheIdx9] = kiRef; /* * blocks 0: g_kuiCache30ScanIdx[iPartIdx]~g_kuiCache30ScanIdx[iPartIdx]+3, 1: g_kuiCache30ScanIdx[iPartIdx]+6~g_kuiCache30ScanIdx[iPartIdx]+9 */ pMvComp->sMotionVectorCache[kiCacheIdx] = *pMv; ST64( &pMvComp->sMotionVectorCache[kiCacheIdx1], kuiMv64 ); pMvComp->sMotionVectorCache[kiCacheIdx3]= *pMv; pMvComp->sMotionVectorCache[kiCacheIdx6]= *pMv; ST64( &pMvComp->sMotionVectorCache[kiCacheIdx7], kuiMv64 ); pMvComp->sMotionVectorCache[kiCacheIdx9]= *pMv; }
/*! ************************************************************************************* * \brief First entrance to decoding core interface. * * \param pCtx decoder context * \param pBufBs bit streaming buffer * \param kBsLen size in bytes length of bit streaming buffer input * \param ppDst picture payload data to be output * \param pDstBufInfo buf information of ouput data * * \return 0 - successed * \return 1 - failed * * \note N/A ************************************************************************************* */ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const int32_t kiBsLen, uint8_t** ppDst, SBufferInfo* pDstBufInfo, SParserBsInfo* pDstBsInfo) { if (!pCtx->bEndOfStreamFlag) { SDataBuffer* pRawData = &pCtx->sRawData; SDataBuffer* pSavedData = NULL; int32_t iSrcIdx = 0; //the index of source bit-stream till now after parsing one or more NALs int32_t iSrcConsumed = 0; // consumed bit count of source bs int32_t iDstIdx = 0; //the size of current NAL after 0x03 removal and 00 00 01 removal int32_t iSrcLength = 0; //the total size of current AU or NAL int32_t iRet = 0; int32_t iConsumedBytes = 0; int32_t iOffset = 0; uint8_t* pSrcNal = NULL; uint8_t* pDstNal = NULL; uint8_t* pNalPayload = NULL; if (NULL == DetectStartCodePrefix (kpBsBuf, &iOffset, kiBsLen)) { //CAN'T find the 00 00 01 start prefix from the source buffer pCtx->iErrorCode |= dsBitstreamError; return dsBitstreamError; } pSrcNal = const_cast<uint8_t*> (kpBsBuf) + iOffset; iSrcLength = kiBsLen - iOffset; if ((kiBsLen + 4) > (pRawData->pEnd - pRawData->pCurPos)) { pRawData->pCurPos = pRawData->pHead; } if (pCtx->bParseOnly) { pSavedData = &pCtx->sSavedData; if ((kiBsLen + 4) > (pSavedData->pEnd - pSavedData->pCurPos)) { pSavedData->pCurPos = pSavedData->pHead; } } //copy raw data from source buffer (application) to raw data buffer (codec inside) //0x03 removal and extract all of NAL Unit from current raw data pDstNal = pRawData->pCurPos; while (iSrcConsumed < iSrcLength) { if ((2 + iSrcConsumed < iSrcLength) && (0 == LD16 (pSrcNal + iSrcIdx)) && ((pSrcNal[2 + iSrcIdx] == 0x03) || (pSrcNal[2 + iSrcIdx] == 0x01))) { if (pSrcNal[2 + iSrcIdx] == 0x03) { ST16 (pDstNal + iDstIdx, 0); iDstIdx += 2; iSrcIdx += 3; iSrcConsumed += 3; } else { iConsumedBytes = 0; pDstNal[iDstIdx] = pDstNal[iDstIdx + 1] = pDstNal[iDstIdx + 2] = pDstNal[iDstIdx + 3] = 0; // set 4 reserved bytes to zero pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes); if (pNalPayload) { //parse correct if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) { CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo); } if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) { iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3); } if (pCtx->bAuReadyFlag) { ConstructAccessUnit (pCtx, ppDst, pDstBufInfo); if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif if (dsOutOfMemory & pCtx->iErrorCode) { return pCtx->iErrorCode; } } } } if (iRet) { iRet = 0; if (dsNoParamSets & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif } return pCtx->iErrorCode; } pDstNal += (iDstIdx + 4); //init, increase 4 reserved zero bytes, used to store the next NAL if ((iSrcLength - iSrcConsumed + 4) > (pRawData->pEnd - pDstNal)) { pDstNal = pRawData->pCurPos = pRawData->pHead; } else { pRawData->pCurPos = pDstNal; } pSrcNal += iSrcIdx + 3; iSrcConsumed += 3; iSrcIdx = 0; iDstIdx = 0; //reset 0, used to statistic the length of next NAL } continue; } pDstNal[iDstIdx++] = pSrcNal[iSrcIdx++]; iSrcConsumed++; } //last NAL decoding iConsumedBytes = 0; pDstNal[iDstIdx] = pDstNal[iDstIdx + 1] = pDstNal[iDstIdx + 2] = pDstNal[iDstIdx + 3] = 0; // set 4 reserved bytes to zero pRawData->pCurPos = pDstNal + iDstIdx + 4; //init, increase 4 reserved zero bytes, used to store the next NAL pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes); if (pNalPayload) { //parse correct if (IS_VCL_NAL (pCtx->sCurNalHead.eNalUnitType, 1)) { CheckAndFinishLastPic (pCtx, ppDst, pDstBufInfo); } if (IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType)) { iRet = ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes, pSrcNal - 3, iSrcIdx + 3); } if (pCtx->bAuReadyFlag) { ConstructAccessUnit (pCtx, ppDst, pDstBufInfo); if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif return pCtx->iErrorCode; } } } if (iRet) { iRet = 0; if (dsNoParamSets & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif } return pCtx->iErrorCode; } } else { /* no supplementary picture payload input, but stored a picture */ PAccessUnit pCurAu = pCtx->pAccessUnitList; // current access unit, it will never point to NULL after decode's successful initialization if (pCurAu->uiAvailUnitsNum == 0) { return pCtx->iErrorCode; } else { pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1; ConstructAccessUnit (pCtx, ppDst, pDstBufInfo); if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif return pCtx->iErrorCode; } } } return pCtx->iErrorCode; }
/*! ************************************************************************************* * \brief First entrance to decoding core interface. * * \param pCtx decoder context * \param pBufBs bit streaming buffer * \param kBsLen size in bytes length of bit streaming buffer input * \param ppDst picture payload data to be output * \param pDstBufInfo buf information of ouput data * * \return 0 - successed * \return 1 - failed * * \note N/A ************************************************************************************* */ int32_t WelsDecodeBs (PWelsDecoderContext pCtx, const uint8_t* kpBsBuf, const int32_t kiBsLen, uint8_t** ppDst, SBufferInfo* pDstBufInfo) { if (!pCtx->bEndOfStreamFlag) { SDataBuffer* pRawData = &pCtx->sRawData; int32_t iSrcIdx = 0; //the index of source bit-stream till now after parsing one or more NALs int32_t iSrcConsumed = 0; // consumed bit count of source bs int32_t iDstIdx = 0; //the size of current NAL after 0x03 removal and 00 00 01 removal int32_t iSrcLength = 0; //the total size of current AU or NAL int32_t iConsumedBytes = 0; int32_t iOffset = 0; uint8_t* pSrcNal = NULL; uint8_t* pDstNal = NULL; uint8_t* pNalPayload = NULL; if (NULL == DetectStartCodePrefix (kpBsBuf, &iOffset, kiBsLen)) { //CAN'T find the 00 00 01 start prefix from the source buffer return dsBitstreamError; } pSrcNal = const_cast<uint8_t*> (kpBsBuf) + iOffset; iSrcLength = kiBsLen - iOffset; if ((kiBsLen + 4) > (pRawData->pEnd - pRawData->pCurPos)) { pRawData->pCurPos = pRawData->pHead; } //copy raw data from source buffer (application) to raw data buffer (codec inside) //0x03 removal and extract all of NAL Unit from current raw data pDstNal = pRawData->pCurPos + 4; //4-bytes used to write the length of current NAL rbsp while (iSrcConsumed < iSrcLength) { if ((2 + iSrcConsumed < iSrcLength) && (0 == LD16 (pSrcNal + iSrcIdx)) && ((pSrcNal[2 + iSrcIdx] == 0x03) || (pSrcNal[2 + iSrcIdx] == 0x01))) { if (pSrcNal[2 + iSrcIdx] == 0x03) { ST16 (pDstNal + iDstIdx, 0); iDstIdx += 2; iSrcIdx += 3; iSrcConsumed += 3; } else { GetValueOf4Bytes (pDstNal - 4, iDstIdx); //pDstNal-4 (non-aligned by 4) in Solaris10(SPARC). Given value by byte. iConsumedBytes = 0; pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes); if (pCtx->bAuReadyFlag) { ConstructAccessUnit (pCtx, ppDst, pDstBufInfo); if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif ResetParameterSetsState (pCtx); if (dsOutOfMemory & pCtx->iErrorCode) { return pCtx->iErrorCode; } } } if ((IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) || IS_SEI_NAL (pCtx->sCurNalHead.eNalUnitType)) && pNalPayload) { if (ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes)) { if (dsNoParamSets & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif ResetParameterSetsState (pCtx); } return pCtx->iErrorCode; } } pDstNal += iDstIdx; //update current position if ((iSrcLength - iSrcConsumed + 4) > (pRawData->pEnd - pDstNal)) { pRawData->pCurPos = pRawData->pHead; } else { pRawData->pCurPos = pDstNal; } pDstNal = pRawData->pCurPos + 4; //init, 4 bytes used to store the next NAL pSrcNal += iSrcIdx + 3; iSrcConsumed += 3; iSrcIdx = 0; iDstIdx = 0; //reset 0, used to statistic the length of next NAL } continue; } pDstNal[iDstIdx++] = pSrcNal[iSrcIdx++]; iSrcConsumed++; } //last NAL decoding GetValueOf4Bytes (pDstNal - 4, iDstIdx); //pDstNal-4 (non-aligned by 4) in Solaris10(SPARC). Given value by byte. iConsumedBytes = 0; pNalPayload = ParseNalHeader (pCtx, &pCtx->sCurNalHead, pDstNal, iDstIdx, pSrcNal - 3, iSrcIdx + 3, &iConsumedBytes); if (pCtx->bAuReadyFlag) { ConstructAccessUnit (pCtx, ppDst, pDstBufInfo); if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif ResetParameterSetsState (pCtx); return pCtx->iErrorCode; } } if ((IS_PARAM_SETS_NALS (pCtx->sCurNalHead.eNalUnitType) || IS_SEI_NAL (pCtx->sCurNalHead.eNalUnitType)) && pNalPayload) { if (ParseNonVclNal (pCtx, pNalPayload, iDstIdx - iConsumedBytes)) { if (dsNoParamSets & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif ResetParameterSetsState (pCtx); } return pCtx->iErrorCode; } } pDstNal += iDstIdx; pRawData->pCurPos = pDstNal; //init the pCurPos for next NAL(s) storage } else { /* no supplementary picture payload input, but stored a picture */ PAccessUnit pCurAu = pCtx->pAccessUnitList; // current access unit, it will never point to NULL after decode's successful initialization if (pCurAu->uiAvailUnitsNum == 0) { return pCtx->iErrorCode; } else { pCtx->pAccessUnitList->uiEndPos = pCtx->pAccessUnitList->uiAvailUnitsNum - 1; ConstructAccessUnit (pCtx, ppDst, pDstBufInfo); if ((dsOutOfMemory | dsNoParamSets) & pCtx->iErrorCode) { #ifdef LONG_TERM_REF pCtx->bParamSetsLostFlag = true; #else pCtx->bReferenceLostAtT0Flag = true; #endif ResetParameterSetsState (pCtx); return pCtx->iErrorCode; } } } return pCtx->iErrorCode; }
int syslinux_shuffle_boot_rm(struct syslinux_movelist *fraglist, struct syslinux_memmap *memmap, uint16_t bootflags, struct syslinux_rm_regs *regs) { const struct syslinux_rm_regs_alt { uint16_t seg[6]; uint32_t gpr[8]; uint32_t csip; bool sti; } *rp; int i, rv; uint8_t handoff_code[8 + 5 * 5 + 8 * 6 + 1 + 5], *p; uint16_t off; struct syslinux_memmap *tmap; addr_t regstub, stublen; /* Assign GPRs for each sreg, don't use AX and SP */ static const uint8_t gpr_for_seg[6] = { R_CX, R_DX, R_BX, R_BP, R_SI, R_DI }; tmap = syslinux_target_memmap(fraglist, memmap); if (!tmap) return -1; /* * Search for a good place to put the real-mode register stub. * We prefer it as low as possible above 0x800. KVM barfs horribly * if we're not aligned to a paragraph boundary, so set the alignment * appropriately. */ regstub = 0x800; stublen = sizeof handoff_code; rv = syslinux_memmap_find_type(tmap, SMT_FREE, ®stub, &stublen, 16); if (rv || (regstub > 0x100000 - sizeof handoff_code)) { /* * Uh-oh. This isn't real-mode accessible memory. * It might be possible to do something insane here like * putting the stub in the IRQ vectors, or in the 0x5xx segment. * This code tries the 0x510-0x7ff range and hopes for the best. */ regstub = 0x510; /* Try the 0x5xx segment... */ stublen = sizeof handoff_code; rv = syslinux_memmap_find_type(tmap, SMT_FREE, ®stub, &stublen, 16); if (!rv && (regstub > 0x100000 - sizeof handoff_code)) rv = -1; /* No acceptable memory found */ } syslinux_free_memmap(tmap); if (rv) return -1; /* Build register-setting stub */ p = handoff_code; rp = (const struct syslinux_rm_regs_alt *)regs; /* Set up GPRs with segment registers - don't use AX */ for (i = 0; i < 6; i++) { if (i != R_CS) MOV_TO_R16(p, gpr_for_seg[i], rp->seg[i]); } /* Actual transition to real mode */ ST32(p, 0xeac0220f); /* MOV CR0,EAX; JMP FAR */ off = (p - handoff_code) + 4; ST16(p, off); /* Offset */ ST16(p, regstub >> 4); /* Segment */ /* Load SS and ESP immediately */ MOV_TO_SEG(p, R_SS, R_BX); MOV_TO_R32(p, R_SP, rp->gpr[R_SP]); /* Load the other segments */ MOV_TO_SEG(p, R_ES, R_CX); MOV_TO_SEG(p, R_DS, R_BP); MOV_TO_SEG(p, R_FS, R_SI); MOV_TO_SEG(p, R_GS, R_DI); for (i = 0; i < 8; i++) { if (i != R_SP) MOV_TO_R32(p, i, rp->gpr[i]); } ST8(p, rp->sti ? 0xfb : 0xfa); /* STI/CLI */ ST8(p, 0xea); /* JMP FAR */ ST32(p, rp->csip); /* Add register-setting stub to shuffle list */ if (syslinux_add_movelist(&fraglist, regstub, (addr_t) handoff_code, sizeof handoff_code)) return -1; return syslinux_do_shuffle(fraglist, memmap, regstub, 0, bootflags); }