WelsErrorType CWelsTaskManageBase::CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiCurDid) { CWelsBaseTask* pTask = NULL; int32_t kiTaskCount; uint32_t uiSliceMode = pEncCtx->pSvcParam->sSpatialLayers[kiCurDid].sSliceArgument.uiSliceMode; if (uiSliceMode != SM_SIZELIMITED_SLICE) { kiTaskCount = m_iTaskNum[kiCurDid] = pEncCtx->pSvcParam->sSpatialLayers[kiCurDid].sSliceArgument.uiSliceNum; } else { kiTaskCount = m_iTaskNum[kiCurDid] = pEncCtx->iActiveThreadsNum; } for (int idx = 0; idx < kiTaskCount; idx++) { pTask = WELS_NEW_OP (CWelsUpdateMbMapTask (this, pEncCtx, idx), CWelsUpdateMbMapTask); WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask) m_cPreEncodingTaskList[kiCurDid]->push_back (pTask); } for (int idx = 0; idx < kiTaskCount; idx++) { if (uiSliceMode==SM_SIZELIMITED_SLICE) { pTask = WELS_NEW_OP (CWelsConstrainedSizeSlicingEncodingTask (this, pEncCtx, idx), CWelsConstrainedSizeSlicingEncodingTask); } else { if (pEncCtx->pSvcParam->bUseLoadBalancing) { pTask = WELS_NEW_OP (CWelsLoadBalancingSlicingEncodingTask (this, pEncCtx, idx), CWelsLoadBalancingSlicingEncodingTask); } else { pTask = WELS_NEW_OP (CWelsSliceEncodingTask (this, pEncCtx, idx), CWelsSliceEncodingTask); } } WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask) m_cEncodingTaskList[kiCurDid]->push_back (pTask); } //printf ("CWelsTaskManageBase CreateTasks m_iThreadNum %d kiTaskCount=%d\n", m_iThreadNum, kiTaskCount); return ENC_RETURN_SUCCESS; }
/* * request memory blocks for decoder avc part */ int32_t WelsRequestMem (PWelsDecoderContext pCtx, const int32_t kiMbWidth, const int32_t kiMbHeight) { const int32_t kiPicWidth = kiMbWidth << 4; const int32_t kiPicHeight = kiMbHeight << 4; int32_t iErr = ERR_NONE; int32_t iListIdx = 0; //, mb_blocks = 0; int32_t iPicQueueSize = 0; // adaptive size of picture queue, = (pSps->iNumRefFrames x 2) bool bNeedChangePicQueue = true; WELS_VERIFY_RETURN_IF (ERR_INFO_INVALID_PARAM, (NULL == pCtx || kiPicWidth <= 0 || kiPicHeight <= 0)) // Fixed the issue about different gop size over last, 5/17/2010 // get picture queue size currently iPicQueueSize = GetTargetRefListSize (pCtx); // adaptive size of picture queue, = (pSps->iNumRefFrames x 2) pCtx->iPicQueueNumber = iPicQueueSize; if (pCtx->pPicBuff[LIST_0] != NULL && pCtx->pPicBuff[LIST_0]->iCapacity == iPicQueueSize) // comparing current picture queue size requested and previous allocation picture queue bNeedChangePicQueue = false; // HD based pic buffer need consider memory size consumed when switch from 720p to other lower size WELS_VERIFY_RETURN_IF (ERR_NONE, pCtx->bHaveGotMemory && (kiPicWidth == pCtx->iImgWidthInPixel && kiPicHeight == pCtx->iImgHeightInPixel) && (!bNeedChangePicQueue)) // have same scaled buffer // sync update pRefList WelsResetRefPic (pCtx); // added to sync update ref list due to pictures are free // for Recycled_Pic_Queue for (iListIdx = LIST_0; iListIdx < LIST_A; ++ iListIdx) { PPicBuff* ppPic = &pCtx->pPicBuff[iListIdx]; if (NULL != ppPic && NULL != *ppPic) { DestroyPicBuff (ppPic); } } pCtx->pPreviousDecodedPictureInDpb = NULL; // currently only active for LIST_0 due to have no B frames iErr = CreatePicBuff (pCtx, &pCtx->pPicBuff[LIST_0], iPicQueueSize, kiPicWidth, kiPicHeight); if (iErr != ERR_NONE) return iErr; pCtx->iImgWidthInPixel = kiPicWidth; // target width of image to be reconstruted while decoding pCtx->iImgHeightInPixel = kiPicHeight; // target height of image to be reconstruted while decoding pCtx->bHaveGotMemory = true; // global memory for decoder context related is requested pCtx->pDec = NULL; // need prefetch a new pic due to spatial size changed return ERR_NONE; }
int32_t CWelsPreProcess::AllocSpatialPictures (sWelsEncCtx* pCtx, SWelsSvcCodingParam* pParam) { CMemoryAlign* pMa = pCtx->pMemAlign; const int32_t kiDlayerCount = pParam->iSpatialLayerNum; int32_t iDlayerIndex = 0; // spatial pictures iDlayerIndex = 0; do { const int32_t kiPicWidth = pParam->sDependencyLayers[iDlayerIndex].iFrameWidth; const int32_t kiPicHeight = pParam->sDependencyLayers[iDlayerIndex].iFrameHeight; const uint8_t kuiLayerInTemporal = 2 + WELS_MAX (pParam->sDependencyLayers[iDlayerIndex].iHighestTemporalId, 1); const uint8_t kuiRefNumInTemporal = kuiLayerInTemporal + pParam->iLTRRefNum; uint8_t i = 0; do { SPicture* pPic = AllocPicture (pMa, kiPicWidth, kiPicHeight, false); WELS_VERIFY_RETURN_IF(1, (NULL == pPic)) m_pSpatialPic[iDlayerIndex][i] = pPic; ++ i; } while (i < kuiRefNumInTemporal); m_uiSpatialLayersInTemporal[iDlayerIndex] = kuiLayerInTemporal; m_uiSpatialPicNum[iDlayerIndex] = kuiRefNumInTemporal; ++ iDlayerIndex; } while (iDlayerIndex < kiDlayerCount); return 0; }
/* * set colorspace format in decoder */ int32_t DecoderSetCsp (PWelsDecoderContext pCtx, const int32_t kiColorFormat) { WELS_VERIFY_RETURN_IF (1, (NULL == pCtx)); pCtx->iOutputColorFormat = kiColorFormat; if (pCtx->pParam != NULL) { pCtx->pParam->iOutputColorFormat = kiColorFormat; } return 0; }
WelsErrorType CWelsTaskManageBase::CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount) { CWelsBaseTask* pTask = NULL; for (int idx = 0; idx < kiTaskCount; idx++) { pTask = WELS_NEW_OP (CWelsSliceEncodingTask (pEncCtx, idx), CWelsSliceEncodingTask); WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask) m_cTaskList->push_back (pTask); } m_iTaskNum = kiTaskCount; //printf("CWelsTaskManageBase CreateTasks m_iThreadNum %d kiTaskCount=%d\n", m_iThreadNum, kiTaskCount); return ENC_RETURN_SUCCESS; }
//TODO: at present there is no diff betweenCWelsTaskManageParallel and CWelsTaskManageBase, to finish later WelsErrorType CWelsTaskManageParallel::ExecuteTasks() { WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == m_pThreadPool) // need lock here? m_iWaitTaskNum = static_cast<int32_t> (m_cTaskList->size()); while (NULL != m_cTaskList->begin()) { m_pThreadPool->QueueTask (m_cTaskList->begin()); m_cTaskList->pop_front(); } WelsEventWait (&m_hTaskEvent); return ENC_RETURN_SUCCESS; }
WelsErrorType CWelsTaskManageBase::CreateTasks (sWelsEncCtx* pEncCtx, const int32_t kiTaskCount) { CWelsBaseTask* pTask = NULL; for (int idx = 0; idx < kiTaskCount; idx++) { pTask = WELS_NEW_OP (CWelsUpdateMbMapTask (pEncCtx, idx), CWelsUpdateMbMapTask); WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask) m_cPreEncodingTaskList->push_back (pTask); } for (int idx = 0; idx < kiTaskCount; idx++) { if (pEncCtx->pSvcParam->bUseLoadBalancing) { pTask = WELS_NEW_OP (CWelsLoadBalancingSlicingEncodingTask (pEncCtx, idx), CWelsLoadBalancingSlicingEncodingTask); } else { pTask = WELS_NEW_OP (CWelsSliceEncodingTask (pEncCtx, idx), CWelsSliceEncodingTask); } WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == pTask) m_cEncodingTaskList->push_back (pTask); } m_iTotalTaskNum = kiTaskCount; //printf ("CWelsTaskManageBase CreateTasks m_iThreadNum %d kiTaskCount=%d\n", m_iThreadNum, kiTaskCount); return ENC_RETURN_SUCCESS; }
WelsErrorType CWelsTaskManageBase::Init (sWelsEncCtx* pEncCtx) { m_pEncCtx = pEncCtx; m_iThreadNum = m_pEncCtx->pSvcParam->iMultipleThreadIdc; m_pThreadPool = WELS_NEW_OP (WelsCommon::CWelsThreadPool (this, m_iThreadNum), WelsCommon::CWelsThreadPool); WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == m_pThreadPool) m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_ENCODING] = m_cEncodingTaskList; m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_UPDATEMBMAP] = m_cPreEncodingTaskList; m_iCurrentTaskNum = pEncCtx->pSvcParam->sSpatialLayers[0].sSliceArgument.uiSliceNum; //printf ("CWelsTaskManageBase Init m_iThreadNum %d m_iCurrentTaskNum %d pEncCtx->iMaxSliceCount %d\n", m_iThreadNum, m_iCurrentTaskNum, pEncCtx->iMaxSliceCount); return CreateTasks (pEncCtx, pEncCtx->iMaxSliceCount); }
/* * set colorspace format in decoder */ int32_t DecoderSetCsp (PWelsDecoderContext pCtx, const int32_t kiColorFormat) { WELS_VERIFY_RETURN_IF (1, (NULL == pCtx)); pCtx->eOutputColorFormat = (EVideoFormatType) kiColorFormat; if (pCtx->pParam != NULL) { pCtx->pParam->eOutputColorFormat = (EVideoFormatType) kiColorFormat; } //For now, support only videoFormatI420! if (kiColorFormat != (int32_t) videoFormatI420) { WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "Support I420 output only for now! Change to I420...\n"); pCtx->pParam->eOutputColorFormat = pCtx->eOutputColorFormat = videoFormatI420; } return 0; }
WelsErrorType CWelsTaskManageBase::Init (sWelsEncCtx* pEncCtx) { m_pEncCtx = pEncCtx; m_iThreadNum = m_pEncCtx->pSvcParam->iMultipleThreadIdc; m_pThreadPool = WELS_NEW_OP (WelsCommon::CWelsThreadPool (this, m_iThreadNum), WelsCommon::CWelsThreadPool); WELS_VERIFY_RETURN_IF (ENC_RETURN_MEMALLOCERR, NULL == m_pThreadPool) int32_t iReturn = 0; for (int32_t iDid = 0; iDid < MAX_DEPENDENCY_LAYER; iDid++) { m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_ENCODING][iDid] = m_cEncodingTaskList[iDid]; m_pcAllTaskList[CWelsBaseTask::WELS_ENC_TASK_UPDATEMBMAP][iDid] = m_cPreEncodingTaskList[iDid]; iReturn |= CreateTasks (pEncCtx, iDid); } //printf ("CWelsTaskManageBase Init m_iThreadNum %d m_iCurrentTaskNum %d pEncCtx->iMaxSliceCount %d\n", m_iThreadNum, m_iCurrentTaskNum, pEncCtx->iMaxSliceCount); return iReturn; }
/*! * \brief Initialize slice segment (Single/multiple slices) * * \param pSliceSeg SSlice segment to be initialized * \param uiSliceMode SSlice mode * \param multi_slice_argv Multiple slices argument * \param iMbWidth MB width * \param iMbHeight MB height * * \return 0 - successful; none 0 - failed; */ int32_t InitSliceSegment (SSliceCtx* pSliceSeg, CMemoryAlign* pMa, SMulSliceOption* pMso, const int32_t kiMbWidth, const int32_t kiMbHeight) { const int32_t kiCountMbNum = kiMbWidth * kiMbHeight; SliceMode uiSliceMode = SM_SINGLE_SLICE; if (NULL == pSliceSeg || NULL == pMso || kiMbWidth == 0 || kiMbHeight == 0) return 1; uiSliceMode = pMso->uiSliceMode; if (pSliceSeg->iMbNumInFrame == kiCountMbNum && pSliceSeg->iMbWidth == kiMbWidth && pSliceSeg->iMbHeight == kiMbHeight && pSliceSeg->uiSliceMode == uiSliceMode && pSliceSeg->pOverallMbMap != NULL) return 0; else if (pSliceSeg->iMbNumInFrame != kiCountMbNum) { if (NULL != pSliceSeg->pOverallMbMap) { pMa->WelsFree (pSliceSeg->pOverallMbMap, "pSliceSeg->pOverallMbMap"); pSliceSeg->pOverallMbMap = NULL; } if (NULL != pSliceSeg->pFirstMbInSlice) { pMa->WelsFree (pSliceSeg->pFirstMbInSlice, "pSliceSeg->pFirstMbInSlice"); pSliceSeg->pFirstMbInSlice = NULL; } if (NULL != pSliceSeg->pCountMbNumInSlice) { pMa->WelsFree (pSliceSeg->pCountMbNumInSlice, "pSliceSeg->pCountMbNumInSlice"); pSliceSeg->pCountMbNumInSlice = NULL; } // just for safe pSliceSeg->iSliceNumInFrame = 0; pSliceSeg->iMbNumInFrame = 0; pSliceSeg->iMbWidth = 0; pSliceSeg->iMbHeight = 0; pSliceSeg->uiSliceMode = SM_SINGLE_SLICE; // sigle in default } if (SM_SINGLE_SLICE == uiSliceMode) { pSliceSeg->pOverallMbMap = (uint8_t*)pMa->WelsMalloc (kiCountMbNum * sizeof (uint8_t), "pSliceSeg->pOverallMbMap"); WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pOverallMbMap) pSliceSeg->iSliceNumInFrame = 1; pSliceSeg->pFirstMbInSlice = (int16_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int16_t), "pSliceSeg->pFirstMbInSlice"); WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pFirstMbInSlice) pSliceSeg->pCountMbNumInSlice = (int32_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int32_t), "pSliceSeg->pCountMbNumInSlice"); WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pCountMbNumInSlice) pSliceSeg->uiSliceMode = uiSliceMode; pSliceSeg->iMbWidth = kiMbWidth; pSliceSeg->iMbHeight = kiMbHeight; pSliceSeg->iMbNumInFrame = kiCountMbNum; pSliceSeg->pCountMbNumInSlice[0] = kiCountMbNum; pSliceSeg->pFirstMbInSlice[0] = 0; return AssignMbMapSingleSlice (pSliceSeg->pOverallMbMap, kiCountMbNum, sizeof (pSliceSeg->pOverallMbMap[0])); } else { //if ( SM_MULTIPLE_SLICE == uiSliceMode ) if (uiSliceMode != SM_FIXEDSLCNUM_SLICE && uiSliceMode != SM_ROWMB_SLICE && uiSliceMode != SM_RASTER_SLICE && uiSliceMode != SM_DYN_SLICE) return 1; pSliceSeg->pOverallMbMap = (uint8_t*)pMa->WelsMalloc (kiCountMbNum * sizeof (uint8_t), "pSliceSeg->pOverallMbMap"); WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pOverallMbMap) //SM_DYN_SLICE: init, set pSliceSeg->iSliceNumInFrame = 1; pSliceSeg->iSliceNumInFrame = GetInitialSliceNum (kiMbWidth, kiMbHeight, pMso); if (-1 == pSliceSeg->iSliceNumInFrame) return 1; pSliceSeg->pCountMbNumInSlice = (int32_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int32_t), "pSliceSeg->pCountMbNumInSlice"); WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pCountMbNumInSlice) pSliceSeg->pFirstMbInSlice = (int16_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int16_t), "pSliceSeg->pFirstMbInSlice"); WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pFirstMbInSlice) pSliceSeg->uiSliceMode = pMso->uiSliceMode; pSliceSeg->iMbWidth = kiMbWidth; pSliceSeg->iMbHeight = kiMbHeight; pSliceSeg->iMbNumInFrame = kiCountMbNum; if (SM_DYN_SLICE == pMso->uiSliceMode) { if (0 < pMso->sSliceArgument.uiSliceSizeConstraint) { pSliceSeg->uiSliceSizeConstraint = pMso->sSliceArgument.uiSliceSizeConstraint; } else { return 1; } } else { pSliceSeg->uiSliceSizeConstraint = DEFAULT_MAXPACKETSIZE_CONSTRAINT; } // about "iMaxSliceNumConstraint" //only used in SM_DYN_SLICE mode so far, //now follows NAL_UNIT_CONSTRAINT, (see definition) //will be adjusted under MT if there is limitation on iLayerNum pSliceSeg->iMaxSliceNumConstraint = MAX_SLICES_NUM; return AssignMbMapMultipleSlices (pSliceSeg, pMso); } return 0; }
int32_t WelsMarkAsRef (PWelsDecoderContext pCtx) { PRefPic pRefPic = &pCtx->sRefPic; PRefPicMarking pRefPicMarking = pCtx->pCurDqLayer->pRefPicMarking; PAccessUnit pCurAU = pCtx->pAccessUnitList; bool bIsIDRAU = false; uint32_t j; int32_t iRet = ERR_NONE; pCtx->pDec->uiQualityId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiQualityId; pCtx->pDec->uiTemporalId = pCtx->pCurDqLayer->sLayerInfo.sNalHeaderExt.uiTemporalId; pCtx->pDec->iSpsId = pCtx->pSps->iSpsId; pCtx->pDec->iPpsId = pCtx->pPps->iPpsId; for (j = pCurAU->uiStartPos; j <= pCurAU->uiEndPos; j++) { if (pCurAU->pNalUnitsList[j]->sNalHeaderExt.sNalUnitHeader.eNalUnitType == NAL_UNIT_CODED_SLICE_IDR || pCurAU->pNalUnitsList[j]->sNalHeaderExt.bIdrFlag) { bIsIDRAU = true; break; } } if (bIsIDRAU) { if (pRefPicMarking->bLongTermRefFlag) { pCtx->sRefPic.iMaxLongTermFrameIdx = 0; AddLongTermToList (pRefPic, pCtx->pDec, 0); } else { pCtx->sRefPic.iMaxLongTermFrameIdx = -1; } } else { if (pRefPicMarking->bAdaptiveRefPicMarkingModeFlag) { iRet = MMCO (pCtx, pRefPicMarking); if (iRet != ERR_NONE) { if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { iRet = RemainOneBufferInDpbForEC (pCtx); WELS_VERIFY_RETURN_IF (iRet, iRet); } else { return iRet; } } if (pCtx->bLastHasMmco5) { pCtx->pDec->iFrameNum = 0; pCtx->pDec->iFramePoc = 0; } } else { iRet = SlidingWindow (pCtx); if (iRet != ERR_NONE) { if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { iRet = RemainOneBufferInDpbForEC (pCtx); WELS_VERIFY_RETURN_IF (iRet, iRet); } else { return iRet; } } } } if (!pCtx->pDec->bIsLongRef) { if (pRefPic->uiLongRefCount[LIST_0] + pRefPic->uiShortRefCount[LIST_0] >= WELS_MAX (1, pCtx->pSps->iNumRefFrames)) { if (pCtx->eErrorConMethod != ERROR_CON_DISABLE) { iRet = RemainOneBufferInDpbForEC (pCtx); WELS_VERIFY_RETURN_IF (iRet, iRet); } else { return ERR_INFO_INVALID_MMCO_REF_NUM_OVERFLOW; } } iRet = AddShortTermToList (pRefPic, pCtx->pDec); } return iRet; }
/* * request memory blocks for decoder avc part */ int32_t WelsRequestMem (PWelsDecoderContext pCtx, const int32_t kiMbWidth, const int32_t kiMbHeight, bool& bReallocFlag) { const int32_t kiPicWidth = kiMbWidth << 4; const int32_t kiPicHeight = kiMbHeight << 4; int32_t iErr = ERR_NONE; int32_t iListIdx = 0; //, mb_blocks = 0; int32_t iPicQueueSize = 0; // adaptive size of picture queue, = (pSps->iNumRefFrames x 2) bReallocFlag = false; bool bNeedChangePicQueue = true; CMemoryAlign* pMa = pCtx->pMemAlign; WELS_VERIFY_RETURN_IF (ERR_INFO_INVALID_PARAM, (NULL == pCtx || kiPicWidth <= 0 || kiPicHeight <= 0)) // Fixed the issue about different gop size over last, 5/17/2010 // get picture queue size currently iPicQueueSize = GetTargetRefListSize (pCtx); // adaptive size of picture queue, = (pSps->iNumRefFrames x 2) pCtx->iPicQueueNumber = iPicQueueSize; if (pCtx->pPicBuff[LIST_0] != NULL && pCtx->pPicBuff[LIST_0]->iCapacity == iPicQueueSize) // comparing current picture queue size requested and previous allocation picture queue bNeedChangePicQueue = false; // HD based pic buffer need consider memory size consumed when switch from 720p to other lower size WELS_VERIFY_RETURN_IF (ERR_NONE, pCtx->bHaveGotMemory && (kiPicWidth == pCtx->iImgWidthInPixel && kiPicHeight == pCtx->iImgHeightInPixel) && (!bNeedChangePicQueue)) // have same scaled buffer // sync update pRefList WelsResetRefPic (pCtx); // added to sync update ref list due to pictures are free if (pCtx->bHaveGotMemory && (kiPicWidth == pCtx->iImgWidthInPixel && kiPicHeight == pCtx->iImgHeightInPixel) && pCtx->pPicBuff[LIST_0] != NULL && pCtx->pPicBuff[LIST_0]->iCapacity != iPicQueueSize) { // currently only active for LIST_0 due to have no B frames WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "WelsRequestMem(): memory re-alloc for no resolution change (size = %d * %d), ref list size change from %d to %d", kiPicWidth, kiPicHeight, pCtx->pPicBuff[LIST_0]->iCapacity, iPicQueueSize); if (pCtx->pPicBuff[LIST_0]->iCapacity < iPicQueueSize) { iErr = IncreasePicBuff (pCtx, &pCtx->pPicBuff[LIST_0], pCtx->pPicBuff[LIST_0]->iCapacity, kiPicWidth, kiPicHeight, iPicQueueSize); } else { iErr = DecreasePicBuff (pCtx, &pCtx->pPicBuff[LIST_0], pCtx->pPicBuff[LIST_0]->iCapacity, kiPicWidth, kiPicHeight, iPicQueueSize); } } else { if (pCtx->bHaveGotMemory) WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "WelsRequestMem(): memory re-alloc for resolution change, size change from %d * %d to %d * %d, ref list size change from %d to %d", pCtx->iImgWidthInPixel, pCtx->iImgHeightInPixel, kiPicWidth, kiPicHeight, pCtx->pPicBuff[LIST_0]->iCapacity, iPicQueueSize); else WelsLog (& (pCtx->sLogCtx), WELS_LOG_INFO, "WelsRequestMem(): memory alloc size = %d * %d, ref list size = %d", kiPicWidth, kiPicHeight, iPicQueueSize); // for Recycled_Pic_Queue for (iListIdx = LIST_0; iListIdx < LIST_A; ++ iListIdx) { PPicBuff* ppPic = &pCtx->pPicBuff[iListIdx]; if (NULL != ppPic && NULL != *ppPic) { DestroyPicBuff (ppPic, pMa); } } pCtx->pPreviousDecodedPictureInDpb = NULL; // currently only active for LIST_0 due to have no B frames iErr = CreatePicBuff (pCtx, &pCtx->pPicBuff[LIST_0], iPicQueueSize, kiPicWidth, kiPicHeight); } if (iErr != ERR_NONE) return iErr; pCtx->iImgWidthInPixel = kiPicWidth; // target width of image to be reconstruted while decoding pCtx->iImgHeightInPixel = kiPicHeight; // target height of image to be reconstruted while decoding pCtx->bHaveGotMemory = true; // global memory for decoder context related is requested pCtx->pDec = NULL; // need prefetch a new pic due to spatial size changed if (pCtx->pCabacDecEngine == NULL) pCtx->pCabacDecEngine = (SWelsCabacDecEngine*) pMa->WelsMallocz (sizeof (SWelsCabacDecEngine), "pCtx->pCabacDecEngine"); WELS_VERIFY_RETURN_IF (ERR_INFO_OUT_OF_MEMORY, (NULL == pCtx->pCabacDecEngine)) bReallocFlag = true; // memory re-allocation successfully finished return ERR_NONE; }