add complexity calculation for screen content
This commit is contained in:
@@ -129,6 +129,7 @@ typedef enum {
|
|||||||
METHOD_BACKGROUND_DETECTION ,
|
METHOD_BACKGROUND_DETECTION ,
|
||||||
METHOD_ADAPTIVE_QUANT ,
|
METHOD_ADAPTIVE_QUANT ,
|
||||||
METHOD_COMPLEXITY_ANALYSIS ,
|
METHOD_COMPLEXITY_ANALYSIS ,
|
||||||
|
METHOD_COMPLEXITY_ANALYSIS_SCREEN,
|
||||||
METHOD_IMAGE_ROTATE ,
|
METHOD_IMAGE_ROTATE ,
|
||||||
METHOD_MASK
|
METHOD_MASK
|
||||||
} EMethods;
|
} EMethods;
|
||||||
|
|||||||
@@ -31,6 +31,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ComplexityAnalysis.h"
|
#include "ComplexityAnalysis.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "macros.h"
|
||||||
|
|
||||||
WELSVP_NAMESPACE_BEGIN
|
WELSVP_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@@ -268,4 +270,201 @@ void CComplexityAnalysis::AnalyzeGomComplexityViaVar (SPixMap* pSrcPixMap, SPixM
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CComplexityAnalysisScreen::CComplexityAnalysisScreen (int32_t iCpuFlag) {
|
||||||
|
m_eMethod = METHOD_COMPLEXITY_ANALYSIS_SCREEN;
|
||||||
|
WelsMemset (&m_ComplexityAnalysisParam, 0, sizeof (m_ComplexityAnalysisParam));
|
||||||
|
|
||||||
|
m_pSadFunc = WelsSampleSad16x16_c;
|
||||||
|
m_pIntraFunc[0] = WelsI16x16LumaPredV_c;
|
||||||
|
m_pIntraFunc[1] = WelsI16x16LumaPredH_c;
|
||||||
|
#ifdef X86_ASM
|
||||||
|
if (iCpuFlag & WELS_CPU_SSE2) {
|
||||||
|
m_pSadFunc = WelsSampleSad16x16_sse2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CComplexityAnalysisScreen::~CComplexityAnalysisScreen() {
|
||||||
|
}
|
||||||
|
|
||||||
|
EResult CComplexityAnalysisScreen::Process (int32_t nType, SPixMap* pSrc, SPixMap* pRef) {
|
||||||
|
bool bScrollFlag = m_ComplexityAnalysisParam.sScrollResult.bScrollDetectFlag;
|
||||||
|
int32_t iIdrFlag = m_ComplexityAnalysisParam.iIdrFlag;
|
||||||
|
int32_t iScrollMvX = m_ComplexityAnalysisParam.sScrollResult.iScrollMvX;
|
||||||
|
int32_t iScrollMvY = m_ComplexityAnalysisParam.sScrollResult.iScrollMvY;
|
||||||
|
|
||||||
|
if (m_ComplexityAnalysisParam.iMbRowInGom <= 0)
|
||||||
|
return RET_INVALIDPARAM;
|
||||||
|
if (!iIdrFlag && pRef == NULL)
|
||||||
|
return RET_INVALIDPARAM;
|
||||||
|
|
||||||
|
if (iIdrFlag || pRef == NULL) {
|
||||||
|
GomComplexityAnalysisIntra (pSrc);
|
||||||
|
} else if (!bScrollFlag || ((iScrollMvX == 0) && (iScrollMvY == 0))) {
|
||||||
|
GomComplexityAnalysisInter (pSrc, pRef, 0);
|
||||||
|
} else {
|
||||||
|
GomComplexityAnalysisInter (pSrc, pRef, 1);;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RET_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EResult CComplexityAnalysisScreen::Set (int32_t nType, void* pParam) {
|
||||||
|
if (pParam == NULL)
|
||||||
|
return RET_INVALIDPARAM;
|
||||||
|
|
||||||
|
m_ComplexityAnalysisParam = * (SComplexityAnalysisScreenParam*)pParam;
|
||||||
|
|
||||||
|
return RET_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
EResult CComplexityAnalysisScreen::Get (int32_t nType, void* pParam) {
|
||||||
|
if (pParam == NULL)
|
||||||
|
return RET_INVALIDPARAM;
|
||||||
|
|
||||||
|
* (SComplexityAnalysisScreenParam*)pParam = m_ComplexityAnalysisParam;
|
||||||
|
|
||||||
|
return RET_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CComplexityAnalysisScreen::GomComplexityAnalysisIntra (SPixMap* pSrc) {
|
||||||
|
int32_t iWidth = pSrc->sRect.iRectWidth;
|
||||||
|
int32_t iHeight = pSrc->sRect.iRectHeight;
|
||||||
|
int32_t iBlockWidth = iWidth >> 4;
|
||||||
|
int32_t iBlockHeight = iHeight >> 4;
|
||||||
|
|
||||||
|
int32_t iBlockSadH, iBlockSadV, iGomSad = 0;
|
||||||
|
int32_t iIdx = 0;
|
||||||
|
|
||||||
|
uint8_t* pPtrY = NULL;
|
||||||
|
int32_t iStrideY = 0;
|
||||||
|
int32_t iRowStrideY = 0;
|
||||||
|
|
||||||
|
uint8_t* pTmpCur = NULL;
|
||||||
|
|
||||||
|
ENFORCE_STACK_ALIGN_1D (uint8_t, iMemPredMb, 256, 16)
|
||||||
|
|
||||||
|
pPtrY = (uint8_t*)pSrc->pPixel[0];
|
||||||
|
|
||||||
|
iStrideY = pSrc->iStride[0];
|
||||||
|
iRowStrideY = iStrideY << 4;
|
||||||
|
|
||||||
|
m_ComplexityAnalysisParam.iFrameComplexity = 0;
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < iBlockHeight; j ++) {
|
||||||
|
pTmpCur = pPtrY;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < iBlockWidth; i++) {
|
||||||
|
iBlockSadH = iBlockSadV = 0x7fffffff; // INT_MAX
|
||||||
|
if (j > 0) {
|
||||||
|
m_pIntraFunc[0] (iMemPredMb, pTmpCur, iStrideY);
|
||||||
|
iBlockSadH = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
|
||||||
|
}
|
||||||
|
if (i > 0) {
|
||||||
|
m_pIntraFunc[1] (iMemPredMb, pTmpCur, iStrideY);
|
||||||
|
iBlockSadV = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
|
||||||
|
}
|
||||||
|
if (i || j)
|
||||||
|
iGomSad += WELS_MIN (iBlockSadH, iBlockSadV);
|
||||||
|
|
||||||
|
pTmpCur += 16;
|
||||||
|
|
||||||
|
if (i == iBlockWidth - 1 && ((j + 1) % m_ComplexityAnalysisParam.iMbRowInGom == 0 || j == iBlockHeight - 1)) {
|
||||||
|
m_ComplexityAnalysisParam.pGomComplexity[iIdx] = iGomSad;
|
||||||
|
m_ComplexityAnalysisParam.iFrameComplexity += iGomSad;
|
||||||
|
iIdx++;
|
||||||
|
iGomSad = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pPtrY += iRowStrideY;
|
||||||
|
}
|
||||||
|
m_ComplexityAnalysisParam.iGomNumInFrame = iIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CComplexityAnalysisScreen::GomComplexityAnalysisInter (SPixMap* pSrc, SPixMap* pRef, bool bScrollFlag) {
|
||||||
|
int32_t iWidth = pSrc->sRect.iRectWidth;
|
||||||
|
int32_t iHeight = pSrc->sRect.iRectHeight;
|
||||||
|
int32_t iBlockWidth = iWidth >> 4;
|
||||||
|
int32_t iBlockHeight = iHeight >> 4;
|
||||||
|
|
||||||
|
int32_t iInterSad, iScrollSad, iBlockSadH, iBlockSadV, iGomSad = 0;
|
||||||
|
int32_t iIdx = 0;
|
||||||
|
|
||||||
|
int32_t iScrollMvX = m_ComplexityAnalysisParam.sScrollResult.iScrollMvX;
|
||||||
|
int32_t iScrollMvY = m_ComplexityAnalysisParam.sScrollResult.iScrollMvY;
|
||||||
|
|
||||||
|
uint8_t* pPtrX = NULL, *pPtrY = NULL;
|
||||||
|
int32_t iStrideX = 0, iStrideY = 0;
|
||||||
|
int32_t iRowStrideX = 0, iRowStrideY = 0;
|
||||||
|
|
||||||
|
uint8_t* pTmpRef = NULL, *pTmpCur = NULL, *pTmpRefScroll = NULL;
|
||||||
|
|
||||||
|
ENFORCE_STACK_ALIGN_1D (uint8_t, iMemPredMb, 256, 16)
|
||||||
|
|
||||||
|
pPtrX = (uint8_t*)pRef->pPixel[0];
|
||||||
|
pPtrY = (uint8_t*)pSrc->pPixel[0];
|
||||||
|
|
||||||
|
iStrideX = pRef->iStride[0];
|
||||||
|
iStrideY = pSrc->iStride[0];
|
||||||
|
|
||||||
|
iRowStrideX = pRef->iStride[0] << 4;
|
||||||
|
iRowStrideY = pSrc->iStride[0] << 4;
|
||||||
|
|
||||||
|
m_ComplexityAnalysisParam.iFrameComplexity = 0;
|
||||||
|
|
||||||
|
for (int32_t j = 0; j < iBlockHeight; j ++) {
|
||||||
|
pTmpRef = pPtrX;
|
||||||
|
pTmpCur = pPtrY;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < iBlockWidth; i++) {
|
||||||
|
int32_t iBlockPointX = i << 4;
|
||||||
|
int32_t iBlockPointY = j << 4;
|
||||||
|
|
||||||
|
iInterSad = m_pSadFunc (pTmpCur, iStrideY, pTmpRef, iStrideX);
|
||||||
|
if (bScrollFlag) {
|
||||||
|
if ((iInterSad != 0) &&
|
||||||
|
(iBlockPointX + iScrollMvX >= 0) && (iBlockPointX + iScrollMvX <= iWidth - 8) &&
|
||||||
|
(iBlockPointY + iScrollMvY >= 0) && (iBlockPointY + iScrollMvY <= iHeight - 8)) {
|
||||||
|
pTmpRefScroll = pTmpRef - iScrollMvY * iStrideX + iScrollMvX;
|
||||||
|
iScrollSad = m_pSadFunc (pTmpCur, iStrideY, pTmpRefScroll, iStrideX);
|
||||||
|
|
||||||
|
if (iScrollSad < iInterSad) {
|
||||||
|
iInterSad = iScrollSad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
iBlockSadH = iBlockSadV = 0x7fffffff; // INT_MAX
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
m_pIntraFunc[0] (iMemPredMb, pTmpCur, iStrideY);
|
||||||
|
iBlockSadH = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
|
||||||
|
}
|
||||||
|
if (i > 0) {
|
||||||
|
m_pIntraFunc[1] (iMemPredMb, pTmpCur, iStrideY);
|
||||||
|
iBlockSadV = m_pSadFunc (pTmpCur, iStrideY, iMemPredMb, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
iGomSad += WELS_MIN (WELS_MIN (iBlockSadH, iBlockSadV), iInterSad);
|
||||||
|
|
||||||
|
if (i == iBlockWidth - 1 && ((j + 1) % m_ComplexityAnalysisParam.iMbRowInGom == 0 || j == iBlockHeight - 1)) {
|
||||||
|
m_ComplexityAnalysisParam.pGomComplexity[iIdx] = iGomSad;
|
||||||
|
m_ComplexityAnalysisParam.iFrameComplexity += iGomSad;
|
||||||
|
iIdx++;
|
||||||
|
iGomSad = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTmpRef += 16;
|
||||||
|
pTmpCur += 16;
|
||||||
|
}
|
||||||
|
pPtrX += iRowStrideX;
|
||||||
|
pPtrY += iRowStrideY;
|
||||||
|
}
|
||||||
|
m_ComplexityAnalysisParam.iGomNumInFrame = iIdx;
|
||||||
|
}
|
||||||
|
|
||||||
WELSVP_NAMESPACE_END
|
WELSVP_NAMESPACE_END
|
||||||
|
|||||||
@@ -46,6 +46,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "WelsFrameWork.h"
|
#include "WelsFrameWork.h"
|
||||||
#include "IWelsVP.h"
|
#include "IWelsVP.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
WELSVP_NAMESPACE_BEGIN
|
WELSVP_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@@ -78,6 +79,30 @@ class CComplexityAnalysis : public IStrategy {
|
|||||||
SComplexityAnalysisParam m_sComplexityAnalysisParam;
|
SComplexityAnalysisParam m_sComplexityAnalysisParam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//for screen content
|
||||||
|
|
||||||
|
class CComplexityAnalysisScreen : public IStrategy
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CComplexityAnalysisScreen(int32_t cpu_flag);
|
||||||
|
~CComplexityAnalysisScreen();
|
||||||
|
|
||||||
|
EResult Process(int32_t nType, SPixMap *src, SPixMap *ref);
|
||||||
|
EResult Set(int32_t nType, void *pParam);
|
||||||
|
EResult Get(int32_t nType, void *pParam);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GomComplexityAnalysisIntra( SPixMap *pSrc );
|
||||||
|
void GomComplexityAnalysisInter( SPixMap *pSrc, SPixMap *pRef,bool bScrollFlag);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PSad16x16Func m_pSadFunc;
|
||||||
|
GetIntraPredPtr m_pIntraFunc[2];
|
||||||
|
SComplexityAnalysisScreenParam m_ComplexityAnalysisParam;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
WELSVP_NAMESPACE_END
|
WELSVP_NAMESPACE_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user