diff --git a/codec/encoder/core/inc/encoder_context.h b/codec/encoder/core/inc/encoder_context.h index a077d82c..000e56e9 100644 --- a/codec/encoder/core/inc/encoder_context.h +++ b/codec/encoder/core/inc/encoder_context.h @@ -116,6 +116,7 @@ typedef struct TagWelsEncCtx { int32_t* pSadCostMb; /* MVD cost tables for Inter MB */ + int32_t iMvRange; uint16_t* pMvdCostTableInter; //[52]; // adaptive to spatial layers SMVUnitXY* pMvUnitBlock4x4; // (*pMvUnitBlock4x4[2])[MB_BLOCK4x4_NUM]; // for store each 4x4 blocks' mv unit, the two swap after different d layer diff --git a/codec/encoder/core/inc/slice.h b/codec/encoder/core/inc/slice.h index 7e0f3c31..092382e2 100644 --- a/codec/encoder/core/inc/slice.h +++ b/codec/encoder/core/inc/slice.h @@ -163,8 +163,8 @@ typedef struct TagSlice { SSliceHeaderExt sSliceHeaderExt; - SMVUnitXY sMvMin; - SMVUnitXY sMvMax; + SMVUnitXY sMvStartMin; + SMVUnitXY sMvStartMax; SMVUnitXY sMvc[5]; uint8_t uiMvcNum; uint8_t sScaleShift; diff --git a/codec/encoder/core/inc/svc_motion_estimate.h b/codec/encoder/core/inc/svc_motion_estimate.h index 1e02e3cd..462c4d53 100644 --- a/codec/encoder/core/inc/svc_motion_estimate.h +++ b/codec/encoder/core/inc/svc_motion_estimate.h @@ -45,9 +45,14 @@ #include "wels_func_ptr_def.h" namespace WelsSVCEnc { -#define MV_RANGE (64) +#define CAMERA_STARTMV_RANGE (64) #define ITERATIVE_TIMES (16) -#define BASE_MV_MB_NMB ((2*(MV_RANGE+ITERATIVE_TIMES)/MB_WIDTH_LUMA)-1) +#define CAMERA_MV_RANGE (CAMERA_STARTMV_RANGE+ITERATIVE_TIMES) +#define CAMERA_MVD_RANGE ((CAMERA_MV_RANGE+1)<<1) //mvd=mv_range*2; +#define BASE_MV_MB_NMB ((2*CAMERA_MV_RANGE/MB_WIDTH_LUMA)-1) +#define CAMERA_HIGHLAYER_MVD_RANGE (243)//mvd range; +#define EXPANDED_MV_RANGE (504) //=512-8 rather than 511 to sacrifice same edge point but save complexity in assemblys +#define EXPANDED_MVD_RANGE ((504+1)<<1) union SadPredISatdUnit { uint32_t uiSadPred; diff --git a/codec/encoder/core/src/encoder_ext.cpp b/codec/encoder/core/src/encoder_ext.cpp index f31f4f20..815a0cd5 100644 --- a/codec/encoder/core/src/encoder_ext.cpp +++ b/codec/encoder/core/src/encoder_ext.cpp @@ -1201,8 +1201,10 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) { int32_t iResult = 0; float fCompressRatioThr = .5f; const int32_t kiNumDependencyLayers = pParam->iSpatialLayerNum; - const uint32_t kuiMvdInterTableSize = (kiNumDependencyLayers == 1 ? (1 + (648 << 1)) : (1 + (972 << 1))); - const uint32_t kuiMvdCacheAlginedSize = kuiMvdInterTableSize * sizeof (uint16_t); + (*ppCtx)->iMvRange = pParam->iUsageType?EXPANDED_MV_RANGE:CAMERA_STARTMV_RANGE; + const int32_t kiMvdRange = (pParam->iUsageType?EXPANDED_MVD_RANGE:((kiNumDependencyLayers == 1)?CAMERA_MVD_RANGE:CAMERA_HIGHLAYER_MVD_RANGE)); + const uint32_t kuiMvdInterTableSize = 1 + (kiMvdRange << 3);//intepel*4=qpel; qpel_mv_range*2=(+/-); + const uint32_t kuiMvdCacheAlignedSize = kuiMvdInterTableSize * sizeof (uint16_t); int32_t iVclLayersBsSizeCount = 0; int32_t iNonVclLayersBsSizeCount = 0; #if defined(MT_ENABLED) @@ -1401,7 +1403,7 @@ int32_t RequestMemorySvc (sWelsEncCtx** ppCtx) { return 1; } - (*ppCtx)->pMvdCostTableInter = (uint16_t*)pMa->WelsMallocz (52 * kuiMvdCacheAlginedSize, "pMvdCostTableInter"); + (*ppCtx)->pMvdCostTableInter = (uint16_t*)pMa->WelsMallocz (52 * kuiMvdCacheAlignedSize, "pMvdCostTableInter"); WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pMvdCostTableInter), FreeMemorySvc (ppCtx)) MvdCostInit ((*ppCtx)->pMvdCostTableInter, kuiMvdInterTableSize); //should put to a better place? diff --git a/codec/encoder/core/src/svc_base_layer_md.cpp b/codec/encoder/core/src/svc_base_layer_md.cpp index 59b00e16..e026cab3 100644 --- a/codec/encoder/core/src/svc_base_layer_md.cpp +++ b/codec/encoder/core/src/svc_base_layer_md.cpp @@ -359,7 +359,7 @@ void WelsMdInterInit (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb, const i ST32 (&pCurMb->sP16x16Mv, 0); ST32 (&pCurLayer->pDecPic->sMvList[kiMbXY], 0); - SetMvWithinMvRange( kiMbWidth, kiMbHeight, kiMbX, kiMbY, MV_RANGE, &(pSlice->sMvMin), &(pSlice->sMvMax)); + SetMvWithinMvRange( kiMbWidth, kiMbHeight, kiMbX, kiMbY, CAMERA_STARTMV_RANGE, &(pSlice->sMvStartMin), &(pSlice->sMvStartMax)); } int32_t WelsMdI16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SMbCache* pMbCache, int32_t iLambda) { diff --git a/codec/encoder/core/src/svc_motion_estimate.cpp b/codec/encoder/core/src/svc_motion_estimate.cpp index 2b4e6dc8..b14a3863 100644 --- a/codec/encoder/core/src/svc_motion_estimate.cpp +++ b/codec/encoder/core/src/svc_motion_estimate.cpp @@ -106,15 +106,15 @@ bool WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe, uint32_t i; const uint32_t kuiMvcNum = pSlice->uiMvcNum; const SMVUnitXY* kpMvcList = &pSlice->sMvc[0]; - const SMVUnitXY ksMvMin = pSlice->sMvMin; - const SMVUnitXY ksMvMax = pSlice->sMvMax; + const SMVUnitXY ksMvStartMin = pSlice->sMvStartMin; + const SMVUnitXY ksMvStartMax = pSlice->sMvStartMax; const SMVUnitXY ksMvp = pMe->sMvp; SMVUnitXY sMv; // Step 1: Initial point prediction // init with sMvp - sMv.iMvX = WELS_CLIP3 ((2 + ksMvp.iMvX) >> 2, ksMvMin.iMvX, ksMvMax.iMvX); - sMv.iMvY = WELS_CLIP3 ((2 + ksMvp.iMvY) >> 2, ksMvMin.iMvY, ksMvMax.iMvY); + sMv.iMvX = WELS_CLIP3 ((2 + ksMvp.iMvX) >> 2, ksMvStartMin.iMvX, ksMvStartMax.iMvX); + sMv.iMvY = WELS_CLIP3 ((2 + ksMvp.iMvY) >> 2, ksMvStartMin.iMvY, ksMvStartMax.iMvY); pRefMb = &pMe->pRefMb[sMv.iMvY * iStrideRef + sMv.iMvX]; @@ -123,8 +123,8 @@ bool WelsMotionEstimateInitialPoint (SWelsFuncPtrList* pFuncList, SWelsME* pMe, for (i = 0; i < kuiMvcNum; i++) { //clipping here is essential since some pOut-of-range MVC may happen here (i.e., refer to baseMV) - iMvc0 = WELS_CLIP3 ((2 + kpMvcList[i].iMvX) >> 2, ksMvMin.iMvX, ksMvMax.iMvX); - iMvc1 = WELS_CLIP3 ((2 + kpMvcList[i].iMvY) >> 2, ksMvMin.iMvY, ksMvMax.iMvY); + iMvc0 = WELS_CLIP3 ((2 + kpMvcList[i].iMvX) >> 2, ksMvStartMin.iMvX, ksMvStartMax.iMvX); + iMvc1 = WELS_CLIP3 ((2 + kpMvcList[i].iMvY) >> 2, ksMvStartMin.iMvY, ksMvStartMax.iMvY); if (((iMvc0 - sMv.iMvX) || (iMvc1 - sMv.iMvY))) { pFref2 = &pMe->pRefMb[iMvc1 * iStrideRef + iMvc0];