shithub: openh264

Download patch

ref: c3cfce52234cff956e541896886c25d8e810ccba
parent: 4da932426cd55708d3fc0227c4b7cc59f125fcad
author: huili2 <[email protected]>
date: Mon Jun 1 11:11:20 EDT 2015

modify some functions extending to sub8x8 usage, especially in ME part

--- a/codec/common/inc/copy_mb.h
+++ b/codec/common/inc/copy_mb.h
@@ -38,7 +38,9 @@
 /****************************************************************************
  * Copy functions
  ****************************************************************************/
-void WelsCopy4x4 (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
+void WelsCopy4x4_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
+void WelsCopy8x4_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
+void WelsCopy4x8_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
 void WelsCopy8x8_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);
 void WelsCopy8x16_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);	//
 void WelsCopy16x8_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS);	//
--- a/codec/common/inc/sad_common.h
+++ b/codec/common/inc/sad_common.h
@@ -41,8 +41,8 @@
 int32_t WelsSampleSad16x8_c (uint8_t*, int32_t, uint8_t*, int32_t);
 int32_t WelsSampleSad8x16_c (uint8_t*, int32_t, uint8_t*, int32_t);
 int32_t WelsSampleSad8x8_c (uint8_t*, int32_t, uint8_t*, int32_t);
-//int32_t WelsSampleSad8x4( uint8_t *, int32_t, uint8_t *, int32_t );
-//int32_t WelsSampleSad4x8( uint8_t *, int32_t, uint8_t *, int32_t );
+int32_t WelsSampleSad8x4_c( uint8_t *, int32_t, uint8_t *, int32_t );
+int32_t WelsSampleSad4x8_c( uint8_t *, int32_t, uint8_t *, int32_t );
 int32_t WelsSampleSad4x4_c (uint8_t*, int32_t, uint8_t*, int32_t);
 
 
@@ -52,6 +52,8 @@
 void WelsSampleSadFour8x16_c (uint8_t* iSample1, int32_t iStride1, uint8_t* iSample2, int32_t iStride2, int32_t* pSad);
 void WelsSampleSadFour8x8_c (uint8_t* iSample1, int32_t iStride1, uint8_t* iSample2, int32_t iStride2, int32_t* pSad);
 void WelsSampleSadFour4x4_c (uint8_t* iSample1, int32_t iStride1, uint8_t* iSample2, int32_t iStride2, int32_t* pSad);
+void WelsSampleSadFour8x4_c (uint8_t* iSample1, int32_t iStride1, uint8_t* iSample2, int32_t iStride2, int32_t* pSad);
+void WelsSampleSadFour4x8_c (uint8_t* iSample1, int32_t iStride1, uint8_t* iSample2, int32_t iStride2, int32_t* pSad);
 
 #if defined(__cplusplus)
 extern "C" {
--- a/codec/common/src/copy_mb.cpp
+++ b/codec/common/src/copy_mb.cpp
@@ -45,7 +45,7 @@
 /****************************************************************************
  * Copy functions
  ****************************************************************************/
-void WelsCopy4x4 (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS) {
+void WelsCopy4x4_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS) {
   const int32_t kiSrcStride2 = iStrideS << 1;
   const int32_t kiSrcStride3 = iStrideS + kiSrcStride2;
   const int32_t kiDstStride2 = iStrideD << 1;
@@ -55,6 +55,14 @@
   ST32 (pDst + iStrideD,	LD32 (pSrc + iStrideS));
   ST32 (pDst + kiDstStride2, LD32 (pSrc + kiSrcStride2));
   ST32 (pDst + kiDstStride3, LD32 (pSrc + kiSrcStride3));
+}
+void WelsCopy8x4_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS) {
+  WelsCopy4x4_c (pDst, iStrideD, pSrc, iStrideS);
+  WelsCopy4x4_c (pDst + 4, iStrideD, pSrc + 4, iStrideS);
+}
+void WelsCopy4x8_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS) {
+  WelsCopy4x4_c (pDst, iStrideD, pSrc, iStrideS);
+  WelsCopy4x4_c (pDst + (iStrideD << 2), iStrideD, pSrc + (iStrideS << 2), iStrideS);
 }
 void WelsCopy8x8_c (uint8_t* pDst, int32_t iStrideD, uint8_t* pSrc, int32_t iStrideS) {
   int32_t i;
--- a/codec/common/src/sad_common.cpp
+++ b/codec/common/src/sad_common.cpp
@@ -59,6 +59,20 @@
   return iSadSum;
 }
 
+int32_t WelsSampleSad8x4_c (uint8_t* pSample1, int32_t iStride1, uint8_t* pSample2, int32_t iStride2) {
+  int32_t iSadSum = 0;
+  iSadSum += WelsSampleSad4x4_c (pSample1,     iStride1, pSample2,     iStride2);
+  iSadSum += WelsSampleSad4x4_c (pSample1 + 4, iStride1, pSample2 + 4, iStride2);
+  return iSadSum;
+}
+
+int32_t WelsSampleSad4x8_c (uint8_t* pSample1, int32_t iStride1, uint8_t* pSample2, int32_t iStride2) {
+  int32_t iSadSum = 0;
+  iSadSum += WelsSampleSad4x4_c (pSample1,                   iStride1, pSample2,                   iStride2);
+  iSadSum += WelsSampleSad4x4_c (pSample1 + (iStride1 << 2), iStride1, pSample2 + (iStride2 << 2), iStride2);
+  return iSadSum;
+}
+
 int32_t WelsSampleSad8x8_c (uint8_t* pSample1, int32_t iStride1, uint8_t* pSample2, int32_t iStride2) {
   int32_t iSadSum = 0;
   int32_t i = 0;
@@ -136,4 +150,16 @@
   * (pSad + 1) = WelsSampleSad4x4_c (iSample1, iStride1, (iSample2 + iStride2), iStride2);
   * (pSad + 2) = WelsSampleSad4x4_c (iSample1, iStride1, (iSample2 - 1), iStride2);
   * (pSad + 3) = WelsSampleSad4x4_c (iSample1, iStride1, (iSample2 + 1), iStride2);
+}
+void WelsSampleSadFour8x4_c (uint8_t* iSample1, int32_t iStride1, uint8_t* iSample2, int32_t iStride2, int32_t* pSad) {
+  * (pSad)     = WelsSampleSad8x4_c (iSample1, iStride1, (iSample2 - iStride2), iStride2);
+  * (pSad + 1) = WelsSampleSad8x4_c (iSample1, iStride1, (iSample2 + iStride2), iStride2);
+  * (pSad + 2) = WelsSampleSad8x4_c (iSample1, iStride1, (iSample2 - 1), iStride2);
+  * (pSad + 3) = WelsSampleSad8x4_c (iSample1, iStride1, (iSample2 + 1), iStride2);
+}
+void WelsSampleSadFour4x8_c (uint8_t* iSample1, int32_t iStride1, uint8_t* iSample2, int32_t iStride2, int32_t* pSad) {
+  * (pSad)     = WelsSampleSad4x8_c (iSample1, iStride1, (iSample2 - iStride2), iStride2);
+  * (pSad + 1) = WelsSampleSad4x8_c (iSample1, iStride1, (iSample2 + iStride2), iStride2);
+  * (pSad + 2) = WelsSampleSad4x8_c (iSample1, iStride1, (iSample2 - 1), iStride2);
+  * (pSad + 3) = WelsSampleSad4x8_c (iSample1, iStride1, (iSample2 + 1), iStride2);
 }
--- a/codec/encoder/core/inc/mb_cache.h
+++ b/codec/encoder/core/inc/mb_cache.h
@@ -79,7 +79,7 @@
 //	must follow with iNonZeroCoeffCount!
 
 int32_t     iSadCost[4];			//avail 1; unavail 0
-SMVUnitXY  sMbMvp[MB_BLOCK8x8_NUM];// for write bs
+SMVUnitXY  sMbMvp[MB_BLOCK4x4_NUM];// for write bs
 
 //for residual decoding (recovery) at the side of Encoder
 int16_t* pCoeffLevel;		// tmep
--- a/codec/encoder/core/inc/md.h
+++ b/codec/encoder/core/inc/md.h
@@ -109,6 +109,9 @@
   SWelsME			sMe8x8[4];
   SWelsME			sMe16x8[2];
   SWelsME			sMe8x16[2];
+  SWelsME			sMe4x4[4][4];
+  SWelsME			sMe8x4[4][2];
+  SWelsME			sMe4x8[4][2];
 //		SMVUnitXY		i_mvbs[MB_BLOCK8x8_NUM];	//scaled MVB
 } sMe;
 
--- a/codec/encoder/core/inc/wels_const.h
+++ b/codec/encoder/core/inc/wels_const.h
@@ -142,9 +142,9 @@
 BLOCK_8x16     = 2,
 BLOCK_8x8      = 3,
 BLOCK_4x4      = 4,
-// BLOCK_8x4      = 5,
-// BLOCK_4x8      = 6,
-BLOCK_SIZE_ALL = 5
+BLOCK_8x4      = 5,
+BLOCK_4x8      = 6,
+BLOCK_SIZE_ALL = 7
 };
 
 typedef enum {
--- a/codec/encoder/core/inc/wels_func_ptr_def.h
+++ b/codec/encoder/core/inc/wels_func_ptr_def.h
@@ -155,7 +155,7 @@
 typedef int32_t (*PCalculateSingleBlockFeature) (uint8_t* pRef, const int32_t kiRefStride);
 typedef void (*PUpdateFMESwitch) (SDqLayer* pCurLayer);
 
-#define     MAX_BLOCK_TYPE 5 // prev 7
+#define     MAX_BLOCK_TYPE BLOCK_SIZE_ALL
 typedef struct TagSampleDealingFunc {
   PSampleSadSatdCostFunc            pfSampleSad[MAX_BLOCK_TYPE];
   PSampleSadSatdCostFunc            pfSampleSatd[MAX_BLOCK_TYPE];
@@ -235,8 +235,10 @@
   PCopyFunc      pfCopy8x8Aligned;    //svc_encode_slice.c svc_mode_decision.c svc_base_layer_md.c md.c
   PCopyFunc    pfCopy16x8NotAligned;  //for MeRefineFracPixel 16x8 based
   PCopyFunc    pfCopy8x16Aligned;    //for MeRefineFracPixel 8x16 based
+  PCopyFunc      pfCopy4x4;    //not sure if aligned or not, need further tune
+  PCopyFunc      pfCopy8x4;    //not sure if aligned or not, need further tune
+  PCopyFunc      pfCopy4x8;    //not sure if aligned or not, need further tune
 
-  //svc_encode_mb.c encode_mb_aux.c
   PDctFunc          pfDctT4;
   PDctFunc                pfDctFourT4;
 
--- a/codec/encoder/core/src/encode_mb_aux.cpp
+++ b/codec/encoder/core/src/encode_mb_aux.cpp
@@ -467,7 +467,9 @@
     pFuncList->pfCopy16x16NotAligned    = WelsCopy16x16_c;
   pFuncList->pfCopy16x8NotAligned       = WelsCopy16x8_c;
   pFuncList->pfCopy8x16Aligned          = WelsCopy8x16_c;
-
+  pFuncList->pfCopy4x4           = WelsCopy4x4_c;
+  pFuncList->pfCopy8x4           = WelsCopy8x4_c;
+  pFuncList->pfCopy4x8           = WelsCopy4x8_c;
   pFuncList->pfQuantizationHadamard2x2          = WelsHadamardQuant2x2_c;
   pFuncList->pfQuantizationHadamard2x2Skip      = WelsHadamardQuant2x2Skip_c;
   pFuncList->pfTransformHadamard4x4Dc           = WelsHadamardT4Dc_c;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -2983,7 +2983,9 @@
       pFuncList->pfSearchMethod[BLOCK_16x8] =
         pFuncList->pfSearchMethod[BLOCK_8x16] =
           pFuncList->pfSearchMethod[BLOCK_8x8] =
-            pFuncList->pfSearchMethod[BLOCK_4x4] = WelsDiamondSearch;
+            pFuncList->pfSearchMethod[BLOCK_4x4] =
+              pFuncList->pfSearchMethod[BLOCK_8x4] =
+                pFuncList->pfSearchMethod[BLOCK_4x8] = WelsDiamondSearch;
     pFuncList->pfFirstIntraMode = WelsMdFirstIntraMode;
     pFuncList->sSampleDealingFuncs.pfMeCost = pCtx->pFuncList->sSampleDealingFuncs.pfSampleSatd;
     pFuncList->pfSetScrollingMv = SetScrollingMvToMdNull;
--- a/codec/encoder/core/src/sample.cpp
+++ b/codec/encoder/core/src/sample.cpp
@@ -95,6 +95,21 @@
 
   return ((iSatdSum + 1) >> 1);
 }
+
+int32_t WelsSampleSatd8x4_c (uint8_t* pSample1, int32_t iStride1, uint8_t* pSample2, int32_t iStride2) {
+  int32_t iSatdSum = 0;
+  iSatdSum += WelsSampleSatd4x4_c (pSample1,   iStride1, pSample2,   iStride2);
+  iSatdSum += WelsSampleSatd4x4_c (pSample1 + 4, iStride1, pSample2 + 4, iStride2);
+  return iSatdSum;
+}
+
+int32_t WelsSampleSatd4x8_c (uint8_t* pSample1, int32_t iStride1, uint8_t* pSample2, int32_t iStride2) {
+  int32_t iSatdSum = 0;
+  iSatdSum += WelsSampleSatd4x4_c (pSample1,                   iStride1, pSample2,                   iStride2);
+  iSatdSum += WelsSampleSatd4x4_c (pSample1 + (iStride1 << 2), iStride1, pSample2 + (iStride2 << 2), iStride2);
+  return iSatdSum;
+}
+
 int32_t WelsSampleSatd8x8_c (uint8_t* pSample1, int32_t iStride1, uint8_t* pSample2, int32_t iStride2) {
   int32_t iSatdSum = 0;
 
@@ -325,6 +340,8 @@
   pFuncList->sSampleDealingFuncs.pfSampleSad[BLOCK_8x16 ] = WelsSampleSad8x16_c;
   pFuncList->sSampleDealingFuncs.pfSampleSad[BLOCK_8x8  ] = WelsSampleSad8x8_c;
   pFuncList->sSampleDealingFuncs.pfSampleSad[BLOCK_4x4  ] = WelsSampleSad4x4_c;
+  pFuncList->sSampleDealingFuncs.pfSampleSad[BLOCK_8x4  ] = WelsSampleSad8x4_c;
+  pFuncList->sSampleDealingFuncs.pfSampleSad[BLOCK_4x8  ] = WelsSampleSad4x8_c;
 
   //pfSampleSatd init
   pFuncList->sSampleDealingFuncs.pfSampleSatd[BLOCK_16x16] = WelsSampleSatd16x16_c;
@@ -332,6 +349,8 @@
   pFuncList->sSampleDealingFuncs.pfSampleSatd[BLOCK_8x16 ] = WelsSampleSatd8x16_c;
   pFuncList->sSampleDealingFuncs.pfSampleSatd[BLOCK_8x8  ] = WelsSampleSatd8x8_c;
   pFuncList->sSampleDealingFuncs.pfSampleSatd[BLOCK_4x4  ] = WelsSampleSatd4x4_c;
+  pFuncList->sSampleDealingFuncs.pfSampleSatd[BLOCK_8x4  ] = WelsSampleSatd8x4_c;
+  pFuncList->sSampleDealingFuncs.pfSampleSatd[BLOCK_4x8  ] = WelsSampleSatd4x8_c;
 
   pFuncList->sSampleDealingFuncs.pfSample4Sad[BLOCK_16x16] = WelsSampleSadFour16x16_c;
   pFuncList->sSampleDealingFuncs.pfSample4Sad[BLOCK_16x8] = WelsSampleSadFour16x8_c;
@@ -338,6 +357,8 @@
   pFuncList->sSampleDealingFuncs.pfSample4Sad[BLOCK_8x16] = WelsSampleSadFour8x16_c;
   pFuncList->sSampleDealingFuncs.pfSample4Sad[BLOCK_8x8] = WelsSampleSadFour8x8_c;
   pFuncList->sSampleDealingFuncs.pfSample4Sad[BLOCK_4x4] = WelsSampleSadFour4x4_c;
+  pFuncList->sSampleDealingFuncs.pfSample4Sad[BLOCK_8x4] = WelsSampleSadFour8x4_c;
+  pFuncList->sSampleDealingFuncs.pfSample4Sad[BLOCK_4x8] = WelsSampleSadFour4x8_c;
 
   pFuncList->sSampleDealingFuncs.pfIntra4x4Combined3Satd   = NULL;
   pFuncList->sSampleDealingFuncs.pfIntra8x8Combined3Satd   = NULL;
--- a/codec/encoder/core/src/svc_encode_mb.cpp
+++ b/codec/encoder/core/src/svc_encode_mb.cpp
@@ -174,7 +174,7 @@
     pFuncList->pfDequantization4x4 (pResI4x4, g_kuiDequantCoeff[uiQp]);
     pFuncList->pfIDctT4 (pPredI4x4, iRecStride, pBestPred, 4, pResI4x4);
   } else
-    WelsCopy4x4 (pPredI4x4, iRecStride, pBestPred, 4);
+    pFuncList->pfCopy4x4 (pPredI4x4, iRecStride, pBestPred, 4);
 }
 
 void WelsEncInterY (SWelsFuncPtrList* pFuncList, SMB* pCurMb, SMbCache* pMbCache) {
--- a/test/encoder/EncUT_EncoderMbAux.cpp
+++ b/test/encoder/EncUT_EncoderMbAux.cpp
@@ -241,7 +241,9 @@
       EXPECT_EQ(ref_dst[i*iDStride+j], dst[i*iDStride+j]); \
 }
 
-GENERATE_UT_FOR_COPY (4, 4, WelsCopy4x4);
+GENERATE_UT_FOR_COPY (4, 4, WelsCopy4x4_c);
+GENERATE_UT_FOR_COPY (8, 4, WelsCopy8x4_c);
+GENERATE_UT_FOR_COPY (4, 8, WelsCopy4x8_c);
 GENERATE_UT_FOR_COPY (8, 8, WelsCopy8x8_c);
 GENERATE_UT_FOR_COPY (8, 16, WelsCopy8x16_c);
 GENERATE_UT_FOR_COPY (16, 8, WelsCopy16x8_c);
--- a/test/encoder/EncUT_Sample.cpp
+++ b/test/encoder/EncUT_Sample.cpp
@@ -188,6 +188,42 @@
   EXPECT_EQ (WelsSampleSad4x4_c (m_pPixSrcA, m_iStrideA, m_pPixSrcB, m_iStrideB), iSumSad);
 }
 
+TEST_F (SadSatdCFuncTest, WelsSampleSad8x4_c) {
+  for (int i = 0; i < (m_iStrideA << 2); i++)
+    m_pPixSrcA[i] = rand() % 256;
+  for (int i = 0; i < (m_iStrideB << 2); i++)
+    m_pPixSrcB[i] = rand() % 256;
+  uint8_t* pPixA = m_pPixSrcA;
+  uint8_t* pPixB = m_pPixSrcB;
+
+  int32_t iSumSad = 0;
+  for (int i = 0; i < 4; i++) {
+    for (int j = 0; j < 8; j++)
+      iSumSad += abs (pPixA[j] - pPixB[j]);
+    pPixA += m_iStrideA;
+    pPixB += m_iStrideB;
+  }
+  EXPECT_EQ (WelsSampleSad8x4_c (m_pPixSrcA, m_iStrideA, m_pPixSrcB, m_iStrideB), iSumSad);
+}
+
+TEST_F (SadSatdCFuncTest, WelsSampleSad4x8_c) {
+  for (int i = 0; i < (m_iStrideA << 2); i++)
+    m_pPixSrcA[i] = rand() % 256;
+  for (int i = 0; i < (m_iStrideB << 2); i++)
+    m_pPixSrcB[i] = rand() % 256;
+  uint8_t* pPixA = m_pPixSrcA;
+  uint8_t* pPixB = m_pPixSrcB;
+
+  int32_t iSumSad = 0;
+  for (int i = 0; i < 8; i++) {
+    for (int j = 0; j < 4; j++)
+      iSumSad += abs (pPixA[j] - pPixB[j]);
+    pPixA += m_iStrideA;
+    pPixB += m_iStrideB;
+  }
+  EXPECT_EQ (WelsSampleSad4x8_c (m_pPixSrcA, m_iStrideA, m_pPixSrcB, m_iStrideB), iSumSad);
+}
+
 TEST_F (SadSatdCFuncTest, WelsSampleSad8x8_c) {
   for (int i = 0; i < (m_iStrideA << 3); i++)
     m_pPixSrcA[i] = rand() % 256;
@@ -444,6 +480,51 @@
   EXPECT_EQ (m_pSad[0] + m_pSad[1] + m_pSad[2] + m_pSad[3], iSumSad);
 }
 
+TEST_F (SadSatdCFuncTest, WelsSampleSadFour8x4_c) {
+  for (int i = 0; i < (m_iStrideA << 3); i++)
+    m_pPixSrcA[i] = rand() % 256;
+  for (int i = 0; i < (m_iStrideB << 3); i++)
+    m_pPixSrcB[i] = rand() % 256;
+  uint8_t* pPixA = m_pPixSrcA;
+  uint8_t* pPixB = m_pPixSrcB + m_iStrideB;
+
+  int32_t iSumSad = 0;
+  for (int i = 0; i < 4; i++) {
+    for (int j = 0; j < 8; j++) {
+      iSumSad += abs (pPixA[j] - pPixB[j - 1]);
+      iSumSad += abs (pPixA[j] - pPixB[j + 1]);
+      iSumSad += abs (pPixA[j] - pPixB[j - m_iStrideB]);
+      iSumSad += abs (pPixA[j] - pPixB[j + m_iStrideB]);
+    }
+    pPixA += m_iStrideA;
+    pPixB += m_iStrideB;
+  }
+  WelsSampleSadFour8x4_c (m_pPixSrcA, m_iStrideA, m_pPixSrcB + m_iStrideB, m_iStrideB, m_pSad);
+  EXPECT_EQ (m_pSad[0] + m_pSad[1] + m_pSad[2] + m_pSad[3], iSumSad);
+}
+
+TEST_F (SadSatdCFuncTest, WelsSampleSadFour4x8_c) {
+  for (int i = 0; i < (m_iStrideA << 3); i++)
+    m_pPixSrcA[i] = rand() % 256;
+  for (int i = 0; i < (m_iStrideB << 3); i++)
+    m_pPixSrcB[i] = rand() % 256;
+  uint8_t* pPixA = m_pPixSrcA;
+  uint8_t* pPixB = m_pPixSrcB + m_iStrideB;
+
+  int32_t iSumSad = 0;
+  for (int i = 0; i < 8; i++) {
+    for (int j = 0; j < 4; j++) {
+      iSumSad += abs (pPixA[j] - pPixB[j - 1]);
+      iSumSad += abs (pPixA[j] - pPixB[j + 1]);
+      iSumSad += abs (pPixA[j] - pPixB[j - m_iStrideB]);
+      iSumSad += abs (pPixA[j] - pPixB[j + m_iStrideB]);
+    }
+    pPixA += m_iStrideA;
+    pPixB += m_iStrideB;
+  }
+  WelsSampleSadFour4x8_c (m_pPixSrcA, m_iStrideA, m_pPixSrcB + m_iStrideB, m_iStrideB, m_pSad);
+  EXPECT_EQ (m_pSad[0] + m_pSad[1] + m_pSad[2] + m_pSad[3], iSumSad);
+}
 
 class SadSatdAssemblyFuncTest : public testing::Test {
  public: