Newer
Older

Karsten Suehring
committed
if( !bestCS || ( bestCS && isModeSplit( bestMode ) ) )
{
return false;
}
else
{
#if REUSE_CU_RESULTS
setFromCs( *bestCS, partitioner );
#endif
// assume the non-split modes are done and set the marks for the best found mode
if( bestCS && bestCU )
{
if( CU::isInter( *bestCU ) )
{
relatedCU.isInter = true;
#if HM_CODED_CU_INFO
relatedCU.isSkip |= bestCU->skip;
relatedCU.isMMVDSkip |= bestCU->mmvdSkip;

Karsten Suehring
committed
#else
relatedCU.isSkip = bestCU->skip;
#endif
relatedCU.GBiIdx = bestCU->GBiIdx;

Karsten Suehring
committed
}
else if (CU::isIBC(*bestCU))
{
relatedCU.isIBC = true;
#if HM_CODED_CU_INFO
relatedCU.isSkip |= bestCU->skip;
#endif
}
#endif

Karsten Suehring
committed
else if( CU::isIntra( *bestCU ) )
{
relatedCU.isIntra = true;
}
#if ENABLE_SPLIT_PARALLELISM
#if REUSE_CU_RESULTS
BestEncInfoCache::touch(partitioner.currArea());
#endif
CacheBlkInfoCtrl::touch(partitioner.currArea());

Karsten Suehring
committed
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
#endif
cuECtx.set( IS_BEST_NOSPLIT_SKIP, bestCU->skip );
}
}
return false;
}
}
bool EncModeCtrlMTnoRQT::useModeResult( const EncTestMode& encTestmode, CodingStructure*& tempCS, Partitioner& partitioner )
{
xExtractFeatures( encTestmode, *tempCS );
ComprCUCtx& cuECtx = m_ComprCUCtxList.back();
if( encTestmode.type == ETM_SPLIT_BT_H )
{
cuECtx.set( BEST_HORZ_SPLIT_COST, tempCS->cost );
}
else if( encTestmode.type == ETM_SPLIT_BT_V )
{
cuECtx.set( BEST_VERT_SPLIT_COST, tempCS->cost );
}
else if( encTestmode.type == ETM_SPLIT_TT_H )
{
cuECtx.set( BEST_TRIH_SPLIT_COST, tempCS->cost );
}
else if( encTestmode.type == ETM_SPLIT_TT_V )
{
cuECtx.set( BEST_TRIV_SPLIT_COST, tempCS->cost );
}

Karsten Suehring
committed
{
const CodingUnit cu = *tempCS->getCU( partitioner.chType );
if( !cu.emtFlag )
{
cuECtx.bestEmtSize2Nx2N1stPass = tempCS->cost;
}
#if JVET_M0102_INTRA_SUBPARTITIONS
if (!cu.ispMode)
{
cuECtx.bestCostEmtFirstPassNoIsp = tempCS->cost;
}
#endif

Karsten Suehring
committed
}

Karsten Suehring
committed
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
if( m_pcEncCfg->getIMV4PelFast() && m_pcEncCfg->getIMV() && encTestmode.type == ETM_INTER_ME )
{
int imvMode = ( encTestmode.opts & ETO_IMV ) >> ETO_IMV_SHIFT;
if( imvMode == 1 )
{
if( tempCS->cost < cuECtx.get<double>( BEST_IMV_COST ) )
{
cuECtx.set( BEST_IMV_COST, tempCS->cost );
}
}
else if( imvMode == 0 )
{
if( tempCS->cost < cuECtx.get<double>( BEST_NO_IMV_COST ) )
{
cuECtx.set( BEST_NO_IMV_COST, tempCS->cost );
}
}
}
if( encTestmode.type == ETM_SPLIT_QT )
{
int maxQtD = 0;
for( const auto& cu : tempCS->cus )
{
maxQtD = std::max<int>( maxQtD, cu->qtDepth );
}
cuECtx.set( MAX_QT_SUB_DEPTH, maxQtD );
}
int maxMtD = tempCS->pcv->getMaxBtDepth( *tempCS->slice, partitioner.chType ) + partitioner.currImplicitBtDepth;

Karsten Suehring
committed
if( encTestmode.type == ETM_SPLIT_BT_H )
{
if( tempCS->cus.size() > 2 )

Karsten Suehring
committed
{
int h_2 = tempCS->area.blocks[partitioner.chType].height / 2;
int cu1_h = tempCS->cus.front()->blocks[partitioner.chType].height;
int cu2_h = tempCS->cus.back() ->blocks[partitioner.chType].height;

Karsten Suehring
committed
cuECtx.set( DO_TRIH_SPLIT, cu1_h < h_2 || cu2_h < h_2 || partitioner.currMtDepth + 1 == maxMtD );

Karsten Suehring
committed
}
}
else if( encTestmode.type == ETM_SPLIT_BT_V )
{
if( tempCS->cus.size() > 2 )

Karsten Suehring
committed
{
int w_2 = tempCS->area.blocks[partitioner.chType].width / 2;
int cu1_w = tempCS->cus.front()->blocks[partitioner.chType].width;
int cu2_w = tempCS->cus.back() ->blocks[partitioner.chType].width;

Karsten Suehring
committed
cuECtx.set( DO_TRIV_SPLIT, cu1_w < w_2 || cu2_w < w_2 || partitioner.currMtDepth + 1 == maxMtD );

Karsten Suehring
committed
}
}
// for now just a simple decision based on RD-cost or choose tempCS if bestCS is not yet coded
#if JVET_M0445_MCTS
if( tempCS->features[ENC_FT_RD_COST] != MAX_DOUBLE && ( !cuECtx.bestCS || ( ( tempCS->features[ENC_FT_RD_COST] + ( tempCS->useDbCost ? tempCS->costDbOffset : 0 ) ) < ( cuECtx.bestCS->features[ENC_FT_RD_COST] + ( tempCS->useDbCost ? cuECtx.bestCS->costDbOffset : 0 ) ) ) ) )
#else
if( !cuECtx.bestCS || ( ( tempCS->features[ENC_FT_RD_COST] + ( tempCS->useDbCost ? tempCS->costDbOffset : 0 ) ) < ( cuECtx.bestCS->features[ENC_FT_RD_COST] + ( tempCS->useDbCost ? cuECtx.bestCS->costDbOffset : 0 ) ) ) )
#endif
#else
#if JVET_M0445_MCTS
if( tempCS->features[ENC_FT_RD_COST] != MAX_DOUBLE && ( !cuECtx.bestCS || tempCS->features[ENC_FT_RD_COST] < cuECtx.bestCS->features[ENC_FT_RD_COST] ) )

Karsten Suehring
committed
if( !cuECtx.bestCS || tempCS->features[ENC_FT_RD_COST] < cuECtx.bestCS->features[ENC_FT_RD_COST] )
#endif

Karsten Suehring
committed
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
{
cuECtx.bestCS = tempCS;
cuECtx.bestCU = tempCS->cus[0];
cuECtx.bestTU = cuECtx.bestCU->firstTU;
if( isModeInter( encTestmode ) )
{
//Here we take the best cost of both inter modes. We are assuming only the inter modes (and all of them) have come before the intra modes!!!
cuECtx.bestInterCost = cuECtx.bestCS->cost;
}
return true;
}
else
{
return false;
}
}
#if ENABLE_SPLIT_PARALLELISM
void EncModeCtrlMTnoRQT::copyState( const EncModeCtrl& other, const UnitArea& area )
{
const EncModeCtrlMTnoRQT* pOther = dynamic_cast<const EncModeCtrlMTnoRQT*>( &other );
CHECK( !pOther, "Trying to copy state from a different type of controller" );
this->EncModeCtrl ::copyState( *pOther, area );
this->CacheBlkInfoCtrl ::copyState( *pOther, area );
#if REUSE_CU_RESULTS
this->BestEncInfoCache ::copyState( *pOther, area );
#endif
this->SaveLoadEncInfoSbt ::copyState( *pOther );

Karsten Suehring
committed
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
m_skipThreshold = pOther->m_skipThreshold;
}
int EncModeCtrlMTnoRQT::getNumParallelJobs( const CodingStructure &cs, Partitioner& partitioner ) const
{
int numJobs = 1; // for no-split coding
if( partitioner.canSplit( CU_QUAD_SPLIT, cs ) )
{
numJobs = 2;
}
if( partitioner.canSplit( CU_VERT_SPLIT, cs ) )
{
numJobs = 3;
}
if( partitioner.canSplit( CU_HORZ_SPLIT, cs ) )
{
numJobs = 4;
}
if( partitioner.canSplit( CU_TRIV_SPLIT, cs ) )
{
numJobs = 5;
}
if( partitioner.canSplit( CU_TRIH_SPLIT, cs ) )
{
numJobs = 6;
}
CHECK( numJobs >= NUM_RESERVERD_SPLIT_JOBS, "More jobs specified than allowed" );
return numJobs;
}
bool EncModeCtrlMTnoRQT::isParallelSplit( const CodingStructure &cs, Partitioner& partitioner ) const
{
if( partitioner.getImplicitSplit( cs ) != CU_DONT_SPLIT || cs.picture->scheduler.getSplitJobId() != 0 ) return false;
const int numJobs = getNumParallelJobs( cs, partitioner );
const int numPxl = partitioner.currArea().Y().area();
const int parlAt = m_pcEncCfg->getNumSplitThreads() <= 3 ? 1024 : 256;
if( cs.slice->isIntra() && numJobs > 2 && ( numPxl == parlAt || !partitioner.canSplit( CU_QUAD_SPLIT, cs ) ) ) return true;
if( !cs.slice->isIntra() && numJobs > 1 && ( numPxl == parlAt || !partitioner.canSplit( CU_QUAD_SPLIT, cs ) ) ) return true;
return false;
}
bool EncModeCtrlMTnoRQT::parallelJobSelector( const EncTestMode& encTestmode, const CodingStructure &cs, Partitioner& partitioner ) const
{
// Job descriptors
// - 1: all non-split modes
// - 2: QT-split
// - 3: all vertical modes but TT_V
// - 4: all horizontal modes but TT_H
// - 5: TT_V
// - 6: TT_H
switch( cs.picture->scheduler.getSplitJobId() )
{
case 1:
// be sure to execute post dont split
return !isModeSplit( encTestmode );
break;
case 2:
return encTestmode.type == ETM_SPLIT_QT;
break;
case 3:
switch( encTestmode.type )
{
case ETM_SPLIT_BT_V:
return true;
break;
default:
return false;
break;
}
break;
case 4:
switch( encTestmode.type )
{
case ETM_SPLIT_BT_H:
return true;
break;
default:
return false;
break;
}
break;
case 5:
return encTestmode.type == ETM_SPLIT_TT_V;
break;
case 6:
return encTestmode.type == ETM_SPLIT_TT_H;
break;
default:
THROW( "Unknown job-ID for parallelization of EncModeCtrlMTnoRQT: " << cs.picture->scheduler.getSplitJobId() );
break;
}
}
#endif