ref: f9080ac0900807a398be120a026b0d78e24d6ada
parent: a73c1e6814973acfe8e2d59346a77f913a77e0fd
author: Sijia Chen <sijchen@cisco.com>
date: Wed Feb 11 12:31:17 EST 2015
complete logic of simulcastavc with sps_pps_listing
--- a/codec/encoder/core/inc/encoder_context.h
+++ b/codec/encoder/core/inc/encoder_context.h
@@ -246,8 +246,8 @@
uint32_t GetNeededSpsNum() {
if (0 == sPSOVector.uiNeededSpsNum) {
- sPSOVector.uiNeededSpsNum = ((SPS_LISTING & pSvcParam->eSpsPpsIdStrategy) ? (MAX_SPS_COUNT) :
- ((pSvcParam->bSimulcastAVC) ? (pSvcParam->iSpatialLayerNum) : (1)));
+ sPSOVector.uiNeededSpsNum = ((SPS_LISTING & pSvcParam->eSpsPpsIdStrategy) ? (MAX_SPS_COUNT) : (1));
+ sPSOVector.uiNeededSpsNum *= ((pSvcParam->bSimulcastAVC) ? (pSvcParam->iSpatialLayerNum) : (1));
}
return sPSOVector.uiNeededSpsNum;
}
@@ -264,6 +264,7 @@
if (0 == sPSOVector.uiNeededPpsNum) {
sPSOVector.uiNeededPpsNum = ((pSvcParam->eSpsPpsIdStrategy & SPS_PPS_LISTING) ? (MAX_PPS_COUNT) :
(1 + pSvcParam->iSpatialLayerNum));
+ sPSOVector.uiNeededPpsNum *= ((pSvcParam->bSimulcastAVC) ? (pSvcParam->iSpatialLayerNum) : (1));
}
return sPSOVector.uiNeededPpsNum;
}
--- a/codec/encoder/core/src/encoder_ext.cpp
+++ b/codec/encoder/core/src/encoder_ext.cpp
@@ -321,7 +321,6 @@
return ENC_RETURN_UNSUPPORTED_PARA;
}
-
//about iMultipleThreadIdc, bDeblockingParallelFlag, iLoopFilterDisableIdc, & uiSliceMode
// (1) Single Thread
// if (THREAD==1)//single thread
@@ -335,9 +334,10 @@
}
// eSpsPpsIdStrategy checkings
- if (pCodingParam->iSpatialLayerNum > 1 && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) {
+ if (pCodingParam->iSpatialLayerNum > 1 && (!pCodingParam->bSimulcastAVC)
+ && (SPS_LISTING & pCodingParam->eSpsPpsIdStrategy)) {
WelsLog (pLogCtx, WELS_LOG_WARNING,
- "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID",
+ "ParamValidationExt(), eSpsPpsIdStrategy setting (%d) with multiple svc SpatialLayers (%d) not supported! eSpsPpsIdStrategy adjusted to CONSTANT_ID",
pCodingParam->eSpsPpsIdStrategy, pCodingParam->iSpatialLayerNum);
pCodingParam->eSpsPpsIdStrategy = CONSTANT_ID;
}
@@ -540,7 +540,8 @@
}
if (pCodingParam->uiMaxNalSize < (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)) {
- WelsLog (pLogCtx, WELS_LOG_ERROR, "ParamValidationExt(), invalid uiMaxNalSize (%d) settings! should be larger than (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)(%d)",
+ WelsLog (pLogCtx, WELS_LOG_ERROR,
+ "ParamValidationExt(), invalid uiMaxNalSize (%d) settings! should be larger than (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE)(%d)",
pCodingParam->uiMaxNalSize, (NAL_HEADER_ADD_0X30BYTES + MAX_MACROBLOCK_SIZE_IN_BYTE));
return ENC_RETURN_UNSUPPORTED_PARA;
}
@@ -3140,6 +3141,7 @@
pCtx->iPosBsBuffer += iNalSize;
return ENC_RETURN_SUCCESS;
}
+
int32_t WelsWriteOnePPS (sWelsEncCtx* pCtx, const int32_t kiPpsIdx, int32_t& iNalSize) {
//TODO
int32_t iNal = pCtx->pOut->iNalIndex;
@@ -3159,6 +3161,29 @@
return ENC_RETURN_SUCCESS;
}
+void UpdatePpsList (sWelsEncCtx* pCtx) {
+ assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM);
+
+ //Generate PPS LIST
+ int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum;
+
+ for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) {
+ for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) {
+ pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT);
+ }
+ }
+
+ for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) {
+ memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS));
+ pCtx->pPPSArray[iPpsId].iPpsId = iPpsId;
+ pCtx->iPpsNum++;
+ }
+
+ assert (pCtx->iPpsNum == MAX_PPS_COUNT);
+ pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum;
+
+}
+
/*!
* \brief write all parameter sets introduced in SVC extension
* \return writing results, success or error
@@ -3245,29 +3270,11 @@
}
/* write all PPS */
- iIdx = 0;
if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) {
- assert (pCtx->iPpsNum <= MAX_DQ_LAYER_NUM);
-
- //Generate PPS LIST
- int32_t iPpsId = 0, iUsePpsNum = pCtx->iPpsNum;
-
- for (int32_t iIdrRound = 0; iIdrRound < MAX_PPS_COUNT; iIdrRound++) {
- for (iPpsId = 0; iPpsId < pCtx->iPpsNum; iPpsId++) {
- pCtx->sPSOVector.iPpsIdList[iPpsId][iIdrRound] = ((iIdrRound * iUsePpsNum + iPpsId) % MAX_PPS_COUNT);
- }
- }
-
- for (iPpsId = iUsePpsNum; iPpsId < MAX_PPS_COUNT; iPpsId++) {
- memcpy (& (pCtx->pPPSArray[iPpsId]), & (pCtx->pPPSArray[iPpsId % iUsePpsNum]), sizeof (SWelsPPS));
- pCtx->pPPSArray[iPpsId].iPpsId = iPpsId;
- pCtx->iPpsNum++;
- }
-
- assert (pCtx->iPpsNum == MAX_PPS_COUNT);
- pCtx->sPSOVector.uiInUsePpsNum = pCtx->iPpsNum;
+ UpdatePpsList (pCtx);
}
+ iIdx = 0;
while (iIdx < pCtx->iPpsNum) {
if ((INCREASING_ID & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
//para_set_type = 2: PPS, use MAX_PPS_COUNT
@@ -3479,7 +3486,6 @@
iCountNal = 1;
//finish writing one NAL
-
pLayerBsInfo->uiSpatialId = iIdx;
pLayerBsInfo->uiTemporalId = 0;
pLayerBsInfo->uiQualityId = 0;
@@ -3511,7 +3517,6 @@
iCountNal = 1;
//finish writing one NAL
-
pLayerBsInfo->uiSpatialId = iIdx;
pLayerBsInfo->uiTemporalId = 0;
pLayerBsInfo->uiQualityId = 0;
@@ -3538,7 +3543,88 @@
return iReturn;
}
+int32_t WriteSavcParaset_Listing (sWelsEncCtx* pCtx, const int32_t kiSpatialNum,
+ SLayerBSInfo*& pLayerBsInfo, int32_t& iLayerNum, int32_t& iFrameSize) {
+ int32_t iNonVclSize = 0, iCountNal = 0, iReturn;
+ // write SPS
+ iNonVclSize = 0;
+
+ for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) {
+ iCountNal = 0;
+ for (int32_t iIdx = 0; iIdx < pCtx->iSpsNum; iIdx++) {
+ //writing one NAL
+ int32_t iNalSize = 0;
+ iReturn = WelsWriteOneSPS (pCtx, iIdx, iNalSize);
+ WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
+
+ pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
+ iNonVclSize += iNalSize;
+ iCountNal ++;
+ //finish writing one NAL
+ }
+
+ pLayerBsInfo->uiSpatialId = iSpatialId;
+ pLayerBsInfo->uiTemporalId = 0;
+ pLayerBsInfo->uiQualityId = 0;
+ pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
+ pLayerBsInfo->iNalCount = iCountNal;
+
+ //point to next pLayerBsInfo
+ ++ pLayerBsInfo;
+ pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
+ pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
+ //update for external countings
+ iCountNal = 0;
+ ++ iLayerNum;
+ }
+
+ // write PPS
+ if ((SPS_PPS_LISTING == pCtx->pSvcParam->eSpsPpsIdStrategy) && (pCtx->iPpsNum < MAX_PPS_COUNT)) {
+ UpdatePpsList (pCtx);
+ }
+
+ //TODO: under new strategy, will PPS be correctly updated?
+ for (int32_t iSpatialId = 0; iSpatialId < kiSpatialNum; iSpatialId++) {
+ iCountNal = 0;
+ for (int32_t iIdx = 0; iIdx < pCtx->iPpsNum; iIdx++) {
+ //writing one NAL
+ int32_t iNalSize = 0;
+ iReturn = WelsWriteOnePPS (pCtx, iIdx, iNalSize);
+ WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS)
+
+ pLayerBsInfo->pNalLengthInByte[iCountNal] = iNalSize;
+ iNonVclSize += iNalSize;
+ iCountNal ++;
+ //finish writing one NAL
+ }
+
+ pLayerBsInfo->uiSpatialId = iSpatialId;
+ pLayerBsInfo->uiTemporalId = 0;
+ pLayerBsInfo->uiQualityId = 0;
+ pLayerBsInfo->uiLayerType = NON_VIDEO_CODING_LAYER;
+ pLayerBsInfo->iNalCount = iCountNal;
+
+ //point to next pLayerBsInfo
+ ++ pLayerBsInfo;
+ pLayerBsInfo->pBsBuf = pCtx->pFrameBs + pCtx->iPosBsBuffer;
+ pLayerBsInfo->pNalLengthInByte = (pLayerBsInfo - 1)->pNalLengthInByte + iCountNal;
+ //update for external countings
+ iCountNal = 0;
+ ++ iLayerNum;
+ }
+
+ // to check number of layers / nals / slices dependencies
+ if (iLayerNum > MAX_LAYER_NUM_OF_FRAME) {
+ WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WriteSavcParaset(), iLayerNum(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!",
+ iLayerNum, MAX_LAYER_NUM_OF_FRAME);
+ return ENC_RETURN_UNEXPECTED;
+ }
+
+ iFrameSize += iNonVclSize;
+ return iReturn;
+}
+
/*!
* \brief core svc encoding process
*
@@ -3637,9 +3723,13 @@
++ pCtx->uiIdrPicId;
// write parameter sets bitstream or SEI/SSEI (if any) here
// TODO: use function pointer instead
- pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC)
- ? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))
- : (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)));
+ if (! (SPS_LISTING & pCtx->pSvcParam->eSpsPpsIdStrategy)) {
+ pCtx->iEncoderError = ((!pSvcParam->bSimulcastAVC)
+ ? (WriteSsvcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize))
+ : (WriteSavcParaset (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize)));
+ } else {
+ pCtx->iEncoderError = WriteSavcParaset_Listing (pCtx, iSpatialNum, pLayerBsInfo, iLayerNum, iFrameSize);
+ }
WELS_VERIFY_RETURN_IFNEQ (pCtx->iEncoderError, ENC_RETURN_SUCCESS)
}
@@ -4217,6 +4307,33 @@
pFbi->eFrameType = eFrameType;
pFbi->iFrameSizeInBytes = iFrameSize;
+
+#ifdef _DEBUG
+ if (pFbi->iLayerNum > MAX_LAYER_NUM_OF_FRAME) {
+ WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WelsEncoderEncodeExt(), iLayerNum(%d) > MAX_LAYER_NUM_OF_FRAME(%d)!",
+ pFbi->iLayerNum, MAX_LAYER_NUM_OF_FRAME);
+ return ENC_RETURN_UNEXPECTED;
+ }
+
+ int32_t iTotalNal = 0;
+ for (int32_t k = 0; k < pFbi->iLayerNum; k++) {
+ iTotalNal += pFbi->sLayerInfo[k].iNalCount;
+
+ if ((pCtx->iActiveThreadsNum > 1) && (MAX_NAL_UNITS_IN_LAYER < pFbi->sLayerInfo[k].iNalCount)) {
+ WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR,
+ "WelsEncoderEncodeExt(), iCountNumNals(%d) > MAX_NAL_UNITS_IN_LAYER(%d) under multi-thread(%d) NOT supported!",
+ pFbi->sLayerInfo[k].iNalCount, MAX_NAL_UNITS_IN_LAYER), pCtx->iActiveThreadsNum;
+ return ENC_RETURN_UNEXPECTED;
+ }
+ }
+
+ if (iTotalNal > pCtx->pOut->iCountNals) {
+ WelsLog (& pCtx->sLogCtx, WELS_LOG_ERROR, "WelsEncoderEncodeExt(), iTotalNal(%d) > iCountNals(%d)!",
+ iTotalNal, pCtx->pOut->iCountNals);
+ return ENC_RETURN_UNEXPECTED;
+ }
+#endif
+
return ENC_RETURN_SUCCESS;
}
--- a/test/api/encode_decode_api_test.cpp
+++ b/test/api/encode_decode_api_test.cpp
@@ -224,6 +224,80 @@
fwrite (info.sLayerInfo[0].pBsBuf, iLen, 1, pfEnc);
}
}
+
+ void TestOneSimulcastAVC (SEncParamExt* pParam, ISVCDecoder** decoder, unsigned char** pBsBuf, int iSpatialLayerNum,
+ int iEncFrameNum,
+ int iCallTimes) {
+//#define DEBUG_FILE_SAVE4
+ int aLen[MAX_SPATIAL_LAYER_NUM] = {0, 0, 0, 0};
+#ifdef DEBUG_FILE_SAVE4
+ FILE* fEnc[MAX_SPATIAL_LAYER_NUM];
+ if (iCallTimes == 0) {
+ fEnc[0] = fopen ("enc00.264", "wb");
+ fEnc[1] = fopen ("enc01.264", "wb");
+ fEnc[2] = fopen ("enc02.264", "wb");
+ fEnc[3] = fopen ("enc03.264", "wb");
+ } else {
+ fEnc[0] = fopen ("enc10.264", "wb");
+ fEnc[1] = fopen ("enc11.264", "wb");
+ fEnc[2] = fopen ("enc12.264", "wb");
+ fEnc[3] = fopen ("enc13.264", "wb");
+ }
+#endif
+
+ int rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, pParam);
+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed pParam: rv = " << rv;
+
+ int iIdx;
+ //begin testing
+ for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
+ int iResult;
+ int iLayerLen = 0;
+ unsigned char* pData[3] = { NULL };
+
+ InitialEncDec (pParam->iPicWidth, pParam->iPicHeight);
+ EncodeOneFrame (0);
+
+ // init
+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
+ aLen[iIdx] = 0;
+ }
+ for (int iLayer = 0; iLayer < info.iLayerNum; ++iLayer) {
+ iLayerLen = 0;
+ const SLayerBSInfo& layerInfo = info.sLayerInfo[iLayer];
+ for (int iNal = 0; iNal < layerInfo.iNalCount; ++iNal) {
+ iLayerLen += layerInfo.pNalLengthInByte[iNal];
+ }
+
+ iIdx = layerInfo.uiSpatialId;
+ EXPECT_TRUE (iIdx < iSpatialLayerNum) << "iIdx = " << iIdx << ", iSpatialLayerNum = " << iSpatialLayerNum;
+ memcpy ((pBsBuf[iIdx] + aLen[iIdx]), layerInfo.pBsBuf, iLayerLen * sizeof (unsigned char));
+ aLen[iIdx] += iLayerLen;
+ }
+
+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
+ pData[0] = pData[1] = pData[2] = 0;
+ memset (&dstBufInfo_, 0, sizeof (SBufferInfo));
+
+#ifdef DEBUG_FILE_SAVE4
+ fwrite (pBsBuf[iIdx], aLen[iIdx], 1, fEnc[iIdx]);
+#endif
+ iResult = decoder[iIdx]->DecodeFrame2 (pBsBuf[iIdx], aLen[iIdx], pData, &dstBufInfo_);
+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << ", LayerIdx=" << iIdx;
+
+ iResult = decoder[iIdx]->DecodeFrame2 (NULL, 0, pData, &dstBufInfo_);
+ EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << ", LayerIdx=" << iIdx;
+ EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
+ }
+ }
+
+#ifdef DEBUG_FILE_SAVE4
+ fclose (fEnc[0]);
+ fclose (fEnc[1]);
+ fclose (fEnc[2]);
+ fclose (fEnc[3]);
+#endif
+ }
};
class EncodeDecodeTestAPI : public ::testing::TestWithParam<EncodeDecodeFileParamBase>, public EncodeDecodeTestAPIBase {
@@ -3194,7 +3268,7 @@
ASSERT_EQ (0, rv);
}
- iEncFrameNum = 1;
+ iEncFrameNum = 10;
for (int iFrame = 0; iFrame < iEncFrameNum; iFrame++) {
int iResult;
int iLayerLen = 0;
@@ -3237,9 +3311,73 @@
EXPECT_TRUE (iResult == cmResultSuccess) << "iResult=" << iResult << "LayerIdx=" << iIdx;
EXPECT_EQ (dstBufInfo_.iBufferStatus, 1) << "LayerIdx=" << iIdx;
}
+ }
+ for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
+ free (pBsBuf[iIdx]);
+
+ if (decoder[iIdx] != NULL) {
+ decoder[iIdx]->Uninitialize();
+ WelsDestroyDecoder (decoder[iIdx]);
+ }
}
+}
+TEST_F (EncodeDecodeTestAPI, SimulcastAVC_SPS_PPS_LISTING) {
+ 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;
+ int iEncFrameNum = WelsClip3 ((rand() % ENCODE_FRAME_NUM) + 1, 1, ENCODE_FRAME_NUM);
+ int iSliceNum = 1;
+
+ // prepare params
+ SEncParamExt sParam1;
+ SEncParamExt sParam2;
+ encoder_->GetDefaultParams (&sParam1);
+ prepareParamDefault (iSpatialLayerNum, iSliceNum, iWidth, iHeight, fFrameRate, &sParam1);
+ //set flag of SPS_PPS_LISTING
+ sParam1.eSpsPpsIdStrategy = SPS_PPS_LISTING;//SPS_LISTING;//
+ //set flag of bSimulcastAVC
+ sParam1.bSimulcastAVC = true;
+ //prepare param2
+ memcpy (&sParam2, &sParam1, sizeof (SEncParamExt));
+ sParam2.sSpatialLayers[0].iVideoWidth = (sParam1.sSpatialLayers[0].iVideoWidth / 2);
+ sParam2.sSpatialLayers[0].iVideoHeight = (sParam1.sSpatialLayers[0].iVideoHeight / 2);
+
+ int rv = encoder_->InitializeExt (&sParam1);
+ ASSERT_TRUE (rv == cmResultSuccess) << "Init Failed sParam1: rv = " << rv;;
+ rv = encoder_->SetOption (ENCODER_OPTION_SVC_ENCODE_PARAM_EXT, &sParam2);
+ ASSERT_TRUE (rv == cmResultSuccess) << "SetOption Failed sParam2: rv = " << rv;
+
+ unsigned char* pBsBuf[MAX_SPATIAL_LAYER_NUM];
+ ISVCDecoder* decoder[MAX_SPATIAL_LAYER_NUM];
+
+ int iIdx = 0;
+
+ //create decoder
+ for (int iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
+ pBsBuf[iIdx] = static_cast<unsigned char*> (malloc (iWidth * iHeight * 3 * sizeof (unsigned char) / 2));
+ EXPECT_TRUE (pBsBuf[iIdx] != NULL);
+
+ long rv = WelsCreateDecoder (&decoder[iIdx]);
+ ASSERT_EQ (0, rv);
+ EXPECT_TRUE (decoder[iIdx] != NULL);
+
+ SDecodingParam decParam;
+ memset (&decParam, 0, sizeof (SDecodingParam));
+ decParam.eOutputColorFormat = videoFormatI420;
+ decParam.uiTargetDqLayer = UCHAR_MAX;
+ decParam.eEcActiveIdc = ERROR_CON_SLICE_COPY;
+ decParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
+
+ rv = decoder[iIdx]->Initialize (&decParam);
+ ASSERT_EQ (0, rv);
+ }
+
+ TestOneSimulcastAVC (&sParam1, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 0);
+ TestOneSimulcastAVC (&sParam2, decoder, pBsBuf, iSpatialLayerNum, iEncFrameNum, 1);
+
for (iIdx = 0; iIdx < iSpatialLayerNum; iIdx++) {
free (pBsBuf[iIdx]);
@@ -3247,9 +3385,7 @@
decoder[iIdx]->Uninitialize();
WelsDestroyDecoder (decoder[iIdx]);
}
-#ifdef DEBUG_FILE_SAVE3
- fclose (fEnc[iIdx]);
-#endif
+
}
}
@@ -3398,5 +3534,4 @@
fclose (pFile);
}
}
-