shithub: openh264

Download patch

ref: e45e85947327631ad48137546a2b9549fb87f99b
parent: a921bc6589620e0e1dbd6d7d3e6eb09f505595db
author: sijchen <sijchen@cisco.com>
date: Thu Feb 20 09:50:04 EST 2014

Squashed merge from writenal_refactor2

--- a/codec/api/svc/codec_app_def.h
+++ b/codec/api/svc/codec_app_def.h
@@ -292,6 +292,7 @@
   int		iLayerNum;
   SLayerBSInfo	sLayerInfo[MAX_LAYER_NUM_OF_FRAME];
 
+  int eOutputFrameType;
 } SFrameBSInfo, *PFrameBSInfo;
 
 typedef struct Source_Picture_s {
--- a/codec/common/macros.h
+++ b/codec/common/macros.h
@@ -196,6 +196,18 @@
 
 /*
  * Description: to check variable validation and return the specified result
+ *	iResult:	value to be checked
+ *	iExpected:	the expected value
+ */
+#ifndef WELS_VERIFY_RETURN_IFNEQ
+#define WELS_VERIFY_RETURN_IFNEQ(iResult, iExpected) \
+	if ( iResult != iExpected ){ \
+		return iResult; \
+	}
+#endif//#if WELS_VERIFY_RETURN_IF
+
+/*
+ * Description: to check variable validation and return the specified result
  *	iResult:	value to be return
  *	bCaseIf:	negative condition to be verified
  */
--- a/codec/encoder/core/inc/encoder.h
+++ b/codec/encoder/core/inc/encoder.h
@@ -58,6 +58,13 @@
 void FreeMemorySvc (sWelsEncCtx** ppCtx);
 
 /*!
+ * \brief	 allocate or reallocate the output bs buffer
+ * \return:		successful - 0; otherwise none 0 for failed
+ */
+int32_t AllocateBsOutputBuffer(CMemoryAlign*pMa, const int32_t iNeededLen, int32_t iOrigLen, const char* kpTag, uint8_t*& pOutputBuffer );
+//TODO: to finish this function and call it
+
+/*!
  * \brief	initialize function pointers that potentially used in Wels encoding
  * \param	pEncCtx		sWelsEncCtx*
  * \return	successful - 0; otherwise none 0 for failed
--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -220,6 +220,11 @@
   SStatSliceInfo				sPerInfo;
 #endif//STAT_OUTPUT
 
+  int32_t iEncoderError;
+#ifdef MT_ENABLED
+  WELS_MUTEX					mutexEncoderError;
+#endif
+
 } sWelsEncCtx/*, *PWelsEncCtx*/;
 }
 #endif//sWelsEncCtx_H__
--- a/codec/encoder/core/inc/nal_encap.h
+++ b/codec/encoder/core/inc/nal_encap.h
@@ -47,6 +47,7 @@
 //SBitStringAux
 namespace WelsSVCEnc {
 
+#define NAL_HEADER_SIZE (4)
 /*
  *	Raw payload pData for NAL unit, AVC/SVC compatible
  */
@@ -56,6 +57,7 @@
 
 SNalUnitHeaderExt		sNalExt;		// NAL header information
 
+int32_t iStartPos; //NAL start position in buffer
 } SWelsNalRaw;
 
 /*
@@ -125,22 +127,9 @@
  * \param	pDstLen		length of pDst NAL output
  * \param	annexeb		annexeb flag
  * \param	pRawNal			pRawNal NAL pData
- * \return	length of pDst NAL
+ * \return	ERR_CODE
  */
-int32_t WelsEncodeNal (SWelsNalRaw* pRawNal, void* pDst, int32_t* pDstLen);
-
-/*!
- * \brief	encode a nal into a pBuffer for any type of NAL, involved WelsEncodeNal introduced in AVC
- *
- * \param	pDst			pDst NAL pData
- * \param	pDstLen		length of pDst NAL output
- * \param	annexeb		annexeb flag
- * \param	pRawNal			pRawNal NAL pData
- * \param	pNalHeaderExt	pointer of SNalUnitHeaderExt
- *
- * \return	length of pDst NAL
- */
-int32_t WelsEncodeNalExt (SWelsNalRaw* pRawNal, void* pNalHeaderExt, void* pDst, int32_t* pDstLen);
+int32_t WelsEncodeNal (SWelsNalRaw* pRawNal, void* pNalHeaderExt, const int32_t kiDstBufferLen, void* pDst, int32_t* pDstLen);
 
 /*!
  * \brief	write prefix nal
--- a/codec/encoder/core/inc/slice_multi_threading.h
+++ b/codec/encoder/core/inc/slice_multi_threading.h
@@ -80,7 +80,7 @@
 void ReleaseMtResource (sWelsEncCtx** ppCtx);
 
 int32_t AppendSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, const int32_t kiSliceCount);
-int32_t WriteSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, uint8_t* pFrameBsBuffer, const int32_t kiSliceIdx);
+int32_t WriteSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, uint8_t* pFrameBsBuffer, const int32_t iSliceIdx, int32_t& iSliceSize);
 
 #if defined(DYNAMIC_SLICE_ASSIGN) && defined(TRY_SLICING_BALANCE)
 #if defined(__GNUC__)
--- a/codec/encoder/core/inc/svc_encode_slice.h
+++ b/codec/encoder/core/inc/svc_encode_slice.h
@@ -72,18 +72,18 @@
 
 //===================MB-level encode====================//
 //encapsulation func: store base rec, highest Dependency Layer(only one quality) rec, single layer rec
-void WelsPSliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice,  const bool kbIsHighestDlayerFlag);
-void WelsPSliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice,  const bool kbIsHighestDlayerFlag);
+int32_t WelsPSliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice,  const bool kbIsHighestDlayerFlag);
+int32_t WelsPSliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice,  const bool kbIsHighestDlayerFlag);
 
 //encapsulation func: store base rec, highest Dependency Layer(only one quality) rec, single layer rec
-void WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice);	// for intra non-dynamic slice
-void WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice);	// for intra dynamic slice
+int32_t WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice);	// for intra non-dynamic slice
+int32_t WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice);	// for intra dynamic slice
 
-void WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
-void WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
+int32_t WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
+int32_t WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice);
 
-void WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx,
-                       const int32_t/*EWelsNalUnitType*/ keNalType/*, bool bNewLayer*/);
+int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx,
+                       const int32_t keNalType);
 
 void WelsInitSliceEncodingFuncs (uint32_t uiCpuFlag);
 
@@ -93,9 +93,9 @@
                                         const int32_t kiLastMbIdxInPartition);
 void AddSliceBoundary (sWelsEncCtx* pEncCtx, SSlice* pCurSlice, SSliceCtx* pSliceCtx, SMB* pCurMb,
                        int32_t iNextSliceFirstMbIdx, const int32_t kiLastMbIdxInPartition);
-void WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pMd,
+int32_t WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pMd,
                         const int32_t kiSliceFirstMbXY);	// for inter non-dynamic slice
-void WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pMd,
+int32_t WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pMd,
                                         const int32_t kiSliceFirstMbXY);	// for inter dynamic slice
 
 
--- a/codec/encoder/core/inc/svc_set_mb_syn_cavlc.h
+++ b/codec/encoder/core/inc/svc_set_mb_syn_cavlc.h
@@ -52,13 +52,12 @@
 
 void WelsWriteMbResidual (SMbCache* sMbCacheInfo, SMB* pCurMb, SBitStringAux* pBs);
 
-//for Enhance Layer CAVLC writing
 void WelsSpatialWriteSubMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
 
 void WelsSpatialWriteMbPred (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
 
 //for Base Layer CAVLC writing
-void WelsSpatialWriteMbSyn (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
+int32_t WelsSpatialWriteMbSyn (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb);
 
 }
 #endif
--- a/codec/encoder/core/inc/wels_const.h
+++ b/codec/encoder/core/inc/wels_const.h
@@ -107,18 +107,7 @@
 
 #define I420_PLANES				3
 
-// Condition of fix unexpected coding violation in case actual compress ratio of coding is less than 2:1 (compress_ratio=i420_base_picture_size/actual_size_of_coded_bs).
-// Coding picture resolution as SubQcif or above size compress ration using 2:1 by default, such normal case regards as ratio can meet 2:1 requirement.
-// Per specific cases, i.e, 16x16 picture size, the compress ration usually less than 2:1, so which results in unexpected violation due not large enough of frame bs pBuffer size.
-// Here SubQcif just like thredshold to distinguish between normal cases and abnormal cases by resolution size from products usage.
-#define COMPRESS_RATION_NORMAL_THR			(0.5f)	// 0.5f, 0.375f, 0.25f
-#define COMPRESS_RATION_ABNORMAL_THR		(1.0f)	// ensure (1.0f >= COMPRESS_RATION_ABNORMAL_THR > COMPRESS_RATION_NORMAL_THR)
-#define RESOLUTION_NORMAL_CX_THR			(128)
-#define RESOLUTION_NORMAL_CY_THR			(96)
-#define COMPRESS_RATIO_DECIDED_BY_RESOLUTION(_cx, _cy)	\
-	(((_cx) >= RESOLUTION_NORMAL_CX_THR && (_cy) >= RESOLUTION_NORMAL_CY_THR) ? \
-	COMPRESS_RATION_NORMAL_THR :	\
-	COMPRESS_RATION_ABNORMAL_THR)
+#define COMPRESS_RATIO_THR (1.0f)	//set to size of the original data, which will be large enough considering MinCR
 
 #if !defined(SSEI_BUFFER_SIZE)
 #define SSEI_BUFFER_SIZE	128
@@ -132,6 +121,9 @@
 #define PPS_BUFFER_SIZE		16
 #endif//PPS_BUFFER_SIZE
 
+#if !defined(MAX_MACROBLOCK_SIZE_IN_BYTE)
+#define MAX_MACROBLOCK_SIZE_IN_BYTE		800 //3200*2/8
+#endif
 
 #if defined(NUM_SPATIAL_LAYERS_CONSTRAINT)
 #define MAX_DEPENDENCY_LAYER		MAX_SPATIAL_LAYER_NUM	// Maximal dependency layer
@@ -188,5 +180,16 @@
   AVC_REWRITE_ENHANCE_MB = 1,
   NON_AVC_REWRITE_ENHANCE_MB = 2
 };
+
+enum {
+  ENC_RETURN_SUCCESS = 0,
+  ENC_RETURN_MEMALLOCERR = 0x01, //will free memory and uninit
+  ENC_RETURN_UNSUPPORTED_PARA = 0x02, //unsupported setting
+  ENC_RETURN_UNEXPECTED = 0x04, //unexpected value
+  ENC_RETURN_CORRECTED = 0x08, //unexpected value but corrected by encoder
+  ENC_RETURN_INVALIDINPUT = 0x10, //invalid input
+  ENC_RETURN_MEMOVERFLOWFOUND = 0x20,
+};
+//TODO: need to complete the return checking in encoder and fill in more types if needed
 
 #endif//WELS_CONSTANCE_H__
--- a/codec/encoder/core/src/encoder.cpp
+++ b/codec/encoder/core/src/encoder.cpp
@@ -151,7 +151,7 @@
  * \return	successful - 0; otherwise none 0 for failed
  */
 int32_t InitFunctionPointers (SWelsFuncPtrList* pFuncList, SWelsSvcCodingParam* pParam, uint32_t uiCpuFlag) {
-  int32_t iReturn = 0;
+  int32_t iReturn = ENC_RETURN_SUCCESS;
 
   /* Functionality utilization of CPU instructions dependency */
   pFuncList->pfSetMemZeroSize8	= WelsSetMemZero_c;		// confirmed_safe_unsafe_usage
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -140,7 +140,7 @@
 
   assert (pCodingParam != NULL);
   if (NULL == pCodingParam)
-    return 1;
+    return ENC_RETURN_INVALIDINPUT;
 
   if (pCodingParam->iSpatialLayerNum < 1 || pCodingParam->iSpatialLayerNum > MAX_DEPENDENCY_LAYER) {
 #if defined (_DEBUG)
@@ -148,7 +148,7 @@
              pCodingParam->iSpatialLayerNum);
 #endif//#if _DEBUG
 
-    return 1;
+    return ENC_RETURN_UNSUPPORTED_PARA;
   }
 
   if (pCodingParam->iTemporalLayerNum < 1 || pCodingParam->iTemporalLayerNum > MAX_TEMPORAL_LEVEL) {
@@ -156,7 +156,7 @@
     fprintf (stderr, "ParamValidationExt(), monitor invalid pCodingParam->iTemporalLayerNum: %d!\n",
              pCodingParam->iTemporalLayerNum);
 #endif//#if _DEBUG
-    return 1;
+    return ENC_RETURN_UNSUPPORTED_PARA;
   }
 
   if (pCodingParam->uiGopSize < 1 || pCodingParam->uiGopSize > MAX_GOP_SIZE) {
@@ -163,7 +163,7 @@
 #if defined (_DEBUG)
     fprintf (stderr, "ParamValidationExt(), monitor invalid pCodingParam->uiGopSize: %d!\n", pCodingParam->uiGopSize);
 #endif//#if _DEBUG
-    return 1;
+    return ENC_RETURN_UNSUPPORTED_PARA;
   }
 
 
@@ -173,7 +173,7 @@
              "ParamValidationExt(), uiIntraPeriod(%d) should be not less than that of uiGopSize(%d) or -1 specified!\n",
              pCodingParam->uiIntraPeriod, pCodingParam->uiGopSize);
 #endif//#if _DEBUG
-    return 1;
+    return ENC_RETURN_UNSUPPORTED_PARA;
   }
 
   if (pCodingParam->uiIntraPeriod && (pCodingParam->uiIntraPeriod & (pCodingParam->uiGopSize - 1)) != 0) {
@@ -181,7 +181,7 @@
     fprintf (stderr, "ParamValidationExt(), uiIntraPeriod(%d) should be multiple of uiGopSize(%d) or -1 specified!\n",
              pCodingParam->uiIntraPeriod, pCodingParam->uiGopSize);
 #endif//#if _DEBUG
-    return 1;
+    return ENC_RETURN_UNSUPPORTED_PARA;
   }
 
 
@@ -213,7 +213,7 @@
 #if defined (_DEBUG)
       fprintf (stderr, "ParamValidationExt(), invalid %d x %d in dependency layer settings!\n", kiPicWidth, kiPicHeight);
 #endif//#if _DEBUG
-      return 1;
+      return ENC_RETURN_UNSUPPORTED_PARA;
     }
     if ((kiPicWidth & 0x0F) != 0 || (kiPicHeight & 0x0F) != 0) {
 #if defined (_DEBUG)
@@ -221,7 +221,7 @@
                "ParamValidationExt(), in layer #%d iWidth x iHeight(%d x %d) both should be multiple of 16, can not support with arbitrary size currently!\n",
                i, kiPicWidth, kiPicHeight);
 #endif//#if _DEBUG
-      return 1;
+      return ENC_RETURN_UNSUPPORTED_PARA;
     }
 
     if (fDlp->sSliceCfg.uiSliceMode >= SM_RESERVED) {
@@ -228,7 +228,7 @@
 #if defined (_DEBUG)
       fprintf (stderr, "ParamValidationExt(), invalid uiSliceMode (%d) settings!\n", fDlp->sSliceCfg.uiSliceMode);
 #endif//#if _DEBUG
-      return 1;
+      return ENC_RETURN_UNSUPPORTED_PARA;
     }
 
     //check pSlice settings under multi-pSlice
@@ -257,7 +257,7 @@
 #if defined (_DEBUG)
         fprintf (stderr, "ParamValidationExt(), invalid uiSliceNum (%d) settings!\n", fDlp->sSliceCfg.sSliceArgument.uiSliceNum);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
       if (fDlp->sSliceCfg.sSliceArgument.uiSliceNum == 1) {
 #if defined (_DEBUG)
@@ -281,7 +281,7 @@
         fprintf (stderr, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!\n",
                  fDlp->sSliceCfg.sSliceArgument.uiSliceMbNum[0]);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
       // considering the coding efficient and performance, iCountMbNum constraint by MIN_NUM_MB_PER_SLICE condition of multi-pSlice mode settting
       if (iMbNumInFrame <= MIN_NUM_MB_PER_SLICE) {
@@ -303,7 +303,7 @@
         fprintf (stderr, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!\n",
                  fDlp->sSliceCfg.sSliceArgument.uiSliceMbNum[0]);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
 
       if (!CheckRasterMultiSliceSetting (iMbNumInFrame, &fDlp->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings
@@ -311,7 +311,7 @@
         fprintf (stderr, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!\n",
                  fDlp->sSliceCfg.sSliceArgument.uiSliceMbNum[0]);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
       if (fDlp->sSliceCfg.sSliceArgument.uiSliceNum <= 0
           || fDlp->sSliceCfg.sSliceArgument.uiSliceNum > iMaxSliceNum) {	// verify interleave mode settings
@@ -319,7 +319,7 @@
         fprintf (stderr, "ParamValidationExt(), invalid uiSliceNum (%d) in SM_RASTER_SLICE settings!\n",
                  fDlp->sSliceCfg.sSliceArgument.uiSliceNum);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
       if (fDlp->sSliceCfg.sSliceArgument.uiSliceNum == 1) {
 #if defined (_DEBUG)
@@ -353,7 +353,7 @@
 #if defined (_DEBUG)
         fprintf (stderr, "ParamValidationExt(), invalid uiSliceNum (%d) settings more than MAX!\n", iMbHeight);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
       fDlp->sSliceCfg.sSliceArgument.uiSliceNum	= iMbHeight;
 
@@ -361,7 +361,7 @@
 #if defined (_DEBUG)
         fprintf (stderr, "ParamValidationExt(), invalid uiSliceNum (%d) settings!\n", fDlp->sSliceCfg.sSliceArgument.uiSliceNum);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
       if (!CheckRowMbMultiSliceSetting (iMbWidth, &fDlp->sSliceCfg.sSliceArgument)) {	// verify interleave mode settings
 #if defined (_DEBUG)
@@ -368,7 +368,7 @@
         fprintf (stderr, "ParamValidationExt(), invalid uiSliceMbNum (%d) settings!\n",
                  fDlp->sSliceCfg.sSliceArgument.uiSliceMbNum[0]);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
     }
     break;
@@ -380,7 +380,7 @@
         fprintf (stderr, "ParamValidationExt(), invalid iSliceSize (%d) settings!\n",
                  fDlp->sSliceCfg.sSliceArgument.uiSliceSizeConstraint);
 #endif//#if _DEBUG
-        return 1;
+        return ENC_RETURN_UNSUPPORTED_PARA;
       }
       // considering the coding efficient and performance, iCountMbNum constraint by MIN_NUM_MB_PER_SLICE condition of multi-pSlice mode settting
       if (iMbWidth * iMbHeight <= MIN_NUM_MB_PER_SLICE) {
@@ -396,7 +396,7 @@
       fprintf (stderr, "ParamValidationExt(), invalid uiSliceMode (%d) settings!\n",
                pCodingParam->sDependencyLayers[0].sSliceCfg.uiSliceMode);
 #endif//#if _DEBUG
-      return 1;
+      return ENC_RETURN_UNSUPPORTED_PARA;
 
     }
     break;
@@ -1322,7 +1322,7 @@
   while (iIndex < pParam->iSpatialLayerNum) {
     SDLayerParam* fDlp = &pParam->sDependencyLayers[iIndex];
 
-    fCompressRatioThr	= COMPRESS_RATIO_DECIDED_BY_RESOLUTION (fDlp->iFrameWidth, fDlp->iFrameHeight);
+    fCompressRatioThr	= COMPRESS_RATIO_THR;
 
     iLayerBsSize = WELS_ROUND (((3 * fDlp->iFrameWidth * fDlp->iFrameHeight) >> 1) * fCompressRatioThr);
     iLayerBsSize	= WELS_ALIGN (iLayerBsSize, 4);			// 4 bytes alinged
@@ -1339,9 +1339,9 @@
   // Output
   (*ppCtx)->pOut = (SWelsEncoderOutput*)pMa->WelsMalloc (sizeof (SWelsEncoderOutput), "SWelsEncoderOutput");
   WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pOut), FreeMemorySvc (ppCtx))
-  (*ppCtx)->pOut->pBsBuffer		= (uint8_t*)pMa->WelsMalloc (iCountBsLen, "pOut->pBsBuffer");
+  (*ppCtx)->pOut->pBsBuffer    = (uint8_t*)pMa->WelsMalloc (iCountBsLen, "pOut->pBsBuffer");
   WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pOut->pBsBuffer), FreeMemorySvc (ppCtx))
-  (*ppCtx)->pOut->uiSize			= iCountBsLen;
+  (*ppCtx)->pOut->uiSize      = iCountBsLen;
   (*ppCtx)->pOut->sNalList		= (SWelsNalRaw*)pMa->WelsMalloc (iCountNals * sizeof (SWelsNalRaw), "pOut->sNalList");
   WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pOut->sNalList), FreeMemorySvc (ppCtx))
   (*ppCtx)->pOut->iCountNals		= iCountNals;
@@ -1349,10 +1349,10 @@
 
 #ifdef MT_ENABLED
   if (pParam->iMultipleThreadIdc > 1) {
-    (*ppCtx)->pFrameBs			= (uint8_t*)pMa->WelsMalloc (iCountBsLen + (iTargetSpatialBsSize * ((*ppCtx)->iMaxSliceCount - 1)),
-                              "pFrameBs");
+    const int32_t iTotalLength = iCountBsLen + (iTargetSpatialBsSize * ((*ppCtx)->iMaxSliceCount - 1));
+    (*ppCtx)->pFrameBs			= (uint8_t*)pMa->WelsMalloc (iTotalLength, "pFrameBs");
     WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pFrameBs), FreeMemorySvc (ppCtx))
-    (*ppCtx)->iFrameBsSize		= iCountBsLen * (*ppCtx)->iMaxSliceCount;
+    (*ppCtx)->iFrameBsSize = iTotalLength;
   } else
 #endif//MT_ENABLED
   {
@@ -2081,7 +2081,7 @@
 #if defined(MEMORY_MONITOR)
   WelsLog (pCtx, WELS_LOG_INFO, "WelsInitEncoderExt() exit, overall memory usage: %llu bytes\n",
            static_cast<unsigned long long> (sizeof (sWelsEncCtx) /* requested size from malloc() or new operator */
-               + pCtx->pMemAlign->WelsGetMemoryUsage())	/* requested size from CMemoryAlign::WelsMalloc() */
+               + pCtx->pMemAlign->WelsGetMemoryUsage())  /* requested size from CMemoryAlign::WelsMalloc() */
           );
 #endif//MEMORY_MONITOR
 
@@ -2749,7 +2749,7 @@
 
 /*!
  * \brief	write all parameter sets introduced in SVC extension
- * \return	size in bytes of bitstream wrote
+ * \return	writing results, success or error
  */
 int32_t WelsWriteParameterSets (sWelsEncCtx* pCtx, int32_t* pNalLen, int32_t* pNumNal) {
   int32_t iSize	= 0;
@@ -2757,9 +2757,11 @@
   int32_t	iIdx	= 0;
   int32_t iId	= 0;
   int32_t iCountNal	= 0;
+  int32_t iNalLength	= 0;
+  int32_t iReturn = ENC_RETURN_SUCCESS;
 
   if (NULL == pCtx || NULL == pNalLen || NULL == pNumNal)
-    return 0;
+    return ENC_RETURN_UNEXPECTED;
 
   /* write all SPS */
   iIdx = 0;
@@ -2804,11 +2806,15 @@
       WelsUnloadNal (pCtx->pOut);
     }
 
-    pNalLen[iCountNal] = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                                        &pNalLen[iCountNal]);
+    iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
+                                            pCtx->iFrameBsSize - pCtx->iPosBsBuffer,//available buffer to be written, so need to substract the used length
+                                            pCtx->pFrameBs + pCtx->iPosBsBuffer,
+                                            &iNalLength);
+    WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
+    pNalLen[iCountNal] =iNalLength;
 
-    pCtx->iPosBsBuffer	+= pNalLen[iCountNal];
-    iSize				+= pNalLen[iCountNal];
+    pCtx->iPosBsBuffer	+= iNalLength;
+    iSize				+= iNalLength;
 
     ++ iIdx;
     ++ iCountNal;
@@ -2829,12 +2835,15 @@
     WelsWritePpsSyntax (&pCtx->pPPSArray[iIdx], &pCtx->pOut->sBsWrite, & (pCtx->sPSOVector));
     WelsUnloadNal (pCtx->pOut);
 
-    pNalLen[iCountNal] = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                                        &pNalLen[iCountNal]);
+    iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
+                                            pCtx->iFrameBsSize - pCtx->iPosBsBuffer,
+                                            pCtx->pFrameBs + pCtx->iPosBsBuffer,
+                                            &iNalLength);
+    WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
+    pNalLen[iCountNal] = iNalLength;
+    pCtx->iPosBsBuffer	+= iNalLength;
+    iSize				+= iNalLength;
 
-    pCtx->iPosBsBuffer	+= pNalLen[iCountNal];
-    iSize				+= pNalLen[iCountNal];
-
     ++ iIdx;
     ++ iCountNal;
   }
@@ -2841,7 +2850,7 @@
 
   *pNumNal = iCountNal;
 
-  return iSize;
+  return ENC_RETURN_SUCCESS;
 }
 
 static inline int32_t AddPrefixNal (sWelsEncCtx* pCtx,
@@ -2849,8 +2858,10 @@
                                     int32_t* pNalLen,
                                     int32_t* pNalIdxInLayer,
                                     const EWelsNalUnitType keNalType,
-                                    const EWelsNalRefIdc keNalRefIdc) {
-  int32_t iPayloadSize = 0;
+                                    const EWelsNalRefIdc keNalRefIdc,
+                                    int32_t& iPayloadSize) {
+  int32_t iReturn = ENC_RETURN_SUCCESS;
+  iPayloadSize = 0;
 
   if (keNalRefIdc != NRI_PRI_LOWEST) {
     WelsLoadNal (pCtx->pOut, NAL_UNIT_PREFIX, keNalRefIdc);
@@ -2859,10 +2870,13 @@
 
     WelsUnloadNal (pCtx->pOut);
 
-    iPayloadSize	= WelsEncodeNalExt (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
-                                      &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
-                                      pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                                      &pNalLen[*pNalIdxInLayer]);
+    iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
+                                            &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
+                                            pCtx->iFrameBsSize-pCtx->iPosBsBuffer,
+                                            pCtx->pFrameBs+pCtx->iPosBsBuffer,
+                                            &pNalLen[*pNalIdxInLayer]);
+    WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
+    iPayloadSize = pNalLen[*pNalIdxInLayer];
 
     pCtx->iPosBsBuffer							+= iPayloadSize;
     pLayerBsInfo->iNalLengthInByte[*pNalIdxInLayer]	= iPayloadSize;
@@ -2873,10 +2887,13 @@
     // No need write any syntax of prefix NAL Unit RBSP here
     WelsUnloadNal (pCtx->pOut);
 
-    iPayloadSize = WelsEncodeNalExt (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
-                                     &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
-                                     pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                                     &pNalLen[*pNalIdxInLayer]);
+    iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
+                                            &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
+                                            pCtx->iFrameBsSize-pCtx->iPosBsBuffer,
+                                            pCtx->pFrameBs+pCtx->iPosBsBuffer,
+                                            &pNalLen[*pNalIdxInLayer]);
+    WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
+    iPayloadSize = pNalLen[*pNalIdxInLayer];
 
     pCtx->iPosBsBuffer							+= iPayloadSize;
     pLayerBsInfo->iNalLengthInByte[*pNalIdxInLayer]	= iPayloadSize;
@@ -2884,16 +2901,16 @@
     (*pNalIdxInLayer) ++;
   }
 
-  return iPayloadSize;
+  return ENC_RETURN_SUCCESS;
 }
 
-int32_t WritePadding (sWelsEncCtx* pCtx, int32_t iLen) {
+int32_t WritePadding (sWelsEncCtx* pCtx, int32_t iLen, int32_t& iSize) {
   int32_t i = 0;
   int32_t iNal	= 0;
   SBitStringAux*	pBs = NULL;
   int32_t iNalLen;
-  int32_t iSize = 0;
 
+  iSize = 0;
   iNal	= pCtx->pOut->iNalIndex;
   pBs	=	&pCtx->pOut->sBsWrite;	// SBitStringAux instance for non VCL NALs decoding
 
@@ -2903,7 +2920,7 @@
              "[RC] paddingcal pBuffer overflow, bufferlen=%lld, paddinglen=%d, iNalIdx= %d, iCountNals= %d\n",
              static_cast<long long int> (pBs->pBufEnd - pBs->pBufPtr), iLen, iNal, pCtx->pOut->iCountNals);
 #endif
-    return 0;
+    return ENC_RETURN_MEMOVERFLOWFOUND;
   }
 
   WelsLoadNal (pCtx->pOut, NAL_UNIT_FILLER_DATA, NRI_PRI_LOWEST);
@@ -2917,12 +2934,16 @@
   BsFlush (pBs);
 
   WelsUnloadNal (pCtx->pOut);
-  iNalLen = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], pCtx->pFrameBs + pCtx->iPosBsBuffer, &iNalLen);
+  int32_t iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[iNal], NULL,
+                                                      pCtx->iFrameBsSize-pCtx->iPosBsBuffer,
+                                                      pCtx->pFrameBs + pCtx->iPosBsBuffer,
+                                                      &iNalLen);
+  WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
 
   pCtx->iPosBsBuffer	+= iNalLen;
   iSize				+= iNalLen;
 
-  return iSize;
+  return ENC_RETURN_SUCCESS;
 }
 
 /*
@@ -3012,7 +3033,8 @@
   pLayerBsInfo->pBsBuf = pCtx->pFrameBs;
   InitBits (&pCtx->pOut->sBsWrite, pCtx->pOut->pBsBuffer, pCtx->pOut->uiSize);
 
-  WelsWriteParameterSets (pCtx, &iNalLen[0], &iCountNal);
+  int32_t iReturn = WelsWriteParameterSets (pCtx, &iNalLen[0], &iCountNal);
+  WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
 
   pLayerBsInfo->uiPriorityId  = 0;
   pLayerBsInfo->uiSpatialId   = 0;
@@ -3031,7 +3053,7 @@
   WelsEmms();
 #endif //X86_ASM
 
-  return 0;
+  return ENC_RETURN_SUCCESS;
 }
 
 /*!
@@ -3082,6 +3104,7 @@
   int32_t i = 0, j = 0, k = 0;
 #endif//_DEBUG
 
+  pCtx->iEncoderError						= ENC_RETURN_SUCCESS;
   pFbi->iLayerNum	= 0;	// for initialization
 
   // perform csc/denoise/downsample/padding, generate spatial layers
@@ -3088,12 +3111,15 @@
   iSpatialNum = pCtx->pVpp->BuildSpatialPicList (pCtx, ppSrcList, iConfiguredLayerNum);
   if (iSpatialNum < 1) {	// skip due to temporal layer settings (different frame rate)
     ++ pCtx->iCodingIndex;
-    return WELS_FRAME_TYPE_SKIP;
+    pFbi->eOutputFrameType = WELS_FRAME_TYPE_SKIP;
+    return ENC_RETURN_SUCCESS;
   }
 
   eFrameType = DecideFrameType (pCtx, iSpatialNum);
-  if (eFrameType == WELS_FRAME_TYPE_SKIP)
-    return eFrameType;
+  if (eFrameType == WELS_FRAME_TYPE_SKIP) {
+    pFbi->eOutputFrameType = eFrameType;
+    return ENC_RETURN_SUCCESS;
+  }
 
   InitFrameCoding (pCtx, eFrameType);
 
@@ -3108,7 +3134,8 @@
     //if ( pSvcParam->bEnableSSEI )
 
     // write parameter sets bitstream here
-    WelsWriteParameterSets (pCtx, &iNalLen[0], &iCountNal);
+    pCtx->iEncoderError = WelsWriteParameterSets (pCtx, &iNalLen[0], &iCountNal);
+    WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
 
     pLayerBsInfo->uiPriorityId	= 0;
     pLayerBsInfo->uiSpatialId		= 0;
@@ -3177,7 +3204,7 @@
     if (iLayerNum >= MAX_LAYER_NUM_OF_FRAME) {	// check available layer_bs_info writing as follows
       WelsLog (pCtx, WELS_LOG_ERROR, "WelsEncoderEncodeExt(), iLayerNum(%d) overflow(max:%d)!", iLayerNum,
                MAX_LAYER_NUM_OF_FRAME);
-      return -1;
+      return ENC_RETURN_UNSUPPORTED_PARA;
     }
 
     iNalIdxInLayer	= 0;
@@ -3215,9 +3242,11 @@
     if (!WelsBuildRefList (pCtx, pCtx->iPOC)) {
       // Force coding IDR as followed
       ForceCodingIDR (pCtx);
-      WelsLog (pCtx, WELS_LOG_WARNING, "WelsEncoderEncodeExt(), WelsBuildRefList failed for P frames, pCtx->iNumRef0= %d.\n",
+      WelsLog (pCtx, WELS_LOG_WARNING, "WelsEncoderEncodeExt(), WelsBuildRefList failed for P frames, pCtx->iNumRef0= %d. ForceCodingIDR!\n",
                pCtx->iNumRef0);
-      return -1;
+      pFbi->eOutputFrameType = WELS_FRAME_TYPE_IDR;
+      pCtx->iEncoderError = ENC_RETURN_CORRECTED;
+      return ENC_RETURN_CORRECTED;
     }
 #ifdef LONG_TERM_REF_DUMP
     dump_ref (pCtx);
@@ -3230,23 +3259,32 @@
     PreprocessSliceCoding (pCtx);	// MUST be called after pfWelsRcPictureInit() and WelsInitCurrentLayer()
 
     iLayerSize	= 0;
+
     if (SM_SINGLE_SLICE == param_d->sSliceCfg.uiSliceMode) {	// only one slice within a sQualityStat layer
       int32_t iSliceSize = 0;
+      int32_t iPayloadSize	= 0;
 
       if (pCtx->bNeedPrefixNalFlag) {
-        iLayerSize += AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, eNalType, eNalRefIdc);
+        pCtx->iEncoderError = AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, eNalType, eNalRefIdc, iPayloadSize);
+        WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+        iLayerSize += iPayloadSize;
       }
 
       WelsLoadNal (pCtx->pOut, eNalType, eNalRefIdc);
 
-      WelsCodeOneSlice (pCtx, 0, eNalType);
+      pCtx->iEncoderError = WelsCodeOneSlice (pCtx, 0, eNalType);
+      WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
 
       WelsUnloadNal (pCtx->pOut);
 
-      iSliceSize = WelsEncodeNalExt (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
-                                     &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
-                                     pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                                     &iNalLen[iNalIdxInLayer]);
+      pCtx->iEncoderError = WelsEncodeNal (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
+                                                                 &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
+                                                                 pCtx->iFrameBsSize-pCtx->iPosBsBuffer,
+                                                                 pCtx->pFrameBs+pCtx->iPosBsBuffer,
+                                                                 &iNalLen[iNalIdxInLayer]);
+      WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+      iSliceSize = iNalLen[iNalIdxInLayer];
+
       iLayerSize += iSliceSize;
       pCtx->iPosBsBuffer	+= iSliceSize;
       pLayerBsInfo->uiLayerType		= VIDEO_CODING_LAYER;
@@ -3265,7 +3303,8 @@
 #endif//MT_ENABLED
     {
       const int32_t kiLastMbInFrame = pCtx->pCurDqLayer->pSliceEncCtx->iMbNumInFrame;
-      WelsCodeOnePicPartition (pCtx, pLayerBsInfo, &iNalIdxInLayer, &iLayerSize, 0, kiLastMbInFrame, 0);
+      pCtx->iEncoderError = WelsCodeOnePicPartition (pCtx, pLayerBsInfo, &iNalIdxInLayer, &iLayerSize, 0, kiLastMbInFrame, 0);
+      WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
     } else {
       //other multi-slice uiSliceMode
 #if defined(MT_ENABLED)
@@ -3283,13 +3322,13 @@
           WelsLog (pCtx, WELS_LOG_ERROR,
                    "WelsEncoderEncodeExt(), iLayerNum(%d) overflow(max:%d) at iDid= %d uiSliceMode= %d, iSliceCount= %d!",
                    iLayerNum, MAX_LAYER_NUM_OF_FRAME, iCurDid, param_d->sSliceCfg.uiSliceMode, iSliceCount);
-          return -1;
+          return ENC_RETURN_UNSUPPORTED_PARA;
         }
         if (iSliceCount <= 1) {
           WelsLog (pCtx, WELS_LOG_ERROR,
                    "WelsEncoderEncodeExt(), iSliceCount(%d) from GetCurrentSliceNum() is untrusted due stack/heap crupted!\n",
                    iSliceCount);
-          return -1;
+          return ENC_RETURN_UNEXPECTED;
         }
 
         if (pSvcParam->iCountThreadsNum >= iSliceCount) {	//THREAD_FULLY_FIRE_MODE
@@ -3313,7 +3352,7 @@
             WelsLog (pCtx, WELS_LOG_ERROR,
                      "[MT] WelsEncoderEncodeExt(), FiredSliceThreads return(%d) failed and exit encoding frame, iCountThreadsNum= %d, iSliceCount= %d, uiSliceMode= %d, iMultipleThreadIdc= %d!!\n",
                      err, pSvcParam->iCountThreadsNum, iSliceCount, param_d->sSliceCfg.uiSliceMode, pSvcParam->iMultipleThreadIdc);
-            return -1;
+            return ENC_RETURN_UNEXPECTED;
           }
 
           WelsMultipleEventsWaitAllBlocking (iSliceCount, &pCtx->pSliceThreading->pSliceCodedEvent[0]);
@@ -3320,6 +3359,8 @@
 
 
           // all slices are finished coding here
+          WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+
           // append exclusive slice 0 bs to pFrameBs
 #if defined(PACKING_ONE_SLICE_PER_LAYER)
           iLayerSize = pCtx->iPosBsBuffer - iOrgSlicePos[0];
@@ -3372,7 +3413,7 @@
             WelsLog (pCtx, WELS_LOG_ERROR,
                      "[MT] WelsEncoderEncodeExt(), FiredSliceThreads return(%d) failed and exit encoding frame, iCountThreadsNum= %d, iSliceCount= %d, uiSliceMode= %d, iMultipleThreadIdc= %d!!\n",
                      err, pSvcParam->iCountThreadsNum, iSliceCount, param_d->sSliceCfg.uiSliceMode, pSvcParam->iMultipleThreadIdc);
-            return -1;
+            return ENC_RETURN_UNEXPECTED;
           }
 
           iIndexOfSliceToBeCoded = iNumThreadsRunning;
@@ -3408,6 +3449,7 @@
             // TODO for pthread platforms
             // alternate implementation using blocking due non-blocking with timeout mode not support at wels thread lib, tune back if available
             WelsMultipleEventsWaitAllBlocking (iNumThreadsRunning, &pCtx->pSliceThreading->pSliceCodedEvent[0]);
+            WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
             if (iIndexOfSliceToBeCoded < iSliceCount) {
               int32_t iThreadIdx = 0;
               // pick up succeeding slices for threading if left
@@ -3464,10 +3506,11 @@
           WelsLog (pCtx, WELS_LOG_ERROR,
                    "[MT] WelsEncoderEncodeExt(), FiredSliceThreads return(%d) failed and exit encoding frame, iCountThreadsNum= %d, iSliceCount= %d, uiSliceMode= %d, iMultipleThreadIdc= %d!!\n",
                    err, pSvcParam->iCountThreadsNum, iSliceCount, param_d->sSliceCfg.uiSliceMode, pSvcParam->iMultipleThreadIdc);
-          return -1;
+          return ENC_RETURN_UNEXPECTED;
         }
 
         WelsMultipleEventsWaitAllBlocking (kiPartitionCnt, &pCtx->pSliceThreading->pSliceCodedEvent[0]);
+        WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
 
 #if defined(PACKING_ONE_SLICE_PER_LAYER)
         iSliceCount = PostProcDynamicSlicingBsWriting (pCtx, pLayerBsInfo, &iLayerSize, kiPartitionCnt);
@@ -3486,19 +3529,26 @@
         iSliceCount	= GetCurrentSliceNum (pCtx->pCurDqLayer->pSliceEncCtx);
         while (iSliceIdx < iSliceCount) {
           int32_t iSliceSize	= 0;
-
+          int32_t iPayloadSize	= 0;
           if (bNeedPrefix) {
-            iLayerSize += AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, eNalType, eNalRefIdc);
+            pCtx->iEncoderError = AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, eNalType, eNalRefIdc, iPayloadSize);
+            WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+            iLayerSize += iPayloadSize;
           }
 
           WelsLoadNal (pCtx->pOut, eNalType, eNalRefIdc);
-          WelsCodeOneSlice (pCtx, iSliceIdx, eNalType);
+          pCtx->iEncoderError = WelsCodeOneSlice (pCtx, iSliceIdx, eNalType);
+          WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+
           WelsUnloadNal (pCtx->pOut);
 
-          iSliceSize = WelsEncodeNalExt (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
-                                         &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
-                                         pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                                         &iNalLen[iNalIdxInLayer]);
+          pCtx->iEncoderError = WelsEncodeNal (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
+                                                      &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
+                                                      pCtx->iFrameBsSize-pCtx->iPosBsBuffer,
+                                                      pCtx->pFrameBs+pCtx->iPosBsBuffer, &iNalLen[iNalIdxInLayer]);
+          WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
+          iSliceSize = iNalLen[iNalIdxInLayer];
+
           pCtx->iPosBsBuffer	+= iSliceSize;
           iLayerSize	+= iSliceSize;
           pLayerBsInfo->iNalLengthInByte[iNalIdxInLayer]	= iSliceSize;
@@ -3542,8 +3592,10 @@
       if (!WelsUpdateRefList (pCtx)) {
         // Force coding IDR as followed
         ForceCodingIDR (pCtx);
-        WelsLog (pCtx, WELS_LOG_WARNING, "WelsEncoderEncodeExt(), WelsUpdateRefList failed.\n");
-        return -1;
+        WelsLog (pCtx, WELS_LOG_WARNING, "WelsEncoderEncodeExt(), WelsUpdateRefList failed. ForceCodingIDR!\n");
+        //the above is to set the next frame to be IDR
+        pFbi->eOutputFrameType = eFrameType;
+        return ENC_RETURN_CORRECTED;
       }
     }
 
@@ -3648,14 +3700,16 @@
     pLayerBsInfo->pBsBuf	= pCtx->pFrameBs + pCtx->iPosBsBuffer;
 
     if (pSvcParam->iPaddingFlag && pCtx->pWelsSvcRc[pCtx->uiDependencyId].iPaddingSize > 0) {
-      const int32_t kiPaddingNalSize = WritePadding (pCtx, pCtx->pWelsSvcRc[pCtx->uiDependencyId].iPaddingSize);
+      int32_t iPaddingNalSize = 0;
+      pCtx->iEncoderError =  WritePadding (pCtx, pCtx->pWelsSvcRc[pCtx->uiDependencyId].iPaddingSize, iPaddingNalSize);
+      WELS_VERIFY_RETURN_IFNEQ(pCtx->iEncoderError, ENC_RETURN_SUCCESS)
 
 #if GOM_TRACE_FLAG
       WelsLog (pCtx, WELS_LOG_INFO, "[RC] encoding_qp%d Padding: %d\n", pCtx->uiDependencyId,
                pCtx->pWelsSvcRc[pCtx->uiDependencyId].iPaddingSize);
 #endif
-      if (kiPaddingNalSize <= 0)
-        return -1;
+      if (iPaddingNalSize <= 0)
+        return ENC_RETURN_UNEXPECTED;
 
       pCtx->pWelsSvcRc[pCtx->uiDependencyId].iPaddingBitrateStat += pCtx->pWelsSvcRc[pCtx->uiDependencyId].iPaddingSize;
 
@@ -3667,7 +3721,7 @@
       pLayerBsInfo->uiQualityId		= 0;
       pLayerBsInfo->uiLayerType		= NON_VIDEO_CODING_LAYER;
       pLayerBsInfo->iNalCount		= 1;
-      pLayerBsInfo->iNalLengthInByte[0] = kiPaddingNalSize;
+      pLayerBsInfo->iNalLengthInByte[0] = iPaddingNalSize;
       ++ pLayerBsInfo;
       pLayerBsInfo->pBsBuf	= pCtx->pFrameBs + pCtx->iPosBsBuffer;
       ++ iLayerNum;
@@ -3697,7 +3751,10 @@
 
     if( pCtx->pVpp->UpdateSpatialPictures(pCtx, pSvcParam, iCurTid, d_idx) != 0 ){
       ForceCodingIDR(pCtx);
-      return -1;
+      WelsLog (pCtx, WELS_LOG_WARNING, "WelsEncoderEncodeExt(), Logic Error Found in temporal level. ForceCodingIDR!\n");
+      //the above is to set the next frame IDR
+      pFbi->eOutputFrameType = eFrameType;
+      return ENC_RETURN_CORRECTED;
     }
 
     if (pSvcParam->bEnableLongTermReference && ((pCtx->pLtr[pCtx->uiDependencyId].bLTRMarkingFlag
@@ -3734,7 +3791,8 @@
   WelsEmms();
 #endif //X86_ASM
 
-  return eFrameType;
+  pFbi->eOutputFrameType = eFrameType;
+  return ENC_RETURN_SUCCESS;
 }
 
 /*!
@@ -3743,7 +3801,7 @@
  */
 int32_t WelsEncoderParamAdjust (sWelsEncCtx** ppCtx, SWelsSvcCodingParam* pNewParam) {
   SWelsSvcCodingParam* pOldParam		= NULL;
-  int32_t iReturn = 0;
+  int32_t iReturn = ENC_RETURN_SUCCESS;
   int8_t iIndexD = 0;
   bool bNeedReset = false;
 
@@ -3751,7 +3809,7 @@
 
   /* Check validation in new parameters */
   iReturn	= ParamValidationExt (pNewParam);
-  if (iReturn != 0)	return iReturn;
+  if (iReturn != ENC_RETURN_SUCCESS)	return iReturn;
 
   pOldParam	= (*ppCtx)->pSvcParam;
 
@@ -3942,6 +4000,7 @@
   const EWelsNalUnitType keNalType	= pCtx->eNalType;
   const EWelsNalRefIdc keNalRefIdc	= pCtx->eNalPriority;
   const bool kbNeedPrefix		= pCtx->bNeedPrefixNalFlag;
+  int32_t iReturn = ENC_RETURN_SUCCESS;
 
   //init
   {
@@ -3953,25 +4012,33 @@
 
   while (iAnyMbLeftInPartition > 0) {
     int32_t iSliceSize	= 0;
+    int32_t iPayloadSize	= 0;
 
     if (iSliceIdx >= pSliceCtx->iMaxSliceNumConstraint) {	// insufficient memory in pSliceInLayer[]
       // TODO: need exception handler for not large enough of MAX_SLICES_NUM related memory usage
       // No idea about its solution due MAX_SLICES_NUM is fixed lenght in relevent pData structure
-      return 1;
+      return ENC_RETURN_MEMALLOCERR;
     }
 
     if (kbNeedPrefix) {
-      iPartitionBsSize += AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, keNalType, keNalRefIdc);
+      iReturn = AddPrefixNal (pCtx, pLayerBsInfo, &iNalLen[0], &iNalIdxInLayer, keNalType, keNalRefIdc, iPayloadSize);
+      WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
+      iPartitionBsSize += iPayloadSize;
     }
 
     WelsLoadNal (pCtx->pOut, keNalType, keNalRefIdc);
-    WelsCodeOneSlice (pCtx, iSliceIdx, keNalType);
+    iReturn=WelsCodeOneSlice (pCtx, iSliceIdx, keNalType);
+    WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
     WelsUnloadNal (pCtx->pOut);
 
-    iSliceSize = WelsEncodeNalExt (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
-                                   &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
-                                   pCtx->pFrameBs + pCtx->iPosBsBuffer,
-                                   &iNalLen[iNalIdxInLayer]);
+    iReturn = WelsEncodeNal (&pCtx->pOut->sNalList[pCtx->pOut->iNalIndex - 1],
+                                                &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt,
+                                                pCtx->iFrameBsSize-pCtx->iPosBsBuffer,
+                                                pCtx->pFrameBs+pCtx->iPosBsBuffer,
+                                                &iNalLen[iNalIdxInLayer]);
+    WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
+    iSliceSize = iNalLen[iNalIdxInLayer];
+
     pCtx->iPosBsBuffer	+= iSliceSize;
     iPartitionBsSize	+= iSliceSize;
     pLayerBsInfo->iNalLengthInByte[iNalIdxInLayer]	= iSliceSize;
@@ -4001,6 +4068,6 @@
   pLayerBsInfo->uiPriorityId	= 0;
   pLayerBsInfo->iNalCount		= iNalIdxInLayer;
 
-  return 0;
+  return ENC_RETURN_SUCCESS;
 }
 } // namespace WelsSVCEnc
--- a/codec/encoder/core/src/nal_encap.cpp
+++ b/codec/encoder/core/src/nal_encap.cpp
@@ -55,6 +55,7 @@
   sNalHeader->uiForbiddenZeroBit	= 0;
 
   pRawNal->pRawData		= &pWelsEncoderOuput->pBsBuffer[kiStartPos];
+  pRawNal->iStartPos	 = kiStartPos;
   pRawNal->iPayloadSize	= 0;
 }
 
@@ -68,7 +69,7 @@
   const int32_t kiEndPos		= (BsGetBitsPos (&pWelsEncoderOuput->sBsWrite) >> 3);
 
   /* count payload size of pRawNal NAL */
-  pRawNal->iPayloadSize	= &pWelsEncoderOuput->pBsBuffer[kiEndPos] - pRawNal->pRawData;
+  pRawNal->iPayloadSize	= kiEndPos - pRawNal->iStartPos;
 
   ++ (*pIdx);
 }
@@ -89,6 +90,7 @@
   sNalHeader->uiForbiddenZeroBit	= 0;
 
   pRawNal->pRawData		= &pSliceBs->pBsBuffer[kiStartPos];
+  pRawNal->iStartPos	 = kiStartPos;
   pRawNal->iPayloadSize	= 0;
 }
 
@@ -103,7 +105,7 @@
   const int32_t kiEndPos		        = (BsGetBitsPos (pBitStringAux) >> 3);
 
   /* count payload size of pRawNal NAL */
-  pRawNal->iPayloadSize	= &pSliceBs->pBsBuffer[kiEndPos] - pRawNal->pRawData;
+  pRawNal->iPayloadSize	= kiEndPos - pRawNal->iStartPos;
 
   ++ (*pIdx);
 }
@@ -114,9 +116,21 @@
  * \param	pDstLen		length of pDst NAL output
  * \param	annexeb		annexeb flag
  * \param	pRawNal			pRawNal NAL pData
- * \return	length of pDst NAL
+ * \return	ERRCODE
  */
-int32_t WelsEncodeNal (SWelsNalRaw* pRawNal, void* pDst, int32_t* pDstLen) {
+//TODO 1: refactor the calling of this func in multi-thread
+//TODO 2: complete the realloc&copy
+int32_t WelsEncodeNal (SWelsNalRaw* pRawNal, void* pNalHeaderExt, const int32_t kiDstBufferLen, void* pDst, int32_t* pDstLen) {
+  const bool kbNALExt = pRawNal->sNalExt.sNalHeader.eNalUnitType == NAL_UNIT_PREFIX
+                                        || pRawNal->sNalExt.sNalHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_EXT;
+  int32_t iAssumedNeededLength		= NAL_HEADER_SIZE+(kbNALExt?3:0)+pRawNal->iPayloadSize+1;
+  WELS_VERIFY_RETURN_IF(ENC_RETURN_UNEXPECTED, (iAssumedNeededLength<=0))
+
+  //since for each 0x000 need a 0x03, so the needed length will not exceed (iAssumeNeedLenth + iAssumeNeedLength/3), here adjust to >>1 to omit division
+  if (kiDstBufferLen < (iAssumedNeededLength + (iAssumedNeededLength>>1)) ) {
+    return ENC_RETURN_MEMALLOCERR;
+    //TODO: call the realloc&copy instead
+  }
   uint8_t* pDstStart	    = (uint8_t*)pDst;
   uint8_t* pDstPointer	= pDstStart;
   uint8_t* pSrcPointer	= pRawNal->pRawData;
@@ -123,8 +137,9 @@
   uint8_t* pSrcEnd		= pRawNal->pRawData + pRawNal->iPayloadSize;
   int32_t iZeroCount		= 0;
   int32_t iNalLength		= 0;
+  *pDstLen = 0;
 
-  static const uint8_t kuiStartCodePrefix[4] = { 0, 0, 0, 1 };
+  static const uint8_t kuiStartCodePrefix[NAL_HEADER_SIZE] = { 0, 0, 0, 1 };
   ST32 (pDstPointer, LD32 (&kuiStartCodePrefix[0]));
   pDstPointer += 4;
 
@@ -131,74 +146,24 @@
   /* NAL Unit Header */
   *pDstPointer++	= (pRawNal->sNalExt.sNalHeader.uiNalRefIdc << 5) | (pRawNal->sNalExt.sNalHeader.eNalUnitType & 0x1f);
 
-  while (pSrcPointer < pSrcEnd) {
-    if (iZeroCount == 2 && *pSrcPointer <= 3) {
-      *pDstPointer++	= 3;
-      iZeroCount		= 0;
-    }
-    if (*pSrcPointer == 0) {
-      ++ iZeroCount;
-    } else {
-      iZeroCount		= 0;
-    }
-    *pDstPointer++ = *pSrcPointer++;
-  }
+  if (kbNALExt) {
+    SNalUnitHeaderExt* sNalExt	= (SNalUnitHeaderExt*)pNalHeaderExt;
 
-  /* count length of NAL Unit */
-  iNalLength	= pDstPointer - pDstStart;
-  if (NULL != pDstLen)
-    *pDstLen	= iNalLength;
+    /* NAL UNIT Extension Header */
+    *pDstPointer++ =	(0x80) |
+      (sNalExt->bIdrFlag << 6);
 
-  return iNalLength;
-}
+    *pDstPointer++ =	(0x80) |
+      (sNalExt->uiDependencyId << 4);
 
-/*!
- * \brief	encode a nal into a pBuffer for any type of NAL, involved WelsEncodeNal introduced in AVC
- *
- * \param	pDst			pDst NAL pData
- * \param	pDstLen		length of pDst NAL output
- * \param	annexeb		annexeb flag
- * \param	pRawNal			pRawNal NAL pData
- * \param	pNalHeaderExt	pointer of SNalUnitHeaderExt
- *
- * \return	length of pDst NAL
- */
-int32_t WelsEncodeNalExt (SWelsNalRaw* pRawNal, void* pNalHeaderExt, void* pDst, int32_t* pDstLen) {
-  SNalUnitHeaderExt* sNalExt	= (SNalUnitHeaderExt*)pNalHeaderExt;
-  uint8_t* pDstStart				    = (uint8_t*)pDst;
-  uint8_t* pDstPointer				= pDstStart;
-  uint8_t* pSrcPointer				= pRawNal->pRawData;
-  uint8_t* pSrcEnd					= pRawNal->pRawData + pRawNal->iPayloadSize;
-  int32_t iZeroCount					= 0;
-  int32_t iNalLength					= 0;
-
-  if (pRawNal->sNalExt.sNalHeader.eNalUnitType != NAL_UNIT_PREFIX
-      && pRawNal->sNalExt.sNalHeader.eNalUnitType != NAL_UNIT_CODED_SLICE_EXT) {
-    return WelsEncodeNal (pRawNal, pDst, pDstLen);
+    *pDstPointer++ =	(sNalExt->uiTemporalId << 5) |
+      (sNalExt->bDiscardableFlag << 3) |
+      (0x07);
   }
 
-  /* FIXME this code doesn't check overflow */
-
-  static const uint8_t kuiStartCodePrefixExt[4] = { 0, 0, 0, 1 };
-  ST32 (pDstPointer, LD32 (&kuiStartCodePrefixExt[0]));
-  pDstPointer += 4;
-
-  /* NAL Unit Header */
-  *pDstPointer++	= (pRawNal->sNalExt.sNalHeader.uiNalRefIdc << 5) | (pRawNal->sNalExt.sNalHeader.eNalUnitType & 0x1f);
-
-  /* NAL UNIT Extension Header */
-  *pDstPointer++ =	(0x80) |
-                    (sNalExt->bIdrFlag << 6);
-
-  *pDstPointer++ =	(0x80) |
-                    (sNalExt->uiDependencyId << 4);
-
-  *pDstPointer++ =	(sNalExt->uiTemporalId << 5) |
-                    (sNalExt->bDiscardableFlag << 3) |
-                    (0x07);
-
   while (pSrcPointer < pSrcEnd) {
     if (iZeroCount == 2 && *pSrcPointer <= 3) {
+      //add the code 03
       *pDstPointer++	= 3;
       iZeroCount		= 0;
     }
@@ -215,7 +180,7 @@
   if (NULL != pDstLen)
     *pDstLen	= iNalLength;
 
-  return iNalLength;
+  return ENC_RETURN_SUCCESS;
 }
 
 /*!
--- a/codec/encoder/core/src/slice_multi_threading.cpp
+++ b/codec/encoder/core/src/slice_multi_threading.cpp
@@ -347,6 +347,7 @@
   int32_t iIdx					= 0;
   int32_t iSliceBsBufferSize = 0;
   int16_t iMaxSliceNum		= 1;
+  int32_t iReturn = ENC_RETURN_SUCCESS;
 
   if (NULL == ppCtx || NULL == pCodingParam || NULL == *ppCtx || iCountBsLen <= 0)
     return 1;
@@ -492,8 +493,6 @@
   WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pSmt->pCountBsSizeInPartition), FreeMemorySvc (ppCtx))
 #endif//PACKING_ONE_SLICE_PER_LAYER
 
-  WelsMutexInit (&pSmt->mutexSliceNumUpdate);
-
   (*ppCtx)->pSliceBs	= (SWelsSliceBs*)pMa->WelsMalloc (sizeof (SWelsSliceBs) * iMaxSliceNum, "pSliceBs");
   WELS_VERIFY_RETURN_PROC_IF (1, (NULL == (*ppCtx)->pSliceBs), FreeMemorySvc (ppCtx))
 
@@ -502,7 +501,7 @@
   iSliceBsBufferSize	= iTargetSpatialBsSize;
   iIdx = 0;
   while (iIdx < iMaxSliceNum) {
-    pSliceB->pBsBuffer	= (uint8_t*)pMa->WelsMalloc (iSliceBsBufferSize, "pSliceB->pBsBuffer");
+    pSliceB->pBsBuffer  = (uint8_t*)pMa->WelsMalloc (iSliceBsBufferSize, "pSliceB->pBsBuffer");
 
     WELS_VERIFY_RETURN_PROC_IF (1, (NULL == pSliceB->pBsBuffer), FreeMemorySvc (ppCtx))
     pSliceB->uiSize	= iSliceBsBufferSize;
@@ -519,6 +518,12 @@
     ++ iIdx;
   }
 
+  iReturn = WelsMutexInit (&pSmt->mutexSliceNumUpdate);
+  WELS_VERIFY_RETURN_PROC_IF (1, (WELS_THREAD_ERROR_OK != iReturn), FreeMemorySvc (ppCtx))
+
+  iReturn = WelsMutexInit (&(*ppCtx)->mutexEncoderError);
+  WELS_VERIFY_RETURN_PROC_IF (1, (WELS_THREAD_ERROR_OK != iReturn), FreeMemorySvc (ppCtx))
+
 #if defined(ENABLE_TRACE_MT)
   WelsLog ((*ppCtx), WELS_LOG_INFO, "RequestMtResource(), iThreadNum=%d, iCountSliceNum= %d\n", pPara->iCountThreadsNum,
            iMaxSliceNum);
@@ -610,7 +615,9 @@
     pSmt->pCountBsSizeInPartition = NULL;
   }
 #endif//PACKING_ONE_SLICE_PER_LAYER
+
   WelsMutexDestroy (&pSmt->mutexSliceNumUpdate);
+  WelsMutexDestroy (&((*ppCtx)->mutexEncoderError));
 
   if (pSmt->pThreadPEncCtx != NULL) {
     pMa->WelsFree (pSmt->pThreadPEncCtx, "pThreadPEncCtx");
@@ -766,14 +773,14 @@
   return iLayerSize;
 }
 
-int32_t WriteSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, uint8_t* pFrameBsBuffer, const int32_t iSliceIdx) {
+int32_t WriteSliceToFrameBs (sWelsEncCtx* pCtx, SLayerBSInfo* pLbi, uint8_t* pFrameBsBuffer, const int32_t iSliceIdx, int32_t& iSliceSize) {
   SWelsSliceBs* pSliceBs			= &pCtx->pSliceBs[iSliceIdx];
   SNalUnitHeaderExt* pNalHdrExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
   uint8_t* pDst					= pFrameBsBuffer;
   int32_t pNalLen[2];
-  int32_t iSliceSize				= 0;
   const int32_t kiNalCnt			= pSliceBs->iNalIndex;
   int32_t iNalIdx					= 0;
+  int32_t iNalSize = 0;
 #if !defined(PACKING_ONE_SLICE_PER_LAYER)
   const int32_t iFirstSlice		= (iSliceIdx == 0);
   int32_t iNalBase				= iFirstSlice ? 0 : pLbi->iNalCount;
@@ -780,11 +787,18 @@
 #else
   int32_t iNalBase				= 0;
 #endif//!PACKING_ONE_SLICE_PER_LAYER
+  int32_t iReturn = ENC_RETURN_SUCCESS;
+  const int32_t kiWrittenLength = pCtx->iPosBsBuffer;
+  iSliceSize				= 0;
 
   while (iNalIdx < kiNalCnt) {
-    iSliceSize += WelsEncodeNalExt (&pSliceBs->sNalList[iNalIdx], pNalHdrExt, pDst, &pNalLen[iNalIdx]);
-    pDst += pNalLen[iNalIdx];
-    pLbi->iNalLengthInByte[iNalBase + iNalIdx]	= pNalLen[iNalIdx];
+    iNalSize = 0;
+    iReturn = WelsEncodeNal (&pSliceBs->sNalList[iNalIdx], pNalHdrExt, pCtx->iFrameBsSize-kiWrittenLength-iSliceSize, pDst, &iNalSize);
+    WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
+    pNalLen[iNalIdx] = iNalSize;
+    iSliceSize += iNalSize;
+    pDst += iNalSize;
+    pLbi->iNalLengthInByte[iNalBase + iNalIdx]	= iNalSize;
 
     ++ iNalIdx;
   }
@@ -811,31 +825,37 @@
   pLbi->iNalCount		= kiNalCnt;
 #endif//PACKING_ONE_SLICE_PER_LAYER
 
-  return iSliceSize;
+  return ENC_RETURN_SUCCESS;
 }
 
-int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pSliceBsBuf, const int32_t iSliceIdx) {
+int32_t WriteSliceBs (sWelsEncCtx* pCtx, uint8_t* pSliceBsBuf, const int32_t iSliceIdx, int32_t& iSliceSize) {
   SWelsSliceBs* pSliceBs			= &pCtx->pSliceBs[iSliceIdx];
   SNalUnitHeaderExt* pNalHdrExt = &pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt;
   uint8_t* pDst					= pSliceBsBuf;
   int32_t* pNalLen				= &pSliceBs->iNalLen[0];
-  int32_t iSliceSize				= 0;
   const int32_t kiNalCnt			= pSliceBs->iNalIndex;
   int32_t iNalIdx					= 0;
+  int32_t iNalSize					= 0;
+  int32_t iReturn = ENC_RETURN_SUCCESS;
+  const int32_t kiWrittenLength = pSliceBs->sBsWrite.pBufPtr - pSliceBs->sBsWrite.pBuf;
 
+  iSliceSize				= 0;
   assert (kiNalCnt <= 2);
   if (kiNalCnt > 2)
     return 0;
 
   while (iNalIdx < kiNalCnt) {
-    iSliceSize += WelsEncodeNalExt (&pSliceBs->sNalList[iNalIdx], pNalHdrExt, pDst, &pNalLen[iNalIdx]);
-    pDst += pNalLen[iNalIdx];
-
+    iNalSize = 0;
+    iReturn = WelsEncodeNal (&pSliceBs->sNalList[iNalIdx], pNalHdrExt, pSliceBs->uiSize-kiWrittenLength-iSliceSize, pDst, &iNalSize);
+    WELS_VERIFY_RETURN_IFNEQ(iReturn, ENC_RETURN_SUCCESS)
+    pNalLen[iNalIdx] = iNalSize;
+    iSliceSize += iNalSize;
+    pDst += iNalSize;
     ++ iNalIdx;
   }
   pSliceBs->uiBsPos	= iSliceSize;
 
-  return iSliceSize;
+  return iReturn;
 }
 
 #if defined(DYNAMIC_SLICE_ASSIGN) && defined(TRY_SLICING_BALANCE)
@@ -901,6 +921,7 @@
   bool bNeedPrefix							= false;
   EWelsNalUnitType eNalType						= NAL_UNIT_UNSPEC_0;
   EWelsNalRefIdc eNalRefIdc						= NRI_PRI_LOWEST;
+  int32_t iReturn = ENC_RETURN_SUCCESS;
 
   if (NULL == pPrivateData)
     WELS_THREAD_ROUTINE_RETURN (1);
@@ -985,7 +1006,11 @@
 
         WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc);
 
-        WelsCodeOneSlice (pEncPEncCtx, iSliceIdx, eNalType);
+        iReturn = WelsCodeOneSlice (pEncPEncCtx, iSliceIdx, eNalType);
+        if (ENC_RETURN_SUCCESS!=iReturn) {
+          uiThrdRet = iReturn;
+          break;
+        }
 
         WelsUnloadNalForSlice (pSliceBs);
 
@@ -992,18 +1017,36 @@
 #if !defined(PACKING_ONE_SLICE_PER_LAYER)
         if (0 == iSliceIdx) {
           pLbi->pBsBuf	= pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer;
-          iSliceSize = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pLbi->pBsBuf, iSliceIdx);
+          iReturn = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pLbi->pBsBuf, iSliceIdx, iSliceSize);
+          if (ENC_RETURN_SUCCESS!=iReturn) {
+            uiThrdRet = iReturn;
+            break;
+          }
           pEncPEncCtx->iPosBsBuffer += iSliceSize;
         } else
-          iSliceSize = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, iSliceIdx);
+        {
+          iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, iSliceIdx, iSliceSize);
+          if (ENC_RETURN_SUCCESS!=iReturn) {
+            uiThrdRet = iReturn;
+            break;
+          }
+        }
 #else// PACKING_ONE_SLICE_PER_LAYER
         if (0 == iSliceIdx) {
           pLbi->pBsBuf	= pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer;
-          iSliceSize = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pLbi->pBsBuf, iSliceIdx);
+          iReturn = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pLbi->pBsBuf, iSliceIdx, &iSliceSize);
+          if (ENC_RETURN_SUCCESS!=iReturn) {
+            uiThrdRet = iReturn;
+            break;
+          }
           pEncPEncCtx->iPosBsBuffer += iSliceSize;
         } else {
           pLbi->pBsBuf	= pSliceBs->bs + pSliceBs->uiBsPos;
-          iSliceSize = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pLbi->pBsBuf, iSliceIdx);
+          iReturn = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pLbi->pBsBuf, iSliceIdx, &iSliceSize);
+          if (ENC_RETURN_SUCCESS!=iReturn) {
+            uiThrdRet = iReturn;
+            break;
+          }
           pSliceBs->uiBsPos += iSliceSize;
         }
 #endif//!PACKING_ONE_SLICE_PER_LAYER
@@ -1101,7 +1144,11 @@
 
           WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc);
 
-          WelsCodeOneSlice (pEncPEncCtx, iSliceIdx, eNalType);
+          iReturn = WelsCodeOneSlice (pEncPEncCtx, iSliceIdx, eNalType);
+          if (ENC_RETURN_SUCCESS!=iReturn) {
+            uiThrdRet = iReturn;
+            break;
+          }
 
           WelsUnloadNalForSlice (pSliceBs);
 
@@ -1109,20 +1156,38 @@
           if (0 == kiPartitionId) {
             if (0 == iSliceIdx)
               pLbi->pBsBuf	= pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer;
-            iSliceSize = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer, iSliceIdx);
+            iReturn = WriteSliceToFrameBs (pEncPEncCtx, pLbi, pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer, iSliceIdx, iSliceSize);
+            if (ENC_RETURN_SUCCESS!=iReturn) {
+              uiThrdRet = iReturn;
+              break;
+            }
             pEncPEncCtx->iPosBsBuffer += iSliceSize;
           } else
-            iSliceSize = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, iSliceIdx);
+          {
+            iSliceSize = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, iSliceIdx, iSliceSize);
+            if (ENC_RETURN_SUCCESS!=iReturn) {
+              uiThrdRet = iReturn;
+              break;
+            }
+          }
 #else// PACKING_ONE_SLICE_PER_LAYER
           pLbiPacking	= pLbi + (iSliceIdx - kiPartitionId);
 
           if (0 == kiPartitionId) {
             pLbiPacking->pBsBuf	= pEncPEncCtx->pFrameBs + pEncPEncCtx->iPosBsBuffer;
-            iSliceSize = WriteSliceToFrameBs (pEncPEncCtx, pLbiPacking, pLbiPacking->pBsBuf, iSliceIdx);
+            iReturn = WriteSliceToFrameBs (pEncPEncCtx, pLbiPacking, pLbiPacking->pBsBuf, iSliceIdx, iSliceSize);
+            if (ENC_RETURN_SUCCESS!=iReturn) {
+              uiThrdRet = iReturn;
+              break;
+            }
             pEncPEncCtx->iPosBsBuffer += iSliceSize;
           } else {
             pLbiPacking->pBsBuf	= pSliceBs->bs + pSliceBs->uiBsPos;
-            iSliceSize = WriteSliceToFrameBs (pEncPEncCtx, pLbiPacking, pLbiPacking->pBsBuf, iSliceIdx);
+            iReturn = WriteSliceToFrameBs (pEncPEncCtx, pLbiPacking, pLbiPacking->pBsBuf, iSliceIdx, iSliceSize);
+            if (ENC_RETURN_SUCCESS!=iReturn) {
+              uiThrdRet = iReturn;
+              break;
+            }
             pSliceBs->uiBsPos += iSliceSize;
           }
           pEncPEncCtx->pSliceThreading->pCountBsSizeInPartition[kiPartitionId] += iSliceSize;
@@ -1197,6 +1262,11 @@
   WelsEventSignal (&pEncPEncCtx->pSliceThreading->pFinSliceCodingEvent[iEventIdx]);	// notify to mother encoding threading
 #endif//WIN32
 
+  //sync multi-threading error
+  WelsMutexLock (&pEncPEncCtx->mutexEncoderError);
+  if (uiThrdRet) pEncPEncCtx->iEncoderError |= uiThrdRet;
+  WelsMutexUnlock (&pEncPEncCtx->mutexEncoderError);
+
   WELS_THREAD_ROUTINE_RETURN (uiThrdRet);
 }
 
@@ -1235,6 +1305,7 @@
                       &pCtx->pSliceThreading->pThreadPEncCtx[iIdx], 0);
 #endif//__GNUC__
 #endif//#if defined(DYNAMIC_SLICE_ASSIGN) && defined(TRY_SLICING_BALANCE)
+
     ++ iIdx;
   }
 #if defined(ENABLE_TRACE_MT)
--- a/codec/encoder/core/src/svc_encode_slice.cpp
+++ b/codec/encoder/core/src/svc_encode_slice.cpp
@@ -50,7 +50,7 @@
 namespace WelsSVCEnc {
 //#define ENC_TRACE
 
-typedef void (*PWelsCodingSliceFunc) (sWelsEncCtx* pCtx, SSlice* pSlice);
+typedef int32_t (*PWelsCodingSliceFunc) (sWelsEncCtx* pCtx, SSlice* pSlice);
 typedef void (*PWelsSliceHeaderWriteFunc) (SBitStringAux* pBs, SDqLayer* pCurLayer, SSlice* pSlice,
     int32_t* pPpsIdDelta);
 
@@ -465,7 +465,7 @@
 //encapsulate two kinds of reconstruction:
 //first. store base or highest Dependency Layer with only one quality (without CS RS reconstruction)
 //second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer)
-void WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
+int32_t WelsISliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
   SDqLayer* pCurLayer				= pEncCtx->pCurDqLayer;
   SSliceCtx* pSliceCtx		= pCurLayer->pSliceEncCtx;
   SMbCache* pMbCache				= &pSlice->sMbCacheInfo;
@@ -479,6 +479,7 @@
   const int32_t kiSliceIdx			= pSlice->uiSliceIdx;
   const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
   SWelsMD sMd;
+  int32_t iEncReturn = ENC_RETURN_SUCCESS;
 
   for (; ;) {
     iCurMbIdx	= iNextMbIdx;
@@ -494,7 +495,9 @@
     WelsMdIntraMb (pEncCtx, &sMd, pCurMb, pMbCache);
     UpdateNonZeroCountCache (pCurMb, pMbCache);
 
-    WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
+    iEncReturn = WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
+    if (ENC_RETURN_SUCCESS != iEncReturn)
+      return iEncReturn;
 
     pCurMb->uiSliceIdc = kiSliceIdx;
 
@@ -511,10 +514,12 @@
       break;
     }
   }
+
+  return ENC_RETURN_SUCCESS;
 }
 
 // Only for intra dynamic slicing
-void WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
+int32_t WelsISliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice) { //pMd + encoding
   SBitStringAux* pBs				= pSlice->pSliceBsa;
   SDqLayer* pCurLayer				= pEncCtx->pCurDqLayer;
   SSliceCtx* pSliceCtx		= pCurLayer->pSliceEncCtx;
@@ -529,6 +534,7 @@
   const int32_t kiSliceIdx				= pSlice->uiSliceIdx;
   const int32_t kiPartitionId			= (kiSliceIdx % pEncCtx->iActiveThreadsNum);
   const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
+  int32_t iEncReturn = ENC_RETURN_SUCCESS;
 
   SWelsMD sMd;
   SDynamicSlicingStack sDss;
@@ -557,7 +563,9 @@
     sDss.uiBsStackCurBits	= pBs->uiCurBits;
     sDss.iBsStackLeftBits	= pBs->iLeftBits;
 
-    WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
+    iEncReturn = WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
+    if (ENC_RETURN_SUCCESS != iEncReturn)
+      return iEncReturn;
 
     sDss.iCurrentPos = BsGetBitsPos (pBs);
 
@@ -574,6 +582,7 @@
       break;
     }
 
+
     pCurMb->uiSliceIdc = kiSliceIdx;
 
 #if defined(MB_TYPES_CHECK)
@@ -593,12 +602,13 @@
       break;
     }
   }
+  return iEncReturn;
 }
 
 //encapsulate two kinds of reconstruction:
 // first. store base or highest Dependency Layer with only one quality (without CS RS reconstruction)
 // second. lower than highest Dependency Layer, and for every Dependency Layer with one quality layer(single layer)
-void WelsPSliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice,  const bool kbIsHighestDlayerFlag) { //pMd + encoding
+int32_t WelsPSliceMdEnc (sWelsEncCtx* pEncCtx, SSlice* pSlice,  const bool kbIsHighestDlayerFlag) { //pMd + encoding
   const SSliceHeaderExt*	kpShExt				= &pSlice->sSliceHeaderExt;
   const SSliceHeader*		kpSh					= &kpShExt->sSliceHeader;
   const int32_t			kiSliceFirstMbXY	= kpSh->iFirstMbInSlice;
@@ -610,10 +620,10 @@
     memset (&sMd.sMe, 0, sizeof (sMd.sMe));
 
   //pMb loop
-  WelsMdInterMbLoop (pEncCtx, pSlice, &sMd, kiSliceFirstMbXY);
+  return WelsMdInterMbLoop (pEncCtx, pSlice, &sMd, kiSliceFirstMbXY);
 }
 
-void WelsPSliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice, const bool kbIsHighestDlayerFlag) {
+int32_t WelsPSliceMdEncDynamic (sWelsEncCtx* pEncCtx, SSlice* pSlice, const bool kbIsHighestDlayerFlag) {
   const SSliceHeaderExt*	kpShExt				= &pSlice->sSliceHeaderExt;
   const SSliceHeader*		kpSh					= &kpShExt->sSliceHeader;
   const int32_t			kiSliceFirstMbXY	= kpSh->iFirstMbInSlice;
@@ -625,10 +635,10 @@
     memset (&sMd.sMe, 0, sizeof (sMd.sMe));
 
   //mb loop
-  WelsMdInterMbLoopOverDynamicSlice (pEncCtx, pSlice, &sMd, kiSliceFirstMbXY);
+  return WelsMdInterMbLoopOverDynamicSlice (pEncCtx, pSlice, &sMd, kiSliceFirstMbXY);
 }
 
-void WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice) {
+int32_t WelsCodePSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice) {
   //pSlice-level init should be outside and before this function
   SDqLayer* pCurLayer			= pEncCtx->pCurDqLayer;
 
@@ -644,10 +654,10 @@
     //initial pMd pointer
     pEncCtx->pFuncList->pfInterMd            = WelsMdInterMb;
   }
-  WelsPSliceMdEnc (pEncCtx, pSlice, kbHighestSpatial);
+  return WelsPSliceMdEnc (pEncCtx, pSlice, kbHighestSpatial);
 }
 
-void WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice) {
+int32_t WelsCodePOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice) {
   //pSlice-level init should be outside and before this function
   SDqLayer* pCurLayer			= pEncCtx->pCurDqLayer;
 
@@ -663,22 +673,22 @@
     //initial pMd pointer
     pEncCtx->pFuncList->pfInterMd            = WelsMdInterMb;
   }
-  WelsPSliceMdEncDynamic (pEncCtx, pSlice, kbHighestSpatial);
+  return WelsPSliceMdEncDynamic (pEncCtx, pSlice, kbHighestSpatial);
 }
 
 // 1st index: 0: for P pSlice; 1: for I pSlice;
 // 2nd index: 0: for non-dynamic pSlice; 1: for dynamic I pSlice;
-const PWelsCodingSliceFunc	g_pWelsSliceCoding[2][2] = {
+PWelsCodingSliceFunc	g_pWelsSliceCoding[2][2] = {
   { WelsCodePSlice, WelsCodePOverDynamicSlice },	// P SSlice
   { WelsISliceMdEnc, WelsISliceMdEncDynamic }	// I SSlice
 };
-const PWelsSliceHeaderWriteFunc		g_pWelsWriteSliceHeader[2] = {	// 0: for base; 1: for ext;
+PWelsSliceHeaderWriteFunc		g_pWelsWriteSliceHeader[2] = {	// 0: for base; 1: for ext;
   WelsSliceHeaderWrite,
   WelsSliceHeaderExtWrite
 };
 
 
-void WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const int32_t kiNalType) {
+int32_t WelsCodeOneSlice (sWelsEncCtx* pEncCtx, const int32_t kiSliceIdx, const int32_t kiNalType) {
   SDqLayer* pCurLayer					= pEncCtx->pCurDqLayer;
   SNalUnitHeaderExt* pNalHeadExt	= &pCurLayer->sLayerInfo.sNalHeaderExt;
   SSlice* pCurSlice					= &pCurLayer->sLayerInfo.pSliceInLayer[kiSliceIdx];
@@ -715,11 +725,15 @@
 
   pCurSlice->uiLastMbQp = pCurLayer->sLayerInfo.pPpsP->iPicInitQp + pCurSlice->sSliceHeaderExt.sSliceHeader.iSliceQpDelta;
 
-  g_pWelsSliceCoding[pNalHeadExt->bIdrFlag][kiDynamicSliceFlag] (pEncCtx, pCurSlice);
+  int32_t iEncReturn = g_pWelsSliceCoding[pNalHeadExt->bIdrFlag][kiDynamicSliceFlag] (pEncCtx, pCurSlice);
+  if (ENC_RETURN_SUCCESS != iEncReturn)
+    return iEncReturn;
 
   BsRbspTrailingBits (pBs);
 
   BsFlush (pBs);
+
+  return ENC_RETURN_SUCCESS;
 }
 
 //pFunc: UpdateMbNeighbourInfoForNextSlice()
@@ -905,7 +919,7 @@
 //  pMb loop
 ///////////////
 // for inter non-dynamic pSlice
-void WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd, const int32_t kiSliceFirstMbXY) {
+int32_t WelsMdInterMbLoop (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd, const int32_t kiSliceFirstMbXY) {
   SWelsMD* pMd					= (SWelsMD*)pWelsMd;
   SBitStringAux* pBs			= pSlice->pSliceBsa;
   SDqLayer* pCurLayer			= pEncCtx->pCurDqLayer;
@@ -923,6 +937,7 @@
   uint16_t* pMvdCostTableInter		= &pEncCtx->pMvdCostTableInter[kiMvdInterTableSize];
   const int32_t kiSliceIdx				= pSlice->uiSliceIdx;
   const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
+  int32_t iEncReturn = ENC_RETURN_SUCCESS;
 
   for (;;) {
     //point to current pMb
@@ -958,7 +973,9 @@
     } else {
       BsWriteUE (pBs, iMbSkipRun);
       iMbSkipRun = 0;
-      WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
+      iEncReturn = WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
+      if (ENC_RETURN_SUCCESS != iEncReturn)
+        return iEncReturn;
     }
 
     //step (7): reconstruct current MB
@@ -984,10 +1001,12 @@
   if (iMbSkipRun) {
     BsWriteUE (pBs, iMbSkipRun);
   }
+
+  return iEncReturn;
 }
 
 // Only for inter dynamic slicing
-void WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd,
+int32_t WelsMdInterMbLoopOverDynamicSlice (sWelsEncCtx* pEncCtx, SSlice* pSlice, void* pWelsMd,
                                         const int32_t kiSliceFirstMbXY) {
   SWelsMD* pMd					= (SWelsMD*)pWelsMd;
   SBitStringAux* pBs			= pSlice->pSliceBsa;
@@ -1007,6 +1026,7 @@
   const int32_t kiSliceIdx				= pSlice->uiSliceIdx;
   const int32_t kiPartitionId			= (kiSliceIdx % pEncCtx->iActiveThreadsNum);
   const uint8_t kuiChromaQpIndexOffset = pCurLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset;
+  int32_t iEncReturn = ENC_RETURN_SUCCESS;
 
   SDynamicSlicingStack sDss;
   sDss.iStartPos = BsGetBitsPos (pBs);
@@ -1063,7 +1083,9 @@
     } else {
       BsWriteUE (pBs, iMbSkipRun);
       iMbSkipRun = 0;
-      WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
+      iEncReturn = WelsSpatialWriteMbSyn (pEncCtx, pSlice, pCurMb);
+      if (ENC_RETURN_SUCCESS != iEncReturn)
+        return iEncReturn;
     }
 
     //DYNAMIC_SLICING_ONE_THREAD - MultiD
@@ -1108,6 +1130,8 @@
   if (iMbSkipRun) {
     BsWriteUE (pBs, iMbSkipRun);
   }
+
+  return iEncReturn;
 }
 
 }//namespace WelsSVCEnc
--- a/codec/encoder/core/src/svc_set_mb_syn_cavlc.cpp
+++ b/codec/encoder/core/src/svc_set_mb_syn_cavlc.cpp
@@ -208,8 +208,20 @@
   }
 }
 
+int32_t CheckBitstreamBuffer(const uint8_t	kuiSliceIdx, sWelsEncCtx* pEncCtx,  SBitStringAux* pBs)
+{
+  const int32_t iLeftLength = pBs->pBufEnd - pBs->pBufPtr - 1;
+  assert(iLeftLength > 0);
+
+  if (iLeftLength < MAX_MACROBLOCK_SIZE_IN_BYTE) {
+    return ENC_RETURN_MEMALLOCERR;
+    //TODO: call the realloc&copy instead
+  }
+  return ENC_RETURN_SUCCESS;
+}
+
 //============================Base Layer CAVLC Writing===============================
-void WelsSpatialWriteMbSyn (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb) {
+int32_t WelsSpatialWriteMbSyn (sWelsEncCtx* pEncCtx, SSlice* pSlice, SMB* pCurMb) {
   SBitStringAux* pBs = pSlice->pSliceBsa;
   SMbCache* pMbCache = &pSlice->sMbCacheInfo;
 
@@ -239,6 +251,9 @@
     pCurMb->uiChromaQp = g_kuiChromaQpTable[CLIP3_QP_0_51 (pCurMb->uiLumaQp +
                                             pEncCtx->pCurDqLayer->sLayerInfo.pPpsP->uiChromaQpIndexOffset)];
   }
+
+  /* Step 4: Check the left buffer */
+  return CheckBitstreamBuffer(pSlice->uiSliceIdx, pEncCtx, pBs);
 }
 
 void WelsWriteMbResidual (SMbCache* sMbCacheInfo, SMB* pCurMb, SBitStringAux* pBs) {
--- a/codec/encoder/plus/src/welsEncoderExt.cpp
+++ b/codec/encoder/plus/src/welsEncoderExt.cpp
@@ -521,22 +521,32 @@
 
 
 int CWelsH264SVCEncoder::EncodeFrame2 (const SSourcePicture**   pSrcPicList, int nSrcPicNum, SFrameBSInfo* pBsInfo) {
-  if (! (pSrcPicList && m_pEncContext && m_bInitialFlag)) {
+  if (!(pSrcPicList && m_pEncContext && m_bInitialFlag) || (nSrcPicNum<=0) ){
     return videoFrameTypeInvalid;
   }
 
   int32_t iFrameTypeReturned = 0;
   int32_t iFrameType = videoFrameTypeInvalid;
+  XMMREG_PROTECT_STORE(CWelsH264SVCEncoder);
+  const int32_t kiEncoderReturn = WelsEncoderEncodeExt (m_pEncContext, pBsInfo, pSrcPicList, nSrcPicNum);
+  XMMREG_PROTECT_LOAD(CWelsH264SVCEncoder);
 
-  if (nSrcPicNum > 0) {
-    XMMREG_PROTECT_STORE(CWelsH264SVCEncoder);
-    iFrameTypeReturned = WelsEncoderEncodeExt (m_pEncContext, pBsInfo, pSrcPicList, nSrcPicNum);
-    XMMREG_PROTECT_LOAD(CWelsH264SVCEncoder);
-  } else {
-    assert (0);
+  switch (kiEncoderReturn) {
+  case ENC_RETURN_MEMALLOCERR:
+    WelsUninitEncoderExt (&m_pEncContext);
     return videoFrameTypeInvalid;
+  case ENC_RETURN_SUCCESS:
+  case ENC_RETURN_CORRECTED:
+    break;//continue processing
+  case ENC_RETURN_UNSUPPORTED_PARA:
+  case ENC_RETURN_UNEXPECTED:
+    return videoFrameTypeInvalid;
+  default:
+    WelsLog (m_pEncContext, WELS_LOG_ERROR, "unexpected return(%d) from WelsEncoderEncodeExt()!\n", kiEncoderReturn);
+    return videoFrameTypeInvalid;
   }
 
+  iFrameTypeReturned = pBsInfo->eOutputFrameType;
   switch (iFrameTypeReturned) {
   case WELS_FRAME_TYPE_P:
     iFrameType	= videoFrameTypeP;
@@ -832,7 +842,7 @@
       return cmInitParaError;
     }
     //adjust to valid range
-    m_pEncContext->pSvcParam->fMaxFrameRate	= WELS_CLIP3 (iValue, MIN_FRAME_RATE, MAX_FRAME_RATE);
+    m_pEncContext->pSvcParam->fMaxFrameRate = WELS_CLIP3 (iValue, MIN_FRAME_RATE, MAX_FRAME_RATE);
     WelsEncoderApplyFrameRate (m_pEncContext->pSvcParam);
   }
   break;