EResult CAdaptiveQuantization::Process (int32_t iType, SPixMap* pSrcPixMap, SPixMap* pRefPixMap) { EResult eReturn = RET_INVALIDPARAM; int32_t iWidth = pSrcPixMap->sRect.iRectWidth; int32_t iHeight = pSrcPixMap->sRect.iRectHeight; int32_t iMbWidth = iWidth >> 4; int32_t iMbHeight = iHeight >> 4; int32_t iMbTotalNum = iMbWidth * iMbHeight; SMotionTextureUnit* pMotionTexture = NULL; SVAACalcResult* pVaaCalcResults = NULL; int8_t iMotionTextureIndexToDeltaQp = 0; int32_t iAverMotionTextureIndexToDeltaQp = 0; // double to uint32 double_t dAverageMotionIndex = 0.0; // double to float double_t dAverageTextureIndex = 0.0; double_t dQStep = 0.0; double_t dLumaMotionDeltaQp = 0; double_t dLumaTextureDeltaQp = 0; uint8_t* pRefFrameY = NULL, *pCurFrameY = NULL; int32_t iRefStride = 0, iCurStride = 0; uint8_t* pRefFrameTmp = NULL, *pCurFrameTmp = NULL; int32_t i = 0, j = 0; pRefFrameY = (uint8_t*)pRefPixMap->pPixel[0]; pCurFrameY = (uint8_t*)pSrcPixMap->pPixel[0]; iRefStride = pRefPixMap->iStride[0]; iCurStride = pSrcPixMap->iStride[0]; /////////////////////////////////////// motion ////////////////////////////////// // motion MB residual variance dAverageMotionIndex = 0.0; dAverageTextureIndex = 0.0; pMotionTexture = m_sAdaptiveQuantParam.pMotionTextureUnit; pVaaCalcResults = m_sAdaptiveQuantParam.pCalcResult; if (pVaaCalcResults->pRefY == pRefFrameY && pVaaCalcResults->pCurY == pCurFrameY) { int32_t iMbIndex = 0; int32_t iSumDiff, iSQDiff, uiSum, iSQSum; for (j = 0; j < iMbHeight; j ++) { pRefFrameTmp = pRefFrameY; pCurFrameTmp = pCurFrameY; for (i = 0; i < iMbWidth; i++) { XMMREG_PROTECT_STORE(AdaptiveQuantization); iSumDiff = pVaaCalcResults->pSad8x8[iMbIndex][0]; iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][1]; iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][2]; iSumDiff += pVaaCalcResults->pSad8x8[iMbIndex][3]; iSQDiff = pVaaCalcResults->pSsd16x16[iMbIndex]; uiSum = pVaaCalcResults->pSum16x16[iMbIndex]; iSQSum = pVaaCalcResults->pSumOfSquare16x16[iMbIndex]; XMMREG_PROTECT_LOAD(AdaptiveQuantization); iSumDiff = iSumDiff >> 8; pMotionTexture->uiMotionIndex = (iSQDiff >> 8) - (iSumDiff * iSumDiff); uiSum = uiSum >> 8; pMotionTexture->uiTextureIndex = (iSQSum >> 8) - (uiSum * uiSum); dAverageMotionIndex += pMotionTexture->uiMotionIndex; dAverageTextureIndex += pMotionTexture->uiTextureIndex; pMotionTexture++; ++iMbIndex; pRefFrameTmp += MB_WIDTH_LUMA; pCurFrameTmp += MB_WIDTH_LUMA; } pRefFrameY += (iRefStride) << 4; pCurFrameY += (iCurStride) << 4; } } else {
DECODING_STATE CWelsDecoder::DecodeFrame2 (const unsigned char* kpSrc, const int kiSrcLen, void** ppDst, SBufferInfo* pDstInfo) { if (kiSrcLen > MAX_ACCESS_UNIT_CAPACITY) { m_pDecContext->iErrorCode |= dsOutOfMemory; IWelsTrace::WelsVTrace (m_pTrace, IWelsTrace::WELS_LOG_INFO, "max AU size exceeded. Allowed size = %d, current size = %d", MAX_ACCESS_UNIT_CAPACITY, kiSrcLen); return dsOutOfMemory; } if (kiSrcLen > 0 && kpSrc != NULL) { #ifdef OUTPUT_BIT_STREAM if (m_pFBS) { WelsFwrite (kpSrc, sizeof (unsigned char), kiSrcLen, m_pFBS); WelsFflush (m_pFBS); } if (m_pFBSSize) { WelsFwrite (&kiSrcLen, sizeof (int), 1, m_pFBSSize); WelsFflush (m_pFBSSize); } #endif//OUTPUT_BIT_STREAM m_pDecContext->bEndOfStreamFlag = false; } else { //For application MODE, the error detection should be added for safe. //But for CONSOLE MODE, when decoding LAST AU, kiSrcLen==0 && kpSrc==NULL. m_pDecContext->bEndOfStreamFlag = true; } ppDst[0] = ppDst[1] = ppDst[2] = NULL; m_pDecContext->iErrorCode = dsErrorFree; //initialize at the starting of AU decoding. m_pDecContext->iFeedbackVclNalInAu = FEEDBACK_UNKNOWN_NAL; //initialize memset (pDstInfo, 0, sizeof (SBufferInfo)); #ifdef LONG_TERM_REF m_pDecContext->bReferenceLostAtT0Flag = false; //initialize for LTR m_pDecContext->bCurAuContainLtrMarkSeFlag = false; m_pDecContext->iFrameNumOfAuMarkedLtr = 0; m_pDecContext->iFrameNum = -1; //initialize #endif m_pDecContext->iFeedbackTidInAu = -1; //initialize XMMREG_PROTECT_STORE(CWelsH264Decoder); WelsDecodeBs (m_pDecContext, kpSrc, kiSrcLen, (unsigned char**)ppDst, pDstInfo); //iErrorCode has been modified in this function XMMREG_PROTECT_LOAD(CWelsH264Decoder); if (m_pDecContext->iErrorCode) { ENalUnitType eNalType = NAL_UNIT_UNSPEC_0; //for NBR, IDR frames are expected to decode as followed if error decoding an IDR currently eNalType = m_pDecContext->sCurNalHead.eNalUnitType; //for AVC bitstream (excluding AVC with temporal scalability, including TP), as long as error occur, SHOULD notify upper layer key frame loss. if ((IS_PARAM_SETS_NALS (eNalType) || NAL_UNIT_CODED_SLICE_IDR == eNalType) || (VIDEO_BITSTREAM_AVC == m_pDecContext->eVideoType)) { #ifdef LONG_TERM_REF m_pDecContext->bParamSetsLostFlag = true; #else m_pDecContext->bReferenceLostAtT0Flag = true; #endif ResetParameterSetsState (m_pDecContext); //initial SPS&PPS ready flag } IWelsTrace::WelsVTrace (m_pTrace, IWelsTrace::WELS_LOG_INFO, "decode failed, failure type:%d \n", m_pDecContext->iErrorCode); return (DECODING_STATE)m_pDecContext->iErrorCode; } return dsErrorFree; }