shithub: openh264

Download patch

ref: 398da807c7f7c4b166b6ade1c0781f65e80d724a
parent: 579a5bc6c255edfde90a3ea5e376fc59c7b2e49b
author: Jan Schmidt <jan@centricular.com>
date: Tue Feb 26 21:06:44 EST 2019

deblocking: Disambiguate reference pictures

Macroblocks can refer to the same reference picture using
different indices when the same picture appears in multiple
slots in the current reference picture lists. That leads to
calculating the wrong loop filter strength for edge processing,
and small errors in the conformance suite on (for example)
CVWP5_TOSHIBA_E.264 and others.

Modify the test-suite and checksums for affected test files
where this situation occurs.

--- a/codec/decoder/core/inc/deblocking.h
+++ b/codec/decoder/core/inc/deblocking.h
@@ -77,7 +77,7 @@
  * \return  NONE
  */
 
-uint32_t DeblockingBsMarginalMBAvcbase (PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy);
+uint32_t DeblockingBsMarginalMBAvcbase (PDeblockingFilter  pFilter, PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy);
 uint32_t DeblockingBSliceBsMarginalMBAvcbase (PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy);
 
 int32_t DeblockingAvailableNoInterlayer (PDqLayer pCurDqLayer, int32_t iFilterIdc);
--- a/codec/decoder/core/inc/decoder_context.h
+++ b/codec/decoder/core/inc/decoder_context.h
@@ -172,6 +172,7 @@
   int8_t  iChromaQP[2];
   int8_t  iLumaQP;
   struct TagDeblockingFunc*  pLoopf;
+  PPicture *pRefPics[LIST_A];
 } SDeblockingFilter, *PDeblockingFilter;
 
 typedef void (*PDeblockingFilterMbFunc) (PDqLayer pCurDqLayer, PDeblockingFilter  filter, int32_t boundry_flag);
--- a/codec/decoder/core/src/deblocking.cpp
+++ b/codec/decoder/core/src/deblocking.cpp
@@ -55,17 +55,17 @@
 #define g_kiBetaTable(x)  g_kiBetaTable[(x)+12]
 #define g_kiTc0Table(x)   g_kiTc0Table[(x)+12]
 
-#define MB_BS_MV(iRefIndex, iMotionVector, iMbXy, iMbBn, iIndex, iNeighIndex) \
+#define MB_BS_MV(pRefPic0, pRefPic1, iMotionVector, iMbXy, iMbBn, iIndex, iNeighIndex) \
 (\
-    ( iRefIndex[iMbXy][iIndex] - iRefIndex[iMbBn][iNeighIndex] )||\
+    ( pRefPic0 != pRefPic1) ||\
     ( WELS_ABS( iMotionVector[iMbXy][iIndex][0] - iMotionVector[iMbBn][iNeighIndex][0] ) >= 4 ) ||\
     ( WELS_ABS( iMotionVector[iMbXy][iIndex][1] - iMotionVector[iMbBn][iNeighIndex][1] ) >= 4 )\
 )
 
 #if defined(SAME_MB_DIFF_REFIDX)
-#define SMB_EDGE_MV(iRefIndex, iMotionVector, iIndex, iNeighIndex) \
+#define SMB_EDGE_MV(pRefPics, iMotionVector, iIndex, iNeighIndex) \
 (\
-    ( iRefIndex[iIndex] - iRefIndex[iNeighIndex] )||(\
+    ( pRefPics[iIndex] != pRefPics[iNeighIndex] )||(\
     ( WELS_ABS( iMotionVector[iIndex][0] - iMotionVector[iNeighIndex][0] ) &(~3) ) |\
     ( WELS_ABS( iMotionVector[iIndex][1] - iMotionVector[iNeighIndex][1] ) &(~3) ))\
 )
@@ -76,8 +76,8 @@
 )
 #endif
 
-#define BS_EDGE(bsx1, iRefIndex, iMotionVector, iIndex, iNeighIndex) \
-( (bsx1|SMB_EDGE_MV(iRefIndex, iMotionVector, iIndex, iNeighIndex))<<((uint8_t)(!!bsx1)))
+#define BS_EDGE(bsx1, pRefPics, iMotionVector, iIndex, iNeighIndex) \
+( (bsx1|SMB_EDGE_MV(pRefPics, iMotionVector, iIndex, iNeighIndex))<<((uint8_t)(!!bsx1)))
 
 #define GET_ALPHA_BETA_FROM_QP(iQp, iAlphaOffset, iBetaOffset, iIndex, iAlpha, iBeta) \
 {\
@@ -201,14 +201,24 @@
   nBS[1][2][2] = nBS[1][2][3] = (i8x8NnzTab[1] | i8x8NnzTab[3]) << iLShiftFactor;
 }
 
-void static inline DeblockingBSInsideMBNormal (PDqLayer pCurDqLayer, uint8_t nBS[2][4][4], int8_t* pNnzTab,
+void static inline DeblockingBSInsideMBNormal (PDeblockingFilter  pFilter, PDqLayer pCurDqLayer, uint8_t nBS[2][4][4], int8_t* pNnzTab,
     int32_t iMbXy) {
   uint32_t uiNnz32b0, uiNnz32b1, uiNnz32b2, uiNnz32b3;
-  int8_t* iRefIndex = pCurDqLayer->pRefIndex[LIST_0][iMbXy];
+  int8_t* iRefIdx = pCurDqLayer->pRefIndex[LIST_0][iMbXy];
+  void *iRefs[MB_BLOCK4x4_NUM];
+  int i;
   ENFORCE_STACK_ALIGN_1D (uint8_t, uiBsx4, 4, 4);
 
   int8_t i8x8NnzTab[4];
 
+  /* Look up each reference picture based on indices */
+  for (i = 0; i < MB_BLOCK4x4_NUM; i++) {
+    if (iRefIdx[i] > REF_NOT_IN_LIST)
+      iRefs[i] = pFilter->pRefPics[LIST_0][iRefIdx[i]];
+    else
+      iRefs[i] = NULL;
+  }
+
   if (pCurDqLayer->pTransformSize8x8Flag[iMbXy]) {
     for (int32_t i = 0; i < 4; i++) {
       int32_t iBlkIdx = i << 2;
@@ -216,15 +226,15 @@
                        pNnzTab[g_kuiMbCountScan4Idx[iBlkIdx + 2]] | pNnzTab[g_kuiMbCountScan4Idx[iBlkIdx + 3]]);
     }
     //vertical
-    nBS[0][2][0] = nBS[0][2][1] = BS_EDGE ((i8x8NnzTab[0] | i8x8NnzTab[1]), iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy],
+    nBS[0][2][0] = nBS[0][2][1] = BS_EDGE ((i8x8NnzTab[0] | i8x8NnzTab[1]), iRefs, pCurDqLayer->pMv[LIST_0][iMbXy],
                                            g_kuiMbCountScan4Idx[1 << 2], g_kuiMbCountScan4Idx[0]);
-    nBS[0][2][2] = nBS[0][2][3] = BS_EDGE ((i8x8NnzTab[2] | i8x8NnzTab[3]), iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy],
+    nBS[0][2][2] = nBS[0][2][3] = BS_EDGE ((i8x8NnzTab[2] | i8x8NnzTab[3]), iRefs, pCurDqLayer->pMv[LIST_0][iMbXy],
                                            g_kuiMbCountScan4Idx[3 << 2], g_kuiMbCountScan4Idx[2 << 2]);
 
     //horizontal
-    nBS[1][2][0] = nBS[1][2][1] = BS_EDGE ((i8x8NnzTab[0] | i8x8NnzTab[2]), iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy],
+    nBS[1][2][0] = nBS[1][2][1] = BS_EDGE ((i8x8NnzTab[0] | i8x8NnzTab[2]), iRefs, pCurDqLayer->pMv[LIST_0][iMbXy],
                                            g_kuiMbCountScan4Idx[2 << 2], g_kuiMbCountScan4Idx[0]);
-    nBS[1][2][2] = nBS[1][2][3] = BS_EDGE ((i8x8NnzTab[1] | i8x8NnzTab[3]), iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy],
+    nBS[1][2][2] = nBS[1][2][3] = BS_EDGE ((i8x8NnzTab[1] | i8x8NnzTab[3]), iRefs, pCurDqLayer->pMv[LIST_0][iMbXy],
                                            g_kuiMbCountScan4Idx[3 << 2], g_kuiMbCountScan4Idx[1 << 2]);
   } else {
     uiNnz32b0 = * (uint32_t*) (pNnzTab + 0);
@@ -234,59 +244,70 @@
 
     for (int i = 0; i < 3; i++)
       uiBsx4[i] = pNnzTab[i] | pNnzTab[i + 1];
-    nBS[0][1][0] = BS_EDGE (uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 1, 0);
-    nBS[0][2][0] = BS_EDGE (uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 2, 1);
-    nBS[0][3][0] = BS_EDGE (uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 3, 2);
+    nBS[0][1][0] = BS_EDGE (uiBsx4[0], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 1, 0);
+    nBS[0][2][0] = BS_EDGE (uiBsx4[1], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 2, 1);
+    nBS[0][3][0] = BS_EDGE (uiBsx4[2], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 3, 2);
 
     for (int i = 0; i < 3; i++)
       uiBsx4[i] = pNnzTab[4 + i] | pNnzTab[4 + i + 1];
-    nBS[0][1][1] = BS_EDGE (uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 5, 4);
-    nBS[0][2][1] = BS_EDGE (uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 6, 5);
-    nBS[0][3][1] = BS_EDGE (uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 7, 6);
+    nBS[0][1][1] = BS_EDGE (uiBsx4[0], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 5, 4);
+    nBS[0][2][1] = BS_EDGE (uiBsx4[1], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 6, 5);
+    nBS[0][3][1] = BS_EDGE (uiBsx4[2], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 7, 6);
 
     for (int i = 0; i < 3; i++)
       uiBsx4[i] = pNnzTab[8 + i] | pNnzTab[8 + i + 1];
-    nBS[0][1][2] = BS_EDGE (uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 9, 8);
-    nBS[0][2][2] = BS_EDGE (uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 10, 9);
-    nBS[0][3][2] = BS_EDGE (uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 11, 10);
+    nBS[0][1][2] = BS_EDGE (uiBsx4[0], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 9, 8);
+    nBS[0][2][2] = BS_EDGE (uiBsx4[1], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 10, 9);
+    nBS[0][3][2] = BS_EDGE (uiBsx4[2], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 11, 10);
 
     for (int i = 0; i < 3; i++)
       uiBsx4[i] = pNnzTab[12 + i] | pNnzTab[12 + i + 1];
-    nBS[0][1][3] = BS_EDGE (uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 13, 12);
-    nBS[0][2][3] = BS_EDGE (uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 14, 13);
-    nBS[0][3][3] = BS_EDGE (uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 15, 14);
+    nBS[0][1][3] = BS_EDGE (uiBsx4[0], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 13, 12);
+    nBS[0][2][3] = BS_EDGE (uiBsx4[1], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 14, 13);
+    nBS[0][3][3] = BS_EDGE (uiBsx4[2], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 15, 14);
 
     // horizontal
     * (uint32_t*)uiBsx4 = (uiNnz32b0 | uiNnz32b1);
-    nBS[1][1][0] = BS_EDGE (uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 4, 0);
-    nBS[1][1][1] = BS_EDGE (uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 5, 1);
-    nBS[1][1][2] = BS_EDGE (uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 6, 2);
-    nBS[1][1][3] = BS_EDGE (uiBsx4[3], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 7, 3);
+    nBS[1][1][0] = BS_EDGE (uiBsx4[0], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 4, 0);
+    nBS[1][1][1] = BS_EDGE (uiBsx4[1], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 5, 1);
+    nBS[1][1][2] = BS_EDGE (uiBsx4[2], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 6, 2);
+    nBS[1][1][3] = BS_EDGE (uiBsx4[3], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 7, 3);
 
     * (uint32_t*)uiBsx4 = (uiNnz32b1 | uiNnz32b2);
-    nBS[1][2][0] = BS_EDGE (uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 8, 4);
-    nBS[1][2][1] = BS_EDGE (uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 9, 5);
-    nBS[1][2][2] = BS_EDGE (uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 10, 6);
-    nBS[1][2][3] = BS_EDGE (uiBsx4[3], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 11, 7);
+    nBS[1][2][0] = BS_EDGE (uiBsx4[0], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 8, 4);
+    nBS[1][2][1] = BS_EDGE (uiBsx4[1], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 9, 5);
+    nBS[1][2][2] = BS_EDGE (uiBsx4[2], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 10, 6);
+    nBS[1][2][3] = BS_EDGE (uiBsx4[3], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 11, 7);
 
     * (uint32_t*)uiBsx4 = (uiNnz32b2 | uiNnz32b3);
-    nBS[1][3][0] = BS_EDGE (uiBsx4[0], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 12, 8);
-    nBS[1][3][1] = BS_EDGE (uiBsx4[1], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 13, 9);
-    nBS[1][3][2] = BS_EDGE (uiBsx4[2], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 14, 10);
-    nBS[1][3][3] = BS_EDGE (uiBsx4[3], iRefIndex, pCurDqLayer->pMv[LIST_0][iMbXy], 15, 11);
+    nBS[1][3][0] = BS_EDGE (uiBsx4[0], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 12, 8);
+    nBS[1][3][1] = BS_EDGE (uiBsx4[1], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 13, 9);
+    nBS[1][3][2] = BS_EDGE (uiBsx4[2], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 14, 10);
+    nBS[1][3][3] = BS_EDGE (uiBsx4[3], iRefs, pCurDqLayer->pMv[LIST_0][iMbXy], 15, 11);
   }
 }
 
-void static inline DeblockingBSliceBSInsideMBNormal (PDqLayer pCurDqLayer, uint8_t nBS[2][4][4], int8_t* pNnzTab,
+void static inline DeblockingBSliceBSInsideMBNormal (PDeblockingFilter  pFilter, PDqLayer pCurDqLayer, uint8_t nBS[2][4][4], int8_t* pNnzTab,
     int32_t iMbXy) {
   uint32_t uiNnz32b0, uiNnz32b1, uiNnz32b2, uiNnz32b3;
-  int8_t* iRefIndex[LIST_A];
-  iRefIndex[LIST_0] = pCurDqLayer->pRefIndex[LIST_0][iMbXy];
-  iRefIndex[LIST_1] = pCurDqLayer->pRefIndex[LIST_1][iMbXy];
-  ENFORCE_STACK_ALIGN_1D (uint8_t, uiBsx4, 4, 4);
+  void *iRefs[LIST_A][MB_BLOCK4x4_NUM];
 
+  ENFORCE_STACK_ALIGN_1D (uint8_t, uiBsx4, 4, 4);
   int8_t i8x8NnzTab[4];
+  int l;
 
+  for (l = 0; l < LIST_A; l++) {
+    int8_t* iRefIdx = pCurDqLayer->pRefIndex[l][iMbXy];
+    int i;
+    /* Look up each reference picture based on indices */
+    for (i = 0; i < MB_BLOCK4x4_NUM; i++) {
+      if (iRefIdx[i] > REF_NOT_IN_LIST)
+        iRefs[l][i] = pFilter->pRefPics[l][iRefIdx[i]];
+      else
+        iRefs[l][i] = NULL;
+    }
+  }
+
   if (pCurDqLayer->pTransformSize8x8Flag[iMbXy]) {
     for (int32_t i = 0; i < 4; i++) {
       int32_t iBlkIdx = i << 2;
@@ -298,8 +319,8 @@
     int8_t iNeigborIndex = g_kuiMbCountScan4Idx[0];
     nBS[0][2][0] = nBS[0][2][1] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][iIndex] > REF_NOT_IN_LIST && iRefIndex[listIdx][iNeigborIndex] > REF_NOT_IN_LIST) {
-        nBS[0][2][0] = nBS[0][2][1] = BS_EDGE ((i8x8NnzTab[0] | i8x8NnzTab[1]), iRefIndex[listIdx],
+      if (iRefs[listIdx][iIndex] && iRefs[listIdx][iNeigborIndex]) {
+        nBS[0][2][0] = nBS[0][2][1] = BS_EDGE ((i8x8NnzTab[0] | i8x8NnzTab[1]), iRefs[listIdx],
                                                pCurDqLayer->pMv[listIdx][iMbXy],
                                                iIndex, iNeigborIndex);
         break;
@@ -309,8 +330,8 @@
     iNeigborIndex = g_kuiMbCountScan4Idx[2 << 2];
     nBS[0][2][2] = nBS[0][2][3] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][iIndex] > REF_NOT_IN_LIST && iRefIndex[listIdx][iNeigborIndex] > REF_NOT_IN_LIST) {
-        nBS[0][2][2] = nBS[0][2][3] = BS_EDGE ((i8x8NnzTab[2] | i8x8NnzTab[3]), iRefIndex[listIdx],
+      if (iRefs[listIdx][iIndex] && iRefs[listIdx][iNeigborIndex]) {
+        nBS[0][2][2] = nBS[0][2][3] = BS_EDGE ((i8x8NnzTab[2] | i8x8NnzTab[3]), iRefs[listIdx],
                                                pCurDqLayer->pMv[listIdx][iMbXy],
                                                iIndex, iNeigborIndex);
         break;
@@ -322,8 +343,8 @@
     iNeigborIndex = g_kuiMbCountScan4Idx[0];
     nBS[1][2][0] = nBS[1][2][1] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][iIndex] > REF_NOT_IN_LIST && iRefIndex[listIdx][iNeigborIndex] > REF_NOT_IN_LIST) {
-        nBS[1][2][0] = nBS[1][2][1] = BS_EDGE ((i8x8NnzTab[0] | i8x8NnzTab[2]), iRefIndex[listIdx],
+      if (iRefs[listIdx][iIndex] && iRefs[listIdx][iNeigborIndex]) {
+        nBS[1][2][0] = nBS[1][2][1] = BS_EDGE ((i8x8NnzTab[0] | i8x8NnzTab[2]), iRefs[listIdx],
                                                pCurDqLayer->pMv[listIdx][iMbXy],
                                                iIndex, iNeigborIndex);
         break;
@@ -334,8 +355,8 @@
     iNeigborIndex = g_kuiMbCountScan4Idx[1 << 2];
     nBS[1][2][2] = nBS[1][2][3] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][iIndex] > REF_NOT_IN_LIST && iRefIndex[listIdx][iNeigborIndex] > REF_NOT_IN_LIST) {
-        nBS[1][2][2] = nBS[1][2][3] = BS_EDGE ((i8x8NnzTab[1] | i8x8NnzTab[3]), iRefIndex[listIdx],
+      if (iRefs[listIdx][iIndex] && iRefs[listIdx][iNeigborIndex]) {
+        nBS[1][2][2] = nBS[1][2][3] = BS_EDGE ((i8x8NnzTab[1] | i8x8NnzTab[3]), iRefs[listIdx],
                                                pCurDqLayer->pMv[listIdx][iMbXy],
                                                iIndex, iNeigborIndex);
         break;
@@ -351,22 +372,22 @@
       uiBsx4[i] = pNnzTab[i] | pNnzTab[i + 1];
     nBS[0][1][0] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][1] > REF_NOT_IN_LIST && iRefIndex[listIdx][0] > REF_NOT_IN_LIST) {
-        nBS[0][1][0] = BS_EDGE (uiBsx4[0], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 1, 0);
+      if (iRefs[listIdx][1] && iRefs[listIdx][0]) {
+        nBS[0][1][0] = BS_EDGE (uiBsx4[0], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 1, 0);
         break;
       }
     }
     nBS[0][2][0] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][2] > REF_NOT_IN_LIST && iRefIndex[listIdx][1] > REF_NOT_IN_LIST) {
-        nBS[0][2][0] = BS_EDGE (uiBsx4[1], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 2, 1);
+      if (iRefs[listIdx][2] && iRefs[listIdx][1]) {
+        nBS[0][2][0] = BS_EDGE (uiBsx4[1], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 2, 1);
         break;
       }
     }
     nBS[0][3][0] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][3] > REF_NOT_IN_LIST && iRefIndex[listIdx][2] > REF_NOT_IN_LIST) {
-        nBS[0][3][0] = BS_EDGE (uiBsx4[2], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 3, 2);
+      if (iRefs[listIdx][3] && iRefs[listIdx][2]) {
+        nBS[0][3][0] = BS_EDGE (uiBsx4[2], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 3, 2);
         break;
       }
     }
@@ -375,22 +396,22 @@
       uiBsx4[i] = pNnzTab[4 + i] | pNnzTab[4 + i + 1];
     nBS[0][1][1] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][5] > REF_NOT_IN_LIST && iRefIndex[listIdx][4] > REF_NOT_IN_LIST) {
-        nBS[0][1][1] = BS_EDGE (uiBsx4[0], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 5, 4);
+      if (iRefs[listIdx][5] && iRefs[listIdx][4]) {
+        nBS[0][1][1] = BS_EDGE (uiBsx4[0], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 5, 4);
         break;
       }
     }
     nBS[0][2][1] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][6] > REF_NOT_IN_LIST && iRefIndex[listIdx][5] > REF_NOT_IN_LIST) {
-        nBS[0][2][1] = BS_EDGE (uiBsx4[1], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 6, 5);
+      if (iRefs[listIdx][6] && iRefs[listIdx][5]) {
+        nBS[0][2][1] = BS_EDGE (uiBsx4[1], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 6, 5);
         break;
       }
     }
     nBS[0][3][1] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][7] > REF_NOT_IN_LIST && iRefIndex[listIdx][6] > REF_NOT_IN_LIST) {
-        nBS[0][3][1] = BS_EDGE (uiBsx4[2], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 7, 6);
+      if (iRefs[listIdx][7] && iRefs[listIdx][6]) {
+        nBS[0][3][1] = BS_EDGE (uiBsx4[2], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 7, 6);
         break;
       }
     }
@@ -399,22 +420,22 @@
       uiBsx4[i] = pNnzTab[8 + i] | pNnzTab[8 + i + 1];
     nBS[0][1][2] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][9] > REF_NOT_IN_LIST && iRefIndex[listIdx][8] > REF_NOT_IN_LIST) {
-        nBS[0][1][2] = BS_EDGE (uiBsx4[0], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 9, 8);
+      if (iRefs[listIdx][9] && iRefs[listIdx][8]) {
+        nBS[0][1][2] = BS_EDGE (uiBsx4[0], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 9, 8);
         break;
       }
     }
     nBS[0][2][2] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][10] > REF_NOT_IN_LIST && iRefIndex[listIdx][9] > REF_NOT_IN_LIST) {
-        nBS[0][2][2] = BS_EDGE (uiBsx4[1], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 10, 9);
+      if (iRefs[listIdx][10] && iRefs[listIdx][9]) {
+        nBS[0][2][2] = BS_EDGE (uiBsx4[1], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 10, 9);
         break;
       }
     }
     nBS[0][3][2] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][11] > REF_NOT_IN_LIST && iRefIndex[listIdx][10] > REF_NOT_IN_LIST) {
-        nBS[0][3][2] = BS_EDGE (uiBsx4[2], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 11, 10);
+      if (iRefs[listIdx][11] && iRefs[listIdx][10]) {
+        nBS[0][3][2] = BS_EDGE (uiBsx4[2], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 11, 10);
         break;
       }
     }
@@ -423,22 +444,22 @@
       uiBsx4[i] = pNnzTab[12 + i] | pNnzTab[12 + i + 1];
     nBS[0][1][3] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][13] > REF_NOT_IN_LIST && iRefIndex[listIdx][12] > REF_NOT_IN_LIST) {
-        nBS[0][1][3] = BS_EDGE (uiBsx4[0], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 13, 12);
+      if (iRefs[listIdx][13] && iRefs[listIdx][12]) {
+        nBS[0][1][3] = BS_EDGE (uiBsx4[0], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 13, 12);
         break;
       }
     }
     nBS[0][2][3] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][14] > REF_NOT_IN_LIST && iRefIndex[listIdx][13] > REF_NOT_IN_LIST) {
-        nBS[0][2][3] = BS_EDGE (uiBsx4[1], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 14, 13);
+      if (iRefs[listIdx][14] && iRefs[listIdx][13]) {
+        nBS[0][2][3] = BS_EDGE (uiBsx4[1], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 14, 13);
         break;
       }
     }
     nBS[0][3][3] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][15] > REF_NOT_IN_LIST && iRefIndex[listIdx][14] > REF_NOT_IN_LIST) {
-        nBS[0][3][3] = BS_EDGE (uiBsx4[2], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 15, 14);
+      if (iRefs[listIdx][15] && iRefs[listIdx][14]) {
+        nBS[0][3][3] = BS_EDGE (uiBsx4[2], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 15, 14);
         break;
       }
     }
@@ -447,29 +468,29 @@
     * (uint32_t*)uiBsx4 = (uiNnz32b0 | uiNnz32b1);
     nBS[1][1][0] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][4] > REF_NOT_IN_LIST && iRefIndex[listIdx][0] > REF_NOT_IN_LIST) {
-        nBS[1][1][0] = BS_EDGE (uiBsx4[0], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 4, 0);
+      if (iRefs[listIdx][4] && iRefs[listIdx][0]) {
+        nBS[1][1][0] = BS_EDGE (uiBsx4[0], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 4, 0);
         break;
       }
     }
     nBS[1][1][1] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][5] > REF_NOT_IN_LIST && iRefIndex[listIdx][1] > REF_NOT_IN_LIST) {
-        nBS[1][1][1] = BS_EDGE (uiBsx4[1], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 5, 1);
+      if (iRefs[listIdx][5] && iRefs[listIdx][1]) {
+        nBS[1][1][1] = BS_EDGE (uiBsx4[1], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 5, 1);
         break;
       }
     }
     nBS[1][1][2] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][6] > REF_NOT_IN_LIST && iRefIndex[listIdx][2] > REF_NOT_IN_LIST) {
-        nBS[1][1][2] = BS_EDGE (uiBsx4[2], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 6, 2);
+      if (iRefs[listIdx][6] && iRefs[listIdx][2]) {
+        nBS[1][1][2] = BS_EDGE (uiBsx4[2], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 6, 2);
         break;
       }
     }
     nBS[1][1][3] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][7] > REF_NOT_IN_LIST && iRefIndex[listIdx][3] > REF_NOT_IN_LIST) {
-        nBS[1][1][3] = BS_EDGE (uiBsx4[3], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 7, 3);
+      if (iRefs[listIdx][7] && iRefs[listIdx][3]) {
+        nBS[1][1][3] = BS_EDGE (uiBsx4[3], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 7, 3);
         break;
       }
     }
@@ -477,29 +498,29 @@
     * (uint32_t*)uiBsx4 = (uiNnz32b1 | uiNnz32b2);
     nBS[1][2][0] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][8] > REF_NOT_IN_LIST && iRefIndex[listIdx][4] > REF_NOT_IN_LIST) {
-        nBS[1][2][0] = BS_EDGE (uiBsx4[0], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 8, 4);
+      if (iRefs[listIdx][8] && iRefs[listIdx][4]) {
+        nBS[1][2][0] = BS_EDGE (uiBsx4[0], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 8, 4);
         break;
       }
     }
     nBS[1][2][1] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][9] > REF_NOT_IN_LIST && iRefIndex[listIdx][5] > REF_NOT_IN_LIST) {
-        nBS[1][2][1] = BS_EDGE (uiBsx4[1], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 9, 5);
+      if (iRefs[listIdx][9] && iRefs[listIdx][5]) {
+        nBS[1][2][1] = BS_EDGE (uiBsx4[1], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 9, 5);
         break;
       }
     }
     nBS[1][2][2] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][10] > REF_NOT_IN_LIST && iRefIndex[listIdx][6] > REF_NOT_IN_LIST) {
-        nBS[1][2][2] = BS_EDGE (uiBsx4[2], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 10, 6);
+      if (iRefs[listIdx][10] && iRefs[listIdx][6]) {
+        nBS[1][2][2] = BS_EDGE (uiBsx4[2], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 10, 6);
         break;
       }
     }
     nBS[1][2][3] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][11] > REF_NOT_IN_LIST && iRefIndex[listIdx][7] > REF_NOT_IN_LIST) {
-        nBS[1][2][3] = BS_EDGE (uiBsx4[3], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 11, 7);
+      if (iRefs[listIdx][11] && iRefs[listIdx][7]) {
+        nBS[1][2][3] = BS_EDGE (uiBsx4[3], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 11, 7);
         break;
       }
     }
@@ -507,29 +528,29 @@
     * (uint32_t*)uiBsx4 = (uiNnz32b2 | uiNnz32b3);
     nBS[1][3][0] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][12] > REF_NOT_IN_LIST && iRefIndex[listIdx][8] > REF_NOT_IN_LIST) {
-        nBS[1][3][0] = BS_EDGE (uiBsx4[0], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 12, 8);
+      if (iRefs[listIdx][12] && iRefs[listIdx][8]) {
+        nBS[1][3][0] = BS_EDGE (uiBsx4[0], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 12, 8);
         break;
       }
     }
     nBS[1][3][1] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][13] > REF_NOT_IN_LIST && iRefIndex[listIdx][9] > REF_NOT_IN_LIST) {
-        nBS[1][3][1] = BS_EDGE (uiBsx4[1], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 13, 9);
+      if (iRefs[listIdx][13] && iRefs[listIdx][9]) {
+        nBS[1][3][1] = BS_EDGE (uiBsx4[1], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 13, 9);
         break;
       }
     }
     nBS[1][3][2] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][14] > REF_NOT_IN_LIST && iRefIndex[listIdx][10] > REF_NOT_IN_LIST) {
-        nBS[1][3][2] = BS_EDGE (uiBsx4[2], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 14, 10);
+      if (iRefs[listIdx][14] && iRefs[listIdx][10]) {
+        nBS[1][3][2] = BS_EDGE (uiBsx4[2], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 14, 10);
         break;
       }
     }
     nBS[1][3][3] = 1;
     for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
-      if (iRefIndex[listIdx][15] > REF_NOT_IN_LIST && iRefIndex[listIdx][11] > REF_NOT_IN_LIST) {
-        nBS[1][3][3] = BS_EDGE (uiBsx4[3], iRefIndex[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 15, 11);
+      if (iRefs[listIdx][15] && iRefs[listIdx][11]) {
+        nBS[1][3][3] = BS_EDGE (uiBsx4[3], iRefs[listIdx], pCurDqLayer->pMv[listIdx][iMbXy], 15, 11);
         break;
       }
     }
@@ -537,7 +558,7 @@
 }
 
 
-uint32_t DeblockingBsMarginalMBAvcbase (PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy) {
+uint32_t DeblockingBsMarginalMBAvcbase (PDeblockingFilter  pFilter, PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy) {
   int32_t i, j;
   uint32_t uiBSx4;
   uint8_t* pBS = (uint8_t*) (&uiBSx4);
@@ -545,6 +566,7 @@
   const uint8_t* pBnIdx     = &g_kuiTableBIdx[iEdge][4];
   const uint8_t* pB8x8Idx   = &g_kuiTableB8x8Idx[iEdge][0];
   const uint8_t* pBn8x8Idx  = &g_kuiTableB8x8Idx[iEdge][8];
+  int8_t (*iRefIdx)[MB_BLOCK4x4_NUM] = pCurDqLayer->pRefIndex[LIST_0];
 
   if (pCurDqLayer->pTransformSize8x8Flag[iMbXy] && pCurDqLayer->pTransformSize8x8Flag[iNeighMb]) {
     for (i = 0; i < 2; i++) {
@@ -555,7 +577,10 @@
       if (uiNzc) {
         pBS[i << 1] = pBS[1 + (i << 1)] = 2;
       } else {
-        pBS[i << 1] = pBS[1 + (i << 1)] = MB_BS_MV (pCurDqLayer->pRefIndex[LIST_0], pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb,
+        PPicture ref0, ref1;
+        ref0 = (iRefIdx[iMbXy][*pB8x8Idx] > REF_NOT_IN_LIST) ? pFilter->pRefPics[LIST_0][iRefIdx[iMbXy][*pB8x8Idx]] : NULL;
+        ref1 = (iRefIdx[iNeighMb][*pBn8x8Idx] > REF_NOT_IN_LIST) ? pFilter->pRefPics[LIST_0][iRefIdx[iNeighMb][*pBn8x8Idx]] : NULL;
+        pBS[i << 1] = pBS[1 + (i << 1)] = MB_BS_MV (ref0, ref1, pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb,
                                           *pB8x8Idx, *pBn8x8Idx);
       }
       pB8x8Idx += 4;
@@ -571,7 +596,10 @@
         if (uiNzc | pCurDqLayer->pNzc[iNeighMb][*pBnIdx]) {
           pBS[j + (i << 1)] = 2;
         } else {
-          pBS[j + (i << 1)] = MB_BS_MV (pCurDqLayer->pRefIndex[LIST_0], pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb, *pB8x8Idx,
+          PPicture ref0, ref1;
+          ref0 = (iRefIdx[iMbXy][*pB8x8Idx] > REF_NOT_IN_LIST) ? pFilter->pRefPics[LIST_0][iRefIdx[iMbXy][*pB8x8Idx]] : NULL;
+          ref1 = (iRefIdx[iNeighMb][*pBnIdx] > REF_NOT_IN_LIST) ? pFilter->pRefPics[LIST_0][iRefIdx[iNeighMb][*pBnIdx]] : NULL;
+          pBS[j + (i << 1)] = MB_BS_MV (ref0, ref1, pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb, *pB8x8Idx,
                                         *pBnIdx);
         }
         pBnIdx++;
@@ -588,7 +616,10 @@
         if (uiNzc | pCurDqLayer->pNzc[iMbXy][*pBIdx]) {
           pBS[j + (i << 1)] = 2;
         } else {
-          pBS[j + (i << 1)] = MB_BS_MV (pCurDqLayer->pRefIndex[LIST_0], pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb, *pBIdx,
+          PPicture ref0, ref1;
+          ref0 = (iRefIdx[iMbXy][*pBIdx] > REF_NOT_IN_LIST) ? pFilter->pRefPics[LIST_0][iRefIdx[iMbXy][*pBIdx]] : NULL;
+          ref1 = (iRefIdx[iNeighMb][*pBn8x8Idx] > REF_NOT_IN_LIST) ? pFilter->pRefPics[LIST_0][iRefIdx[iNeighMb][*pBn8x8Idx]] : NULL;
+          pBS[j + (i << 1)] = MB_BS_MV (ref0, ref1, pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb, *pBIdx,
                                         *pBn8x8Idx);
         }
         pBIdx++;
@@ -601,8 +632,10 @@
       if (pCurDqLayer->pNzc[iMbXy][*pBIdx] | pCurDqLayer->pNzc[iNeighMb][*pBnIdx]) {
         pBS[i] = 2;
       } else {
-        pBS[i] = MB_BS_MV (pCurDqLayer->pRefIndex[LIST_0], pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb, *pBIdx,
-                           *pBnIdx);
+        PPicture ref0, ref1;
+        ref0 = (iRefIdx[iMbXy][*pBIdx] > REF_NOT_IN_LIST) ? pFilter->pRefPics[LIST_0][iRefIdx[iMbXy][*pBIdx]] : NULL;
+        ref1 = (iRefIdx[iNeighMb][*pBnIdx] > REF_NOT_IN_LIST) ? pFilter->pRefPics[LIST_0][iRefIdx[iNeighMb][*pBnIdx]] : NULL;
+        pBS[i] = MB_BS_MV (ref0, ref1, pCurDqLayer->pMv[LIST_0], iMbXy, iNeighMb, *pBIdx, *pBnIdx);
       }
       pBIdx++;
       pBnIdx++;
@@ -611,7 +644,7 @@
 
   return uiBSx4;
 }
-uint32_t DeblockingBSliceBsMarginalMBAvcbase (PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy) {
+uint32_t DeblockingBSliceBsMarginalMBAvcbase (PDeblockingFilter  pFilter, PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy) {
   int32_t i, j;
   uint32_t uiBSx4;
   uint8_t* pBS = (uint8_t*) (&uiBSx4);
@@ -619,6 +652,7 @@
   const uint8_t* pBnIdx = &g_kuiTableBIdx[iEdge][4];
   const uint8_t* pB8x8Idx = &g_kuiTableB8x8Idx[iEdge][0];
   const uint8_t* pBn8x8Idx = &g_kuiTableB8x8Idx[iEdge][8];
+  PPicture ref0, ref1;
 
   if (pCurDqLayer->pTransformSize8x8Flag[iMbXy] && pCurDqLayer->pTransformSize8x8Flag[iNeighMb]) {
     for (i = 0; i < 2; i++) {
@@ -633,7 +667,10 @@
         for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
           if (pCurDqLayer->pRefIndex[listIdx][iMbXy][*pB8x8Idx] > REF_NOT_IN_LIST
               && pCurDqLayer->pRefIndex[listIdx][iMbXy][*pBn8x8Idx] > REF_NOT_IN_LIST) {
-            pBS[i << 1] = pBS[1 + (i << 1)] = MB_BS_MV (pCurDqLayer->pRefIndex[listIdx], pCurDqLayer->pMv[listIdx], iMbXy, iNeighMb,
+            int8_t (*iRefIdx)[MB_BLOCK4x4_NUM] = pCurDqLayer->pRefIndex[listIdx];
+            ref0 = pFilter->pRefPics[listIdx][iRefIdx[iMbXy][*pB8x8Idx]];
+            ref1 = pFilter->pRefPics[listIdx][iRefIdx[iNeighMb][*pBn8x8Idx]];
+            pBS[i << 1] = pBS[1 + (i << 1)] = MB_BS_MV (ref0, ref1, pCurDqLayer->pMv[listIdx], iMbXy, iNeighMb,
                                               *pB8x8Idx, *pBn8x8Idx);
             break;
           }
@@ -656,7 +693,10 @@
           for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
             if (pCurDqLayer->pRefIndex[listIdx][iMbXy][*pB8x8Idx] > REF_NOT_IN_LIST
                 && pCurDqLayer->pRefIndex[listIdx][iMbXy][*pBnIdx] > REF_NOT_IN_LIST) {
-              pBS[j + (i << 1)] = MB_BS_MV (pCurDqLayer->pRefIndex[listIdx], pCurDqLayer->pMv[listIdx], iMbXy, iNeighMb, *pB8x8Idx,
+              int8_t (*iRefIdx)[MB_BLOCK4x4_NUM] = pCurDqLayer->pRefIndex[listIdx];
+              ref0 = pFilter->pRefPics[listIdx][iRefIdx[iMbXy][*pB8x8Idx]];
+              ref1 = pFilter->pRefPics[listIdx][iRefIdx[iNeighMb][*pBnIdx]];
+              pBS[j + (i << 1)] = MB_BS_MV (ref0, ref1, pCurDqLayer->pMv[listIdx], iMbXy, iNeighMb, *pB8x8Idx,
                                             *pBnIdx);
               break;
             }
@@ -680,8 +720,10 @@
           for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
             if (pCurDqLayer->pRefIndex[listIdx][iMbXy][*pBIdx] > REF_NOT_IN_LIST
                 && pCurDqLayer->pRefIndex[listIdx][iMbXy][*pBn8x8Idx] > REF_NOT_IN_LIST) {
-              pBS[j + (i << 1)] = MB_BS_MV (pCurDqLayer->pRefIndex[listIdx], pCurDqLayer->pMv[listIdx], iMbXy, iNeighMb, *pBIdx,
-                                            *pBn8x8Idx);
+              int8_t (*iRefIdx)[MB_BLOCK4x4_NUM] = pCurDqLayer->pRefIndex[listIdx];
+              ref0 = pFilter->pRefPics[listIdx][iRefIdx[iMbXy][*pBIdx]];
+              ref1 = pFilter->pRefPics[listIdx][iRefIdx[iNeighMb][*pBn8x8Idx]];
+              pBS[j + (i << 1)] = MB_BS_MV (ref0, ref1, pCurDqLayer->pMv[listIdx], iMbXy, iNeighMb, *pBIdx, *pBn8x8Idx);
               break;
             }
           }
@@ -700,7 +742,10 @@
         for (int32_t listIdx = LIST_0; listIdx < LIST_A; ++listIdx) {
           if (pCurDqLayer->pRefIndex[listIdx][iMbXy][*pBIdx] > REF_NOT_IN_LIST
               && pCurDqLayer->pRefIndex[listIdx][iMbXy][*pBnIdx] > REF_NOT_IN_LIST) {
-            pBS[i] = MB_BS_MV (pCurDqLayer->pRefIndex[listIdx], pCurDqLayer->pMv[listIdx], iMbXy, iNeighMb, *pBIdx, *pBnIdx);
+            int8_t (*iRefIdx)[MB_BLOCK4x4_NUM] = pCurDqLayer->pRefIndex[listIdx];
+            ref0 = pFilter->pRefPics[listIdx][iRefIdx[iMbXy][*pBIdx]];
+            ref1 = pFilter->pRefPics[listIdx][iRefIdx[iNeighMb][*pBnIdx]];
+            pBS[i] = MB_BS_MV (ref0, ref1, pCurDqLayer->pMv[listIdx], iMbXy, iNeighMb, *pBIdx, *pBnIdx);
             break;
           }
         }
@@ -943,7 +988,7 @@
   pDestCb = pFilter->pCsData[1] + ((iMbY * iLineSizeUV + iMbX) << 3);
   pDestCr = pFilter->pCsData[2] + ((iMbY * iLineSizeUV + iMbX) << 3);
 
-//Vertical margrin
+  //Vertical margin
   if (iBoundryFlag & LEFT_FLAG_MASK) {
     int32_t iLeftXyIndex = iMbXyIndex - 1;
     pFilter->iLumaQP   = (iCurLumaQp + pCurDqLayer->pLumaQp[iLeftXyIndex] + 1) >> 1;
@@ -1199,10 +1244,10 @@
       iMbNb = iMbXyIndex - 1;
       if (bBSlice) {
         * (uint32_t*)nBS[0][0] = IS_INTRA (pCurDqLayer->pMbType[iMbNb]) ? 0x04040404 : DeblockingBSliceBsMarginalMBAvcbase (
-                                   pCurDqLayer, 0, iMbNb, iMbXyIndex);
+                                   pFilter, pCurDqLayer, 0, iMbNb, iMbXyIndex);
       } else {
         * (uint32_t*)nBS[0][0] = IS_INTRA (pCurDqLayer->pMbType[iMbNb]) ? 0x04040404 : DeblockingBsMarginalMBAvcbase (
-                                   pCurDqLayer, 0, iMbNb, iMbXyIndex);
+                                   pFilter, pCurDqLayer, 0, iMbNb, iMbXyIndex);
       }
     } else {
       * (uint32_t*)nBS[0][0] = 0;
@@ -1211,10 +1256,10 @@
       iMbNb = iMbXyIndex - pCurDqLayer->iMbWidth;
       if (bBSlice) {
         * (uint32_t*)nBS[1][0] = IS_INTRA (pCurDqLayer->pMbType[iMbNb]) ? 0x04040404 : DeblockingBSliceBsMarginalMBAvcbase (
-                                   pCurDqLayer, 1, iMbNb, iMbXyIndex);
+                                   pFilter, pCurDqLayer, 1, iMbNb, iMbXyIndex);
       } else {
         * (uint32_t*)nBS[1][0] = IS_INTRA (pCurDqLayer->pMbType[iMbNb]) ? 0x04040404 : DeblockingBsMarginalMBAvcbase (
-                                   pCurDqLayer, 1, iMbNb, iMbXyIndex);
+                                   pFilter, pCurDqLayer, 1, iMbNb, iMbXyIndex);
       }
     } else {
       * (uint32_t*)nBS[1][0] = 0;
@@ -1233,9 +1278,9 @@
       } else {
 
         if (bBSlice) {
-          DeblockingBSliceBSInsideMBNormal (pCurDqLayer, nBS, pCurDqLayer->pNzc[iMbXyIndex], iMbXyIndex);
+          DeblockingBSliceBSInsideMBNormal (pFilter, pCurDqLayer, nBS, pCurDqLayer->pNzc[iMbXyIndex], iMbXyIndex);
         } else {
-          DeblockingBSInsideMBNormal (pCurDqLayer, nBS, pCurDqLayer->pNzc[iMbXyIndex], iMbXyIndex);
+          DeblockingBSInsideMBNormal (pFilter, pCurDqLayer, nBS, pCurDqLayer->pNzc[iMbXyIndex], iMbXyIndex);
         }
       }
     }
@@ -1280,6 +1325,8 @@
   pFilter.iSliceBetaOffset     = pSliceHeaderExt->sSliceHeader.iSliceBetaOffset;
 
   pFilter.pLoopf = &pCtx->sDeblockingFunc;
+  pFilter.pRefPics[0] = pCtx->sRefPic.pRefList[0];
+  pFilter.pRefPics[1] = pCtx->sRefPic.pRefList[1];
 
   /* Step2: macroblock deblocking */
   if (0 == iFilterIdc || 2 == iFilterIdc) {
--- a/test/api/decoder_test.cpp
+++ b/test/api/decoder_test.cpp
@@ -134,12 +134,12 @@
   {"res/Cisco_Men_whisper_640x320_CABAC_Bframe_9.264", "88b8864a69cee7656202bc54d2ffa8b7b6f1f6c5"},
   {"res/Cisco_Men_whisper_640x320_CAVLC_Bframe_9.264", "270a500d2f91c9e2c8ffabc03f62e0dc0b3a24ed"},
   {"res/Cisco_Adobe_PDF_sample_a_1024x768_CAVLC_Bframe_9.264", "d3b2b986178ce3eafa806cd984543d0da830f408"},
-  {"res/VID_1280x544_cabac_temporal_direct.264", "46ec1d702ffef31492f933afdd0b1ea155aac922"},
-  {"res/VID_1280x720_cabac_temporal_direct.264", "449e70d68b2b216d7d1cf3439d80298df3c3d50c"},
-  {"res/VID_1920x1080_cabac_temporal_direct.264", "7da13d15f660c953094e238220fdba29f29465e5"},
-  {"res/VID_1280x544_cavlc_temporal_direct.264", "290b06a9be6a991269d2d2dd42d85bd4ba02783f"},
-  {"res/VID_1280x720_cavlc_temporal_direct.264", "a339f84be1a3268638cc389f611ac4648c8c26c8"},
-  {"res/VID_1920x1080_cavlc_temporal_direct.264", "fbc5a3253180f1e24d9a2d3c4a2ae0d43630c8f9"},
+  {"res/VID_1280x544_cabac_temporal_direct.264", "8d946d46a8cb248269c4294203397daed8dace1d"},
+  {"res/VID_1280x720_cabac_temporal_direct.264", "419faadd8362918e6d908addd3e92fddb925624a"},
+  {"res/VID_1920x1080_cabac_temporal_direct.264", "2c93dc4ea4617636d2554c68896ce3ba16d678e7"},
+  {"res/VID_1280x544_cavlc_temporal_direct.264", "c89756e76e57c6a84cc55146b18845d4d24e4cd5"},
+  {"res/VID_1280x720_cavlc_temporal_direct.264", "be1af190f5eba34102a9de42917c8ec50073c5a0"},
+  {"res/VID_1920x1080_cavlc_temporal_direct.264", "6c58378bc51beb909381e634700706737fd17be2"},
 };
 
 INSTANTIATE_TEST_CASE_P (DecodeFile, DecoderOutputTest,
--- a/test/decoder/DecUT_DeblockCommon.cpp
+++ b/test/decoder/DecUT_DeblockCommon.cpp
@@ -776,9 +776,11 @@
 
 /////////// Bs calculation functions
 TEST (DecoderDeblocking, DeblockingBsMarginalMBAvcbase) {
-  // uint32_t DeblockingBsMarginalMBAvcbase (PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy)
+  // uint32_t DeblockingBsMarginalMBAvcbase (PDeblockingFilter pFilter, PDqLayer pCurDqLayer, int32_t iEdge, int32_t iNeighMb, int32_t iMbXy)
   /* Calculate the Bs equal to 2 or 1 */
   SDqLayer sDqLayer;
+  SDeblockingFilter sFilter;
+  int i;
 
   // Only define 2 MBs here
   int8_t iNoZeroCount[24 * 2]; // (*pNzc)[24]
@@ -787,6 +789,8 @@
   uint32_t uiBSx4;
   uint8_t* pBS = (uint8_t*) (&uiBSx4);
 
+  PPicture iFilterPics[2][MAX_DPB_COUNT]; // Dummy reference pictures list
+
   sDqLayer.pNzc = (int8_t (*)[24])iNoZeroCount;
   sDqLayer.pRefIndex[0] = (int8_t (*)[16])&iLayerRefIndex[0];
   sDqLayer.pRefIndex[1] = (int8_t (*)[16])&iLayerRefIndex[1];
@@ -797,7 +801,14 @@
   bool bTSize8x8Flag[50] = {false};
   sDqLayer.pTransformSize8x8Flag = bTSize8x8Flag;
   memset (bTSize8x8Flag, 0, sizeof (bool) * 50);
+  // Dummy picture list pointers to 1..MAX_DPB_COUNT
+  // the pointer values don't need to be valid, just different
+  for (i = 0; i < MAX_DPB_COUNT; i++)
+    iFilterPics[0][i] = iFilterPics[1][i] = (PPicture)(iFilterPics + (i<<3));
 
+  sFilter.pRefPics[0] = iFilterPics[0];
+  sFilter.pRefPics[1] = iFilterPics[1];
+
 #define UT_DB_CLEAN_STATUS \
   memset(iNoZeroCount, 0, sizeof(int8_t)*24*2); \
   memset(iLayerRefIndex, 0, sizeof(int8_t)*2*16*2); \
@@ -819,7 +830,7 @@
       UT_DB_CLEAN_STATUS
       iNoZeroCount[0 * 24 + iCurrBlock] = 1; // Current MB_block position
       SET_REF_VALUE(2, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " NoZeroCount!=0";
 
       // (2) iEdge == 0, neighbor block NoZeroCount != 0
@@ -826,7 +837,7 @@
       UT_DB_CLEAN_STATUS
       iNoZeroCount[1 * 24 + iNeighborBlock ] = 1; // Neighbor MB_block position
       SET_REF_VALUE(2, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " NoZeroCount!=0";
 
       // (3) iEdge == 0, reference idx diff
@@ -834,49 +845,49 @@
       iLayerRefIndex[0][0 * 16 + iCurrBlock] = 0;
       iLayerRefIndex[0][1 * 16 + iNeighborBlock] = 1;
       SET_REF_VALUE(1, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " Ref idx diff";
 
       // (4) iEdge == 0, abs(mv diff) < 4
       UT_DB_CLEAN_STATUS
       iLayerMv[0][0 * 16 + iCurrBlock][0] = rand() % 4;
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1, 0) == 0) << iEdge << " " << iPos << " diff_mv < 4";
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1, 0) == 0) << iEdge << " " << iPos << " diff_mv < 4";
 
       UT_DB_CLEAN_STATUS
       iLayerMv[0][0 * 16 + iCurrBlock][1] = rand() % 4;
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1, 0) == 0) << iEdge << " " << iPos << " diff_mv < 4";
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1, 0) == 0) << iEdge << " " << iPos << " diff_mv < 4";
 
       UT_DB_CLEAN_STATUS
       iLayerMv[0][1 * 16 + iNeighborBlock][0] = rand() % 4;
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1, 0) == 0) << iEdge << " " << iPos << " diff_mv < 4";
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1, 0) == 0) << iEdge << " " << iPos << " diff_mv < 4";
 
       UT_DB_CLEAN_STATUS
       iLayerMv[0][1 * 16 + iNeighborBlock][1] = rand() % 4;
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1, 0) == 0) << iEdge << " " << iPos << " diff_mv < 4";
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1, 0) == 0) << iEdge << " " << iPos << " diff_mv < 4";
 
       // (5) iEdge == 0, abs(mv diff) > 4
       UT_DB_CLEAN_STATUS
       iLayerMv[0][0 * 16 + iCurrBlock][0] = 4;
       SET_REF_VALUE(1, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " diff_mv == 4";
 
       UT_DB_CLEAN_STATUS
       iLayerMv[0][0 * 16 + iCurrBlock][1] = 4;
       SET_REF_VALUE(1, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " diff_mv == 4";
 
       UT_DB_CLEAN_STATUS
       iLayerMv[0][1 * 16 + iNeighborBlock][0] = 4;
       SET_REF_VALUE(1, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " diff_mv == 4";
 
       UT_DB_CLEAN_STATUS
       iLayerMv[0][1 * 16 + iNeighborBlock][1] = 4;
       SET_REF_VALUE(1, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " diff_mv == 4";
 
       UT_DB_CLEAN_STATUS
@@ -883,7 +894,7 @@
       iLayerMv[0][0 * 16 + iCurrBlock][0] = -2048;
       iLayerMv[0][1 * 16 + iNeighborBlock][0] = 2047;
       SET_REF_VALUE(1, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " diff_mv == maximum";
 
       UT_DB_CLEAN_STATUS
@@ -890,7 +901,7 @@
       iLayerMv[0][0 * 16 + iCurrBlock][1] = -2048;
       iLayerMv[0][1 * 16 + iNeighborBlock][1] = 2047;
       SET_REF_VALUE(1, iPos);
-      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sDqLayer, iEdge, 1,
+      EXPECT_TRUE (DeblockingBsMarginalMBAvcbase (&sFilter, &sDqLayer, iEdge, 1,
                    0) == uiBSx4) << iEdge << " " << iPos << " diff_mv == maximum";
     }
   }
@@ -913,6 +924,7 @@
   sFilter.pLoopf->pfLumaDeblockingEQ4Hor = &UT_DeblockingFuncLumaEQ4Func;
   sFilter.pLoopf->pfLumaDeblockingLT4Ver = &UT_DeblockingFuncLumaLT4Func;
   sFilter.pLoopf->pfLumaDeblockingEQ4Ver = &UT_DeblockingFuncLumaEQ4Func;
+  sFilter.pRefPics[0] = sFilter.pRefPics[1] = NULL; // Don't need Ref pics for intra tests
 
   sDqLayer.iMbX = sDqLayer.iMbY = 0;
   sDqLayer.iMbXyIndex = 1;