WelsErrorType CWelsSliceEncodingTask::ExecuteTask() { #if MT_DEBUG_BS_WR m_pSliceBs->bSliceCodedFlag = false; #endif//MT_DEBUG_BS_WR if (m_bNeedPrefix) { if (m_eNalRefIdc != NRI_PRI_LOWEST) { WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc); WelsWriteSVCPrefixNal (&m_pSliceBs->sBsWrite, m_eNalRefIdc, (NAL_UNIT_CODED_SLICE_IDR == m_eNalType)); WelsUnloadNalForSlice (m_pSliceBs); } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc); // No need write any syntax of prefix NAL Unit RBSP here WelsUnloadNalForSlice (m_pSliceBs); } } WelsLoadNalForSlice (m_pSliceBs, m_eNalType, m_eNalRefIdc); int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_iSliceIdx, m_eNalType); if (ENC_RETURN_SUCCESS != iReturn) { return iReturn; } WelsUnloadNalForSlice (m_pSliceBs); m_iSliceSize = 0; int32_t iLeftBufferSize = (m_iSliceIdx > 0) ? (m_pSliceBs->uiSize - (int32_t) (m_pSliceBs->sBsWrite.pCurBuf - m_pSliceBs->sBsWrite.pStartBuf)) : (m_pCtx->iFrameBsSize - m_pCtx->iPosBsBuffer); iReturn = WriteSliceBs (m_pCtx, m_pSliceBs->pBs, &m_pSliceBs->iNalLen[0], iLeftBufferSize, m_iSliceIdx, m_iSliceSize); if (ENC_RETURN_SUCCESS != iReturn) { WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING, "[MT] CWelsSliceEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, um_iSliceIdx %d", m_pCtx->iCodingIndex, m_iSliceIdx); return iReturn; } if (0 == m_iSliceIdx) { m_pCtx->iPosBsBuffer += m_iSliceSize; } m_pCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (m_pCtx->pCurDqLayer, m_pCtx->pFuncList, m_iSliceIdx); WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DETAIL, "@pSlice=%-6d sliceType:%c idc:%d size:%-6d", m_iSliceIdx, (m_pCtx->eSliceType == P_SLICE ? 'P' : 'I'), m_eNalRefIdc, m_iSliceSize); #if MT_DEBUG_BS_WR m_pSliceBs->bSliceCodedFlag = true; #endif//MT_DEBUG_BS_WR return ENC_RETURN_SUCCESS; }
WelsErrorType CWelsSliceEncodingTask::ExecuteTask() { #if MT_DEBUG_BS_WR m_pSliceBs->bSliceCodedFlag = false; #endif//MT_DEBUG_BS_WR SSpatialLayerInternal* pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId]; if (m_bNeedPrefix) { if (m_eNalRefIdc != NRI_PRI_LOWEST) { WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc); WelsWriteSVCPrefixNal (&m_pSliceBs->sBsWrite, m_eNalRefIdc, (NAL_UNIT_CODED_SLICE_IDR == m_eNalType)); WelsUnloadNalForSlice (m_pSliceBs); } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc); // No need write any syntax of prefix NAL Unit RBSP here WelsUnloadNalForSlice (m_pSliceBs); } } WelsLoadNalForSlice (m_pSliceBs, m_eNalType, m_eNalRefIdc); assert (m_iSliceIdx == (int) m_pSlice->iSliceIdx); int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_pSlice, m_eNalType); if (ENC_RETURN_SUCCESS != iReturn) { return iReturn; } WelsUnloadNalForSlice (m_pSliceBs); m_iSliceSize = 0; iReturn = WriteSliceBs (m_pCtx, m_pSliceBs, m_iSliceIdx, m_iSliceSize); if (ENC_RETURN_SUCCESS != iReturn) { WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING, "[MT] CWelsSliceEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, um_iSliceIdx %d", pParamInternal->iCodingIndex, m_iSliceIdx); return iReturn; } m_pCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (m_pCtx->pCurDqLayer, m_pCtx->pFuncList, m_pSlice); WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DETAIL, "@pSlice=%-6d sliceType:%c idc:%d size:%-6d", m_iSliceIdx, (m_pCtx->eSliceType == P_SLICE ? 'P' : 'I'), m_eNalRefIdc, m_iSliceSize); #if MT_DEBUG_BS_WR m_pSliceBs->bSliceCodedFlag = true; #endif//MT_DEBUG_BS_WR return ENC_RETURN_SUCCESS; }
// thread process for coding one pSlice WELS_THREAD_ROUTINE_TYPE CodingSliceThreadProc (void* arg) { SSliceThreadPrivateData* pPrivateData = (SSliceThreadPrivateData*)arg; sWelsEncCtx* pEncPEncCtx = NULL; SDqLayer* pCurDq = NULL; SSlice* pSlice = NULL; SWelsSliceBs* pSliceBs = NULL; WELS_EVENT pEventsList[3]; int32_t iEventCount = 0; WELS_THREAD_ERROR_CODE iWaitRet = WELS_THREAD_ERROR_GENERAL; uint32_t uiThrdRet = 0; int32_t iSliceSize = 0; int32_t iSliceIdx = -1; int32_t iThreadIdx = -1; int32_t iEventIdx = -1; 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); pEncPEncCtx = (sWelsEncCtx*)pPrivateData->pWelsPEncCtx; iThreadIdx = pPrivateData->iThreadIndex; iEventIdx = iThreadIdx; pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pReadySliceCodingEvent[iEventIdx]; pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pExitEncodeEvent[iEventIdx]; pEventsList[iEventCount++] = pEncPEncCtx->pSliceThreading->pUpdateMbListEvent[iEventIdx]; WelsThreadSetName ("OpenH264Enc_CodingSliceThreadProc"); do { MT_TRACE_LOG (pEncPEncCtx, WELS_LOG_INFO, "[MT] CodingSliceThreadProc(), try to call WelsMultipleEventsWaitSingleBlocking(pEventsList= %p %p %p), pEncPEncCtx= %p!", pEventsList[0], pEventsList[1], pEventsList[1], (void*)pEncPEncCtx); iWaitRet = WelsMultipleEventsWaitSingleBlocking (iEventCount, &pEventsList[0], &pEncPEncCtx->pSliceThreading->pThreadMasterEvent[iEventIdx]); // blocking until at least one event is signalled if (WELS_THREAD_ERROR_WAIT_OBJECT_0 == iWaitRet) { // start pSlice coding signal waited //int iLayerIndex = pEncPEncCtx->pOut->iLayerBsIndex; //SFrameBSInfo* pFrameBsInfo = pPrivateData->pFrameBsInfo; //SLayerBSInfo* pLbi = &pFrameBsInfo->sLayerInfo [iLayerIndex]; const int32_t kiCurDid = pEncPEncCtx->uiDependencyId; SWelsSvcCodingParam* pCodingParam = pEncPEncCtx->pSvcParam; SSpatialLayerConfig* pParamD = &pCodingParam->sSpatialLayers[kiCurDid]; pCurDq = pEncPEncCtx->pCurDqLayer; eNalType = pEncPEncCtx->eNalType; eNalRefIdc = pEncPEncCtx->eNalPriority; bNeedPrefix = pEncPEncCtx->bNeedPrefixNalFlag; if (pParamD->sSliceArgument.uiSliceMode != SM_SIZELIMITED_SLICE) { int64_t iSliceStart = 0; bool bDsaFlag = false; iSliceIdx = pPrivateData->iSliceIndex; pSlice = &pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx]; pSliceBs = &pEncPEncCtx->pSliceBs[iSliceIdx]; bDsaFlag = ((pParamD->sSliceArgument.uiSliceMode == SM_FIXEDSLCNUM_SLICE) && pCodingParam->iMultipleThreadIdc > 1 && pCodingParam->iMultipleThreadIdc >= pParamD->sSliceArgument.uiSliceNum); if (bDsaFlag) iSliceStart = WelsTime(); pSliceBs->uiBsPos = 0; pSliceBs->iNalIndex = 0; assert ((void*) (&pSliceBs->sBsWrite) == (void*)pSlice->pSliceBsa); InitBits (&pSliceBs->sBsWrite, pSliceBs->pBsBuffer, pSliceBs->uiSize); #if MT_DEBUG_BS_WR pSliceBs->bSliceCodedFlag = false; #endif//MT_DEBUG_BS_WR if (bNeedPrefix) { if (eNalRefIdc != NRI_PRI_LOWEST) { WelsLoadNalForSlice (pSliceBs, NAL_UNIT_PREFIX, eNalRefIdc); WelsWriteSVCPrefixNal (&pSliceBs->sBsWrite, eNalRefIdc, (NAL_UNIT_CODED_SLICE_IDR == eNalType)); WelsUnloadNalForSlice (pSliceBs); } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension WelsLoadNalForSlice (pSliceBs, NAL_UNIT_PREFIX, eNalRefIdc); // No need write any syntax of prefix NAL Unit RBSP here WelsUnloadNalForSlice (pSliceBs); } } WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc); iReturn = WelsCodeOneSlice (pEncPEncCtx, iSliceIdx, eNalType); if (ENC_RETURN_SUCCESS != iReturn) { uiThrdRet = iReturn; WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, iEventIdx); } WelsUnloadNalForSlice (pSliceBs); int32_t iLeftBufferSize = (iSliceIdx > 0) ? (pSliceBs->uiSize - pSliceBs->uiBsPos) : (pEncPEncCtx->iFrameBsSize - pEncPEncCtx->iPosBsBuffer); iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, &pSliceBs->iNalLen[0], iLeftBufferSize, iSliceIdx, iSliceSize); if (ENC_RETURN_SUCCESS != iReturn) { uiThrdRet = iReturn; WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, iEventIdx); } if (0 == iSliceIdx) { pEncPEncCtx->iPosBsBuffer += iSliceSize; } pEncPEncCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (pCurDq, pEncPEncCtx->pFuncList, iSliceIdx); if (bDsaFlag) { pEncPEncCtx->pCurDqLayer->sLayerInfo.pSliceInLayer[iSliceIdx].uiSliceConsumeTime = (uint32_t) ( WelsTime() - iSliceStart); MT_TRACE_LOG (& (pEncPEncCtx->sLogCtx), WELS_LOG_INFO, "[MT] CodingSliceThreadProc(), coding_idx %d, uiSliceIdx %d, uiSliceConsumeTime %d, iSliceSize %d, iFirstMbInSlice %d, count_num_mb_in_slice %d", pEncPEncCtx->iCodingIndex, iSliceIdx, pEncPEncCtx->pCurDqLayer->sLayerInfo.pSliceInLayer[iSliceIdx].uiSliceConsumeTime, iSliceSize, pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx].sSliceHeaderExt.sSliceHeader.iFirstMbInSlice, pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx].iCountMbNumInSlice); } #if defined(SLICE_INFO_OUTPUT) fprintf (stderr, "@pSlice=%-6d sliceType:%c idc:%d size:%-6d\n", iSliceIdx, (pEncPEncCtx->eSliceType == P_SLICE ? 'P' : 'I'), eNalRefIdc, iSliceSize ); #endif//SLICE_INFO_OUTPUT #if MT_DEBUG_BS_WR pSliceBs->bSliceCodedFlag = true; #endif//MT_DEBUG_BS_WR WelsEventSignal ( &pEncPEncCtx->pSliceThreading->pSliceCodedEvent[iEventIdx]); // mean finished coding current pSlice WelsEventSignal ( &pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent); } else { // for SM_SIZELIMITED_SLICE parallelization SSliceCtx* pSliceCtx = &pCurDq->sSliceEncCtx; const int32_t kiPartitionId = iThreadIdx; const int32_t kiSliceIdxStep = pEncPEncCtx->iActiveThreadsNum; const int32_t kiFirstMbInPartition = pPrivateData->iStartMbIndex; // inclusive const int32_t kiEndMbInPartition = pPrivateData->iEndMbIndex; // exclusive int32_t iAnyMbLeftInPartition = kiEndMbInPartition - kiFirstMbInPartition; iSliceIdx = pPrivateData->iSliceIndex; SSliceHeaderExt* pStartSliceHeaderExt = &pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx].sSliceHeaderExt; pStartSliceHeaderExt->sSliceHeader.iFirstMbInSlice = kiFirstMbInPartition; pCurDq->pNumSliceCodedOfPartition[kiPartitionId] = 1; // one pSlice per partition intialized, dynamic slicing inside pCurDq->pLastMbIdxOfPartition[kiPartitionId] = kiEndMbInPartition - 1; pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId] = 0; while (iAnyMbLeftInPartition > 0) { if (iSliceIdx >= pSliceCtx->iMaxSliceNumConstraint) { // 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 uiThrdRet = 1; WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, iEventIdx); } SetOneSliceBsBufferUnderMultithread (pEncPEncCtx, kiPartitionId, iSliceIdx); pSlice = &pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx]; pSliceBs = &pEncPEncCtx->pSliceBs[iSliceIdx]; pSliceBs->uiBsPos = 0; pSliceBs->iNalIndex = 0; InitBits (&pSliceBs->sBsWrite, pSliceBs->pBsBuffer, pSliceBs->uiSize); if (bNeedPrefix) { if (eNalRefIdc != NRI_PRI_LOWEST) { WelsLoadNalForSlice (pSliceBs, NAL_UNIT_PREFIX, eNalRefIdc); WelsWriteSVCPrefixNal (&pSliceBs->sBsWrite, eNalRefIdc, (NAL_UNIT_CODED_SLICE_IDR == eNalType)); WelsUnloadNalForSlice (pSliceBs); } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension WelsLoadNalForSlice (pSliceBs, NAL_UNIT_PREFIX, eNalRefIdc); // No need write any syntax of prefix NAL Unit RBSP here WelsUnloadNalForSlice (pSliceBs); } } WelsLoadNalForSlice (pSliceBs, eNalType, eNalRefIdc); iReturn = WelsCodeOneSlice (pEncPEncCtx, iSliceIdx, eNalType); if (ENC_RETURN_SUCCESS != iReturn) { uiThrdRet = iReturn; WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, iEventIdx); } WelsUnloadNalForSlice (pSliceBs); int32_t iLeftBufferSize = (iSliceIdx > 0) ? (pSliceBs->uiSize - pSliceBs->uiBsPos) : (pEncPEncCtx->iFrameBsSize - pEncPEncCtx->iPosBsBuffer); iReturn = WriteSliceBs (pEncPEncCtx, pSliceBs->pBs, &pSliceBs->iNalLen[0], iLeftBufferSize, iSliceIdx, iSliceSize); if (ENC_RETURN_SUCCESS != iReturn) { uiThrdRet = iReturn; WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, iEventIdx); } if (0 == iSliceIdx) { pEncPEncCtx->iPosBsBuffer += iSliceSize; } pEncPEncCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (pCurDq, pEncPEncCtx->pFuncList, iSliceIdx); #if defined(SLICE_INFO_OUTPUT) fprintf (stderr, "@pSlice=%-6d sliceType:%c idc:%d size:%-6d\n", iSliceIdx, (pEncPEncCtx->eSliceType == P_SLICE ? 'P' : 'I'), eNalRefIdc, iSliceSize ); #endif//SLICE_INFO_OUTPUT MT_TRACE_LOG (pEncPEncCtx, WELS_LOG_INFO, "[MT] CodingSliceThreadProc(), coding_idx %d, iPartitionId %d, uiSliceIdx %d, iSliceSize %d, count_mb_slice %d, iEndMbInPartition %d, pCurDq->pLastCodedMbIdxOfPartition[%d] %d\n", pEncPEncCtx->iCodingIndex, kiPartitionId, iSliceIdx, iSliceSize, pCurDq->sLayerInfo.pSliceInLayer[iSliceIdx].iCountMbNumInSlice, kiEndMbInPartition, kiPartitionId, pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]); iAnyMbLeftInPartition = kiEndMbInPartition - (1 + pCurDq->pLastCodedMbIdxOfPartition[kiPartitionId]); iSliceIdx += kiSliceIdxStep; } if (uiThrdRet) { // any exception?? WELS_THREAD_SIGNAL_AND_BREAK (pEncPEncCtx->pSliceThreading->pSliceCodedEvent, pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent, iEventIdx); } WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedEvent[iEventIdx]); // mean finished coding current pSlice WelsEventSignal (&pEncPEncCtx->pSliceThreading->pSliceCodedMasterEvent); } } else if (WELS_THREAD_ERROR_WAIT_OBJECT_0 + 1 == iWaitRet) { // exit thread signal uiThrdRet = 0; break; } else if (WELS_THREAD_ERROR_WAIT_OBJECT_0 + 2 == iWaitRet) { // update pMb list singal iSliceIdx = iEventIdx; // pPrivateData->iSliceIndex; old threads can not be terminated, pPrivateData is not correct for applicable pCurDq = pEncPEncCtx->pCurDqLayer; UpdateMbListNeighborParallel (pCurDq, pCurDq->sMbDataP, iSliceIdx); WelsEventSignal ( &pEncPEncCtx->pSliceThreading->pFinUpdateMbListEvent[iEventIdx]); // mean finished update pMb list for this pSlice } else { // WELS_THREAD_ERROR_WAIT_TIMEOUT, or WELS_THREAD_ERROR_WAIT_FAILED WelsLog (& (pEncPEncCtx->sLogCtx), WELS_LOG_WARNING, "[MT] CodingSliceThreadProc(), waiting pReadySliceCodingEvent[%d] failed(%d) and thread%d terminated!", iEventIdx, iWaitRet, iThreadIdx); uiThrdRet = 1; break; } } while (1); //sync multi-threading error WelsMutexLock (&pEncPEncCtx->mutexEncoderError); if (uiThrdRet) pEncPEncCtx->iEncoderError |= uiThrdRet; WelsMutexUnlock (&pEncPEncCtx->mutexEncoderError); WELS_THREAD_ROUTINE_RETURN (uiThrdRet); }
//CWelsConstrainedSizeSlicingEncodingTask WelsErrorType CWelsConstrainedSizeSlicingEncodingTask::ExecuteTask() { SDqLayer* pCurDq = m_pCtx->pCurDqLayer; const int32_t kiSliceIdxStep = m_pCtx->iActiveThreadsNum; SSpatialLayerInternal* pParamInternal = &m_pCtx->pSvcParam->sDependencyLayers[m_pCtx->uiDependencyId]; const int32_t kiPartitionId = m_iSliceIdx % kiSliceIdxStep; const int32_t kiFirstMbInPartition = pCurDq->FirstMbIdxOfPartition[kiPartitionId]; const int32_t kiEndMbIdxInPartition = pCurDq->EndMbIdxOfPartition[kiPartitionId]; const int32_t kiCodedSliceNumByThread = pCurDq->sSliceBufferInfo[m_iThreadIdx].iCodedSliceNum; m_pSlice = &pCurDq->sSliceBufferInfo[m_iThreadIdx].pSliceBuffer[kiCodedSliceNumByThread]; m_pSlice->sSliceHeaderExt.sSliceHeader.iFirstMbInSlice = kiFirstMbInPartition; int32_t iReturn = 0; bool bNeedReallocate = false; int32_t iDiffMbIdx = kiEndMbIdxInPartition - kiFirstMbInPartition; if( 0 == iDiffMbIdx) { m_pSlice->iSliceIdx = -1; return ENC_RETURN_SUCCESS; } int32_t iAnyMbLeftInPartition = iDiffMbIdx + 1; int32_t iLocalSliceIdx = m_iSliceIdx; while (iAnyMbLeftInPartition > 0) { bNeedReallocate = (pCurDq->sSliceBufferInfo[m_iThreadIdx].iCodedSliceNum >= pCurDq->sSliceBufferInfo[m_iThreadIdx].iMaxSliceNum -1) ? true : false; if (bNeedReallocate) { WelsMutexLock (&m_pCtx->pSliceThreading->mutexThreadSlcBuffReallocate); //for memory statistic variable iReturn = ReallocateSliceInThread(m_pCtx, pCurDq, m_pCtx->uiDependencyId, m_iThreadIdx); WelsMutexUnlock (&m_pCtx->pSliceThreading->mutexThreadSlcBuffReallocate); if (ENC_RETURN_SUCCESS != iReturn) { return iReturn; } } iReturn = InitOneSliceInThread (m_pCtx, m_pSlice, m_iThreadIdx, m_pCtx->uiDependencyId, iLocalSliceIdx); WELS_VERIFY_RETURN_IFNEQ (iReturn, ENC_RETURN_SUCCESS) m_pSliceBs = &m_pSlice->sSliceBs; InitBits (&m_pSliceBs->sBsWrite, m_pSliceBs->pBsBuffer, m_pSliceBs->uiSize); if (m_bNeedPrefix) { if (m_eNalRefIdc != NRI_PRI_LOWEST) { WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc); WelsWriteSVCPrefixNal (&m_pSliceBs->sBsWrite, m_eNalRefIdc, (NAL_UNIT_CODED_SLICE_IDR == m_eNalType)); WelsUnloadNalForSlice (m_pSliceBs); } else { // No Prefix NAL Unit RBSP syntax here, but need add NAL Unit Header extension WelsLoadNalForSlice (m_pSliceBs, NAL_UNIT_PREFIX, m_eNalRefIdc); // No need write any syntax of prefix NAL Unit RBSP here WelsUnloadNalForSlice (m_pSliceBs); } } WelsLoadNalForSlice (m_pSliceBs, m_eNalType, m_eNalRefIdc); assert (iLocalSliceIdx == (int) m_pSlice->iSliceIdx); int32_t iReturn = WelsCodeOneSlice (m_pCtx, m_pSlice, m_eNalType); if (ENC_RETURN_SUCCESS != iReturn) { return iReturn; } WelsUnloadNalForSlice (m_pSliceBs); iReturn = WriteSliceBs (m_pCtx, m_pSliceBs, iLocalSliceIdx, m_iSliceSize); if (ENC_RETURN_SUCCESS != iReturn) { WelsLog (&m_pCtx->sLogCtx, WELS_LOG_WARNING, "[MT] CWelsConstrainedSizeSlicingEncodingTask ExecuteTask(), WriteSliceBs not successful: coding_idx %d, uiLocalSliceIdx %d, BufferSize %d, m_iSliceSize %d, iPayloadSize %d", pParamInternal->iCodingIndex, iLocalSliceIdx, m_pSliceBs->uiSize, m_iSliceSize, m_pSliceBs->sNalList[0].iPayloadSize); return iReturn; } m_pCtx->pFuncList->pfDeblocking.pfDeblockingFilterSlice (pCurDq, m_pCtx->pFuncList, m_pSlice); WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DETAIL, "@pSlice=%-6d sliceType:%c idc:%d size:%-6d\n", iLocalSliceIdx, (m_pCtx->eSliceType == P_SLICE ? 'P' : 'I'), m_eNalRefIdc, m_iSliceSize ); WelsLog (&m_pCtx->sLogCtx, WELS_LOG_DEBUG, "[MT] CWelsConstrainedSizeSlicingEncodingTask(), coding_idx %d, iPartitionId %d, m_iThreadIdx %d, iLocalSliceIdx %d, m_iSliceSize %d, ParamValidationExt(), invalid uiMaxNalSizeiEndMbInPartition %d, pCurDq->LastCodedMbIdxOfPartition[%d] %d\n", pParamInternal->iCodingIndex, kiPartitionId, m_iThreadIdx, iLocalSliceIdx, m_iSliceSize, kiEndMbIdxInPartition, kiPartitionId, pCurDq->LastCodedMbIdxOfPartition[kiPartitionId]); iAnyMbLeftInPartition = kiEndMbIdxInPartition - pCurDq->LastCodedMbIdxOfPartition[kiPartitionId]; iLocalSliceIdx += kiSliceIdxStep; m_pCtx->pCurDqLayer->sSliceBufferInfo[m_iThreadIdx].iCodedSliceNum ++; } return ENC_RETURN_SUCCESS; }