shithub: openh264

Download patch

ref: bc1b28b5dda881b6cdd17dd31bc035c5b9590cbd
parent: 09518da5457fcf0960ed0e233e26c5bcfaa02a14
author: Sijia Chen <[email protected]>
date: Thu Feb 5 11:34:28 EST 2015

fix for in-middle changing simulcast avc setting

--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -243,6 +243,30 @@
   bool bDependencyRecFlag[MAX_DEPENDENCY_LAYER];
   bool bRecFlag;
 #endif
+
+  uint32_t GetNeededSpsNum() {
+    if (0 == sPSOVector.uiNeededSpsNum) {
+      sPSOVector.uiNeededSpsNum = ((SPS_LISTING & pSvcParam->eSpsPpsIdStrategy) ? (MAX_SPS_COUNT) :
+                                   ((pSvcParam->bSimulcastAVC) ? (pSvcParam->iSpatialLayerNum) : (1)));
+    }
+    return sPSOVector.uiNeededSpsNum;
+  }
+
+  uint32_t GetNeededSubsetSpsNum() {
+    if (0 == sPSOVector.uiNeededSubsetSpsNum) {
+      sPSOVector.uiNeededSubsetSpsNum = ((pSvcParam->bSimulcastAVC) ? (0) :
+                                         ((SPS_LISTING & pSvcParam->eSpsPpsIdStrategy) ? (MAX_SPS_COUNT) : (pSvcParam->iSpatialLayerNum - 1)));
+    }
+    return sPSOVector.uiNeededSubsetSpsNum;
+  }
+
+  uint32_t GetNeededPpsNum() {
+    if (0 == sPSOVector.uiNeededPpsNum) {
+      sPSOVector.uiNeededPpsNum = ((pSvcParam->eSpsPpsIdStrategy & SPS_PPS_LISTING) ? (MAX_PPS_COUNT) :
+                                   (1 + pSvcParam->iSpatialLayerNum));
+    }
+    return sPSOVector.uiNeededPpsNum;
+  }
 } sWelsEncCtx/*, *PWelsEncCtx*/;
 }
 #endif//sWelsEncCtx_H__
--- a/codec/encoder/core/inc/wels_common_basis.h
+++ b/codec/encoder/core/inc/wels_common_basis.h
@@ -89,6 +89,10 @@
   int32_t  eSpsPpsIdStrategy;
 #endif
 
+  uint32_t uiNeededSpsNum;
+  uint32_t uiNeededSubsetSpsNum;
+  uint32_t uiNeededPpsNum;
+
   uint32_t uiInUseSpsNum;
   uint32_t uiInUseSubsetSpsNum;
   uint32_t uiInUsePpsNum;
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -141,7 +141,7 @@
   SSpatialLayerConfig* pLayerInfo = &pParam->sSpatialLayers[iLayer];
   pLayerInfo->uiLevelIdc = uiLevelIdc;
   if (uiLevelIdc > LEVEL_5_2) {
-    WelsLog (pLogCtx, WELS_LOG_INFO, "change unexpected levelidc(%d) setting to LEVEL_UNKNOWN", pLayerInfo->uiLevelIdc );
+    WelsLog (pLogCtx, WELS_LOG_INFO, "change unexpected levelidc(%d) setting to LEVEL_UNKNOWN", pLayerInfo->uiLevelIdc);
     pLayerInfo->uiLevelIdc = LEVEL_UNKNOWN;
   }
 }
@@ -337,12 +337,14 @@
   // eSpsPpsIdStrategy checkings
   if (pCodingParam->iSpatialLayerNum > 1 && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) {
     WelsLog (pLogCtx, WELS_LOG_WARNING,
-             "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID", pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum);
+             "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID",
+             pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum);
     pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID;
   }
   if (pCodingParam->iUsageType == SCREEN_CONTENT_REAL_TIME && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) {
     WelsLog (pLogCtx, WELS_LOG_WARNING,
-             "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with iUsageType (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID", pCodingParam->eSpsPpsIdStrategy, pCodingParam->iUsageType);
+             "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with iUsageType (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID",
+             pCodingParam->eSpsPpsIdStrategy, pCodingParam->iUsageType);
     pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID;
   }
 
@@ -502,7 +504,8 @@
       iMbHeight	= (kiPicHeight + 15) >> 4;
       iMaxSliceNum = MAX_SLICES_NUM;
       if (iMbHeight > iMaxSliceNum) {
-        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings more than MAX(%d)!", iMbHeight, MAX_SLICES_NUM);
+        WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiSliceNum (%d) settings more than MAX(%d)!",
+                 iMbHeight, MAX_SLICES_NUM);
         return ENC_RETURN_UNSUPPORTED_PARA;
       }
       pSpatialLayer->sSliceCfg.sSliceArgument.uiSliceNum	= iMbHeight;
@@ -698,9 +701,9 @@
   // count parasets
   iCountNumNals += 1 + iNumDependencyLayers + (iCountNumLayers << 1) +
                    iCountNumLayers // plus iCountNumLayers for reserved application
-                   + ((SPS_LISTING & pParam->eSpsPpsIdStrategy) ? MAX_SPS_COUNT : 0) //for Sps
-                   + (((SPS_LISTING & pParam->eSpsPpsIdStrategy) && (iNumDependencyLayers > 1)) ? MAX_SPS_COUNT : 0) //for SubsetSps
-                   + ((SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) ? MAX_PPS_COUNT : 0);
+                   + (*ppCtx)->GetNeededSpsNum()
+                   + (*ppCtx)->GetNeededSubsetSpsNum()
+                   + (*ppCtx)->GetNeededPpsNum();
 
   // to check number of layers / nals / slices dependencies, 12/8/2010
   if (iCountNumLayers > MAX_LAYER_NUM_OF_FRAME) {
@@ -1026,7 +1029,6 @@
   return INVALID_ID;
 }
 
-
 /*!
  * \brief	initialize ppDqLayerList and slicepEncCtx_list due to count number of layers available
  * \pParam	pCtx			sWelsEncCtx*
@@ -1195,54 +1197,41 @@
   }
 
   // for dynamically malloc for parameter sets memory instead of maximal items for standard to reduce size, 3/18/2010
-  // SPS
-  if (!pParam->bSimulcastAVC) {
-    if (! (SPS_LISTING & pParam->eSpsPpsIdStrategy)) {
-      (*ppCtx)->pSpsArray	= (SWelsSPS*)pMa->WelsMalloc (sizeof (SWelsSPS), "pSpsArray");
-      WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
-      if (iDlayerCount > 1) {
-        (*ppCtx)->pSubsetArray	= (SSubsetSps*)pMa->WelsMalloc ((iDlayerCount - 1) * sizeof (SSubsetSps), "pSubsetArray");
-        WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))
-      }
-    } else {
-      // pParam->eSpsPpsIdStrategy == SPS_LISTING_AND_PPS_INCREASING
-      // new memory
-      (*ppCtx)->pSpsArray	= (SWelsSPS*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SWelsSPS), "pSpsArray");
-      WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
-
-      (*ppCtx)->pSubsetArray	= (SSubsetSps*)pMa->WelsMalloc (MAX_SPS_COUNT * sizeof (SSubsetSps), "pSubsetArray");
-      WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))
-
-      // copy from existing if the pointer exists
-      if (NULL != pExistingParasetList) {
-        (*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum;
-        (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum;
-        memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS));
-        memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps));
-      }
-    }
+  const int32_t kiNeededSpsNum = (*ppCtx)->GetNeededSpsNum();
+  const int32_t kiNeededSubsetSpsNum = (*ppCtx)->GetNeededSubsetSpsNum();
+  (*ppCtx)->pSpsArray	= (SWelsSPS*)pMa->WelsMalloc (kiNeededSpsNum * sizeof (SWelsSPS), "pSpsArray");
+  WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
+  if (kiNeededSubsetSpsNum > 0) {
+    (*ppCtx)->pSubsetArray	= (SSubsetSps*)pMa->WelsMalloc (kiNeededSubsetSpsNum * sizeof (SSubsetSps), "pSubsetArray");
+    WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSubsetArray), FreeMemorySvc (ppCtx))
   } else {
-    //bSimulcastAVC
-    (*ppCtx)->pSpsArray	= (SWelsSPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsSPS), "pSpsArray");
-    WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSpsArray), FreeMemorySvc (ppCtx))
     (*ppCtx)->pSubsetArray = NULL;
   }
-  // PPS
-  if (! (SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy)) {
-    (*ppCtx)->pPPSArray	= (SWelsPPS*)pMa->WelsMalloc (iDlayerCount * sizeof (SWelsPPS), "pPPSArray");
-    WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
-  } else {
-    (*ppCtx)->pPPSArray	= (SWelsPPS*)pMa->WelsMalloc (MAX_PPS_COUNT * sizeof (SWelsPPS), "pPPSArray");
-    WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
 
+  if ((SPS_LISTING & pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) {
+    (*ppCtx)->sPSOVector.uiInUseSpsNum = pExistingParasetList->uiInUseSpsNum;
+    memcpy ((*ppCtx)->pSpsArray, pExistingParasetList->sSps, MAX_SPS_COUNT * sizeof (SWelsSPS));
 
-    // copy from existing if the pointer exists
-    if (NULL != pExistingParasetList) {
-      (*ppCtx)->sPSOVector.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum;
-      memcpy ((*ppCtx)->pPPSArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
+    if (kiNeededSubsetSpsNum > 0) {
+      (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = pExistingParasetList->uiInUseSubsetSpsNum;
+      memcpy ((*ppCtx)->pSubsetArray, pExistingParasetList->sSubsetSps, MAX_SPS_COUNT * sizeof (SSubsetSps));
+    } else {
+      (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum = 0;
     }
   }
 
+  // PPS
+  const int32_t kiNeededPpsNum = (*ppCtx)->GetNeededPpsNum();
+  (*ppCtx)->pPPSArray	= (SWelsPPS*)pMa->WelsMalloc (kiNeededPpsNum * sizeof (SWelsPPS), "pPPSArray");
+  WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pPPSArray), FreeMemorySvc (ppCtx))
+
+  // copy from existing if the pointer exists
+  if ((SPS_PPS_LISTING == pParam->eSpsPpsIdStrategy) && (NULL != pExistingParasetList)) {
+    (*ppCtx)->sPSOVector.uiInUsePpsNum = pExistingParasetList->uiInUsePpsNum;
+    memcpy ((*ppCtx)->pPPSArray, pExistingParasetList->sPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
+  }
+
+
   if (INCREASING_ID & pParam->eSpsPpsIdStrategy) {
     (*ppCtx)->pPSOVector = & ((*ppCtx)->sPSOVector);
   } else {
@@ -1728,8 +1717,8 @@
     return 1;
   }
 
-  const int32_t kiSpsSize = (pParam->eSpsPpsIdStrategy & SPS_LISTING) ? (MAX_SPS_COUNT * SPS_BUFFER_SIZE): (pParam->iSpatialLayerNum * SPS_BUFFER_SIZE);
-  const int32_t kiPpsSize = (pParam->eSpsPpsIdStrategy & SPS_PPS_LISTING) ? (MAX_PPS_COUNT * SPS_BUFFER_SIZE) : ((1 + pParam->iSpatialLayerNum) * PPS_BUFFER_SIZE);
+  const int32_t kiSpsSize = (*ppCtx)->GetNeededSpsNum() * SPS_BUFFER_SIZE;
+  const int32_t kiPpsSize = (*ppCtx)->GetNeededPpsNum() * PPS_BUFFER_SIZE;
   iNonVclLayersBsSizeCount = SSEI_BUFFER_SIZE + kiSpsSize + kiPpsSize;
 
   int32_t iLayerBsSize = 0;
@@ -3469,8 +3458,9 @@
 
   // write SPS
   iNonVclSize = 0;
-  assert (kiSpatialNum == pCtx->iSpsNum);
 
+  assert ((kiSpatialNum == pCtx->iSpsNum) || (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy));
+
   for (int32_t iIdx = 0; iIdx < pCtx->iSpsNum; iIdx++) {
     //writing one NAL
     int32_t iNalSize = 0;
@@ -4252,7 +4242,9 @@
   pOldParam	= (*ppCtx)->pSvcParam;
 
   if (pOldParam->iUsageType != pNewParam->iUsageType) {
-    WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR, "WelsEncoderParamAdjust(), does not expect in-middle change of iUsgaeType from %d to %d", pOldParam->iUsageType, pNewParam->iUsageType);
+    WelsLog (& (*ppCtx)->sLogCtx, WELS_LOG_ERROR,
+             "WelsEncoderParamAdjust(), does not expect in-middle change of iUsgaeType from %d to %d", pOldParam->iUsageType,
+             pNewParam->iUsageType);
     return ENC_RETURN_UNSUPPORTED_PARA;
   }
 
@@ -4259,6 +4251,7 @@
   /* Decide whether need reset for IDR frame based on adjusting prarameters changed */
   /* Temporal levels, spatial settings and/ or quality settings changed need update parameter sets related. */
   bNeedReset	=	(pOldParam == NULL) ||
+                (pOldParam->bSimulcastAVC != pNewParam->bSimulcastAVC) ||
                 (pOldParam->iSpatialLayerNum != pNewParam->iSpatialLayerNum) ||
                 (pOldParam->iPicWidth != pNewParam->iPicWidth
                  || pOldParam->iPicHeight != pNewParam->iPicHeight) ||
@@ -4339,9 +4332,13 @@
           && (SPS_LISTING & pNewParam->eSpsPpsIdStrategy)) {
         pExistingParasetList = &sExistingParasetList;
         sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
-        sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
         memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
-        memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
+        if (NULL != (*ppCtx)->pSubsetArray) {
+          sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
+          memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
+        } else {
+          sExistingParasetList.uiInUseSubsetSpsNum = 0;
+        }
       }
 
       if ((SPS_PPS_LISTING == iOldSpsPpsIdStrategy)
@@ -4348,11 +4345,16 @@
           && (SPS_PPS_LISTING == pNewParam->eSpsPpsIdStrategy)) {
         pExistingParasetList = &sExistingParasetList;
         sExistingParasetList.uiInUseSpsNum = (*ppCtx)->sPSOVector.uiInUseSpsNum;
-        sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
         sExistingParasetList.uiInUsePpsNum = (*ppCtx)->sPSOVector.uiInUsePpsNum;
         memcpy (sExistingParasetList.sSps, (*ppCtx)->pSpsArray, MAX_SPS_COUNT * sizeof (SWelsSPS));
-        memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
         memcpy (sExistingParasetList.sPps, (*ppCtx)->pPps, MAX_PPS_COUNT * sizeof (SWelsPPS));
+
+        if (NULL != (*ppCtx)->pSubsetArray) {
+          sExistingParasetList.uiInUseSubsetSpsNum = (*ppCtx)->sPSOVector.uiInUseSubsetSpsNum;
+          memcpy (sExistingParasetList.sSubsetSps, (*ppCtx)->pSubsetArray, MAX_SPS_COUNT * sizeof (SSubsetSps));
+        } else {
+          sExistingParasetList.uiInUseSubsetSpsNum = 0;
+        }
 
         memcpy (iTmpPpsIdList, ((*ppCtx)->sPSOVector.iPpsIdList), MAX_DQ_LAYER_NUM * MAX_PPS_COUNT * sizeof (int32_t));
       }
--- a/test/api/encode_decode_api_test.cpp
+++ b/test/api/encode_decode_api_test.cpp
@@ -3030,8 +3030,7 @@
 
 
 TEST_F (EncodeDecodeTestAPI, SimulcastSVC) {
-#define LAYER_NUM (4)
-  int iSpatialLayerNum = WelsClip3 ((rand() % LAYER_NUM), 2, LAYER_NUM);
+  int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
   float fFrameRate = rand() + 0.5f;
@@ -3043,12 +3042,12 @@
   int rv = encoder_->InitializeExt (&param_);
   ASSERT_TRUE (rv == cmResultSuccess);
 
-  unsigned char*  pBsBuf[LAYER_NUM];
-  int aLen[LAYER_NUM] = {0};
-  ISVCDecoder* decoder[LAYER_NUM];
+  unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
+  int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
+  ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
 
 #ifdef DEBUG_FILE_SAVE2
-  FILE* fEnc[LAYER_NUM] = { NULL };
+  FILE* fEnc[MAX_SPATIAL_LAYER_NUM] = { NULL };
   fEnc[0] = fopen ("enc0.264", "wb");
   fEnc[1] = fopen ("enc1.264", "wb");
   fEnc[2] = fopen ("enc2.264", "wb");
@@ -3059,11 +3058,12 @@
   int iIdx = 0;
   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
+    EXPECT_TRUE (pBsBuf[iIdx] != NULL);
     aLen[iIdx] = 0;
 
     long rv = WelsCreateDecoder (&decoder[iIdx]);
     ASSERT_EQ (0, rv);
-    ASSERT_TRUE (decoder[iIdx] != NULL);
+    EXPECT_TRUE (decoder[iIdx] != NULL);
 
     SDecodingParam decParam;
     memset (&decParam, 0, sizeof (SDecodingParam));
@@ -3144,8 +3144,7 @@
 
 TEST_F (EncodeDecodeTestAPI, SimulcastAVC) {
 //#define DEBUG_FILE_SAVE3
-#define LAYER_NUM (4)
-  int iSpatialLayerNum = WelsClip3 ((rand() % LAYER_NUM), 2, LAYER_NUM);
+  int iSpatialLayerNum = WelsClip3 ((rand() % MAX_SPATIAL_LAYER_NUM), 2, MAX_SPATIAL_LAYER_NUM);
   int iWidth       = WelsClip3 ((((rand() % MAX_WIDTH) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_WIDTH);
   int iHeight      = WelsClip3 ((((rand() % MAX_HEIGHT) >> 1)  + 1) << 1, 1 << iSpatialLayerNum, MAX_HEIGHT);
   float fFrameRate = rand() + 0.5f;
@@ -3160,12 +3159,12 @@
   int rv = encoder_->InitializeExt (&param_);
   ASSERT_TRUE (rv == cmResultSuccess);
 
-  unsigned char*  pBsBuf[LAYER_NUM];
-  int aLen[LAYER_NUM] = {0};
-  ISVCDecoder* decoder[LAYER_NUM];
+  unsigned char*  pBsBuf[MAX_SPATIAL_LAYER_NUM];
+  int aLen[MAX_SPATIAL_LAYER_NUM] = {0};
+  ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
 
 #ifdef DEBUG_FILE_SAVE3
-  FILE* fEnc[LAYER_NUM];
+  FILE* fEnc[MAX_SPATIAL_LAYER_NUM];
   fEnc[0] = fopen ("enc0.264", "wb");
   fEnc[1] = fopen ("enc1.264", "wb");
   fEnc[2] = fopen ("enc2.264", "wb");
@@ -3177,11 +3176,12 @@
   //create decoder
   for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
     pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
+    EXPECT_TRUE (pBsBuf[iIdx] != NULL);
     aLen[iIdx] = 0;
 
     long rv = WelsCreateDecoder (&decoder[iIdx]);
     ASSERT_EQ (0, rv);
-    ASSERT_TRUE (decoder[iIdx] != NULL);
+    EXPECT_TRUE (decoder[iIdx] != NULL);
 
     SDecodingParam decParam;
     memset (&decParam, 0, sizeof (SDecodingParam));