/*! * \brief Assign MB map for multiple slice(s) segment * * \param pMbMap overall MB map * \param iCountMbNum count number of MB * * \return 0 - successful; none 0 - failed */ int32_t AssignMbMapMultipleSlices (SSliceCtx* pSliceSeg, const SSliceConfig* kpMso) { if (NULL == pSliceSeg || SM_SINGLE_SLICE == pSliceSeg->uiSliceMode) return 1; if (SM_ROWMB_SLICE == pSliceSeg->uiSliceMode) { const int32_t kiMbWidth = pSliceSeg->iMbWidth; int32_t iSliceNum = pSliceSeg->iSliceNumInFrame, uiSliceIdx = 0; while (uiSliceIdx < iSliceNum) { const int32_t kiFirstMb = uiSliceIdx * kiMbWidth; pSliceSeg->pCountMbNumInSlice[uiSliceIdx] = kiMbWidth; pSliceSeg->pFirstMbInSlice[uiSliceIdx] = kiFirstMb; WelsSetMemMultiplebytes_c(pSliceSeg->pOverallMbMap + kiFirstMb, uiSliceIdx, kiMbWidth, sizeof(uint16_t)); ++ uiSliceIdx; } return 0; } else if (SM_RASTER_SLICE == pSliceSeg->uiSliceMode || SM_FIXEDSLCNUM_SLICE == pSliceSeg->uiSliceMode || SM_AUTO_SLICE == pSliceSeg->uiSliceMode) { const int32_t* kpSlicesAssignList = (int32_t*) & (kpMso->sSliceArgument.uiSliceMbNum[0]); const int32_t kiCountNumMbInFrame = pSliceSeg->iMbNumInFrame; const int32_t kiCountSliceNumInFrame = pSliceSeg->iSliceNumInFrame; uint16_t iSliceIdx = 0; int32_t iMbIdx = 0; do { const int32_t kiCurRunLength = kpSlicesAssignList[iSliceIdx]; int32_t iRunIdx = 0; pSliceSeg->pFirstMbInSlice[iSliceIdx] = iMbIdx; pSliceSeg->pCountMbNumInSlice[iSliceIdx] = kiCurRunLength; // due here need check validate mb_assign_map for input pData, can not use memset do { pSliceSeg->pOverallMbMap[iMbIdx + iRunIdx] = iSliceIdx; ++ iRunIdx; } while (iRunIdx < kiCurRunLength && iMbIdx + iRunIdx < kiCountNumMbInFrame); iMbIdx += kiCurRunLength; ++ iSliceIdx; } while (iSliceIdx < kiCountSliceNumInFrame && iMbIdx < kiCountNumMbInFrame); } else if (SM_DYN_SLICE == pSliceSeg->uiSliceMode) { int32_t iSliceIdx = 0; const int32_t kiMaxSliceNum = pSliceSeg->iMaxSliceNumConstraint; const int32_t kiCountNumMbInFrame = pSliceSeg->iMbNumInFrame; do { pSliceSeg->pFirstMbInSlice[iSliceIdx] = 0; pSliceSeg->pCountMbNumInSlice[iSliceIdx] = kiCountNumMbInFrame; iSliceIdx++; } while (iSliceIdx < kiMaxSliceNum); } else { // any else uiSliceMode? assert (0); } // extention for other multiple slice type in the future return 1; }
/*! * \brief Assign MB map for multiple slice(s) segment * * \param pCurDq current layer which its MB map will be assigned * \param kpSliceArgument slice argument for current layer * * \return 0 - successful; none 0 - failed */ int32_t AssignMbMapMultipleSlices (SDqLayer* pCurDq,const SSliceArgument* kpSliceArgument) { SSliceCtx* pSliceSeg = &pCurDq->sSliceEncCtx; int32_t iSliceIdx = 0; if (NULL == pSliceSeg || SM_SINGLE_SLICE == pSliceSeg->uiSliceMode) return 1; if ((SM_RASTER_SLICE == pSliceSeg->uiSliceMode) && (0 == kpSliceArgument->uiSliceMbNum[0])) { const int32_t kiMbWidth = pSliceSeg->iMbWidth; int32_t iSliceNum = pSliceSeg->iSliceNumInFrame; iSliceIdx = 0; while (iSliceIdx < iSliceNum) { const int32_t kiFirstMb = iSliceIdx * kiMbWidth; WelsSetMemMultiplebytes_c(pSliceSeg->pOverallMbMap + kiFirstMb, iSliceIdx, kiMbWidth, sizeof(uint16_t)); ++ iSliceIdx; } return 0; } else if (SM_RASTER_SLICE == pSliceSeg->uiSliceMode || SM_FIXEDSLCNUM_SLICE == pSliceSeg->uiSliceMode) { const int32_t* kpSlicesAssignList = (int32_t*) & (kpSliceArgument->uiSliceMbNum[0]); const int32_t kiCountNumMbInFrame = pSliceSeg->iMbNumInFrame; const int32_t kiCountSliceNumInFrame = pSliceSeg->iSliceNumInFrame; int32_t iMbIdx = 0; iSliceIdx = 0; do { const int32_t kiCurRunLength = kpSlicesAssignList[iSliceIdx]; int32_t iRunIdx = 0; // due here need check validate mb_assign_map for input pData, can not use memset do { pSliceSeg->pOverallMbMap[iMbIdx + iRunIdx] = iSliceIdx; ++ iRunIdx; } while (iRunIdx < kiCurRunLength && iMbIdx + iRunIdx < kiCountNumMbInFrame); iMbIdx += kiCurRunLength; ++ iSliceIdx; } while (iSliceIdx < kiCountSliceNumInFrame && iMbIdx < kiCountNumMbInFrame); } else if (SM_SIZELIMITED_SLICE == pSliceSeg->uiSliceMode) { // do nothing,pSliceSeg->pOverallMbMap will be initial later } else { // any else uiSliceMode? assert (0); } // extention for other multiple slice type in the future return 1; }
int32_t DynamicAdjustSlicePEncCtxAll (SSliceCtx* pSliceCtx, int32_t* pRunLength) { const int32_t iCountNumMbInFrame = pSliceCtx->iMbNumInFrame; const int32_t iCountSliceNumInFrame = pSliceCtx->iSliceNumInFrame; int32_t iSameRunLenFlag = 1; int32_t iFirstMbIdx = 0; int32_t iSliceIdx = 0; assert (iCountSliceNumInFrame <= MAX_THREADS_NUM); while (iSliceIdx < iCountSliceNumInFrame) { if (pRunLength[iSliceIdx] != pSliceCtx->pCountMbNumInSlice[iSliceIdx]) { iSameRunLenFlag = 0; break; } ++ iSliceIdx; } if (iSameRunLenFlag) { return 1; // do not need adjust it due to same running length as before to save complexity } iSliceIdx = 0; do { const int32_t kiSliceRun = pRunLength[iSliceIdx]; pSliceCtx->pFirstMbInSlice[iSliceIdx] = iFirstMbIdx; pSliceCtx->pCountMbNumInSlice[iSliceIdx] = kiSliceRun; WelsSetMemMultiplebytes_c(pSliceCtx->pOverallMbMap + iFirstMbIdx, iSliceIdx, kiSliceRun, sizeof(uint16_t)); iFirstMbIdx += kiSliceRun; ++ iSliceIdx; } while (iSliceIdx < iCountSliceNumInFrame && iFirstMbIdx < iCountNumMbInFrame); return 0; }
/*! * \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, SSliceConfig* pMso, const int32_t kiMbWidth, const int32_t kiMbHeight) { const int32_t kiCountMbNum = kiMbWidth * kiMbHeight; SliceModeEnum 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 = (uint16_t*)pMa->WelsMalloc (kiCountMbNum * sizeof (uint16_t), "pSliceSeg->pOverallMbMap"); WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pOverallMbMap) pSliceSeg->iSliceNumInFrame = 1; pSliceSeg->pFirstMbInSlice = (int32_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int32_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 && uiSliceMode != SM_AUTO_SLICE) return 1; pSliceSeg->pOverallMbMap = (uint16_t*)pMa->WelsMalloc (kiCountMbNum * sizeof (uint16_t), "pSliceSeg->pOverallMbMap"); WELS_VERIFY_RETURN_IF (1, NULL == pSliceSeg->pOverallMbMap) WelsSetMemMultiplebytes_c(pSliceSeg->pOverallMbMap, 0, kiCountMbNum, sizeof(uint16_t)); //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 = (int32_t*)pMa->WelsMalloc (pSliceSeg->iSliceNumInFrame * sizeof (int32_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; }