diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp index d1af1a867b6afcb9b66ac70f1907ca599ccc77a2..5142ea3a4521908b99fcaa2b17c4900dc4070d27 100644 --- a/source/Lib/EncoderLib/EncCu.cpp +++ b/source/Lib/EncoderLib/EncCu.cpp @@ -72,64 +72,59 @@ //! \ingroup EncoderLib //! \{ +//ALBERTO CONCEPT FORK +//CONTROL CENTER +bool singleMode = false; +//COMENTAR LA SIGUIENTE DIRECTIVA PARA ELIMINAR MENSAJES DE DEBUG +//#define DEBUG_MESSAGE +#define TIME_MESSAGE +#define IGNORE_CHILD_BUFFER_WARNING +//CONTROL CENTER +//END ALBERTO CONCEPT FORK + //ALBERTO +#ifdef TIME_MESSAGE int EncCu::seconds = 0; int EncCu::iter = 0; +#endif //END ALBERTO //ALBERTO CONCEPT FORK -//CONTROL CENTER -bool singleMode = false; -bool debugMessage = true; -//CONTROL CENTER - -//GLOBAL VARIABLES +//VARIABLES GLOBALES vectorModeCostStruct* vector; //VECTOR OF PROCESSING RESULTS bool father; //TRUE IF THE PROCESS IS NOT A CHILD int threadNumber; //NUMBER OF THREAD IF WE ARE IN A CHILD int posActualNode = 0; //NODE THAT IS BEING PROCESSED -bool ignore_vector; //IGNORE THE VECTOR IF WE ARE UNDER A SPLIT THAT IS NOT QUATERNARY -int NumberOfThreads = 6; //NUMBER OF THREADS CREATED -int repartLevelNumber = 0; //NUMBER IN WHICH THREAD REPART IS PERFORMED -//GLOBAL VARIABLES +//bool ignore_vector; //IGNORE THE VECTOR IF WE ARE UNDER A SPLIT THAT IS NOT QUATERNARY +//int NumberOfThreads = 4; //NUMBER OF THREADS CREATED +//int repartLevelNumber = 0; //NUMBER IN WHICH THREAD REPART IS PERFORMED +//VARIABLES GLOBALES -//TOSTRING_VECTOR +//TO_STRING VECTOR DE MODOS Y COSTE +#ifdef DEBUG_MESSAGE void toStringVector() { - for (int i = 0; i < VECTOR_SIZE && debugMessage; i++) { + for (int i = 0; i < VECTOR_SIZE; i++) { std::cout << vector[i].mode << ", "; std::cout << vector[i].cost << std::endl; } } -void toStringVector(double Level) +void toStringVector(int level) { int end = 0; - for(int i=Level-1; i>-1 && debugMessage; i--) + for(int i=level-1; i>-1; i--) { end += pow(4,i); } - for (int i = 0; i < end && debugMessage; i++) { + for (int i = 0; i < end; i++) { std::cout << vector[i].posFather << ", "; std::cout << vector[i].threadNumber << ", "; std::cout << vector[i].mode << ", "; std::cout << vector[i].cost << std::endl; } } -void toStringVector(int Level) -{ - int end = 0; - for(int i=Level-1; i>-1 && debugMessage; i--) - { - end += pow(4,i); - } - - for (int i = 0; i < end && debugMessage; i++) { - std::cout << vector[i].posFather << ", "; - std::cout << vector[i].threadNumber << std::endl; - } -} -//TOSTRING_VECTOR - +#endif +//TO_STRING VECTOR DE MODOS Y COSTE //END ALBERTO CONCEPT FORK // ==================================================================================================================== @@ -285,7 +280,6 @@ void EncCu::destroy() } #endif //ALBERTO CONCEPT FORK - //sem_destroy(sem); munmap(vector, VECTOR_BYTES); shm_unlink("/myshm"); //END ALBERTO CONCEPT FORK @@ -294,59 +288,20 @@ void EncCu::destroy() EncCu::~EncCu() { //ALBERTO CONCEPT FORK - //sem_destroy(sem); munmap(vector, VECTOR_BYTES); shm_unlink("/myshm"); //END ALBERTO CONCEPT FORK } -/** \param pcEncLib pointer of encoder class - */ -void EncCu::init( EncLib* pcEncLib, const SPS& sps ) -{ - m_pcEncCfg = pcEncLib; - m_pcIntraSearch = pcEncLib->getIntraSearch(); - m_pcInterSearch = pcEncLib->getInterSearch(); - m_pcTrQuant = pcEncLib->getTrQuant(); - m_pcRdCost = pcEncLib->getRdCost (); - m_CABACEstimator = pcEncLib->getCABACEncoder()->getCABACEstimator( &sps ); - m_CABACEstimator->setEncCu(this); - m_ctxPool = pcEncLib->getCtxCache(); - m_pcRateCtrl = pcEncLib->getRateCtrl(); - m_pcSliceEncoder = pcEncLib->getSliceEncoder(); - m_deblockingFilter = pcEncLib->getDeblockingFilter(); - m_geoCostList.init(m_pcEncCfg->getMaxNumGeoCand()); - m_AFFBestSATDCost = MAX_DOUBLE; - - DecCu::init( m_pcTrQuant, m_pcIntraSearch, m_pcInterSearch ); - - m_modeCtrl->init( m_pcEncCfg, m_pcRateCtrl, m_pcRdCost ); - m_modeCtrl->setBIMQPMap( m_pcEncCfg->getAdaptQPmap() ); - - m_pcInterSearch->setModeCtrl( m_modeCtrl ); - m_modeCtrl->setInterSearch(m_pcInterSearch); - m_pcIntraSearch->setModeCtrl( m_modeCtrl ); - - m_pcGOPEncoder = pcEncLib->getGOPEncoder(); - m_pcGOPEncoder->setModeCtrl( m_modeCtrl ); - - //ALBERTO CONCEPT FORK - // Crear memoria compartida para el vector - createSharedVector(); - //Rellenar el vector - initStructVector(); - toStringVector(5); //IMPRIMIR 5 (TODOS) LOS NIVELES - //END ALBERTO CONCEPT -} - //ALBERTO CONCEPT FORK +//FUNCIONES AUXILIARES DE init() void EncCu::createSharedVector() { int fd = shm_open("/myshm", O_CREAT | O_RDWR, 0666); ftruncate(fd, VECTOR_BYTES + sizeof(sem_t)); vector = (vectorModeCostStruct*) mmap(NULL, VECTOR_BYTES, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); } -void EncCu::repartLevel() +/*void EncCu::repartLevel() { for(int i=0; i<5; i++) { @@ -357,8 +312,8 @@ void EncCu::repartLevel() } } -} -int EncCu::repartStart() +}*/ +/*int EncCu::repartStart() { int repartStartNode = 0; for(int i=0; i<= repartLevelNumber-1; i++) @@ -366,8 +321,8 @@ int EncCu::repartStart() repartStartNode += levelValues[i]; } return repartStartNode; -} -int EncCu::repartEnd() +}*/ +/*int EncCu::repartEnd() { int repartEndNode = -1; for(int i=0; i<= repartLevelNumber; i++) @@ -375,15 +330,15 @@ int EncCu::repartEnd() repartEndNode += levelValues[i]; } return repartEndNode; -} -void EncCu::initStructVectorBeforeRepartStart(int repartStartNode) +}*/ +/*void EncCu::initStructVectorBeforeRepartStart(int repartStartNode) { for(int i=0; i=(LEVEL0) && posPadreActual<=(LEVEL1)) //Estamos en el nivel 1 { - updateFatherAndThreadNumbers(0,1,posPadreActual,i,1,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); + updateFatherAndThreadNumbers(0,1,posPadreActual,i);//,1,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); } else if(posPadreActual>=(LEVEL1+LEVEL0) && posPadreActual<=(LEVEL2+LEVEL1)) //Estamos en el nivel 2 { - updateFatherAndThreadNumbers(1,2,posPadreActual,i,2,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); + updateFatherAndThreadNumbers(1,2,posPadreActual,i);//,2,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); } else if(posPadreActual>=(LEVEL2+LEVEL1+LEVEL0) && posPadreActual<=(LEVEL3+LEVEL2+LEVEL1)) //Estamos en el nivel 3 { - updateFatherAndThreadNumbers(2,3,posPadreActual,i,3,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); + updateFatherAndThreadNumbers(2,3,posPadreActual,i);//,3,childCounter,thread1ChildNumber,threadNumber,numberOfNodesPerThread); } } } -void EncCu::updateFatherAndThreadNumbersLevel0(int posPadreActual, int thread1ChildNumber, int numberOfNodesPerThread) +void EncCu::updateFatherAndThreadNumbersLevel0(int posPadreActual)//, int thread1ChildNumber, int numberOfNodesPerThread) { - if(repartLevelNumber==1) //Estamos en el nivel 0, el padre realiza el reparto de threads + /*if(repartLevelNumber==1) //Estamos en el nivel 0, el padre realiza el reparto de threads { int salto = 1; int threadNumber = 1; @@ -456,7 +411,7 @@ void EncCu::updateFatherAndThreadNumbersLevel0(int posPadreActual, int thread1Ch } } else - { + {*/ int salto = 1; int threadNumber = 1; int start = posPadreActual+salto; @@ -465,12 +420,13 @@ void EncCu::updateFatherAndThreadNumbersLevel0(int posPadreActual, int thread1Ch { vector[j].posFather=posPadreActual; vector[j].threadNumber=threadNumber; + threadNumber++; } - } + //} } -void EncCu::updateFatherAndThreadNumbers(int LevelLowIndex, int LevelUpIndex, int posPadreActual, int i, int LevelActualIndex, int& childCounter,int thread1ChildNumber, int& threadNumber, int numberOfNodesPerThread) +void EncCu::updateFatherAndThreadNumbers(int LevelLowIndex, int LevelUpIndex, int posPadreActual, int i)//, int LevelActualIndex, int& childCounter,int thread1ChildNumber, int& threadNumber, int numberOfNodesPerThread) { - if(LevelActualIndex+1 == repartLevelNumber) //SI ESTAMOS EN EL PADRE DEL NIVEL DONDE SE HACE EL REPARTO + /*if(LevelActualIndex+1 == repartLevelNumber) //SI ESTAMOS EN EL PADRE DEL NIVEL DONDE SE HACE EL REPARTO { int LevelLow = 0; int LevelUp = levelValues[LevelUpIndex]; @@ -502,7 +458,7 @@ void EncCu::updateFatherAndThreadNumbers(int LevelLowIndex, int LevelUpIndex, in } else - { + {*/ int LevelLow = 0; int LevelUp = levelValues[LevelUpIndex]; for(int j=LevelLowIndex; j>-1;j--) @@ -519,20 +475,98 @@ void EncCu::updateFatherAndThreadNumbers(int LevelLowIndex, int LevelUpIndex, in vector[j].posFather=posPadreActual; vector[j].threadNumber=threadNumber; } + //} +} +//END ALBERTO CONCEPT FORK + +/** \param pcEncLib pointer of encoder class + */ +void EncCu::init( EncLib* pcEncLib, const SPS& sps ) +{ + m_pcEncCfg = pcEncLib; + m_pcIntraSearch = pcEncLib->getIntraSearch(); + m_pcInterSearch = pcEncLib->getInterSearch(); + m_pcTrQuant = pcEncLib->getTrQuant(); + m_pcRdCost = pcEncLib->getRdCost (); + m_CABACEstimator = pcEncLib->getCABACEncoder()->getCABACEstimator( &sps ); + m_CABACEstimator->setEncCu(this); + m_ctxPool = pcEncLib->getCtxCache(); + m_pcRateCtrl = pcEncLib->getRateCtrl(); + m_pcSliceEncoder = pcEncLib->getSliceEncoder(); + m_deblockingFilter = pcEncLib->getDeblockingFilter(); + m_geoCostList.init(m_pcEncCfg->getMaxNumGeoCand()); + m_AFFBestSATDCost = MAX_DOUBLE; + + DecCu::init( m_pcTrQuant, m_pcIntraSearch, m_pcInterSearch ); + + m_modeCtrl->init( m_pcEncCfg, m_pcRateCtrl, m_pcRdCost ); + m_modeCtrl->setBIMQPMap( m_pcEncCfg->getAdaptQPmap() ); + + m_pcInterSearch->setModeCtrl( m_modeCtrl ); + m_modeCtrl->setInterSearch(m_pcInterSearch); + m_pcIntraSearch->setModeCtrl( m_modeCtrl ); + + m_pcGOPEncoder = pcEncLib->getGOPEncoder(); + m_pcGOPEncoder->setModeCtrl( m_modeCtrl ); + + //ALBERTO CONCEPT FORK + // Crear memoria compartida para el vector + createSharedVector(); + //Rellenar el vector + initStructVector(); + #ifdef DEBUG_MESSAGE + toStringVector(5); //IMPRIMIR 5 (TODOS) LOS NIVELES + #endif //DEBUG_MESSAGE + //END ALBERTO CONCEPT +} + +// ==================================================================================================================== +// Public member functions +// ==================================================================================================================== + +//ALBERTO CONCEPT FORK +//FUNCIONES AUXILIARES compressCtuForks() +void EncCu::reduceVector() +{ + for(int i=VECTOR_SIZE-1 ; (i-4)>=0 ; i=i-4) + { + int valueChild_1 = vector[i-3].cost; + int valueChild_2 = vector[i-2].cost; + int valueChild_3 = vector[i-1].cost; + int valueChild_4 = vector[i].cost; + if(valueChild_1==-1 || valueChild_2==-1 || valueChild_3==-1 || valueChild_4==-1) + { + continue; + } + else + { + int childSum = valueChild_1 + valueChild_2 + valueChild_3 + valueChild_4; + int posFather = vector[i].posFather; + int costFather = vector[posFather].cost; + int modeFather = vector[posFather].mode; + if(costFather <= childSum && modeFather!=ETM_SPLIT_QT) + { + vector[i-3].cost = vector[i-2].cost = vector[i-1].cost = vector[i].cost = -1; + vector[i-3].mode = vector[i-2].mode = vector[i-1].mode = vector[i].mode = -1; + } + else if(costFather > childSum && modeFather!=ETM_SPLIT_QT) + { + vector[posFather].cost = childSum; + vector[posFather].mode = ETM_SPLIT_QT; + } + } } } void EncCu::cleanCostModeVector() { for(int i=0; iprevQP[ChannelType::CHROMA] = bestCS->prevQP[ChannelType::CHROMA] = prevQP[ChannelType::CHROMA]; //ALBERTO CONCEPT FORK - bool activation = false; - if(!singleMode) - { - activation = singleMode = true; - } compressCtuForks(tempCS,bestCS,partitioner); - if(activation) - { - activation = singleMode = false; - } //END ALBERTO CONCEPT FORK const bool copyUnsplitCTUSignals = bestCS->cus.size() == 1; @@ -823,10 +855,13 @@ bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS, void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Partitioner& partitioner, double maxCostAllowed ) { //ALBERTO + #ifdef TIME_MESSAGE iter += 1; int iterLocal = iter; auto start = std::chrono::high_resolution_clock::now(); + #endif //TIME MESSAGE //END ALBERTO + CHECK(maxCostAllowed < 0, "Wrong value of maxCostAllowed!"); uint32_t compBegin; @@ -1046,8 +1081,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par m_bestBcwIdx.fill(BCW_NUM); } -EncTestMode savedEncMode; -bool activeIgnoreVector = false; +EncTestMode saveMode; +//COMPROBAMOS SI EL MODO DEL VECTOR EN ESA POSICIÓN ES ADECUADO +bool vectorModeAvailable = posActualNode!=0 && vector[posActualNode].mode!=-1 && m_modeCtrl->vectorModeAvailable(vector[posActualNode].mode); do { for (int i = compBegin; i < (compBegin + numComp); i++) @@ -1056,19 +1092,26 @@ bool activeIgnoreVector = false; tempCS->prevPLT.curPLTSize[comID] = curLastPLTSize[comID]; memcpy(tempCS->prevPLT.curPLT[i], curLastPLT[i], curLastPLTSize[comID] * sizeof(Pel)); } - EncTestMode currTestMode = savedEncMode = m_modeCtrl->currTestMode(); + EncTestMode currTestMode = saveMode = m_modeCtrl->currTestMode(); + currTestMode.maxCostAllowed = maxCostAllowed; + //ALBERTO CONCEPT FORK - bool lastModeAvailable = (!singleMode && father && m_modeCtrl->lastModeAvailable(*tempCS, partitioner) && tempCS->cost == MAX_DOUBLE); //SI SOLO QUEDA UN MODO Y EL COSTE ES MÁXIMO, NO PODEMOS SKIPEAR - bool skipMode = (!singleMode && father && vector[posActualNode].mode!=-1 && vector[posActualNode].mode!=currTestMode.type && !ignore_vector && vector[posActualNode].mode!=ETM_RECO_CACHED && !lastModeAvailable); - bool skipCU = (!singleMode && !father && /*1<=posActualNode && posActualNode<=4 &&*/ vector[posActualNode].threadNumber!=threadNumber);//SI ESTAMOS EN UN THREAD INCORRECTO SE HACE SKIP - if(debugMessage) { std::cout << "posActualNode:" << posActualNode << ", Vector:" << vector[posActualNode].mode << ", CurrMode:" << currTestMode.type << std::endl;} + //SI ESTAMOS EN UN THREAD HIJO INCORRECTO EN EL NIVEL DE REPARTO SE HACE SKIP + bool skipCU = (!singleMode && !father && 1<=posActualNode && posActualNode<=4 && vector[posActualNode].threadNumber!=threadNumber); + + #ifdef DEBUG_MESSAGE + std::cout << "posActualNode:" << posActualNode << ", Vector:" << vector[posActualNode].mode << ", CurrMode:" << currTestMode.type << std::endl; + #endif + //SI EL MODO NO COINCIDE CON EL DEL VECTOR DE MODOS SKIP + bool skipMode = (!singleMode && father && vectorModeAvailable && !m_modeCtrl->lastModeAvailable() && vector[posActualNode].mode!=currTestMode.type && vector[posActualNode].mode!=ETM_RECO_CACHED); if(skipMode) { - if(debugMessage) { std::cout << "skip" << std::endl; } + #ifdef DEBUG_MESSAGE + std::cout << "skip" << std::endl; + #endif continue; } //END ALBERTO CONCEPT FORK - currTestMode.maxCostAllowed = maxCostAllowed; if (pps.getUseDQP() && partitioner.isSepTree(*tempCS) && isChroma( partitioner.chType )) { @@ -1108,7 +1151,7 @@ bool activeIgnoreVector = false; } #endif - if( currTestMode.type == ETM_INTER_ME ) + if( currTestMode.type == ETM_INTER_ME && !skipCU) { if( ( currTestMode.opts & ETO_IMV ) != 0 ) { @@ -1133,14 +1176,14 @@ bool activeIgnoreVector = false; } } - else if (currTestMode.type == ETM_HASH_INTER) + else if (currTestMode.type == ETM_HASH_INTER && !skipCU) { xCheckRDCostHashInter( tempCS, bestCS, partitioner, currTestMode ); splitRdCostBest[CTU_LEVEL] = bestCS->cost; tempCS->splitRdCostBest = splitRdCostBest; } #if !JVET_AC0139_UNIFIED_MERGE - else if( currTestMode.type == ETM_AFFINE ) + else if( currTestMode.type == ETM_AFFINE && !skipCU) { xCheckRDCostAffineMerge2Nx2N( tempCS, bestCS, partitioner, currTestMode ); splitRdCostBest[CTU_LEVEL] = bestCS->cost; @@ -1148,14 +1191,14 @@ bool activeIgnoreVector = false; } #endif #if REUSE_CU_RESULTS - else if( currTestMode.type == ETM_RECO_CACHED ) + else if( currTestMode.type == ETM_RECO_CACHED && !skipCU) { xReuseCachedResult( tempCS, bestCS, partitioner ); splitRdCostBest[CTU_LEVEL] = bestCS->cost; tempCS->splitRdCostBest = splitRdCostBest; } #endif - else if( currTestMode.type == ETM_MERGE_SKIP) + else if( currTestMode.type == ETM_MERGE_SKIP && !skipCU) { #if JVET_AC0139_UNIFIED_MERGE xCheckRDCostUnifiedMerge(tempCS, bestCS, partitioner, currTestMode); @@ -1171,7 +1214,7 @@ bool activeIgnoreVector = false; tempCS->splitRdCostBest = splitRdCostBest; } #if !JVET_AC0139_UNIFIED_MERGE - else if( currTestMode.type == ETM_MERGE_GEO ) + else if( currTestMode.type == ETM_MERGE_GEO && !skipCU) { xCheckRDCostMergeGeo2Nx2N( tempCS, bestCS, partitioner, currTestMode ); splitRdCostBest[CTU_LEVEL] = bestCS->cost; @@ -1236,10 +1279,6 @@ bool activeIgnoreVector = false; } else if( isModeSplit( currTestMode ) ) { - //ALBERTO CONCEPT FORK - if(!ignore_vector && currTestMode.type!=ETM_SPLIT_QT) { activeIgnoreVector = ignore_vector = true; }//SI ES LA PRIMERA VEZ QUE NOS ENCONTRAMOS CON UN SPLIT NO QT IGNORAMOS AL VECTOR - //END ALBERTO CONCEPT FORK - if (bestCS->cus.size() != 0) { splitmode = bestCS->cus[0]->splitSeries; @@ -1317,9 +1356,6 @@ bool activeIgnoreVector = false; memcpy(bestLastPLT[i], bestCS->cus[0]->cs->prevPLT.curPLT[i], bestCS->cus[0]->cs->prevPLT.curPLTSize[comID] * sizeof(Pel)); } } - //ALBERTO CONCEPT FORK - if(activeIgnoreVector) { activeIgnoreVector = ignore_vector = false; }//SI SE MARCÓ EN ESTA ITERACIÓN EL IGNORAR AL VECTOR, AL REGRESAR DE DEVUELVE EL VALOR FALSO - //END ALBERTO CONCEPT FORK } else { @@ -1332,11 +1368,13 @@ bool activeIgnoreVector = false; //ALBERTO CONCEPT FORK //PASO 5 -> AL TERMINAR EL BUCLE SE GUARDA EN EL PADRE EL VALOR DEL COSTE Y SE RETORNA - if(debugMessage) { std::cout << "SAVING --> código bucle split " << posActualNode << " : " << " (" << tempCS->area.lheight() <<","<< tempCS->area.lwidth() << ") " << std::endl; } + #ifdef DEBUG_MESSAGE + std::cout << "SAVING --> código bucle split " << posActualNode << " : " << " (" << tempCS->area.lheight() <<","<< tempCS->area.lwidth() << ") " << std::endl; + #endif bool saveModeCost = (!singleMode && !father && vector[posActualNode].mode==-1 && vector[posActualNode].cost==-1 && vector[posActualNode].threadNumber==threadNumber); if(saveModeCost) { - vector[posActualNode].mode=savedEncMode.type; + vector[posActualNode].mode=saveMode.type; vector[posActualNode].cost=bestCS->cost; } //ALBERTO END CONCEPT FORK @@ -1421,6 +1459,7 @@ bool activeIgnoreVector = false; CHECK( bestCS->cost == MAX_DOUBLE , "No possible encoding found" ); //ALBERTO + #ifdef TIME_MESSAGE if (iterLocal == 1) { auto end = std::chrono::high_resolution_clock::now(); @@ -1430,6 +1469,7 @@ bool activeIgnoreVector = false; std::cout << "La func xCompressCU realiza " << iter << " iter que tardan " << static_cast(duration.count() / 1000) << " + " << before << " = " << seconds << " segundos en ejecutarse." << std::endl; iter = 0; } + #endif //END ALBERTO } @@ -1483,36 +1523,7 @@ void EncCu::updateLambda(Slice *slice, const int dQP, #endif // SHARP_LUMA_DELTA_QP || ENABLE_QPA_SUB_CTU //ALBERTO CONCEPT FORK -int EncCu::determinePosNodeInVector(std::string posNode) -{ - int index = -1; - for(int i=0; i1) - { - bool childToSum = true; - for(int j=i; j-1>-1; j--) - { - int codeParent = posNode[j-1] - '0'; - int codeChild = posNode[j] - '0'; - int nodesParentLevel = levelValues[j-1]; - int NodesOtherChild = codeParent * nodesParentLevel; - int NodesChild = 0; - if(childToSum) - { - childToSum = false; - NodesChild = (codeChild + 1); - } - index += NodesOtherChild + NodesChild; - } - } - else - { - index += levelValues[i]; - } - } - return index; -} +//FUNCIONES AUXILIARES PARA xCheckModeSplit() int EncCu::searchFirstChild(int posFather) { int posChild = -1; @@ -1525,37 +1536,6 @@ int EncCu::searchFirstChild(int posFather) } return posChild; } -void EncCu::reduceVector() -{ - for(int i=VECTOR_SIZE-1 ; (i-4)>=0 ; i=i-4) - { - int valueChild_1 = vector[i-3].cost; - int valueChild_2 = vector[i-2].cost; - int valueChild_3 = vector[i-1].cost; - int valueChild_4 = vector[i].cost; - if(valueChild_1==-1 || valueChild_2==-1 || valueChild_3==-1 || valueChild_4==-1) - { - continue; - } - else - { - int childSum = valueChild_1 + valueChild_2 + valueChild_3 + valueChild_4; - int posFather = vector[i].posFather; - int costFather = vector[posFather].cost; - int modeFather = vector[posFather].mode; - if(costFather <= childSum && modeFather!=ETM_SPLIT_QT) - { - vector[i-3].cost = vector[i-2].cost = vector[i-1].cost = vector[i].cost = -1; - vector[i-3].mode = vector[i-2].mode = vector[i-1].mode = vector[i].mode = -1; - } - else if(costFather > childSum && modeFather!=ETM_SPLIT_QT) - { - vector[posFather].cost = childSum; - vector[posFather].mode = ETM_SPLIT_QT; - } - } - } -} //END ALBERTO CONCEPT FORK void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode, const ModeType modeTypeParent, bool &skipInterPass, double *splitRdCostBest ) @@ -1702,21 +1682,21 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, //ALBERTO CONCEPT FORK //PASO 2 -> SI EL SPLIT ES QUAD SE ACTUALIZA NODO ACTUAL - if(debugMessage) - { + #ifdef DEBUG_MESSAGE std::cout << "CONTROL --> código bucle split " << posActualNode << "->" << posChild << " : " << " (" << tempCS->area.lheight() <<","<< tempCS->area.lwidth() << ") " << "->" << " (" << tempSubCS->area.lheight() <<","<< tempSubCS->area.lwidth() <<") " << std::endl; - } + #endif //DEBUG_MESSAGE int restorePosActualNode = posActualNode; - bool fatherUpdate = ((!singleMode && !father && split == CU_QUAD_SPLIT) || (!singleMode && father && split == CU_QUAD_SPLIT && !ignore_vector)); - if(fatherUpdate) { posActualNode=posChild; } - + bool updatePosActualNode = (!singleMode && split == CU_QUAD_SPLIT); + if(updatePosActualNode) { posActualNode=posChild; } + //END ALBERTO CONCEPT FORK + //PASO 3 -> LLAMADA RECURSIVA CON EL HIJO QUE AHORA ES EL PADRE xCompressCU(tempSubCS, bestSubCS, partitioner, newMaxCostAllowed); tempSubCS->bestParent = bestSubCS->bestParent = nullptr; //ALBERTO CONCEPT FORK //PASO 4 -> AL REGRESAR DE LA LLAMADA SI SE HA MODIFICADO EL PADRE SE RESTAURA EL PADRE Y SE AVANZA AL SIGUIENTE HIJO DE LOS 4 - if(fatherUpdate) { posActualNode=restorePosActualNode; posChild++;} + if(updatePosActualNode) { posActualNode=restorePosActualNode; posChild++;} //END ALBERTO CONCEPT FORK if( bestSubCS->cost == MAX_DOUBLE ) diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h index 61a55dea0b4eb0593ce16fed1e2950f4fdd9db6e..c4003e6218990dbbdf5688519b69ae96ee9104dd 100644 --- a/source/Lib/EncoderLib/EncCu.h +++ b/source/Lib/EncoderLib/EncCu.h @@ -320,23 +320,21 @@ private: #endif public: - /// copy parameters from encoder class - void init ( EncLib* pcEncLib, const SPS& sps ); - - //ALBERTO CONCEPT FORK void createSharedVector(); - void repartLevel(); + /*void repartLevel(); int repartStart(); int repartEnd(); void initStructVectorBeforeRepartStart(int repartStartNode); - int thread1NumberOfChild(int numberOfNodesPerThread); + int thread1NumberOfChild(int numberOfNodesPerThread);*/ void initStructVector(); - void updateFatherAndThreadNumbersLevel0(int posPadreActual,int thread1ChildNumber,int numberOfNodesPerThread); - void updateFatherAndThreadNumbers(int LevelLowIndex, int LevelUpIndex, int posPadreActual, int i,int LevelActualIndex,int& childCounter,int thread1ChildNumber,int& threadNumber,int numberOfNodesPerThread); - void cleanCostModeVector(); + void updateFatherAndThreadNumbersLevel0(int posPadreActual);//,int thread1ChildNumber,int numberOfNodesPerThread); + void updateFatherAndThreadNumbers(int LevelLowIndex, int LevelUpIndex, int posPadreActual, int i);//,int LevelActualIndex,int& childCounter,int thread1ChildNumber,int& threadNumber,int numberOfNodesPerThread); // END ALBERTO CONCEPT FORK + /// copy parameters from encoder class + void init ( EncLib* pcEncLib, const SPS& sps ); + void setDecCuReshaperInEncCU(EncReshape* pcReshape, ChromaFormat chromaFormatIdc) { initDecCuReshaper((Reshape*) pcReshape, chromaFormatIdc); @@ -347,9 +345,10 @@ public: /// destroy internal buffers void destroy (); - //ALBERTO CONCEPT FORK - void compressCtuForks(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner); + void compressCtuForks(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner); + void reduceVector(); + void cleanCostModeVector(); //END ALBERTO CONCEPT FORK /// CTU analysis function @@ -382,12 +381,7 @@ protected: xCheckBestMode ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestmode ); //ALBERTO CONCEPT FORK - bool digits_below_or_equal(std::string a, std::string b); - int determinePosNodeInVectorRec(std::string posNode, std::string posSearch, int index, int counter); - int determinePosNodeInVector(std::string posNode); - int searchFirstChildEmpty(int posFather); int searchFirstChild(int posFather); - void reduceVector(); // END ALBERTO CONCEPT FORK void xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode &encTestMode, const ModeType modeTypeParent, bool &skipInterPass, double *splitRdCostBest); diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp index 089345c6241e085d421266f8a36d164affb38bb6..96119c55c328634ae93bd790dca5404087e8762c 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.cpp +++ b/source/Lib/EncoderLib/EncModeCtrl.cpp @@ -104,10 +104,25 @@ bool EncModeCtrl::nextMode( const CodingStructure &cs, Partitioner &partitioner } //ALBERTO CONCEPT FORK -bool EncModeCtrl::lastModeAvailable( const CodingStructure &cs, Partitioner &partitioner ) +bool EncModeCtrl::lastModeAvailable() const { return !m_ComprCUCtxList.empty() && !m_ComprCUCtxList.back().testModes.empty() && m_ComprCUCtxList.back().testModes.size()==1; } +bool EncModeCtrl::vectorModeAvailable(int objetiveModeType) const +{ + bool vectorModeAvailable = false; + const auto& lastElem = m_ComprCUCtxList.back(); + const auto& testModes = lastElem.testModes; + + for (const auto& actualMode : testModes) + { + if(actualMode.type == objetiveModeType) + { + vectorModeAvailable = true; + } + } + return vectorModeAvailable; +} //END ALBERTO CONCEPT FORK EncTestMode EncModeCtrl::currTestMode() const diff --git a/source/Lib/EncoderLib/EncModeCtrl.h b/source/Lib/EncoderLib/EncModeCtrl.h index 0eedb8b33b4bc931e3523b898d4b676866862aae..3ff9a90c4527e86c1dc7a6614255518a170bd689 100644 --- a/source/Lib/EncoderLib/EncModeCtrl.h +++ b/source/Lib/EncoderLib/EncModeCtrl.h @@ -327,7 +327,8 @@ public: bool tryModeMaster ( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner ); bool nextMode ( const CodingStructure &cs, Partitioner &partitioner ); //ALBERTO CONCEPT FORK - bool lastModeAvailable(const CodingStructure &cs, Partitioner &partitioner); + bool lastModeAvailable() const; + bool vectorModeAvailable(int modeType) const; //END ALBERTO CONCEPT FORK EncTestMode currTestMode() const; EncTestMode lastTestMode () const;