shithub: openh264

Download patch

ref: 26a4ca212233f9854d306e39d3f0024108143321
parent: 4936a87ae82a530ffd170354d9abe174a33296eb
author: xiaotianshicomcast <[email protected]>
date: Thu Jul 12 06:25:14 EDT 2018

Add two more HighProfile with B-frame test cases and try to address undefined behavior sanitizer testing and got some runtime errors

--- a/codec/decoder/core/src/mv_pred.cpp
+++ b/codec/decoder/core/src/mv_pred.cpp
@@ -164,123 +164,123 @@
 
   int8_t iLeftRef;
   int8_t iTopRef;
-  int8_t iRightTopRef;
-  int8_t iLeftTopRef;
-  int8_t iDiagonalRef;
-  int8_t iMatchRef;
-  int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];
-
-  iCurXy = pCurLayer->iMbXyIndex;
-  iCurX  = pCurLayer->iMbX;
-  iCurY  = pCurLayer->iMbY;
-  iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
-
-  if (iCurX != 0) {
-    iLeftXy = iCurXy - 1;
-    iLeftSliceIdc = pCurLayer->pSliceIdc[iLeftXy];
-    bLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
-  } else {
-    bLeftAvail = 0;
-    bLeftTopAvail = 0;
-  }
-
-  if (iCurY != 0) {
-    iTopXy = iCurXy - pCurLayer->iMbWidth;
-    iTopSliceIdc = pCurLayer->pSliceIdc[iTopXy];
-    bTopAvail = (iTopSliceIdc == iCurSliceIdc);
-    if (iCurX != 0) {
-      iLeftTopXy = iTopXy - 1;
-      iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
-      bLeftTopAvail = (iLeftTopSliceIdc  == iCurSliceIdc);
-    } else {
-      bLeftTopAvail = 0;
-    }
-    if (iCurX != (pCurLayer->iMbWidth - 1)) {
-      iRightTopXy = iTopXy + 1;
-      iRightTopSliceIdc = pCurLayer->pSliceIdc[iRightTopXy];
-      bRightTopAvail = (iRightTopSliceIdc == iCurSliceIdc);
-    } else {
-      bRightTopAvail = 0;
-    }
-  } else {
-    bTopAvail = 0;
-    bLeftTopAvail = 0;
-    bRightTopAvail = 0;
-  }
-
-  iLeftType = ((iCurX != 0 && bLeftAvail) ? pCurLayer->pMbType[iLeftXy] : 0);
-  iTopType = ((iCurY != 0 && bTopAvail) ? pCurLayer->pMbType[iTopXy] : 0);
-  iLeftTopType = ((iCurX != 0 && iCurY != 0 && bLeftTopAvail)
-                  ? pCurLayer->pMbType[iLeftTopXy] : 0);
-  iRightTopType = ((iCurX != pCurLayer->iMbWidth - 1 && iCurY != 0 && bRightTopAvail)
-                   ? pCurLayer->pMbType[iRightTopXy] : 0);
-
-  /*get neb mv&iRefIdxArray*/
-  /*left*/
-  if (bLeftAvail && IS_INTER (iLeftType)) {
-    ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));
-    iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];
-  } else {
-    ST32 (iMvA, 0);
-    if (0 == bLeftAvail) { //not available
-      iLeftRef = REF_NOT_AVAIL;
-    } else { //available but is intra mb type
-      iLeftRef = REF_NOT_IN_LIST;
-    }
-  }
-  if (REF_NOT_AVAIL == iLeftRef ||
-      (0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
-    ST32 (iMvp, 0);
-    return;
-  }
-
-  /*top*/
-  if (bTopAvail && IS_INTER (iTopType)) {
-    ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));
-    iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];
-  } else {
-    ST32 (iMvB, 0);
-    if (0 == bTopAvail) { //not available
-      iTopRef = REF_NOT_AVAIL;
-    } else { //available but is intra mb type
-      iTopRef = REF_NOT_IN_LIST;
-    }
-  }
-  if (REF_NOT_AVAIL == iTopRef ||
-      (0 == iTopRef  && 0 == * (int32_t*)iMvB)) {
-    ST32 (iMvp, 0);
-    return;
-  }
-
-  /*right_top*/
-  if (bRightTopAvail && IS_INTER (iRightTopType)) {
-    ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
-    iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];
-  } else {
-    ST32 (iMvC, 0);
-    if (0 == bRightTopAvail) { //not available
-      iRightTopRef = REF_NOT_AVAIL;
-    } else { //available but is intra mb type
-      iRightTopRef = REF_NOT_IN_LIST;
-    }
-  }
-
-  /*left_top*/
-  if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
-    ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
-    iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];
-  } else {
-    ST32 (iMvD, 0);
-    if (0 == bLeftTopAvail) { //not available
-      iLeftTopRef = REF_NOT_AVAIL;
-    } else { //available but is intra mb type
-      iLeftTopRef = REF_NOT_IN_LIST;
-    }
-  }
-
-  iDiagonalRef = iRightTopRef;
-  if (REF_NOT_AVAIL == iDiagonalRef) {
-    iDiagonalRef = iLeftTopRef;
+  int8_t iRightTopRef;
+  int8_t iLeftTopRef;
+  int8_t iDiagonalRef;
+  int8_t iMatchRef;
+  int16_t iMvA[2], iMvB[2], iMvC[2], iMvD[2];
+
+  iCurXy = pCurLayer->iMbXyIndex;
+  iCurX  = pCurLayer->iMbX;
+  iCurY  = pCurLayer->iMbY;
+  iCurSliceIdc = pCurLayer->pSliceIdc[iCurXy];
+
+  if (iCurX != 0) {
+    iLeftXy = iCurXy - 1;
+    iLeftSliceIdc = pCurLayer->pSliceIdc[iLeftXy];
+    bLeftAvail = (iLeftSliceIdc == iCurSliceIdc);
+  } else {
+    bLeftAvail = 0;
+    bLeftTopAvail = 0;
+  }
+
+  if (iCurY != 0) {
+    iTopXy = iCurXy - pCurLayer->iMbWidth;
+    iTopSliceIdc = pCurLayer->pSliceIdc[iTopXy];
+    bTopAvail = (iTopSliceIdc == iCurSliceIdc);
+    if (iCurX != 0) {
+      iLeftTopXy = iTopXy - 1;
+      iLeftTopSliceIdc = pCurLayer->pSliceIdc[iLeftTopXy];
+      bLeftTopAvail = (iLeftTopSliceIdc  == iCurSliceIdc);
+    } else {
+      bLeftTopAvail = 0;
+    }
+    if (iCurX != (pCurLayer->iMbWidth - 1)) {
+      iRightTopXy = iTopXy + 1;
+      iRightTopSliceIdc = pCurLayer->pSliceIdc[iRightTopXy];
+      bRightTopAvail = (iRightTopSliceIdc == iCurSliceIdc);
+    } else {
+      bRightTopAvail = 0;
+    }
+  } else {
+    bTopAvail = 0;
+    bLeftTopAvail = 0;
+    bRightTopAvail = 0;
+  }
+
+  iLeftType = ((iCurX != 0 && bLeftAvail) ? pCurLayer->pMbType[iLeftXy] : 0);
+  iTopType = ((iCurY != 0 && bTopAvail) ? pCurLayer->pMbType[iTopXy] : 0);
+  iLeftTopType = ((iCurX != 0 && iCurY != 0 && bLeftTopAvail)
+                  ? pCurLayer->pMbType[iLeftTopXy] : 0);
+  iRightTopType = ((iCurX != pCurLayer->iMbWidth - 1 && iCurY != 0 && bRightTopAvail)
+                   ? pCurLayer->pMbType[iRightTopXy] : 0);
+
+  /*get neb mv&iRefIdxArray*/
+  /*left*/
+  if (bLeftAvail && IS_INTER (iLeftType)) {
+    ST32 (iMvA, LD32 (pCurLayer->pMv[0][iLeftXy][3]));
+    iLeftRef = pCurLayer->pRefIndex[0][iLeftXy][3];
+  } else {
+    ST32 (iMvA, 0);
+    if (0 == bLeftAvail) { //not available
+      iLeftRef = REF_NOT_AVAIL;
+    } else { //available but is intra mb type
+      iLeftRef = REF_NOT_IN_LIST;
+    }
+  }
+  if (REF_NOT_AVAIL == iLeftRef ||
+      (0 == iLeftRef && 0 == * (int32_t*)iMvA)) {
+    ST32 (iMvp, 0);
+    return;
+  }
+
+  /*top*/
+  if (bTopAvail && IS_INTER (iTopType)) {
+    ST32 (iMvB, LD32 (pCurLayer->pMv[0][iTopXy][12]));
+    iTopRef = pCurLayer->pRefIndex[0][iTopXy][12];
+  } else {
+    ST32 (iMvB, 0);
+    if (0 == bTopAvail) { //not available
+      iTopRef = REF_NOT_AVAIL;
+    } else { //available but is intra mb type
+      iTopRef = REF_NOT_IN_LIST;
+    }
+  }
+  if (REF_NOT_AVAIL == iTopRef ||
+      (0 == iTopRef  && 0 == * (int32_t*)iMvB)) {
+    ST32 (iMvp, 0);
+    return;
+  }
+
+  /*right_top*/
+  if (bRightTopAvail && IS_INTER (iRightTopType)) {
+    ST32 (iMvC, LD32 (pCurLayer->pMv[0][iRightTopXy][12]));
+    iRightTopRef = pCurLayer->pRefIndex[0][iRightTopXy][12];
+  } else {
+    ST32 (iMvC, 0);
+    if (0 == bRightTopAvail) { //not available
+      iRightTopRef = REF_NOT_AVAIL;
+    } else { //available but is intra mb type
+      iRightTopRef = REF_NOT_IN_LIST;
+    }
+  }
+
+  /*left_top*/
+  if (bLeftTopAvail && IS_INTER (iLeftTopType)) {
+    ST32 (iMvD, LD32 (pCurLayer->pMv[0][iLeftTopXy][15]));
+    iLeftTopRef = pCurLayer->pRefIndex[0][iLeftTopXy][15];
+  } else {
+    ST32 (iMvD, 0);
+    if (0 == bLeftTopAvail) { //not available
+      iLeftTopRef = REF_NOT_AVAIL;
+    } else { //available but is intra mb type
+      iLeftTopRef = REF_NOT_IN_LIST;
+    }
+  }
+
+  iDiagonalRef = iRightTopRef;
+  if (REF_NOT_AVAIL == iDiagonalRef) {
+    iDiagonalRef = iLeftTopRef;
     * (int32_t*)iMvC = * (int32_t*)iMvD;
   }
 
@@ -843,7 +843,7 @@
 //update iMVs and iRefIndex cache for current MB, only for P_16*16 (SKIP inclusive)
 /* can be further optimized */
 void UpdateP16x16MotionInfo (PDqLayer pCurDqLayer, int32_t listIdx, int8_t iRef, int16_t iMVs[2]) {
-  const int16_t kiRef2 = (iRef << 8) | iRef;
+  const int16_t kiRef2 = ((uint8_t)iRef << 8) | (uint8_t)iRef;
   const int32_t kiMV32 = LD32 (iMVs);
   int32_t i;
   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
@@ -866,7 +866,7 @@
 //update iRefIndex cache for current MB, only for P_16*16 (SKIP inclusive)
 /* can be further optimized */
 void UpdateP16x16RefIdx (PDqLayer pCurDqLayer, int32_t listIdx, int8_t iRef) {
-  const int16_t kiRef2 = (iRef << 8) | iRef;
+  const int16_t kiRef2 = ((uint8_t)iRef << 8) | (uint8_t)iRef;
   int32_t i;
   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
 
@@ -904,7 +904,7 @@
 void UpdateP16x8MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A],
                             int8_t iRefIndex[LIST_A][30],
                             int32_t listIdx, int32_t iPartIdx, int8_t iRef, int16_t iMVs[2]) {
-  const int16_t kiRef2 = (iRef << 8) | iRef;
+  const int16_t kiRef2 = ((uint8_t)iRef << 8) | (uint8_t)iRef;
   const int32_t kiMV32 = LD32 (iMVs);
   int32_t i;
   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
@@ -934,7 +934,7 @@
 void UpdateP8x16MotionInfo (PDqLayer pCurDqLayer, int16_t iMotionVector[LIST_A][30][MV_A],
                             int8_t iRefIndex[LIST_A][30],
                             int32_t listIdx, int32_t iPartIdx, int8_t iRef, int16_t iMVs[2]) {
-  const int16_t kiRef2 = (iRef << 8) | iRef;
+  const int16_t kiRef2 = ((uint8_t)iRef << 8) | (uint8_t)iRef;
   const int32_t kiMV32 = LD32 (iMVs);
   int32_t i;
   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
--- a/codec/decoder/core/src/parse_mb_syn_cabac.cpp
+++ b/codec/decoder/core/src/parse_mb_syn_cabac.cpp
@@ -102,7 +102,7 @@
 
 void UpdateP16x8RefIdxCabac (PDqLayer pCurDqLayer, int8_t pRefIndex[LIST_A][30], int32_t iPartIdx, const int8_t iRef,
                              const int8_t iListIdx) {
-  int32_t iRef32Bit = (int32_t) iRef;
+  uint32_t iRef32Bit = (uint32_t) iRef;
   const int32_t iRef4Bytes = (iRef32Bit << 24) | (iRef32Bit << 16) | (iRef32Bit << 8) | iRef32Bit;
   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
   const uint8_t iScan4Idx = g_kuiScan4[iPartIdx];
@@ -119,7 +119,7 @@
 
 void UpdateP8x16RefIdxCabac (PDqLayer pCurDqLayer, int8_t pRefIndex[LIST_A][30], int32_t iPartIdx, const int8_t iRef,
                              const int8_t iListIdx) {
-  int16_t iRef16Bit = (int16_t) iRef;
+  uint16_t iRef16Bit = (uint16_t) iRef;
   const int16_t iRef2Bytes = (iRef16Bit << 8) | iRef16Bit;
   int32_t i;
   int32_t iMbXy = pCurDqLayer->iMbXyIndex;
--- a/codec/decoder/core/src/rec_mb.cpp
+++ b/codec/decoder/core/src/rec_mb.cpp
@@ -219,14 +219,16 @@
   PPicture pRefPic;
 
   int8_t iRefIdx = pRefIdxList[iIndex];
-  pRefPic = pCtx->sRefPic.pRefList[listIdx][iRefIdx];
+  if (iRefIdx >= 0) {
+    pRefPic = pCtx->sRefPic.pRefList[listIdx][iRefIdx];
 
-  pMCRefMem->iSrcLineLuma   = pRefPic->iLinesize[0];
-  pMCRefMem->iSrcLineChroma = pRefPic->iLinesize[1];
+    pMCRefMem->iSrcLineLuma = pRefPic->iLinesize[0];
+    pMCRefMem->iSrcLineChroma = pRefPic->iLinesize[1];
 
-  pMCRefMem->pSrcY = pRefPic->pData[0];
-  pMCRefMem->pSrcU = pRefPic->pData[1];
-  pMCRefMem->pSrcV = pRefPic->pData[2];
+    pMCRefMem->pSrcY = pRefPic->pData[0];
+    pMCRefMem->pSrcU = pRefPic->pData[1];
+    pMCRefMem->pSrcV = pRefPic->pData[2];
+  }
 }
 
 
binary files /dev/null b/res/HighProfile_B_Frame_1280x544_2397p.h264 differ
binary files /dev/null b/res/HighProfile_B_Frame_1280x720_2397p.h264 differ
--- a/test/api/decoder_test.cpp
+++ b/test/api/decoder_test.cpp
@@ -130,8 +130,10 @@
   {"res/test_scalinglist_jm.264", "f690a3af2896a53360215fb5d35016bfd41499b3"},
   {"res/test_vd_1d.264", "5827d2338b79ff82cd091c707823e466197281d3"},
   {"res/test_vd_rc.264", "eea02e97bfec89d0418593a8abaaf55d02eaa1ca"},
-  {"res/HighProfile_B_Frame_1920x1080p_30fps.h264", "50c5b8d175598c1d9e604542c4160fa1c6639adc" },
-  {"res/HighProfile_B_Frame_1920x1080p_2397fps.h264", "16967cc21b6853b651cfd0a1a858eeec8565836a" },
+  {"res/HighProfile_B_Frame_1920x1080p_30fps.h264", "50c5b8d175598c1d9e604542c4160fa1c6639adc"},
+  {"res/HighProfile_B_Frame_1920x1080p_2397fps.h264", "16967cc21b6853b651cfd0a1a858eeec8565836a"},
+  {"res/HighProfile_B_Frame_1280x544_2397p.h264", "8567f85b1162b70bb2ccc49fd16d8aa27523efcf"},
+  {"res/HighProfile_B_Frame_1280x720_2397p.h264", "5a3176bd9bc1af2a5d58e880088434ee57c57602"},
 };
 
 INSTANTIATE_TEST_CASE_P (DecodeFile, DecoderOutputTest,