1 | /* The copyright in this software is being made available under the BSD |
---|
2 | * License, included below. This software may be subject to other third party |
---|
3 | * and contributor rights, including patent rights, and no such rights are |
---|
4 | * granted under this license. |
---|
5 | * |
---|
6 | * Copyright (c) 2010-2018, ITU/ISO/IEC |
---|
7 | * All rights reserved. |
---|
8 | * |
---|
9 | * Redistribution and use in source and binary forms, with or without |
---|
10 | * modification, are permitted provided that the following conditions are met: |
---|
11 | * |
---|
12 | * * Redistributions of source code must retain the above copyright notice, |
---|
13 | * this list of conditions and the following disclaimer. |
---|
14 | * * Redistributions in binary form must reproduce the above copyright notice, |
---|
15 | * this list of conditions and the following disclaimer in the documentation |
---|
16 | * and/or other materials provided with the distribution. |
---|
17 | * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may |
---|
18 | * be used to endorse or promote products derived from this software without |
---|
19 | * specific prior written permission. |
---|
20 | * |
---|
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
---|
22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS |
---|
25 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
---|
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
---|
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
---|
28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
---|
29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
---|
30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
---|
31 | * THE POSSIBILITY OF SUCH DAMAGE. |
---|
32 | */ |
---|
33 | |
---|
34 | /** \file EncSearch.cpp |
---|
35 | * \brief encoder inter search class |
---|
36 | */ |
---|
37 | |
---|
38 | #include "InterSearch.h" |
---|
39 | |
---|
40 | |
---|
41 | #include "CommonLib/CommonDef.h" |
---|
42 | #include "CommonLib/Rom.h" |
---|
43 | #include "CommonLib/MotionInfo.h" |
---|
44 | #include "CommonLib/Picture.h" |
---|
45 | #include "CommonLib/UnitTools.h" |
---|
46 | #include "CommonLib/dtrace_next.h" |
---|
47 | #include "CommonLib/dtrace_buffer.h" |
---|
48 | #if JEM_TOOLS |
---|
49 | #include "CommonLib/BilateralFilter.h" |
---|
50 | #endif |
---|
51 | |
---|
52 | #include "EncModeCtrl.h" |
---|
53 | #include "EncLib.h" |
---|
54 | |
---|
55 | #include <math.h> |
---|
56 | #include <limits> |
---|
57 | |
---|
58 | |
---|
59 | //! \ingroup EncoderLib |
---|
60 | //! \{ |
---|
61 | |
---|
62 | static const Mv s_acMvRefineH[9] = |
---|
63 | { |
---|
64 | Mv( 0, 0 ), // 0 |
---|
65 | Mv( 0, -1 ), // 1 |
---|
66 | Mv( 0, 1 ), // 2 |
---|
67 | Mv( -1, 0 ), // 3 |
---|
68 | Mv( 1, 0 ), // 4 |
---|
69 | Mv( -1, -1 ), // 5 |
---|
70 | Mv( 1, -1 ), // 6 |
---|
71 | Mv( -1, 1 ), // 7 |
---|
72 | Mv( 1, 1 ) // 8 |
---|
73 | }; |
---|
74 | |
---|
75 | static const Mv s_acMvRefineQ[9] = |
---|
76 | { |
---|
77 | Mv( 0, 0 ), // 0 |
---|
78 | Mv( 0, -1 ), // 1 |
---|
79 | Mv( 0, 1 ), // 2 |
---|
80 | Mv( -1, -1 ), // 5 |
---|
81 | Mv( 1, -1 ), // 6 |
---|
82 | Mv( -1, 0 ), // 3 |
---|
83 | Mv( 1, 0 ), // 4 |
---|
84 | Mv( -1, 1 ), // 7 |
---|
85 | Mv( 1, 1 ) // 8 |
---|
86 | }; |
---|
87 | |
---|
88 | |
---|
89 | InterSearch::InterSearch() |
---|
90 | : m_modeCtrl (nullptr) |
---|
91 | , m_pSplitCS (nullptr) |
---|
92 | , m_pFullCS (nullptr) |
---|
93 | , m_pcEncCfg (nullptr) |
---|
94 | , m_pcTrQuant (nullptr) |
---|
95 | #if JEM_TOOLS |
---|
96 | , m_bilateralFilter (nullptr) |
---|
97 | #endif |
---|
98 | , m_iSearchRange (0) |
---|
99 | , m_bipredSearchRange (0) |
---|
100 | , m_motionEstimationSearchMethod(MESEARCH_FULL) |
---|
101 | , m_CABACEstimator (nullptr) |
---|
102 | , m_CtxCache (nullptr) |
---|
103 | , m_pTempPel (nullptr) |
---|
104 | , m_isInitialized (false) |
---|
105 | { |
---|
106 | for (int i=0; i<MAX_NUM_REF_LIST_ADAPT_SR; i++) |
---|
107 | { |
---|
108 | memset (m_aaiAdaptSR[i], 0, MAX_IDX_ADAPT_SR * sizeof (int)); |
---|
109 | } |
---|
110 | for (int i=0; i<AMVP_MAX_NUM_CANDS+1; i++) |
---|
111 | { |
---|
112 | memset (m_auiMVPIdxCost[i], 0, (AMVP_MAX_NUM_CANDS+1) * sizeof (uint32_t) ); |
---|
113 | } |
---|
114 | |
---|
115 | setWpScalingDistParam( -1, REF_PIC_LIST_X, nullptr ); |
---|
116 | } |
---|
117 | |
---|
118 | |
---|
119 | void InterSearch::destroy() |
---|
120 | { |
---|
121 | CHECK(!m_isInitialized, "Not initialized"); |
---|
122 | if ( m_pTempPel ) |
---|
123 | { |
---|
124 | delete [] m_pTempPel; |
---|
125 | m_pTempPel = NULL; |
---|
126 | } |
---|
127 | |
---|
128 | m_pSplitCS = m_pFullCS = nullptr; |
---|
129 | |
---|
130 | m_pSaveCS = nullptr; |
---|
131 | |
---|
132 | for(uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++) |
---|
133 | { |
---|
134 | m_tmpPredStorage[i].destroy(); |
---|
135 | } |
---|
136 | m_tmpStorageLCU.destroy(); |
---|
137 | m_tmpAffiStorage.destroy(); |
---|
138 | |
---|
139 | if ( m_tmpAffiError != NULL ) |
---|
140 | { |
---|
141 | delete[] m_tmpAffiError; |
---|
142 | } |
---|
143 | if ( m_tmpAffiDeri[0] != NULL ) |
---|
144 | { |
---|
145 | delete[] m_tmpAffiDeri[0]; |
---|
146 | } |
---|
147 | if ( m_tmpAffiDeri[1] != NULL ) |
---|
148 | { |
---|
149 | delete[] m_tmpAffiDeri[1]; |
---|
150 | } |
---|
151 | #if JEM_TOOLS |
---|
152 | m_obmcOrgMod.destroy(); |
---|
153 | #endif |
---|
154 | m_isInitialized = false; |
---|
155 | } |
---|
156 | |
---|
157 | void InterSearch::setTempBuffers( CodingStructure ****pSplitCS, CodingStructure ****pFullCS, CodingStructure **pSaveCS ) |
---|
158 | { |
---|
159 | m_pSplitCS = pSplitCS; |
---|
160 | m_pFullCS = pFullCS; |
---|
161 | m_pSaveCS = pSaveCS; |
---|
162 | } |
---|
163 | |
---|
164 | #if ENABLE_SPLIT_PARALLELISM |
---|
165 | void InterSearch::copyState( const InterSearch& other ) |
---|
166 | { |
---|
167 | if( !m_pcEncCfg->getQTBT() ) |
---|
168 | { |
---|
169 | memcpy( m_integerMv2Nx2N, other.m_integerMv2Nx2N, sizeof( m_integerMv2Nx2N ) ); |
---|
170 | } |
---|
171 | |
---|
172 | memcpy( m_aaiAdaptSR, other.m_aaiAdaptSR, sizeof( m_aaiAdaptSR ) ); |
---|
173 | } |
---|
174 | #endif |
---|
175 | |
---|
176 | InterSearch::~InterSearch() |
---|
177 | { |
---|
178 | if (m_isInitialized) |
---|
179 | { |
---|
180 | destroy(); |
---|
181 | } |
---|
182 | } |
---|
183 | |
---|
184 | void InterSearch::init( EncCfg* pcEncCfg, |
---|
185 | TrQuant* pcTrQuant, |
---|
186 | #if JEM_TOOLS |
---|
187 | BilateralFilter* |
---|
188 | bilateralFilter, |
---|
189 | #endif |
---|
190 | int iSearchRange, |
---|
191 | int bipredSearchRange, |
---|
192 | MESearchMethod motionEstimationSearchMethod, |
---|
193 | const uint32_t maxCUWidth, |
---|
194 | const uint32_t maxCUHeight, |
---|
195 | const uint32_t maxTotalCUDepth, |
---|
196 | RdCost* pcRdCost, |
---|
197 | CABACWriter* CABACEstimator, |
---|
198 | CtxCache* ctxCache |
---|
199 | ) |
---|
200 | { |
---|
201 | CHECK(m_isInitialized, "Already initialized"); |
---|
202 | m_pcEncCfg = pcEncCfg; |
---|
203 | m_pcTrQuant = pcTrQuant; |
---|
204 | #if JEM_TOOLS |
---|
205 | m_bilateralFilter = bilateralFilter; |
---|
206 | #endif |
---|
207 | m_iSearchRange = iSearchRange; |
---|
208 | m_bipredSearchRange = bipredSearchRange; |
---|
209 | m_motionEstimationSearchMethod = motionEstimationSearchMethod; |
---|
210 | m_CABACEstimator = CABACEstimator; |
---|
211 | m_CtxCache = ctxCache; |
---|
212 | |
---|
213 | for( uint32_t iDir = 0; iDir < MAX_NUM_REF_LIST_ADAPT_SR; iDir++ ) |
---|
214 | { |
---|
215 | for( uint32_t iRefIdx = 0; iRefIdx < MAX_IDX_ADAPT_SR; iRefIdx++ ) |
---|
216 | { |
---|
217 | m_aaiAdaptSR[iDir][iRefIdx] = iSearchRange; |
---|
218 | } |
---|
219 | } |
---|
220 | |
---|
221 | // initialize motion cost |
---|
222 | for( int iNum = 0; iNum < AMVP_MAX_NUM_CANDS + 1; iNum++ ) |
---|
223 | { |
---|
224 | for( int iIdx = 0; iIdx < AMVP_MAX_NUM_CANDS; iIdx++ ) |
---|
225 | { |
---|
226 | if( iIdx < iNum ) |
---|
227 | { |
---|
228 | m_auiMVPIdxCost[iIdx][iNum] = xGetMvpIdxBits( iIdx, iNum ); |
---|
229 | } |
---|
230 | else |
---|
231 | { |
---|
232 | #if DISTORTION_TYPE_BUGFIX |
---|
233 | m_auiMVPIdxCost[iIdx][iNum] = MAX_UINT; |
---|
234 | #else |
---|
235 | m_auiMVPIdxCost[iIdx][iNum] = MAX_INT; |
---|
236 | #endif |
---|
237 | } |
---|
238 | } |
---|
239 | } |
---|
240 | |
---|
241 | const ChromaFormat cform = pcEncCfg->getChromaFormatIdc(); |
---|
242 | InterPrediction::init( pcRdCost, cform ); |
---|
243 | |
---|
244 | for( uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++ ) |
---|
245 | { |
---|
246 | m_tmpPredStorage[i].create( UnitArea( cform, Area( 0, 0, MAX_CU_SIZE, MAX_CU_SIZE ) ) ); |
---|
247 | } |
---|
248 | m_tmpStorageLCU.create( UnitArea( cform, Area( 0, 0, MAX_CU_SIZE, MAX_CU_SIZE ) ) ); |
---|
249 | m_tmpAffiStorage.create( UnitArea( cform, Area( 0, 0, MAX_CU_SIZE, MAX_CU_SIZE ) ) ); |
---|
250 | #if JVET_K0367_AFFINE_FIX_POINT |
---|
251 | m_tmpAffiError = new Pel[MAX_CU_SIZE * MAX_CU_SIZE]; |
---|
252 | m_tmpAffiDeri[0] = new int[MAX_CU_SIZE * MAX_CU_SIZE]; |
---|
253 | m_tmpAffiDeri[1] = new int[MAX_CU_SIZE * MAX_CU_SIZE]; |
---|
254 | #else |
---|
255 | m_tmpAffiError = new int [MAX_CU_SIZE * MAX_CU_SIZE]; |
---|
256 | m_tmpAffiDeri[0] = new double[MAX_CU_SIZE * MAX_CU_SIZE]; |
---|
257 | m_tmpAffiDeri[1] = new double[MAX_CU_SIZE * MAX_CU_SIZE]; |
---|
258 | #endif |
---|
259 | #if JEM_TOOLS |
---|
260 | m_obmcOrgMod.create( UnitArea( cform, Area( 0, 0, MAX_CU_SIZE, MAX_CU_SIZE ) ) ); |
---|
261 | #endif |
---|
262 | m_pTempPel = new Pel[maxCUWidth*maxCUHeight]; |
---|
263 | |
---|
264 | m_isInitialized = true; |
---|
265 | } |
---|
266 | |
---|
267 | |
---|
268 | inline void InterSearch::xTZSearchHelp( IntTZSearchStruct& rcStruct, const int iSearchX, const int iSearchY, const uint8_t ucPointNr, const uint32_t uiDistance ) |
---|
269 | { |
---|
270 | Distortion uiSad = 0; |
---|
271 | |
---|
272 | // CHECK(!( !( rcStruct.searchRange.left > iSearchX || rcStruct.searchRange.right < iSearchX || rcStruct.searchRange.top > iSearchY || rcStruct.searchRange.bottom < iSearchY )), "Unspecified error"); |
---|
273 | |
---|
274 | const Pel* const piRefSrch = rcStruct.piRefY + iSearchY * rcStruct.iRefStride + iSearchX; |
---|
275 | |
---|
276 | m_cDistParam.cur.buf = piRefSrch; |
---|
277 | |
---|
278 | if( 1 == rcStruct.subShiftMode ) |
---|
279 | { |
---|
280 | // motion cost |
---|
281 | #if JVET_K0357_AMVR |
---|
282 | Distortion uiBitCost = m_pcRdCost->getCostOfVectorWithPredictor( iSearchX, iSearchY, rcStruct.imvShift ); |
---|
283 | #else |
---|
284 | Distortion uiBitCost = m_pcRdCost->getCostOfVectorWithPredictor( iSearchX, iSearchY ); |
---|
285 | #endif |
---|
286 | |
---|
287 | // Skip search if bit cost is already larger than best SAD |
---|
288 | if (uiBitCost < rcStruct.uiBestSad) |
---|
289 | { |
---|
290 | Distortion uiTempSad = m_cDistParam.distFunc( m_cDistParam ); |
---|
291 | |
---|
292 | if((uiTempSad + uiBitCost) < rcStruct.uiBestSad) |
---|
293 | { |
---|
294 | // it's not supposed that any member of DistParams is manipulated beside cur.buf |
---|
295 | int subShift = m_cDistParam.subShift; |
---|
296 | const Pel* pOrgCpy = m_cDistParam.org.buf; |
---|
297 | uiSad += uiTempSad >> m_cDistParam.subShift; |
---|
298 | |
---|
299 | while( m_cDistParam.subShift > 0 ) |
---|
300 | { |
---|
301 | int isubShift = m_cDistParam.subShift -1; |
---|
302 | m_cDistParam.org.buf = rcStruct.pcPatternKey->buf + (rcStruct.pcPatternKey->stride << isubShift); |
---|
303 | m_cDistParam.cur.buf = piRefSrch + (rcStruct.iRefStride << isubShift); |
---|
304 | uiTempSad = m_cDistParam.distFunc( m_cDistParam ); |
---|
305 | uiSad += uiTempSad >> m_cDistParam.subShift; |
---|
306 | |
---|
307 | if(((uiSad << isubShift) + uiBitCost) > rcStruct.uiBestSad) |
---|
308 | { |
---|
309 | break; |
---|
310 | } |
---|
311 | |
---|
312 | m_cDistParam.subShift--; |
---|
313 | } |
---|
314 | |
---|
315 | if(m_cDistParam.subShift == 0) |
---|
316 | { |
---|
317 | uiSad += uiBitCost; |
---|
318 | |
---|
319 | if( uiSad < rcStruct.uiBestSad ) |
---|
320 | { |
---|
321 | rcStruct.uiBestSad = uiSad; |
---|
322 | rcStruct.iBestX = iSearchX; |
---|
323 | rcStruct.iBestY = iSearchY; |
---|
324 | rcStruct.uiBestDistance = uiDistance; |
---|
325 | rcStruct.uiBestRound = 0; |
---|
326 | rcStruct.ucPointNr = ucPointNr; |
---|
327 | m_cDistParam.maximumDistortionForEarlyExit = uiSad; |
---|
328 | } |
---|
329 | } |
---|
330 | |
---|
331 | // restore org ptr |
---|
332 | m_cDistParam.org.buf = pOrgCpy; |
---|
333 | m_cDistParam.subShift = subShift; |
---|
334 | } |
---|
335 | } |
---|
336 | } |
---|
337 | else |
---|
338 | { |
---|
339 | uiSad = m_cDistParam.distFunc( m_cDistParam ); |
---|
340 | |
---|
341 | // only add motion cost if uiSad is smaller than best. Otherwise pointless |
---|
342 | // to add motion cost. |
---|
343 | if( uiSad < rcStruct.uiBestSad ) |
---|
344 | { |
---|
345 | // motion cost |
---|
346 | #if JVET_K0357_AMVR |
---|
347 | uiSad += m_pcRdCost->getCostOfVectorWithPredictor( iSearchX, iSearchY, rcStruct.imvShift ); |
---|
348 | #else |
---|
349 | uiSad += m_pcRdCost->getCostOfVectorWithPredictor( iSearchX, iSearchY ); |
---|
350 | #endif |
---|
351 | |
---|
352 | if( uiSad < rcStruct.uiBestSad ) |
---|
353 | { |
---|
354 | rcStruct.uiBestSad = uiSad; |
---|
355 | rcStruct.iBestX = iSearchX; |
---|
356 | rcStruct.iBestY = iSearchY; |
---|
357 | rcStruct.uiBestDistance = uiDistance; |
---|
358 | rcStruct.uiBestRound = 0; |
---|
359 | rcStruct.ucPointNr = ucPointNr; |
---|
360 | m_cDistParam.maximumDistortionForEarlyExit = uiSad; |
---|
361 | } |
---|
362 | } |
---|
363 | } |
---|
364 | } |
---|
365 | |
---|
366 | |
---|
367 | |
---|
368 | inline void InterSearch::xTZ2PointSearch( IntTZSearchStruct& rcStruct ) |
---|
369 | { |
---|
370 | const SearchRange& sr = rcStruct.searchRange; |
---|
371 | |
---|
372 | static const int xOffset[2][9] = { { 0, -1, -1, 0, -1, +1, -1, -1, +1 }, { 0, 0, +1, +1, -1, +1, 0, +1, 0 } }; |
---|
373 | static const int yOffset[2][9] = { { 0, 0, -1, -1, +1, -1, 0, +1, 0 }, { 0, -1, -1, 0, -1, +1, +1, +1, +1 } }; |
---|
374 | |
---|
375 | // 2 point search, // 1 2 3 |
---|
376 | // check only the 2 untested points // 4 0 5 |
---|
377 | // around the start point // 6 7 8 |
---|
378 | const int iX1 = rcStruct.iBestX + xOffset[0][rcStruct.ucPointNr]; |
---|
379 | const int iX2 = rcStruct.iBestX + xOffset[1][rcStruct.ucPointNr]; |
---|
380 | |
---|
381 | const int iY1 = rcStruct.iBestY + yOffset[0][rcStruct.ucPointNr]; |
---|
382 | const int iY2 = rcStruct.iBestY + yOffset[1][rcStruct.ucPointNr]; |
---|
383 | |
---|
384 | if( iX1 >= sr.left && iX1 <= sr.right && iY1 >= sr.top && iY1 <= sr.bottom ) |
---|
385 | { |
---|
386 | xTZSearchHelp( rcStruct, iX1, iY1, 0, 2 ); |
---|
387 | } |
---|
388 | |
---|
389 | if( iX2 >= sr.left && iX2 <= sr.right && iY2 >= sr.top && iY2 <= sr.bottom ) |
---|
390 | { |
---|
391 | xTZSearchHelp( rcStruct, iX2, iY2, 0, 2 ); |
---|
392 | } |
---|
393 | } |
---|
394 | |
---|
395 | |
---|
396 | inline void InterSearch::xTZ8PointSquareSearch( IntTZSearchStruct& rcStruct, const int iStartX, const int iStartY, const int iDist ) |
---|
397 | { |
---|
398 | const SearchRange& sr = rcStruct.searchRange; |
---|
399 | // 8 point search, // 1 2 3 |
---|
400 | // search around the start point // 4 0 5 |
---|
401 | // with the required distance // 6 7 8 |
---|
402 | CHECK( iDist == 0 , "Invalid distance"); |
---|
403 | const int iTop = iStartY - iDist; |
---|
404 | const int iBottom = iStartY + iDist; |
---|
405 | const int iLeft = iStartX - iDist; |
---|
406 | const int iRight = iStartX + iDist; |
---|
407 | rcStruct.uiBestRound += 1; |
---|
408 | |
---|
409 | if ( iTop >= sr.top ) // check top |
---|
410 | { |
---|
411 | if ( iLeft >= sr.left ) // check top left |
---|
412 | { |
---|
413 | xTZSearchHelp( rcStruct, iLeft, iTop, 1, iDist ); |
---|
414 | } |
---|
415 | // top middle |
---|
416 | xTZSearchHelp( rcStruct, iStartX, iTop, 2, iDist ); |
---|
417 | |
---|
418 | if ( iRight <= sr.right ) // check top right |
---|
419 | { |
---|
420 | xTZSearchHelp( rcStruct, iRight, iTop, 3, iDist ); |
---|
421 | } |
---|
422 | } // check top |
---|
423 | if ( iLeft >= sr.left ) // check middle left |
---|
424 | { |
---|
425 | xTZSearchHelp( rcStruct, iLeft, iStartY, 4, iDist ); |
---|
426 | } |
---|
427 | if ( iRight <= sr.right ) // check middle right |
---|
428 | { |
---|
429 | xTZSearchHelp( rcStruct, iRight, iStartY, 5, iDist ); |
---|
430 | } |
---|
431 | if ( iBottom <= sr.bottom ) // check bottom |
---|
432 | { |
---|
433 | if ( iLeft >= sr.left ) // check bottom left |
---|
434 | { |
---|
435 | xTZSearchHelp( rcStruct, iLeft, iBottom, 6, iDist ); |
---|
436 | } |
---|
437 | // check bottom middle |
---|
438 | xTZSearchHelp( rcStruct, iStartX, iBottom, 7, iDist ); |
---|
439 | |
---|
440 | if ( iRight <= sr.right ) // check bottom right |
---|
441 | { |
---|
442 | xTZSearchHelp( rcStruct, iRight, iBottom, 8, iDist ); |
---|
443 | } |
---|
444 | } // check bottom |
---|
445 | } |
---|
446 | |
---|
447 | |
---|
448 | |
---|
449 | |
---|
450 | inline void InterSearch::xTZ8PointDiamondSearch( IntTZSearchStruct& rcStruct, |
---|
451 | const int iStartX, |
---|
452 | const int iStartY, |
---|
453 | const int iDist, |
---|
454 | const bool bCheckCornersAtDist1 ) |
---|
455 | { |
---|
456 | const SearchRange& sr = rcStruct.searchRange; |
---|
457 | // 8 point search, // 1 2 3 |
---|
458 | // search around the start point // 4 0 5 |
---|
459 | // with the required distance // 6 7 8 |
---|
460 | CHECK( iDist == 0, "Invalid distance" ); |
---|
461 | const int iTop = iStartY - iDist; |
---|
462 | const int iBottom = iStartY + iDist; |
---|
463 | const int iLeft = iStartX - iDist; |
---|
464 | const int iRight = iStartX + iDist; |
---|
465 | rcStruct.uiBestRound += 1; |
---|
466 | |
---|
467 | if ( iDist == 1 ) |
---|
468 | { |
---|
469 | if ( iTop >= sr.top ) // check top |
---|
470 | { |
---|
471 | if (bCheckCornersAtDist1) |
---|
472 | { |
---|
473 | if ( iLeft >= sr.left) // check top-left |
---|
474 | { |
---|
475 | xTZSearchHelp( rcStruct, iLeft, iTop, 1, iDist ); |
---|
476 | } |
---|
477 | xTZSearchHelp( rcStruct, iStartX, iTop, 2, iDist ); |
---|
478 | if ( iRight <= sr.right ) // check middle right |
---|
479 | { |
---|
480 | xTZSearchHelp( rcStruct, iRight, iTop, 3, iDist ); |
---|
481 | } |
---|
482 | } |
---|
483 | else |
---|
484 | { |
---|
485 | xTZSearchHelp( rcStruct, iStartX, iTop, 2, iDist ); |
---|
486 | } |
---|
487 | } |
---|
488 | if ( iLeft >= sr.left ) // check middle left |
---|
489 | { |
---|
490 | xTZSearchHelp( rcStruct, iLeft, iStartY, 4, iDist ); |
---|
491 | } |
---|
492 | if ( iRight <= sr.right ) // check middle right |
---|
493 | { |
---|
494 | xTZSearchHelp( rcStruct, iRight, iStartY, 5, iDist ); |
---|
495 | } |
---|
496 | if ( iBottom <= sr.bottom ) // check bottom |
---|
497 | { |
---|
498 | if (bCheckCornersAtDist1) |
---|
499 | { |
---|
500 | if ( iLeft >= sr.left) // check top-left |
---|
501 | { |
---|
502 | xTZSearchHelp( rcStruct, iLeft, iBottom, 6, iDist ); |
---|
503 | } |
---|
504 | xTZSearchHelp( rcStruct, iStartX, iBottom, 7, iDist ); |
---|
505 | if ( iRight <= sr.right ) // check middle right |
---|
506 | { |
---|
507 | xTZSearchHelp( rcStruct, iRight, iBottom, 8, iDist ); |
---|
508 | } |
---|
509 | } |
---|
510 | else |
---|
511 | { |
---|
512 | xTZSearchHelp( rcStruct, iStartX, iBottom, 7, iDist ); |
---|
513 | } |
---|
514 | } |
---|
515 | } |
---|
516 | else |
---|
517 | { |
---|
518 | if ( iDist <= 8 ) |
---|
519 | { |
---|
520 | const int iTop_2 = iStartY - (iDist>>1); |
---|
521 | const int iBottom_2 = iStartY + (iDist>>1); |
---|
522 | const int iLeft_2 = iStartX - (iDist>>1); |
---|
523 | const int iRight_2 = iStartX + (iDist>>1); |
---|
524 | |
---|
525 | if ( iTop >= sr.top && iLeft >= sr.left && |
---|
526 | iRight <= sr.right && iBottom <= sr.bottom ) // check border |
---|
527 | { |
---|
528 | xTZSearchHelp( rcStruct, iStartX, iTop, 2, iDist ); |
---|
529 | xTZSearchHelp( rcStruct, iLeft_2, iTop_2, 1, iDist>>1 ); |
---|
530 | xTZSearchHelp( rcStruct, iRight_2, iTop_2, 3, iDist>>1 ); |
---|
531 | xTZSearchHelp( rcStruct, iLeft, iStartY, 4, iDist ); |
---|
532 | xTZSearchHelp( rcStruct, iRight, iStartY, 5, iDist ); |
---|
533 | xTZSearchHelp( rcStruct, iLeft_2, iBottom_2, 6, iDist>>1 ); |
---|
534 | xTZSearchHelp( rcStruct, iRight_2, iBottom_2, 8, iDist>>1 ); |
---|
535 | xTZSearchHelp( rcStruct, iStartX, iBottom, 7, iDist ); |
---|
536 | } |
---|
537 | else // check border |
---|
538 | { |
---|
539 | if ( iTop >= sr.top ) // check top |
---|
540 | { |
---|
541 | xTZSearchHelp( rcStruct, iStartX, iTop, 2, iDist ); |
---|
542 | } |
---|
543 | if ( iTop_2 >= sr.top ) // check half top |
---|
544 | { |
---|
545 | if ( iLeft_2 >= sr.left ) // check half left |
---|
546 | { |
---|
547 | xTZSearchHelp( rcStruct, iLeft_2, iTop_2, 1, (iDist>>1) ); |
---|
548 | } |
---|
549 | if ( iRight_2 <= sr.right ) // check half right |
---|
550 | { |
---|
551 | xTZSearchHelp( rcStruct, iRight_2, iTop_2, 3, (iDist>>1) ); |
---|
552 | } |
---|
553 | } // check half top |
---|
554 | if ( iLeft >= sr.left ) // check left |
---|
555 | { |
---|
556 | xTZSearchHelp( rcStruct, iLeft, iStartY, 4, iDist ); |
---|
557 | } |
---|
558 | if ( iRight <= sr.right ) // check right |
---|
559 | { |
---|
560 | xTZSearchHelp( rcStruct, iRight, iStartY, 5, iDist ); |
---|
561 | } |
---|
562 | if ( iBottom_2 <= sr.bottom ) // check half bottom |
---|
563 | { |
---|
564 | if ( iLeft_2 >= sr.left ) // check half left |
---|
565 | { |
---|
566 | xTZSearchHelp( rcStruct, iLeft_2, iBottom_2, 6, (iDist>>1) ); |
---|
567 | } |
---|
568 | if ( iRight_2 <= sr.right ) // check half right |
---|
569 | { |
---|
570 | xTZSearchHelp( rcStruct, iRight_2, iBottom_2, 8, (iDist>>1) ); |
---|
571 | } |
---|
572 | } // check half bottom |
---|
573 | if ( iBottom <= sr.bottom ) // check bottom |
---|
574 | { |
---|
575 | xTZSearchHelp( rcStruct, iStartX, iBottom, 7, iDist ); |
---|
576 | } |
---|
577 | } // check border |
---|
578 | } |
---|
579 | else // iDist > 8 |
---|
580 | { |
---|
581 | if ( iTop >= sr.top && iLeft >= sr.left && |
---|
582 | iRight <= sr.right && iBottom <= sr.bottom ) // check border |
---|
583 | { |
---|
584 | xTZSearchHelp( rcStruct, iStartX, iTop, 0, iDist ); |
---|
585 | xTZSearchHelp( rcStruct, iLeft, iStartY, 0, iDist ); |
---|
586 | xTZSearchHelp( rcStruct, iRight, iStartY, 0, iDist ); |
---|
587 | xTZSearchHelp( rcStruct, iStartX, iBottom, 0, iDist ); |
---|
588 | for ( int index = 1; index < 4; index++ ) |
---|
589 | { |
---|
590 | const int iPosYT = iTop + ((iDist>>2) * index); |
---|
591 | const int iPosYB = iBottom - ((iDist>>2) * index); |
---|
592 | const int iPosXL = iStartX - ((iDist>>2) * index); |
---|
593 | const int iPosXR = iStartX + ((iDist>>2) * index); |
---|
594 | xTZSearchHelp( rcStruct, iPosXL, iPosYT, 0, iDist ); |
---|
595 | xTZSearchHelp( rcStruct, iPosXR, iPosYT, 0, iDist ); |
---|
596 | xTZSearchHelp( rcStruct, iPosXL, iPosYB, 0, iDist ); |
---|
597 | xTZSearchHelp( rcStruct, iPosXR, iPosYB, 0, iDist ); |
---|
598 | } |
---|
599 | } |
---|
600 | else // check border |
---|
601 | { |
---|
602 | if ( iTop >= sr.top ) // check top |
---|
603 | { |
---|
604 | xTZSearchHelp( rcStruct, iStartX, iTop, 0, iDist ); |
---|
605 | } |
---|
606 | if ( iLeft >= sr.left ) // check left |
---|
607 | { |
---|
608 | xTZSearchHelp( rcStruct, iLeft, iStartY, 0, iDist ); |
---|
609 | } |
---|
610 | if ( iRight <= sr.right ) // check right |
---|
611 | { |
---|
612 | xTZSearchHelp( rcStruct, iRight, iStartY, 0, iDist ); |
---|
613 | } |
---|
614 | if ( iBottom <= sr.bottom ) // check bottom |
---|
615 | { |
---|
616 | xTZSearchHelp( rcStruct, iStartX, iBottom, 0, iDist ); |
---|
617 | } |
---|
618 | for ( int index = 1; index < 4; index++ ) |
---|
619 | { |
---|
620 | const int iPosYT = iTop + ((iDist>>2) * index); |
---|
621 | const int iPosYB = iBottom - ((iDist>>2) * index); |
---|
622 | const int iPosXL = iStartX - ((iDist>>2) * index); |
---|
623 | const int iPosXR = iStartX + ((iDist>>2) * index); |
---|
624 | |
---|
625 | if ( iPosYT >= sr.top ) // check top |
---|
626 | { |
---|
627 | if ( iPosXL >= sr.left ) // check left |
---|
628 | { |
---|
629 | xTZSearchHelp( rcStruct, iPosXL, iPosYT, 0, iDist ); |
---|
630 | } |
---|
631 | if ( iPosXR <= sr.right ) // check right |
---|
632 | { |
---|
633 | xTZSearchHelp( rcStruct, iPosXR, iPosYT, 0, iDist ); |
---|
634 | } |
---|
635 | } // check top |
---|
636 | if ( iPosYB <= sr.bottom ) // check bottom |
---|
637 | { |
---|
638 | if ( iPosXL >= sr.left ) // check left |
---|
639 | { |
---|
640 | xTZSearchHelp( rcStruct, iPosXL, iPosYB, 0, iDist ); |
---|
641 | } |
---|
642 | if ( iPosXR <= sr.right ) // check right |
---|
643 | { |
---|
644 | xTZSearchHelp( rcStruct, iPosXR, iPosYB, 0, iDist ); |
---|
645 | } |
---|
646 | } // check bottom |
---|
647 | } // for ... |
---|
648 | } // check border |
---|
649 | } // iDist <= 8 |
---|
650 | } // iDist == 1 |
---|
651 | } |
---|
652 | |
---|
653 | Distortion InterSearch::xPatternRefinement( const CPelBuf* pcPatternKey, |
---|
654 | Mv baseRefMv, |
---|
655 | int iFrac, Mv& rcMvFrac, |
---|
656 | bool bAllowUseOfHadamard ) |
---|
657 | { |
---|
658 | Distortion uiDist; |
---|
659 | Distortion uiDistBest = std::numeric_limits<Distortion>::max(); |
---|
660 | uint32_t uiDirecBest = 0; |
---|
661 | |
---|
662 | Pel* piRefPos; |
---|
663 | int iRefStride = pcPatternKey->width + 1; |
---|
664 | m_pcRdCost->setDistParam( m_cDistParam, *pcPatternKey, m_filteredBlock[0][0][0], iRefStride, m_lumaClpRng.bd, COMPONENT_Y, 0, 1, m_pcEncCfg->getUseHADME() && bAllowUseOfHadamard ); |
---|
665 | |
---|
666 | const Mv* pcMvRefine = (iFrac == 2 ? s_acMvRefineH : s_acMvRefineQ); |
---|
667 | for (uint32_t i = 0; i < 9; i++) |
---|
668 | { |
---|
669 | Mv cMvTest = pcMvRefine[i]; |
---|
670 | cMvTest += baseRefMv; |
---|
671 | |
---|
672 | int horVal = cMvTest.getHor() * iFrac; |
---|
673 | int verVal = cMvTest.getVer() * iFrac; |
---|
674 | piRefPos = m_filteredBlock[verVal & 3][horVal & 3][0]; |
---|
675 | |
---|
676 | if (horVal == 2 && (verVal & 1) == 0) |
---|
677 | { |
---|
678 | piRefPos += 1; |
---|
679 | } |
---|
680 | if ((horVal & 1) == 0 && verVal == 2) |
---|
681 | { |
---|
682 | piRefPos += iRefStride; |
---|
683 | } |
---|
684 | cMvTest = pcMvRefine[i]; |
---|
685 | cMvTest += rcMvFrac; |
---|
686 | |
---|
687 | |
---|
688 | m_cDistParam.cur.buf = piRefPos; |
---|
689 | uiDist = m_cDistParam.distFunc( m_cDistParam ); |
---|
690 | #if JVET_K0357_AMVR |
---|
691 | uiDist += m_pcRdCost->getCostOfVectorWithPredictor( cMvTest.getHor(), cMvTest.getVer(), 0 ); |
---|
692 | #else |
---|
693 | uiDist += m_pcRdCost->getCostOfVectorWithPredictor( cMvTest.getHor(), cMvTest.getVer() ); |
---|
694 | #endif |
---|
695 | |
---|
696 | if ( uiDist < uiDistBest ) |
---|
697 | { |
---|
698 | uiDistBest = uiDist; |
---|
699 | uiDirecBest = i; |
---|
700 | m_cDistParam.maximumDistortionForEarlyExit = uiDist; |
---|
701 | } |
---|
702 | } |
---|
703 | |
---|
704 | rcMvFrac = pcMvRefine[uiDirecBest]; |
---|
705 | |
---|
706 | return uiDistBest; |
---|
707 | } |
---|
708 | |
---|
709 | Distortion InterSearch::xGetInterPredictionError( PredictionUnit& pu, PelUnitBuf& origBuf, const RefPicList &eRefPicList ) |
---|
710 | { |
---|
711 | PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
712 | |
---|
713 | motionCompensation( pu, predBuf, eRefPicList ); |
---|
714 | |
---|
715 | DistParam cDistParam; |
---|
716 | cDistParam.applyWeight = false; |
---|
717 | |
---|
718 | m_pcRdCost->setDistParam( cDistParam, origBuf.Y(), predBuf.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, m_pcEncCfg->getUseHADME() && !pu.cu->transQuantBypass ); |
---|
719 | |
---|
720 | return (Distortion)cDistParam.distFunc( cDistParam ); |
---|
721 | } |
---|
722 | |
---|
723 | //! estimation of best merge coding |
---|
724 | void InterSearch::xMergeEstimation( PredictionUnit& pu, PelUnitBuf& origBuf, int iPUIdx, uint32_t& uiMergeIdx, Distortion& ruiCost, MergeCtx &mergeCtx ) |
---|
725 | { |
---|
726 | PartSize partSize = pu.cu->partSize; |
---|
727 | |
---|
728 | if ( pu.cs->pps->getLog2ParallelMergeLevelMinus2() && partSize != SIZE_2Nx2N && pu.cu->lumaSize().width <= 8 ) |
---|
729 | { |
---|
730 | if ( iPUIdx == 0 ) |
---|
731 | { |
---|
732 | UnitArea unitArea = pu; |
---|
733 | |
---|
734 | pu.UnitArea::operator=( *pu.cu ); |
---|
735 | pu.cu->partSize = SIZE_2Nx2N; |
---|
736 | |
---|
737 | PU::getInterMergeCandidates( pu, mergeCtx ); |
---|
738 | |
---|
739 | pu.UnitArea::operator=( unitArea ); |
---|
740 | pu.cu->partSize = partSize; |
---|
741 | } |
---|
742 | } |
---|
743 | else |
---|
744 | { |
---|
745 | PU::getInterMergeCandidates( pu, mergeCtx ); |
---|
746 | } |
---|
747 | |
---|
748 | PU::restrictBiPredMergeCands( pu, mergeCtx ); |
---|
749 | |
---|
750 | ruiCost = std::numeric_limits<Distortion>::max(); |
---|
751 | for( uint32_t uiMergeCand = 0; uiMergeCand < mergeCtx.numValidMergeCand; ++uiMergeCand ) |
---|
752 | { |
---|
753 | mergeCtx.setMergeInfo( pu, uiMergeCand ); |
---|
754 | |
---|
755 | PU::spanMotionInfo( pu, mergeCtx ); |
---|
756 | |
---|
757 | Distortion uiCostCand = xGetInterPredictionError( pu, origBuf ); |
---|
758 | uint32_t uiBitsCand = uiMergeCand + 1; |
---|
759 | |
---|
760 | if( uiMergeCand == m_pcEncCfg->getMaxNumMergeCand() - 1 ) |
---|
761 | { |
---|
762 | uiBitsCand--; |
---|
763 | } |
---|
764 | uiCostCand = uiCostCand + m_pcRdCost->getCost( uiBitsCand ); |
---|
765 | if ( uiCostCand < ruiCost ) |
---|
766 | { |
---|
767 | ruiCost = uiCostCand; |
---|
768 | uiMergeIdx = uiMergeCand; |
---|
769 | } |
---|
770 | } |
---|
771 | } |
---|
772 | |
---|
773 | #if JEM_TOOLS |
---|
774 | void InterSearch::xFRUCMrgEstimation( PredictionUnit& pu, PelUnitBuf& origBuf, Distortion& ruiMinCost, uint8_t& ruhFRUCMode, MergeCtx &mrgCtx ) |
---|
775 | { |
---|
776 | ruiMinCost = std::numeric_limits<Distortion>::max(); |
---|
777 | |
---|
778 | CHECK( pu.mergeFlag == 0, "merge flag must be set" ); |
---|
779 | const uint8_t uhFRUCME[2] = { FRUC_MERGE_BILATERALMV , FRUC_MERGE_TEMPLATE }; |
---|
780 | |
---|
781 | for( int nME = 0 ; nME < 2 ; nME++ ) |
---|
782 | { |
---|
783 | pu.frucMrgMode = uhFRUCME[nME]; |
---|
784 | pu.mergeType = MRG_TYPE_FRUC; |
---|
785 | |
---|
786 | bool bAvailable = deriveFRUCMV( pu ); |
---|
787 | if( bAvailable ) |
---|
788 | { |
---|
789 | Distortion uiCostCand = xGetInterPredictionError( pu, origBuf ); |
---|
790 | |
---|
791 | uint32_t uiBitsCand = 1; |
---|
792 | #if DISTORTION_TYPE_BUGFIX |
---|
793 | Distortion uiCost = uiCostCand + m_pcRdCost->getCost(uiBitsCand); |
---|
794 | #else |
---|
795 | uint32_t uiCost = uiCostCand + m_pcRdCost->getCost( uiBitsCand ); |
---|
796 | #endif |
---|
797 | |
---|
798 | if( uiCost < ruiMinCost ) |
---|
799 | { |
---|
800 | ruiMinCost = uiCost; |
---|
801 | ruhFRUCMode = uhFRUCME[nME]; |
---|
802 | |
---|
803 | if( ruhFRUCMode == FRUC_MERGE_BILATERALMV ) |
---|
804 | { |
---|
805 | CHECK( mrgCtx.subPuFrucMiBuf.area() == 0 || !mrgCtx.subPuFrucMiBuf.buf, "Buffer not initialized" ); |
---|
806 | mrgCtx.subPuFrucMiBuf.fill( MotionInfo() ); |
---|
807 | |
---|
808 | mrgCtx.subPuFrucMiBuf.copyFrom( pu.getMotionBuf() ); |
---|
809 | } |
---|
810 | } |
---|
811 | } |
---|
812 | } |
---|
813 | } |
---|
814 | #endif |
---|
815 | |
---|
816 | //! search of the best candidate for inter prediction |
---|
817 | void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner) |
---|
818 | { |
---|
819 | CodingStructure& cs = *cu.cs; |
---|
820 | |
---|
821 | AMVPInfo amvp[2]; |
---|
822 | Mv cMvSrchRngLT; |
---|
823 | Mv cMvSrchRngRB; |
---|
824 | |
---|
825 | Mv cMvZero; |
---|
826 | |
---|
827 | Mv cMv[2]; |
---|
828 | Mv cMvBi[2]; |
---|
829 | Mv cMvTemp[2][33]; |
---|
830 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
831 | Mv cMvHevcTemp[2][33]; |
---|
832 | #endif |
---|
833 | int iNumPredDir = cs.slice->isInterP() ? 1 : 2; |
---|
834 | |
---|
835 | Mv cMvPred[2][33]; |
---|
836 | |
---|
837 | Mv cMvPredBi[2][33]; |
---|
838 | int aaiMvpIdxBi[2][33]; |
---|
839 | |
---|
840 | int aaiMvpIdx[2][33]; |
---|
841 | int aaiMvpNum[2][33]; |
---|
842 | |
---|
843 | AMVPInfo aacAMVPInfo[2][33]; |
---|
844 | |
---|
845 | int iRefIdx[2]={0,0}; //If un-initialized, may cause SEGV in bi-directional prediction iterative stage. |
---|
846 | int iRefIdxBi[2]; |
---|
847 | |
---|
848 | uint32_t uiMbBits[3] = {1, 1, 0}; |
---|
849 | |
---|
850 | uint32_t uiLastMode = 0; |
---|
851 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
852 | uint32_t uiLastModeTemp = 0; |
---|
853 | #endif |
---|
854 | int iRefStart, iRefEnd; |
---|
855 | |
---|
856 | int bestBiPRefIdxL1 = 0; |
---|
857 | int bestBiPMvpL1 = 0; |
---|
858 | Distortion biPDistTemp = std::numeric_limits<Distortion>::max(); |
---|
859 | |
---|
860 | MergeCtx mergeCtx; |
---|
861 | |
---|
862 | // Loop over Prediction Units |
---|
863 | CHECK(!cu.firstPU, "CU does not contain any PUs"); |
---|
864 | uint32_t puIdx = 0; |
---|
865 | auto &pu = *cu.firstPU; |
---|
866 | |
---|
867 | { |
---|
868 | // motion estimation only evaluates luma component |
---|
869 | m_maxCompIDToPred = MAX_NUM_COMPONENT; |
---|
870 | // m_maxCompIDToPred = COMPONENT_Y; |
---|
871 | |
---|
872 | CHECK(pu.cu != &cu, "PU is contained in another CU"); |
---|
873 | |
---|
874 | #if JEM_TOOLS |
---|
875 | if( cu.cs->sps->getSpsNext().getUseSubPuMvp() ) |
---|
876 | { |
---|
877 | Size bufSize = g_miScaling.scale( pu.lumaSize() ); |
---|
878 | mergeCtx.subPuMvpMiBuf = MotionBuf( m_SubPuMiBuf, bufSize ); |
---|
879 | mergeCtx.subPuMvpExtMiBuf = MotionBuf( m_SubPuExtMiBuf, bufSize ); |
---|
880 | } |
---|
881 | |
---|
882 | if( cu.cs->sps->getSpsNext().getUseFRUCMrgMode() ) |
---|
883 | { |
---|
884 | Size bufSize = g_miScaling.scale( pu.lumaSize() ); |
---|
885 | mergeCtx.subPuFrucMiBuf = MotionBuf( m_SubPuFrucBuf, bufSize ); |
---|
886 | } |
---|
887 | #endif |
---|
888 | #if !JEM_TOOLS && JVET_K0346 |
---|
889 | if (cu.cs->sps->getSpsNext().getUseSubPuMvp()) |
---|
890 | { |
---|
891 | Size bufSize = g_miScaling.scale(pu.lumaSize()); |
---|
892 | mergeCtx.subPuMvpMiBuf = MotionBuf(m_SubPuMiBuf, bufSize); |
---|
893 | } |
---|
894 | #endif |
---|
895 | |
---|
896 | PU::spanMotionInfo( pu ); |
---|
897 | #if JEM_TOOLS |
---|
898 | PelUnitBuf obmcOrgBuf = m_obmcOrgMod.subBuf( UnitAreaRelative( pu, pu ) ); |
---|
899 | obmcOrgBuf.copyFrom( pu.cs->getOrgBuf( pu ) ); |
---|
900 | //consider OBMC in motion estimation |
---|
901 | subBlockOBMC( pu, &obmcOrgBuf, true ); |
---|
902 | |
---|
903 | Distortion uiHevcCost = std::numeric_limits<Distortion>::max(); |
---|
904 | Distortion uiAffineCost = std::numeric_limits<Distortion>::max(); |
---|
905 | #endif |
---|
906 | #if !JEM_TOOLS && JVET_K_AFFINE |
---|
907 | Distortion uiHevcCost = std::numeric_limits<Distortion>::max(); |
---|
908 | Distortion uiAffineCost = std::numeric_limits<Distortion>::max(); |
---|
909 | #endif |
---|
910 | Distortion uiCost[2] = { std::numeric_limits<Distortion>::max(), std::numeric_limits<Distortion>::max() }; |
---|
911 | Distortion uiCostBi = std::numeric_limits<Distortion>::max(); |
---|
912 | Distortion uiCostTemp; |
---|
913 | |
---|
914 | uint32_t uiBits[3]; |
---|
915 | uint32_t uiBitsTemp; |
---|
916 | Distortion bestBiPDist = std::numeric_limits<Distortion>::max(); |
---|
917 | |
---|
918 | Distortion uiCostTempL0[MAX_NUM_REF]; |
---|
919 | for (int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) |
---|
920 | { |
---|
921 | uiCostTempL0[iNumRef] = std::numeric_limits<Distortion>::max(); |
---|
922 | } |
---|
923 | uint32_t uiBitsTempL0[MAX_NUM_REF]; |
---|
924 | |
---|
925 | Mv mvValidList1; |
---|
926 | int refIdxValidList1 = 0; |
---|
927 | uint32_t bitsValidList1 = MAX_UINT; |
---|
928 | Distortion costValidList1 = std::numeric_limits<Distortion>::max(); |
---|
929 | |
---|
930 | #if JEM_TOOLS |
---|
931 | PelUnitBuf origBuf = cu.obmcFlag ? obmcOrgBuf.subBuf( UnitAreaRelative( cu, pu ) ) : pu.cs->getOrgBuf( pu ); |
---|
932 | #else |
---|
933 | PelUnitBuf origBuf = pu.cs->getOrgBuf( pu ); |
---|
934 | #endif |
---|
935 | |
---|
936 | xGetBlkBits( cu.partSize, cs.slice->isInterP(), puIdx, uiLastMode, uiMbBits ); |
---|
937 | |
---|
938 | m_pcRdCost->selectMotionLambda( cu.transQuantBypass ); |
---|
939 | |
---|
940 | #if !JVET_K0220_ENC_CTRL |
---|
941 | bool bFastSkipBi = false; |
---|
942 | if( auto slsCtrl = dynamic_cast< SaveLoadEncInfoCtrl* >( m_modeCtrl ) ) |
---|
943 | { |
---|
944 | bFastSkipBi = ( LOAD_ENC_INFO == slsCtrl->getSaveLoadTag( pu ) && 3 != slsCtrl->getSaveLoadInterDir( pu ) ); |
---|
945 | } |
---|
946 | |
---|
947 | #endif |
---|
948 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
949 | #if !JVET_K0220_ENC_CTRL |
---|
950 | bool bFastSkipAffine = false; |
---|
951 | if( pu.cs->sps->getSpsNext().getUseQTBT() && m_pcEncCfg->getUseSaveLoadEncInfo() ) |
---|
952 | { |
---|
953 | SaveLoadEncInfoCtrl* modeCtrl = dynamic_cast<SaveLoadEncInfoCtrl*>( m_modeCtrl ); |
---|
954 | bFastSkipAffine = modeCtrl && LOAD_ENC_INFO == modeCtrl->getSaveLoadTag( pu ) && !modeCtrl->getSaveLoadAffineFlag( pu ); |
---|
955 | } |
---|
956 | #endif |
---|
957 | #endif |
---|
958 | #if JVET_K0357_AMVR |
---|
959 | unsigned imvShift = pu.cu->imv << 1; |
---|
960 | #endif |
---|
961 | // Uni-directional prediction |
---|
962 | for ( int iRefList = 0; iRefList < iNumPredDir; iRefList++ ) |
---|
963 | { |
---|
964 | RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); |
---|
965 | |
---|
966 | for ( int iRefIdxTemp = 0; iRefIdxTemp < cs.slice->getNumRefIdx(eRefPicList); iRefIdxTemp++ ) |
---|
967 | { |
---|
968 | uiBitsTemp = uiMbBits[iRefList]; |
---|
969 | if ( cs.slice->getNumRefIdx(eRefPicList) > 1 ) |
---|
970 | { |
---|
971 | uiBitsTemp += iRefIdxTemp+1; |
---|
972 | if ( iRefIdxTemp == cs.slice->getNumRefIdx(eRefPicList)-1 ) |
---|
973 | { |
---|
974 | uiBitsTemp--; |
---|
975 | } |
---|
976 | } |
---|
977 | xEstimateMvPredAMVP( pu, origBuf, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], amvp[eRefPicList], false, &biPDistTemp); |
---|
978 | |
---|
979 | aaiMvpIdx[iRefList][iRefIdxTemp] = pu.mvpIdx[eRefPicList]; |
---|
980 | aaiMvpNum[iRefList][iRefIdxTemp] = pu.mvpNum[eRefPicList]; |
---|
981 | |
---|
982 | if(cs.slice->getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist) |
---|
983 | { |
---|
984 | bestBiPDist = biPDistTemp; |
---|
985 | bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp]; |
---|
986 | bestBiPRefIdxL1 = iRefIdxTemp; |
---|
987 | } |
---|
988 | |
---|
989 | uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS]; |
---|
990 | |
---|
991 | if ( m_pcEncCfg->getFastMEForGenBLowDelayEnabled() && iRefList == 1 ) // list 1 |
---|
992 | { |
---|
993 | if ( cs.slice->getList1IdxToList0Idx( iRefIdxTemp ) >= 0 ) |
---|
994 | { |
---|
995 | cMvTemp[1][iRefIdxTemp] = cMvTemp[0][cs.slice->getList1IdxToList0Idx( iRefIdxTemp )]; |
---|
996 | uiCostTemp = uiCostTempL0[cs.slice->getList1IdxToList0Idx( iRefIdxTemp )]; |
---|
997 | /*first subtract the bit-rate part of the cost of the other list*/ |
---|
998 | uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[cs.slice->getList1IdxToList0Idx( iRefIdxTemp )] ); |
---|
999 | /*correct the bit-rate part of the current ref*/ |
---|
1000 | m_pcRdCost->setPredictor ( cMvPred[iRefList][iRefIdxTemp] ); |
---|
1001 | #if JVET_K0357_AMVR |
---|
1002 | uiBitsTemp += m_pcRdCost->getBitsOfVectorWithPredictor( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer(), imvShift ); |
---|
1003 | #else |
---|
1004 | uiBitsTemp += m_pcRdCost->getBitsOfVectorWithPredictor( cMvTemp[1][iRefIdxTemp].getHor(), cMvTemp[1][iRefIdxTemp].getVer() ); |
---|
1005 | #endif |
---|
1006 | /*calculate the correct cost*/ |
---|
1007 | uiCostTemp += m_pcRdCost->getCost( uiBitsTemp ); |
---|
1008 | } |
---|
1009 | else |
---|
1010 | { |
---|
1011 | xMotionEstimation( pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList] ); |
---|
1012 | } |
---|
1013 | } |
---|
1014 | else |
---|
1015 | { |
---|
1016 | xMotionEstimation( pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList] ); |
---|
1017 | } |
---|
1018 | xCopyAMVPInfo( &amvp[eRefPicList], &aacAMVPInfo[iRefList][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE ) |
---|
1019 | #if JVET_K0357_AMVR |
---|
1020 | xCheckBestMVP( eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp, pu.cu->imv ); |
---|
1021 | #else |
---|
1022 | xCheckBestMVP( eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp ); |
---|
1023 | #endif |
---|
1024 | |
---|
1025 | if ( iRefList == 0 ) |
---|
1026 | { |
---|
1027 | uiCostTempL0[iRefIdxTemp] = uiCostTemp; |
---|
1028 | uiBitsTempL0[iRefIdxTemp] = uiBitsTemp; |
---|
1029 | } |
---|
1030 | if ( uiCostTemp < uiCost[iRefList] ) |
---|
1031 | { |
---|
1032 | uiCost[iRefList] = uiCostTemp; |
---|
1033 | uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction |
---|
1034 | |
---|
1035 | // set motion |
---|
1036 | cMv [iRefList] = cMvTemp[iRefList][iRefIdxTemp]; |
---|
1037 | iRefIdx[iRefList] = iRefIdxTemp; |
---|
1038 | } |
---|
1039 | |
---|
1040 | if ( iRefList == 1 && uiCostTemp < costValidList1 && cs.slice->getList1IdxToList0Idx( iRefIdxTemp ) < 0 ) |
---|
1041 | { |
---|
1042 | costValidList1 = uiCostTemp; |
---|
1043 | bitsValidList1 = uiBitsTemp; |
---|
1044 | |
---|
1045 | // set motion |
---|
1046 | mvValidList1 = cMvTemp[iRefList][iRefIdxTemp]; |
---|
1047 | refIdxValidList1 = iRefIdxTemp; |
---|
1048 | } |
---|
1049 | } |
---|
1050 | } |
---|
1051 | |
---|
1052 | #if JVET_K0220_ENC_CTRL |
---|
1053 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() |
---|
1054 | #if JEM_TOOLS |
---|
1055 | && !cu.LICFlag |
---|
1056 | #endif |
---|
1057 | #if JVET_K0357_AMVR |
---|
1058 | && cu.imv == 0 |
---|
1059 | #endif |
---|
1060 | ) |
---|
1061 | #else |
---|
1062 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() |
---|
1063 | #if JEM_TOOLS |
---|
1064 | && !cu.LICFlag |
---|
1065 | #endif |
---|
1066 | #if JVET_K0357_AMVR |
---|
1067 | && cu.imv == 0 |
---|
1068 | #endif |
---|
1069 | && !bFastSkipAffine) |
---|
1070 | #endif |
---|
1071 | { |
---|
1072 | ::memcpy( cMvHevcTemp, cMvTemp, sizeof( cMvTemp ) ); |
---|
1073 | } |
---|
1074 | #if !JEM_TOOLS && JVET_K_AFFINE |
---|
1075 | #if JVET_K0220_ENC_CTRL |
---|
1076 | if ( cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() ) |
---|
1077 | #else |
---|
1078 | if ( cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() && !bFastSkipAffine ) |
---|
1079 | #endif |
---|
1080 | { |
---|
1081 | ::memcpy( cMvHevcTemp, cMvTemp, sizeof( cMvTemp ) ); |
---|
1082 | } |
---|
1083 | #endif |
---|
1084 | // Bi-predictive Motion estimation |
---|
1085 | #if JVET_K0220_ENC_CTRL |
---|
1086 | if( ( cs.slice->isInterB() ) && ( PU::isBipredRestriction( pu ) == false ) ) |
---|
1087 | #else |
---|
1088 | if ( (cs.slice->isInterB()) && ( PU::isBipredRestriction(pu) == false) && !bFastSkipBi ) |
---|
1089 | #endif |
---|
1090 | { |
---|
1091 | cMvBi[0] = cMv[0]; |
---|
1092 | cMvBi[1] = cMv[1]; |
---|
1093 | iRefIdxBi[0] = iRefIdx[0]; |
---|
1094 | iRefIdxBi[1] = iRefIdx[1]; |
---|
1095 | |
---|
1096 | ::memcpy( cMvPredBi, cMvPred, sizeof( cMvPred ) ); |
---|
1097 | ::memcpy( aaiMvpIdxBi, aaiMvpIdx, sizeof( aaiMvpIdx ) ); |
---|
1098 | |
---|
1099 | uint32_t uiMotBits[2]; |
---|
1100 | |
---|
1101 | if(cs.slice->getMvdL1ZeroFlag()) |
---|
1102 | { |
---|
1103 | xCopyAMVPInfo(&aacAMVPInfo[1][bestBiPRefIdxL1], &amvp[REF_PIC_LIST_1]); |
---|
1104 | aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1; |
---|
1105 | cMvPredBi [1][bestBiPRefIdxL1] = amvp[REF_PIC_LIST_1].mvCand[bestBiPMvpL1]; |
---|
1106 | |
---|
1107 | cMvBi [1] = cMvPredBi[1][bestBiPRefIdxL1]; |
---|
1108 | iRefIdxBi[1] = bestBiPRefIdxL1; |
---|
1109 | pu.mv [REF_PIC_LIST_1] = cMvBi[1]; |
---|
1110 | pu.refIdx[REF_PIC_LIST_1] = iRefIdxBi[1]; |
---|
1111 | pu.mvpIdx[REF_PIC_LIST_1] = bestBiPMvpL1; |
---|
1112 | |
---|
1113 | PelUnitBuf predBufTmp = m_tmpPredStorage[REF_PIC_LIST_1].getBuf( UnitAreaRelative(cu, pu) ); |
---|
1114 | motionCompensation( pu, predBufTmp, REF_PIC_LIST_1 ); |
---|
1115 | |
---|
1116 | uiMotBits[0] = uiBits[0] - uiMbBits[0]; |
---|
1117 | uiMotBits[1] = uiMbBits[1]; |
---|
1118 | |
---|
1119 | if ( cs.slice->getNumRefIdx(REF_PIC_LIST_1) > 1 ) |
---|
1120 | { |
---|
1121 | uiMotBits[1] += bestBiPRefIdxL1 + 1; |
---|
1122 | if ( bestBiPRefIdxL1 == cs.slice->getNumRefIdx(REF_PIC_LIST_1)-1 ) |
---|
1123 | { |
---|
1124 | uiMotBits[1]--; |
---|
1125 | } |
---|
1126 | } |
---|
1127 | |
---|
1128 | uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][AMVP_MAX_NUM_CANDS]; |
---|
1129 | |
---|
1130 | uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1]; |
---|
1131 | |
---|
1132 | cMvTemp[1][bestBiPRefIdxL1] = cMvBi[1]; |
---|
1133 | } |
---|
1134 | else |
---|
1135 | { |
---|
1136 | uiMotBits[0] = uiBits[0] - uiMbBits[0]; |
---|
1137 | uiMotBits[1] = uiBits[1] - uiMbBits[1]; |
---|
1138 | uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1]; |
---|
1139 | } |
---|
1140 | |
---|
1141 | // 4-times iteration (default) |
---|
1142 | int iNumIter = 4; |
---|
1143 | |
---|
1144 | // fast encoder setting: only one iteration |
---|
1145 | if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || cs.slice->getMvdL1ZeroFlag() ) |
---|
1146 | { |
---|
1147 | iNumIter = 1; |
---|
1148 | } |
---|
1149 | |
---|
1150 | for ( int iIter = 0; iIter < iNumIter; iIter++ ) |
---|
1151 | { |
---|
1152 | int iRefList = iIter % 2; |
---|
1153 | |
---|
1154 | if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 ) |
---|
1155 | { |
---|
1156 | if( uiCost[0] <= uiCost[1] ) |
---|
1157 | { |
---|
1158 | iRefList = 1; |
---|
1159 | } |
---|
1160 | else |
---|
1161 | { |
---|
1162 | iRefList = 0; |
---|
1163 | } |
---|
1164 | } |
---|
1165 | else if ( iIter == 0 ) |
---|
1166 | { |
---|
1167 | iRefList = 0; |
---|
1168 | } |
---|
1169 | if ( iIter == 0 && !cs.slice->getMvdL1ZeroFlag()) |
---|
1170 | { |
---|
1171 | pu.mv [1 - iRefList] = cMv [1 - iRefList]; |
---|
1172 | pu.refIdx[1 - iRefList] = iRefIdx[1 - iRefList]; |
---|
1173 | |
---|
1174 | PelUnitBuf predBufTmp = m_tmpPredStorage[1 - iRefList].getBuf( UnitAreaRelative(cu, pu) ); |
---|
1175 | motionCompensation( pu, predBufTmp, RefPicList(1 - iRefList) ); |
---|
1176 | } |
---|
1177 | |
---|
1178 | RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); |
---|
1179 | |
---|
1180 | if(cs.slice->getMvdL1ZeroFlag()) |
---|
1181 | { |
---|
1182 | iRefList = 0; |
---|
1183 | eRefPicList = REF_PIC_LIST_0; |
---|
1184 | } |
---|
1185 | |
---|
1186 | bool bChanged = false; |
---|
1187 | |
---|
1188 | iRefStart = 0; |
---|
1189 | iRefEnd = cs.slice->getNumRefIdx(eRefPicList)-1; |
---|
1190 | |
---|
1191 | for ( int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ ) |
---|
1192 | { |
---|
1193 | uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList]; |
---|
1194 | if ( cs.slice->getNumRefIdx(eRefPicList) > 1 ) |
---|
1195 | { |
---|
1196 | uiBitsTemp += iRefIdxTemp+1; |
---|
1197 | if ( iRefIdxTemp == cs.slice->getNumRefIdx(eRefPicList)-1 ) |
---|
1198 | { |
---|
1199 | uiBitsTemp--; |
---|
1200 | } |
---|
1201 | } |
---|
1202 | uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS]; |
---|
1203 | |
---|
1204 | // call ME |
---|
1205 | xCopyAMVPInfo(&aacAMVPInfo[iRefList][iRefIdxTemp], &amvp[eRefPicList] ); |
---|
1206 | xMotionEstimation ( pu, origBuf, eRefPicList, cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, amvp[eRefPicList], true ); |
---|
1207 | #if JVET_K0357_AMVR |
---|
1208 | xCheckBestMVP( eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp, pu.cu->imv); |
---|
1209 | #else |
---|
1210 | xCheckBestMVP( eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], amvp[eRefPicList], uiBitsTemp, uiCostTemp); |
---|
1211 | #endif |
---|
1212 | if ( uiCostTemp < uiCostBi ) |
---|
1213 | { |
---|
1214 | bChanged = true; |
---|
1215 | |
---|
1216 | cMvBi[iRefList] = cMvTemp[iRefList][iRefIdxTemp]; |
---|
1217 | iRefIdxBi[iRefList] = iRefIdxTemp; |
---|
1218 | |
---|
1219 | uiCostBi = uiCostTemp; |
---|
1220 | uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList]; |
---|
1221 | uiBits[2] = uiBitsTemp; |
---|
1222 | |
---|
1223 | if(iNumIter!=1) |
---|
1224 | { |
---|
1225 | // Set motion |
---|
1226 | pu.mv [eRefPicList] = cMvBi [iRefList]; |
---|
1227 | pu.refIdx[eRefPicList] = iRefIdxBi[iRefList]; |
---|
1228 | |
---|
1229 | PelUnitBuf predBufTmp = m_tmpPredStorage[iRefList].getBuf( UnitAreaRelative(cu, pu) ); |
---|
1230 | motionCompensation( pu, predBufTmp, eRefPicList ); |
---|
1231 | } |
---|
1232 | } |
---|
1233 | } // for loop-iRefIdxTemp |
---|
1234 | |
---|
1235 | if ( !bChanged ) |
---|
1236 | { |
---|
1237 | if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] ) |
---|
1238 | { |
---|
1239 | xCopyAMVPInfo(&aacAMVPInfo[0][iRefIdxBi[0]], &amvp[REF_PIC_LIST_0]); |
---|
1240 | #if JVET_K0357_AMVR |
---|
1241 | xCheckBestMVP( REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], amvp[eRefPicList], uiBits[2], uiCostBi, pu.cu->imv); |
---|
1242 | #else |
---|
1243 | xCheckBestMVP( REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], amvp[eRefPicList], uiBits[2], uiCostBi); |
---|
1244 | #endif |
---|
1245 | if(!cs.slice->getMvdL1ZeroFlag()) |
---|
1246 | { |
---|
1247 | xCopyAMVPInfo(&aacAMVPInfo[1][iRefIdxBi[1]], &amvp[REF_PIC_LIST_1]); |
---|
1248 | #if JVET_K0357_AMVR |
---|
1249 | xCheckBestMVP( REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], amvp[eRefPicList], uiBits[2], uiCostBi, pu.cu->imv); |
---|
1250 | #else |
---|
1251 | xCheckBestMVP( REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], amvp[eRefPicList], uiBits[2], uiCostBi); |
---|
1252 | #endif |
---|
1253 | } |
---|
1254 | } |
---|
1255 | break; |
---|
1256 | } |
---|
1257 | } // for loop-iter |
---|
1258 | } // if (B_SLICE) |
---|
1259 | |
---|
1260 | |
---|
1261 | |
---|
1262 | // Clear Motion Field |
---|
1263 | pu.mv [REF_PIC_LIST_0] = Mv(); |
---|
1264 | pu.mv [REF_PIC_LIST_1] = Mv(); |
---|
1265 | pu.mvd [REF_PIC_LIST_0] = cMvZero; |
---|
1266 | pu.mvd [REF_PIC_LIST_1] = cMvZero; |
---|
1267 | pu.refIdx[REF_PIC_LIST_0] = NOT_VALID; |
---|
1268 | pu.refIdx[REF_PIC_LIST_1] = NOT_VALID; |
---|
1269 | pu.mvpIdx[REF_PIC_LIST_0] = NOT_VALID; |
---|
1270 | pu.mvpIdx[REF_PIC_LIST_1] = NOT_VALID; |
---|
1271 | pu.mvpNum[REF_PIC_LIST_0] = NOT_VALID; |
---|
1272 | pu.mvpNum[REF_PIC_LIST_1] = NOT_VALID; |
---|
1273 | |
---|
1274 | |
---|
1275 | uint32_t uiMEBits = 0; |
---|
1276 | |
---|
1277 | // Set Motion Field |
---|
1278 | |
---|
1279 | cMv [1] = mvValidList1; |
---|
1280 | iRefIdx[1] = refIdxValidList1; |
---|
1281 | uiBits [1] = bitsValidList1; |
---|
1282 | uiCost [1] = costValidList1; |
---|
1283 | |
---|
1284 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
1285 | uiLastModeTemp = uiLastMode; |
---|
1286 | #endif |
---|
1287 | if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1]) |
---|
1288 | { |
---|
1289 | uiLastMode = 2; |
---|
1290 | pu.mv [REF_PIC_LIST_0] = cMvBi[0]; |
---|
1291 | pu.mv [REF_PIC_LIST_1] = cMvBi[1]; |
---|
1292 | pu.mvd [REF_PIC_LIST_0] = cMvBi[0] - cMvPredBi[0][iRefIdxBi[0]]; |
---|
1293 | pu.mvd [REF_PIC_LIST_1] = cMvBi[1] - cMvPredBi[1][iRefIdxBi[1]]; |
---|
1294 | pu.refIdx[REF_PIC_LIST_0] = iRefIdxBi[0]; |
---|
1295 | pu.refIdx[REF_PIC_LIST_1] = iRefIdxBi[1]; |
---|
1296 | pu.mvpIdx[REF_PIC_LIST_0] = aaiMvpIdxBi[0][iRefIdxBi[0]]; |
---|
1297 | pu.mvpIdx[REF_PIC_LIST_1] = aaiMvpIdxBi[1][iRefIdxBi[1]]; |
---|
1298 | pu.mvpNum[REF_PIC_LIST_0] = aaiMvpNum[0][iRefIdxBi[0]]; |
---|
1299 | pu.mvpNum[REF_PIC_LIST_1] = aaiMvpNum[1][iRefIdxBi[1]]; |
---|
1300 | pu.interDir = 3; |
---|
1301 | |
---|
1302 | uiMEBits = uiBits[2]; |
---|
1303 | } |
---|
1304 | else if ( uiCost[0] <= uiCost[1] ) |
---|
1305 | { |
---|
1306 | uiLastMode = 0; |
---|
1307 | pu.mv [REF_PIC_LIST_0] = cMv[0]; |
---|
1308 | pu.mvd [REF_PIC_LIST_0] = cMv[0] - cMvPred[0][iRefIdx[0]]; |
---|
1309 | pu.refIdx[REF_PIC_LIST_0] = iRefIdx[0]; |
---|
1310 | pu.mvpIdx[REF_PIC_LIST_0] = aaiMvpIdx[0][iRefIdx[0]]; |
---|
1311 | pu.mvpNum[REF_PIC_LIST_0] = aaiMvpNum[0][iRefIdx[0]]; |
---|
1312 | pu.interDir = 1; |
---|
1313 | |
---|
1314 | uiMEBits = uiBits[0]; |
---|
1315 | } |
---|
1316 | else |
---|
1317 | { |
---|
1318 | uiLastMode = 1; |
---|
1319 | pu.mv [REF_PIC_LIST_1] = cMv[1]; |
---|
1320 | pu.mvd [REF_PIC_LIST_1] = cMv[1] - cMvPred[1][iRefIdx[1]]; |
---|
1321 | pu.refIdx[REF_PIC_LIST_1] = iRefIdx[1]; |
---|
1322 | pu.mvpIdx[REF_PIC_LIST_1] = aaiMvpIdx[1][iRefIdx[1]]; |
---|
1323 | pu.mvpNum[REF_PIC_LIST_1] = aaiMvpNum[1][iRefIdx[1]]; |
---|
1324 | pu.interDir = 2; |
---|
1325 | |
---|
1326 | uiMEBits = uiBits[1]; |
---|
1327 | } |
---|
1328 | |
---|
1329 | if ( cu.partSize != SIZE_2Nx2N ) |
---|
1330 | { |
---|
1331 | uint32_t uiMRGIndex = 0; |
---|
1332 | |
---|
1333 | // calculate ME cost |
---|
1334 | Distortion uiMEError = xGetInterPredictionError( pu, origBuf ); |
---|
1335 | Distortion uiMECost = uiMEError + m_pcRdCost->getCost( uiMEBits ); |
---|
1336 | // save ME result. |
---|
1337 | InterPredictionData savedPU = pu; |
---|
1338 | |
---|
1339 | // find Merge result |
---|
1340 | Distortion uiMRGCost = std::numeric_limits<Distortion>::max(); |
---|
1341 | |
---|
1342 | pu.initData(); |
---|
1343 | xMergeEstimation( pu, origBuf, puIdx, uiMRGIndex, uiMRGCost, mergeCtx ); |
---|
1344 | |
---|
1345 | #if JEM_TOOLS |
---|
1346 | Distortion uiFRUCMrgCost = std::numeric_limits<Distortion>::max(); |
---|
1347 | uint8_t uhFRUCMode = 0; |
---|
1348 | if( pu.cs->slice->getSPS()->getSpsNext().getUseFRUCMrgMode() ) |
---|
1349 | { |
---|
1350 | xFRUCMrgEstimation( pu, origBuf, uiFRUCMrgCost, uhFRUCMode, mergeCtx ); |
---|
1351 | } |
---|
1352 | |
---|
1353 | if( uiMRGCost < uiMECost || uiFRUCMrgCost < uiMECost ) |
---|
1354 | { |
---|
1355 | if( uiMRGCost <= uiFRUCMrgCost ) |
---|
1356 | { |
---|
1357 | // set Merge result |
---|
1358 | mergeCtx.setMergeInfo( pu, uiMRGIndex ); |
---|
1359 | pu.frucMrgMode = FRUC_MERGE_OFF; |
---|
1360 | } |
---|
1361 | else |
---|
1362 | { |
---|
1363 | pu.frucMrgMode = uhFRUCMode; |
---|
1364 | if( pu.frucMrgMode == FRUC_MERGE_BILATERALMV ) |
---|
1365 | { |
---|
1366 | pu.mergeType = MRG_TYPE_FRUC_SET; |
---|
1367 | PU::spanMotionInfo( pu, mergeCtx ); |
---|
1368 | pu.mergeType = MRG_TYPE_FRUC; |
---|
1369 | } |
---|
1370 | } |
---|
1371 | } |
---|
1372 | #else |
---|
1373 | if( uiMRGCost < uiMECost ) |
---|
1374 | { |
---|
1375 | // set Merge result |
---|
1376 | mergeCtx.setMergeInfo( pu, uiMRGIndex ); |
---|
1377 | } |
---|
1378 | #endif |
---|
1379 | else |
---|
1380 | { |
---|
1381 | pu = savedPU; |
---|
1382 | } |
---|
1383 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
1384 | uiHevcCost = ( uiMRGCost < uiMECost ) ? uiMRGCost : uiMECost; |
---|
1385 | #endif |
---|
1386 | } |
---|
1387 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
1388 | if( cu.cs->pcv->only2Nx2N || cu.partSize == SIZE_2Nx2N ) |
---|
1389 | { |
---|
1390 | uiHevcCost = ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] ) ? uiCostBi : ( ( uiCost[0] <= uiCost[1] ) ? uiCost[0] : uiCost[1] ); |
---|
1391 | } |
---|
1392 | #endif |
---|
1393 | CHECK( !( !cu.cs->pcv->only2Nx2N || cu.partSize == SIZE_2Nx2N ), "Unexpected part size for QTBT." ); |
---|
1394 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
1395 | #if JEM_TOOLS |
---|
1396 | #if JVET_K0220_ENC_CTRL |
---|
1397 | #if JVET_K0357_AMVR |
---|
1398 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() && !cu.LICFlag && cu.imv == 0) |
---|
1399 | #else |
---|
1400 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() && !cu.LICFlag) |
---|
1401 | #endif |
---|
1402 | #else |
---|
1403 | #if JVET_K0357_AMVR |
---|
1404 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() && !cu.LICFlag && cu.imv == 0 && !bFastSkipAffine) |
---|
1405 | #else |
---|
1406 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() && !cu.LICFlag && !bFastSkipAffine) |
---|
1407 | #endif |
---|
1408 | #endif |
---|
1409 | #else |
---|
1410 | #if JVET_K0220_ENC_CTRL |
---|
1411 | #if JVET_K0357_AMVR |
---|
1412 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() && cu.imv == 0) |
---|
1413 | #else |
---|
1414 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine()) |
---|
1415 | #endif |
---|
1416 | #else |
---|
1417 | #if JVET_K0357_AMVR |
---|
1418 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() && cu.imv == 0 && !bFastSkipAffine) |
---|
1419 | #else |
---|
1420 | if (cu.Y().width > 8 && cu.Y().height > 8 && cu.partSize == SIZE_2Nx2N && cu.slice->getSPS()->getSpsNext().getUseAffine() && !bFastSkipAffine) |
---|
1421 | #endif |
---|
1422 | #endif |
---|
1423 | #endif |
---|
1424 | { |
---|
1425 | // save normal hevc result |
---|
1426 | uint32_t uiMRGIndex = pu.mergeIdx; |
---|
1427 | bool bMergeFlag = pu.mergeFlag; |
---|
1428 | uint32_t uiInterDir = pu.interDir; |
---|
1429 | |
---|
1430 | Mv cMvd[2]; |
---|
1431 | uint32_t uiMvpIdx[2], uiMvpNum[2]; |
---|
1432 | uiMvpIdx[0] = pu.mvpIdx[REF_PIC_LIST_0]; |
---|
1433 | uiMvpIdx[1] = pu.mvpIdx[REF_PIC_LIST_1]; |
---|
1434 | uiMvpNum[0] = pu.mvpNum[REF_PIC_LIST_0]; |
---|
1435 | uiMvpNum[1] = pu.mvpNum[REF_PIC_LIST_1]; |
---|
1436 | cMvd[0] = pu.mvd[REF_PIC_LIST_0]; |
---|
1437 | cMvd[1] = pu.mvd[REF_PIC_LIST_1]; |
---|
1438 | |
---|
1439 | MvField cHevcMvField[2]; |
---|
1440 | cHevcMvField[0].setMvField( pu.mv[REF_PIC_LIST_0], pu.refIdx[REF_PIC_LIST_0] ); |
---|
1441 | cHevcMvField[1].setMvField( pu.mv[REF_PIC_LIST_1], pu.refIdx[REF_PIC_LIST_1] ); |
---|
1442 | |
---|
1443 | // do affine ME & Merge |
---|
1444 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
1445 | cu.affineType = AFFINEMODEL_4PARAM; |
---|
1446 | Mv acMvAffine4Para[2][33][3]; |
---|
1447 | int refIdx4Para[2] = { -1, -1 }; |
---|
1448 | |
---|
1449 | #if JVET_K0220_ENC_CTRL |
---|
1450 | xPredAffineInterSearch( pu, origBuf, puIdx, uiLastModeTemp, uiAffineCost, cMvHevcTemp, acMvAffine4Para, refIdx4Para ); |
---|
1451 | #else |
---|
1452 | xPredAffineInterSearch( pu, origBuf, puIdx, uiLastModeTemp, uiAffineCost, cMvHevcTemp, bFastSkipBi, acMvAffine4Para, refIdx4Para ); |
---|
1453 | #endif |
---|
1454 | if ( cu.slice->getSPS()->getSpsNext().getUseAffineType() ) |
---|
1455 | { |
---|
1456 | if ( uiAffineCost < uiHevcCost * 1.05 ) ///< condition for 6 parameter affine ME |
---|
1457 | { |
---|
1458 | // save 4 parameter results |
---|
1459 | Mv bestMv[2][3], bestMvd[2][3]; |
---|
1460 | int bestMvpIdx[2], bestMvpNum[2], bestRefIdx[2]; |
---|
1461 | uint8_t bestInterDir; |
---|
1462 | |
---|
1463 | bestInterDir = pu.interDir; |
---|
1464 | bestRefIdx[0] = pu.refIdx[0]; |
---|
1465 | bestRefIdx[1] = pu.refIdx[1]; |
---|
1466 | bestMvpIdx[0] = pu.mvpIdx[0]; |
---|
1467 | bestMvpIdx[1] = pu.mvpIdx[1]; |
---|
1468 | bestMvpNum[0] = pu.mvpNum[0]; |
---|
1469 | bestMvpNum[1] = pu.mvpNum[1]; |
---|
1470 | |
---|
1471 | const CMotionBuf &mb = pu.getMotionBuf(); |
---|
1472 | for ( int refList = 0; refList < 2; refList++ ) |
---|
1473 | { |
---|
1474 | bestMv[refList][0] = mb.at( 0, 0 ).mv[refList]; |
---|
1475 | bestMv[refList][1] = mb.at( mb.width - 1, 0 ).mv[refList]; |
---|
1476 | bestMv[refList][2] = mb.at( 0, mb.height - 1 ).mv[refList]; |
---|
1477 | |
---|
1478 | bestMvd[refList][0] = pu.mvdAffi[refList][0]; |
---|
1479 | bestMvd[refList][1] = pu.mvdAffi[refList][1]; |
---|
1480 | bestMvd[refList][2] = pu.mvdAffi[refList][2]; |
---|
1481 | } |
---|
1482 | |
---|
1483 | refIdx4Para[0] = bestRefIdx[0]; |
---|
1484 | refIdx4Para[1] = bestRefIdx[1]; |
---|
1485 | |
---|
1486 | Distortion uiAffine6Cost = std::numeric_limits<Distortion>::max(); |
---|
1487 | cu.affineType = AFFINEMODEL_6PARAM; |
---|
1488 | #if JVET_K0220_ENC_CTRL |
---|
1489 | xPredAffineInterSearch( pu, origBuf, puIdx, uiLastModeTemp, uiAffine6Cost, cMvHevcTemp, acMvAffine4Para, refIdx4Para ); |
---|
1490 | #else |
---|
1491 | xPredAffineInterSearch( pu, origBuf, puIdx, uiLastModeTemp, uiAffine6Cost, cMvHevcTemp, bFastSkipBi, acMvAffine4Para, refIdx4Para ); |
---|
1492 | #endif |
---|
1493 | |
---|
1494 | // reset to 4 parameter affine inter mode |
---|
1495 | if ( uiAffineCost <= uiAffine6Cost ) |
---|
1496 | { |
---|
1497 | cu.affineType = AFFINEMODEL_4PARAM; |
---|
1498 | pu.interDir = bestInterDir; |
---|
1499 | pu.refIdx[0] = bestRefIdx[0]; |
---|
1500 | pu.refIdx[1] = bestRefIdx[1]; |
---|
1501 | pu.mvpIdx[0] = bestMvpIdx[0]; |
---|
1502 | pu.mvpIdx[1] = bestMvpIdx[1]; |
---|
1503 | pu.mvpNum[0] = bestMvpNum[0]; |
---|
1504 | pu.mvpNum[1] = bestMvpNum[1]; |
---|
1505 | |
---|
1506 | for ( int verIdx = 0; verIdx < 3; verIdx++ ) |
---|
1507 | { |
---|
1508 | pu.mvdAffi[REF_PIC_LIST_0][verIdx] = bestMvd[0][verIdx]; |
---|
1509 | pu.mvdAffi[REF_PIC_LIST_1][verIdx] = bestMvd[1][verIdx]; |
---|
1510 | } |
---|
1511 | |
---|
1512 | PU::setAllAffineMv( pu, bestMv[0][0], bestMv[0][1], bestMv[0][2], REF_PIC_LIST_0 ); |
---|
1513 | PU::setAllAffineMv( pu, bestMv[1][0], bestMv[1][1], bestMv[1][2], REF_PIC_LIST_1 ); |
---|
1514 | } |
---|
1515 | else |
---|
1516 | { |
---|
1517 | uiAffineCost = uiAffine6Cost; |
---|
1518 | } |
---|
1519 | } |
---|
1520 | |
---|
1521 | uiAffineCost += m_pcRdCost->getCost( 1 ); // add one bit for affine_type |
---|
1522 | } |
---|
1523 | #else |
---|
1524 | #if JVET_K0220_ENC_CTRL |
---|
1525 | xPredAffineInterSearch( pu, origBuf, puIdx, uiLastModeTemp, uiAffineCost, cMvHevcTemp ); |
---|
1526 | #else |
---|
1527 | xPredAffineInterSearch( pu, origBuf, puIdx, uiLastModeTemp, uiAffineCost, cMvHevcTemp, bFastSkipBi ); |
---|
1528 | #endif |
---|
1529 | #endif |
---|
1530 | |
---|
1531 | if ( uiHevcCost <= uiAffineCost ) |
---|
1532 | { |
---|
1533 | // set hevc me result |
---|
1534 | cu.affine = false; |
---|
1535 | pu.mergeFlag = bMergeFlag; |
---|
1536 | pu.mergeIdx = uiMRGIndex; |
---|
1537 | pu.interDir = uiInterDir; |
---|
1538 | pu.mv [REF_PIC_LIST_0] = cHevcMvField[0].mv; |
---|
1539 | pu.refIdx[REF_PIC_LIST_0] = cHevcMvField[0].refIdx; |
---|
1540 | pu.mv [REF_PIC_LIST_1] = cHevcMvField[1].mv; |
---|
1541 | pu.refIdx[REF_PIC_LIST_1] = cHevcMvField[1].refIdx; |
---|
1542 | pu.mvpIdx[REF_PIC_LIST_0] = uiMvpIdx[0]; |
---|
1543 | pu.mvpIdx[REF_PIC_LIST_1] = uiMvpIdx[1]; |
---|
1544 | pu.mvpNum[REF_PIC_LIST_0] = uiMvpNum[0]; |
---|
1545 | pu.mvpNum[REF_PIC_LIST_1] = uiMvpNum[1]; |
---|
1546 | pu.mvd[REF_PIC_LIST_0] = cMvd[0]; |
---|
1547 | pu.mvd[REF_PIC_LIST_1] = cMvd[1]; |
---|
1548 | } |
---|
1549 | else |
---|
1550 | { |
---|
1551 | CHECK( !cu.affine, "Wrong." ); |
---|
1552 | uiLastMode = uiLastModeTemp; |
---|
1553 | } |
---|
1554 | } |
---|
1555 | #endif |
---|
1556 | m_maxCompIDToPred = MAX_NUM_COMPONENT; |
---|
1557 | |
---|
1558 | #if JEM_TOOLS |
---|
1559 | if( pu.frucMrgMode == FRUC_MERGE_OFF ) |
---|
1560 | #endif |
---|
1561 | { |
---|
1562 | PU::spanMotionInfo( pu, mergeCtx ); |
---|
1563 | } |
---|
1564 | |
---|
1565 | // MC |
---|
1566 | PelUnitBuf predBuf = pu.cs->getPredBuf(pu); |
---|
1567 | motionCompensation( pu, predBuf, REF_PIC_LIST_X ); |
---|
1568 | puIdx++; |
---|
1569 | } |
---|
1570 | |
---|
1571 | setWpScalingDistParam( -1, REF_PIC_LIST_X, cu.cs->slice ); |
---|
1572 | |
---|
1573 | return; |
---|
1574 | } |
---|
1575 | |
---|
1576 | |
---|
1577 | |
---|
1578 | |
---|
1579 | // AMVP |
---|
1580 | void InterSearch::xEstimateMvPredAMVP( PredictionUnit& pu, PelUnitBuf& origBuf, RefPicList eRefPicList, int iRefIdx, Mv& rcMvPred, AMVPInfo& rAMVPInfo, bool bFilled, Distortion* puiDistBiP ) |
---|
1581 | { |
---|
1582 | Mv cBestMv; |
---|
1583 | int iBestIdx = 0; |
---|
1584 | Distortion uiBestCost = std::numeric_limits<Distortion>::max(); |
---|
1585 | int i; |
---|
1586 | |
---|
1587 | AMVPInfo* pcAMVPInfo = &rAMVPInfo; |
---|
1588 | |
---|
1589 | // Fill the MV Candidates |
---|
1590 | if (!bFilled) |
---|
1591 | { |
---|
1592 | #if JEM_TOOLS |
---|
1593 | PU::fillMvpCand( pu, eRefPicList, iRefIdx, *pcAMVPInfo, this ); |
---|
1594 | #else |
---|
1595 | PU::fillMvpCand( pu, eRefPicList, iRefIdx, *pcAMVPInfo ); |
---|
1596 | #endif |
---|
1597 | } |
---|
1598 | |
---|
1599 | // initialize Mvp index & Mvp |
---|
1600 | iBestIdx = 0; |
---|
1601 | cBestMv = pcAMVPInfo->mvCand[0]; |
---|
1602 | |
---|
1603 | PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
1604 | |
---|
1605 | //-- Check Minimum Cost. |
---|
1606 | for( i = 0 ; i < pcAMVPInfo->numCand; i++) |
---|
1607 | { |
---|
1608 | Distortion uiTmpCost = xGetTemplateCost( pu, origBuf, predBuf, pcAMVPInfo->mvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx ); |
---|
1609 | if( uiBestCost > uiTmpCost ) |
---|
1610 | { |
---|
1611 | uiBestCost = uiTmpCost; |
---|
1612 | cBestMv = pcAMVPInfo->mvCand[i]; |
---|
1613 | iBestIdx = i; |
---|
1614 | (*puiDistBiP) = uiTmpCost; |
---|
1615 | } |
---|
1616 | } |
---|
1617 | |
---|
1618 | // Setting Best MVP |
---|
1619 | rcMvPred = cBestMv; |
---|
1620 | pu.mvpIdx[eRefPicList] = iBestIdx; |
---|
1621 | pu.mvpNum[eRefPicList] = pcAMVPInfo->numCand; |
---|
1622 | |
---|
1623 | return; |
---|
1624 | } |
---|
1625 | |
---|
1626 | uint32_t InterSearch::xGetMvpIdxBits(int iIdx, int iNum) |
---|
1627 | { |
---|
1628 | CHECK(iIdx < 0 || iNum < 0 || iIdx >= iNum, "Invalid parameters"); |
---|
1629 | |
---|
1630 | if (iNum == 1) |
---|
1631 | { |
---|
1632 | return 0; |
---|
1633 | } |
---|
1634 | |
---|
1635 | uint32_t uiLength = 1; |
---|
1636 | int iTemp = iIdx; |
---|
1637 | if ( iTemp == 0 ) |
---|
1638 | { |
---|
1639 | return uiLength; |
---|
1640 | } |
---|
1641 | |
---|
1642 | bool bCodeLast = ( iNum-1 > iTemp ); |
---|
1643 | |
---|
1644 | uiLength += (iTemp-1); |
---|
1645 | |
---|
1646 | if( bCodeLast ) |
---|
1647 | { |
---|
1648 | uiLength++; |
---|
1649 | } |
---|
1650 | |
---|
1651 | return uiLength; |
---|
1652 | } |
---|
1653 | |
---|
1654 | void InterSearch::xGetBlkBits( PartSize eCUMode, bool bPSlice, int iPartIdx, uint32_t uiLastMode, uint32_t uiBlkBit[3]) |
---|
1655 | { |
---|
1656 | if ( eCUMode == SIZE_2Nx2N ) |
---|
1657 | { |
---|
1658 | uiBlkBit[0] = (! bPSlice) ? 3 : 1; |
---|
1659 | uiBlkBit[1] = 3; |
---|
1660 | uiBlkBit[2] = 5; |
---|
1661 | } |
---|
1662 | else |
---|
1663 | { |
---|
1664 | THROW("Wrong part size!"); |
---|
1665 | } |
---|
1666 | } |
---|
1667 | |
---|
1668 | void InterSearch::xCopyAMVPInfo (AMVPInfo* pSrc, AMVPInfo* pDst) |
---|
1669 | { |
---|
1670 | pDst->numCand = pSrc->numCand; |
---|
1671 | for (int i = 0; i < pSrc->numCand; i++) |
---|
1672 | { |
---|
1673 | pDst->mvCand[i] = pSrc->mvCand[i]; |
---|
1674 | } |
---|
1675 | } |
---|
1676 | |
---|
1677 | #if JVET_K0357_AMVR |
---|
1678 | void InterSearch::xCheckBestMVP ( RefPicList eRefPicList, Mv cMv, Mv& rcMvPred, int& riMVPIdx, AMVPInfo& amvpInfo, uint32_t& ruiBits, Distortion& ruiCost, const uint8_t imv ) |
---|
1679 | #else |
---|
1680 | void InterSearch::xCheckBestMVP ( RefPicList eRefPicList, Mv cMv, Mv& rcMvPred, int& riMVPIdx, AMVPInfo& amvpInfo, uint32_t& ruiBits, Distortion& ruiCost ) |
---|
1681 | #endif |
---|
1682 | { |
---|
1683 | #if JVET_K0357_AMVR |
---|
1684 | if( imv > 0 ) |
---|
1685 | { |
---|
1686 | return; |
---|
1687 | } |
---|
1688 | unsigned imvshift = imv << 1; |
---|
1689 | #endif |
---|
1690 | |
---|
1691 | AMVPInfo* pcAMVPInfo = &amvpInfo; |
---|
1692 | |
---|
1693 | CHECK(pcAMVPInfo->mvCand[riMVPIdx] != rcMvPred, "Invalid MV prediction candidate"); |
---|
1694 | |
---|
1695 | if (pcAMVPInfo->numCand < 2) |
---|
1696 | { |
---|
1697 | return; |
---|
1698 | } |
---|
1699 | |
---|
1700 | m_pcRdCost->setCostScale ( 0 ); |
---|
1701 | |
---|
1702 | int iBestMVPIdx = riMVPIdx; |
---|
1703 | |
---|
1704 | m_pcRdCost->setPredictor( rcMvPred ); |
---|
1705 | #if JVET_K0357_AMVR |
---|
1706 | int iOrgMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), imvshift); |
---|
1707 | #else |
---|
1708 | int iOrgMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer()); |
---|
1709 | #endif |
---|
1710 | iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS]; |
---|
1711 | int iBestMvBits = iOrgMvBits; |
---|
1712 | |
---|
1713 | for (int iMVPIdx = 0; iMVPIdx < pcAMVPInfo->numCand; iMVPIdx++) |
---|
1714 | { |
---|
1715 | if (iMVPIdx == riMVPIdx) |
---|
1716 | { |
---|
1717 | continue; |
---|
1718 | } |
---|
1719 | |
---|
1720 | m_pcRdCost->setPredictor( pcAMVPInfo->mvCand[iMVPIdx] ); |
---|
1721 | #if JVET_K0357_AMVR |
---|
1722 | int iMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer(), imvshift); |
---|
1723 | #else |
---|
1724 | int iMvBits = m_pcRdCost->getBitsOfVectorWithPredictor(cMv.getHor(), cMv.getVer()); |
---|
1725 | #endif |
---|
1726 | iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS]; |
---|
1727 | |
---|
1728 | if (iMvBits < iBestMvBits) |
---|
1729 | { |
---|
1730 | iBestMvBits = iMvBits; |
---|
1731 | iBestMVPIdx = iMVPIdx; |
---|
1732 | } |
---|
1733 | } |
---|
1734 | |
---|
1735 | if (iBestMVPIdx != riMVPIdx) //if changed |
---|
1736 | { |
---|
1737 | rcMvPred = pcAMVPInfo->mvCand[iBestMVPIdx]; |
---|
1738 | |
---|
1739 | riMVPIdx = iBestMVPIdx; |
---|
1740 | uint32_t uiOrgBits = ruiBits; |
---|
1741 | ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits; |
---|
1742 | ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits )) + m_pcRdCost->getCost( ruiBits ); |
---|
1743 | } |
---|
1744 | } |
---|
1745 | |
---|
1746 | |
---|
1747 | Distortion InterSearch::xGetTemplateCost( const PredictionUnit& pu, |
---|
1748 | PelUnitBuf& origBuf, |
---|
1749 | PelUnitBuf& predBuf, |
---|
1750 | Mv cMvCand, |
---|
1751 | int iMVPIdx, |
---|
1752 | int iMVPNum, |
---|
1753 | RefPicList eRefPicList, |
---|
1754 | int iRefIdx |
---|
1755 | ) |
---|
1756 | { |
---|
1757 | Distortion uiCost = std::numeric_limits<Distortion>::max(); |
---|
1758 | |
---|
1759 | const Picture* picRef = pu.cu->slice->getRefPic( eRefPicList, iRefIdx ); |
---|
1760 | |
---|
1761 | clipMv( cMvCand, pu.cu->lumaPos(), *pu.cs->sps ); |
---|
1762 | |
---|
1763 | |
---|
1764 | // prediction pattern |
---|
1765 | #if JEM_TOOLS |
---|
1766 | const bool bi = !pu.cu->LICFlag && pu.cu->slice->testWeightPred() && pu.cu->slice->getSliceType()==P_SLICE; |
---|
1767 | #else |
---|
1768 | const bool bi = pu.cu->slice->testWeightPred() && pu.cu->slice->getSliceType()==P_SLICE; |
---|
1769 | #endif |
---|
1770 | |
---|
1771 | |
---|
1772 | xPredInterBlk( COMPONENT_Y, pu, picRef, cMvCand, predBuf, bi, pu.cu->slice->clpRng( COMPONENT_Y ) |
---|
1773 | #if JEM_TOOLS |
---|
1774 | , false, false, FRUC_MERGE_OFF, true |
---|
1775 | #endif |
---|
1776 | ); |
---|
1777 | |
---|
1778 | |
---|
1779 | if ( bi ) |
---|
1780 | { |
---|
1781 | xWeightedPredictionUni( pu, predBuf, eRefPicList, predBuf, iRefIdx, m_maxCompIDToPred ); |
---|
1782 | } |
---|
1783 | |
---|
1784 | // calc distortion |
---|
1785 | |
---|
1786 | uiCost = m_pcRdCost->getDistPart( origBuf.Y(), predBuf.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, DF_SAD ); |
---|
1787 | uiCost += m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] ); |
---|
1788 | |
---|
1789 | return uiCost; |
---|
1790 | } |
---|
1791 | |
---|
1792 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
1793 | Distortion InterSearch::xGetAffineTemplateCost( PredictionUnit& pu, PelUnitBuf& origBuf, PelUnitBuf& predBuf, Mv acMvCand[3], int iMVPIdx, int iMVPNum, RefPicList eRefPicList, int iRefIdx ) |
---|
1794 | { |
---|
1795 | Distortion uiCost = std::numeric_limits<Distortion>::max(); |
---|
1796 | |
---|
1797 | const Picture* picRef = pu.cu->slice->getRefPic( eRefPicList, iRefIdx ); |
---|
1798 | |
---|
1799 | // prediction pattern |
---|
1800 | const bool bi = pu.cu->slice->testWeightPred() && pu.cu->slice->getSliceType()==P_SLICE; |
---|
1801 | xPredAffineBlk( COMPONENT_Y, pu, picRef, acMvCand, predBuf, bi, pu.cu->slice->clpRng( COMPONENT_Y ) ); |
---|
1802 | if( bi ) |
---|
1803 | { |
---|
1804 | xWeightedPredictionUni( pu, predBuf, eRefPicList, predBuf, iRefIdx, m_maxCompIDToPred ); |
---|
1805 | } |
---|
1806 | |
---|
1807 | // calc distortion |
---|
1808 | |
---|
1809 | uiCost = m_pcRdCost->getDistPart( origBuf.Y(), predBuf.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, DF_SAD ); |
---|
1810 | uiCost += m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] ); |
---|
1811 | DTRACE( g_trace_ctx, D_COMMON, " (%d) affineTemplateCost=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiCost ); |
---|
1812 | return uiCost; |
---|
1813 | } |
---|
1814 | #endif |
---|
1815 | |
---|
1816 | void InterSearch::xMotionEstimation(PredictionUnit& pu, PelUnitBuf& origBuf, RefPicList eRefPicList, Mv& rcMvPred, int iRefIdxPred, Mv& rcMv, int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost, const AMVPInfo& amvpInfo, bool bBi) |
---|
1817 | { |
---|
1818 | Mv cMvHalf, cMvQter; |
---|
1819 | |
---|
1820 | CHECK(eRefPicList >= MAX_NUM_REF_LIST_ADAPT_SR || iRefIdxPred>=int(MAX_IDX_ADAPT_SR), "Invalid reference picture list"); |
---|
1821 | m_iSearchRange = m_aaiAdaptSR[eRefPicList][iRefIdxPred]; |
---|
1822 | |
---|
1823 | int iSrchRng = (bBi ? m_bipredSearchRange : m_iSearchRange); |
---|
1824 | double fWeight = 1.0; |
---|
1825 | |
---|
1826 | PelUnitBuf origBufTmp = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
1827 | PelUnitBuf* pBuf = &origBuf; |
---|
1828 | |
---|
1829 | if(bBi) // Bi-predictive ME |
---|
1830 | { |
---|
1831 | // NOTE: Other buf contains predicted signal from another direction |
---|
1832 | PelUnitBuf otherBuf = m_tmpPredStorage[1 - (int)eRefPicList].getBuf( UnitAreaRelative(*pu.cu, pu )); |
---|
1833 | origBufTmp.copyFrom(origBuf); |
---|
1834 | origBufTmp.removeHighFreq(otherBuf, m_pcEncCfg->getClipForBiPredMeEnabled(), pu.cu->slice->clpRngs() ); |
---|
1835 | |
---|
1836 | pBuf = &origBufTmp; |
---|
1837 | |
---|
1838 | fWeight = 0.5; |
---|
1839 | } |
---|
1840 | m_cDistParam.isBiPred = bBi; |
---|
1841 | #if JEM_TOOLS |
---|
1842 | m_cDistParam.useMR = pu.cu->LICFlag; |
---|
1843 | #endif |
---|
1844 | |
---|
1845 | // Search key pattern initialization |
---|
1846 | CPelBuf tmpPattern = pBuf->Y(); |
---|
1847 | CPelBuf* pcPatternKey = &tmpPattern; |
---|
1848 | |
---|
1849 | m_lumaClpRng = pu.cs->slice->clpRng( COMPONENT_Y ); |
---|
1850 | |
---|
1851 | CPelBuf buf = pu.cu->slice->getRefPic(eRefPicList, iRefIdxPred)->getRecoBuf(pu.blocks[COMPONENT_Y]); |
---|
1852 | |
---|
1853 | IntTZSearchStruct cStruct; |
---|
1854 | cStruct.pcPatternKey = pcPatternKey; |
---|
1855 | cStruct.iRefStride = buf.stride; |
---|
1856 | cStruct.piRefY = buf.buf; |
---|
1857 | #if JVET_K0357_AMVR |
---|
1858 | cStruct.imvShift = pu.cu->imv << 1; |
---|
1859 | #endif |
---|
1860 | auto blkCache = dynamic_cast<CacheBlkInfoCtrl*>( m_modeCtrl ); |
---|
1861 | |
---|
1862 | bool bQTBTMV = false; |
---|
1863 | bool bQTBTMV2 = false; |
---|
1864 | Mv cIntMv; |
---|
1865 | if( !bBi ) |
---|
1866 | { |
---|
1867 | bool bValid = blkCache && blkCache->getMv( pu, eRefPicList, iRefIdxPred, cIntMv ); |
---|
1868 | if( bValid ) |
---|
1869 | { |
---|
1870 | bQTBTMV2 = true; |
---|
1871 | cIntMv <<= 2; |
---|
1872 | } |
---|
1873 | } |
---|
1874 | |
---|
1875 | |
---|
1876 | m_pcRdCost->setPredictor( rcMvPred ); |
---|
1877 | |
---|
1878 | m_pcRdCost->setCostScale(2); |
---|
1879 | |
---|
1880 | #if JEM_TOOLS |
---|
1881 | if( pu.cu->LICFlag ) |
---|
1882 | { |
---|
1883 | m_cDistParam.applyWeight = false; |
---|
1884 | } |
---|
1885 | else |
---|
1886 | #endif |
---|
1887 | { |
---|
1888 | setWpScalingDistParam(iRefIdxPred, eRefPicList, pu.cu->slice); |
---|
1889 | } |
---|
1890 | |
---|
1891 | // Do integer search |
---|
1892 | if( ( m_motionEstimationSearchMethod == MESEARCH_FULL ) || bBi || bQTBTMV ) |
---|
1893 | { |
---|
1894 | if( !bQTBTMV ) |
---|
1895 | { |
---|
1896 | xSetSearchRange( pu, ( bBi ? rcMv : rcMvPred ), iSrchRng, cStruct.searchRange ); |
---|
1897 | } |
---|
1898 | cStruct.subShiftMode = m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE3 ? 2 : 0; |
---|
1899 | xPatternSearch( cStruct, rcMv, ruiCost); |
---|
1900 | } |
---|
1901 | else if( bQTBTMV2 ) |
---|
1902 | { |
---|
1903 | rcMv = cIntMv; |
---|
1904 | |
---|
1905 | cStruct.subShiftMode = ( !m_pcEncCfg->getRestrictMESampling() && m_pcEncCfg->getMotionEstimationSearchMethod() == MESEARCH_SELECTIVE ) ? 1 : |
---|
1906 | ( m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE3 ) ? 2 : 0; |
---|
1907 | xTZSearch( pu, cStruct, rcMv, ruiCost, NULL, false, true ); |
---|
1908 | } |
---|
1909 | else |
---|
1910 | { |
---|
1911 | cStruct.subShiftMode = ( !m_pcEncCfg->getRestrictMESampling() && m_pcEncCfg->getMotionEstimationSearchMethod() == MESEARCH_SELECTIVE ) ? 1 : |
---|
1912 | ( m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode() == FASTINTERSEARCH_MODE3 ) ? 2 : 0; |
---|
1913 | rcMv = rcMvPred; |
---|
1914 | const Mv *pIntegerMv2Nx2NPred = 0; |
---|
1915 | if( !pu.cs->pcv->only2Nx2N && ( pu.cu->partSize != SIZE_2Nx2N || pu.cu->qtDepth != 0 ) ) |
---|
1916 | { |
---|
1917 | pIntegerMv2Nx2NPred = &( m_integerMv2Nx2N[eRefPicList][iRefIdxPred] ); |
---|
1918 | } |
---|
1919 | xPatternSearchFast( pu, cStruct, rcMv, ruiCost, pIntegerMv2Nx2NPred ); |
---|
1920 | if( blkCache ) |
---|
1921 | { |
---|
1922 | blkCache->setMv( pu.cs->area, eRefPicList, iRefIdxPred, rcMv ); |
---|
1923 | } |
---|
1924 | else if( pu.cu->partSize == SIZE_2Nx2N ) |
---|
1925 | { |
---|
1926 | m_integerMv2Nx2N[eRefPicList][iRefIdxPred] = rcMv; |
---|
1927 | } |
---|
1928 | } |
---|
1929 | |
---|
1930 | #if JEM_TOOLS |
---|
1931 | DTRACE( g_trace_ctx, D_ME, "%d %d %d :MECostFPel<L%d,%d>: %d,%d,%dx%d,%2d: %d", DTRACE_GET_COUNTER( g_trace_ctx, D_ME ), pu.cu->slice->getPOC(), pu.cu->imv, (int)eRefPicList, (int)bBi, pu.Y().x, pu.Y().y, pu.Y().width, pu.Y().height, pu.cu->partSize, ruiCost ); |
---|
1932 | #else |
---|
1933 | DTRACE( g_trace_ctx, D_ME, "%d %d %d :MECostFPel<L%d,%d>: %d,%d,%dx%d,%2d: %d", DTRACE_GET_COUNTER( g_trace_ctx, D_ME ), pu.cu->slice->getPOC(), 0, ( int ) eRefPicList, ( int ) bBi, pu.Y().x, pu.Y().y, pu.Y().width, pu.Y().height, pu.cu->partSize, ruiCost ); |
---|
1934 | #endif |
---|
1935 | // sub-pel refinement for sub-pel resolution |
---|
1936 | #if JVET_K0357_AMVR |
---|
1937 | if( pu.cu->imv == 0 ) |
---|
1938 | #endif |
---|
1939 | { |
---|
1940 | xPatternSearchFracDIF( pu, eRefPicList, iRefIdxPred, cStruct, rcMv, cMvHalf, cMvQter, ruiCost ); |
---|
1941 | m_pcRdCost->setCostScale( 0 ); |
---|
1942 | rcMv <<= 2; |
---|
1943 | rcMv += ( cMvHalf <<= 1 ); |
---|
1944 | rcMv += cMvQter; |
---|
1945 | #if JVET_K0357_AMVR |
---|
1946 | uint32_t uiMvBits = m_pcRdCost->getBitsOfVectorWithPredictor( rcMv.getHor(), rcMv.getVer(), cStruct.imvShift ); |
---|
1947 | #else |
---|
1948 | uint32_t uiMvBits = m_pcRdCost->getBitsOfVectorWithPredictor( rcMv.getHor(), rcMv.getVer() ); |
---|
1949 | #endif |
---|
1950 | ruiBits += uiMvBits; |
---|
1951 | ruiCost = ( Distortion ) ( floor( fWeight * ( ( double ) ruiCost - ( double ) m_pcRdCost->getCost( uiMvBits ) ) ) + ( double ) m_pcRdCost->getCost( ruiBits ) ); |
---|
1952 | } |
---|
1953 | #if JVET_K0357_AMVR |
---|
1954 | else // integer refinement for integer-pel and 4-pel resolution |
---|
1955 | { |
---|
1956 | xPatternSearchIntRefine( pu, cStruct, rcMv, rcMvPred, riMVPIdx, ruiBits, ruiCost, amvpInfo, fWeight); |
---|
1957 | } |
---|
1958 | DTRACE( g_trace_ctx, D_ME, " MECost<L%d,%d>: %6d (%d) MV:%d,%d\n", ( int ) eRefPicList, ( int ) bBi, ruiCost, ruiBits, rcMv.getHor() << ( pu.cs->sps->getSpsNext().getUseHighPrecMv() ? 2 : 0 ), rcMv.getVer() << ( pu.cs->sps->getSpsNext().getUseHighPrecMv() ? 2 : 0 ) ); |
---|
1959 | #else |
---|
1960 | DTRACE( g_trace_ctx, D_ME, " MECost<L%d,%d>: %6d (%d) MV:%d,%d\n", ( int ) eRefPicList, ( int ) bBi, ruiCost, ruiBits, rcMv.getHor(), rcMv.getVer() ); |
---|
1961 | #endif |
---|
1962 | } |
---|
1963 | |
---|
1964 | |
---|
1965 | |
---|
1966 | void InterSearch::xSetSearchRange ( const PredictionUnit& pu, |
---|
1967 | const Mv& cMvPred, |
---|
1968 | const int iSrchRng, |
---|
1969 | SearchRange& sr ) |
---|
1970 | { |
---|
1971 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
1972 | const int iMvShift = cMvPred.highPrec ? 4 : 2; |
---|
1973 | #else |
---|
1974 | const int iMvShift = 2; |
---|
1975 | #endif |
---|
1976 | Mv cFPMvPred = cMvPred; |
---|
1977 | clipMv( cFPMvPred, pu.cu->lumaPos(), *pu.cs->sps ); |
---|
1978 | |
---|
1979 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
1980 | Mv mvTL( cFPMvPred.getHor() - ( iSrchRng << iMvShift ), cFPMvPred.getVer() - ( iSrchRng << iMvShift ), cFPMvPred.highPrec ); |
---|
1981 | Mv mvBR( cFPMvPred.getHor() + ( iSrchRng << iMvShift ), cFPMvPred.getVer() + ( iSrchRng << iMvShift ), cFPMvPred.highPrec ); |
---|
1982 | #else |
---|
1983 | Mv mvTL( cFPMvPred.getHor() - ( iSrchRng << iMvShift ), cFPMvPred.getVer() - ( iSrchRng << iMvShift ) ); |
---|
1984 | Mv mvBR( cFPMvPred.getHor() + ( iSrchRng << iMvShift ), cFPMvPred.getVer() + ( iSrchRng << iMvShift ) ); |
---|
1985 | #endif |
---|
1986 | |
---|
1987 | clipMv( mvTL, pu.cu->lumaPos(), *pu.cs->sps ); |
---|
1988 | clipMv( mvBR, pu.cu->lumaPos(), *pu.cs->sps ); |
---|
1989 | |
---|
1990 | mvTL.divideByPowerOf2( iMvShift ); |
---|
1991 | mvBR.divideByPowerOf2( iMvShift ); |
---|
1992 | |
---|
1993 | sr.left = mvTL.hor; |
---|
1994 | sr.top = mvTL.ver; |
---|
1995 | sr.right = mvBR.hor; |
---|
1996 | sr.bottom = mvBR.ver; |
---|
1997 | } |
---|
1998 | |
---|
1999 | |
---|
2000 | void InterSearch::xPatternSearch( IntTZSearchStruct& cStruct, |
---|
2001 | Mv& rcMv, |
---|
2002 | Distortion& ruiSAD ) |
---|
2003 | { |
---|
2004 | Distortion uiSad; |
---|
2005 | Distortion uiSadBest = std::numeric_limits<Distortion>::max(); |
---|
2006 | int iBestX = 0; |
---|
2007 | int iBestY = 0; |
---|
2008 | |
---|
2009 | //-- jclee for using the SAD function pointer |
---|
2010 | m_pcRdCost->setDistParam( m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode ); |
---|
2011 | |
---|
2012 | const SearchRange& sr = cStruct.searchRange; |
---|
2013 | |
---|
2014 | const Pel* piRef = cStruct.piRefY + (sr.top * cStruct.iRefStride); |
---|
2015 | for ( int y = sr.top; y <= sr.bottom; y++ ) |
---|
2016 | { |
---|
2017 | for ( int x = sr.left; x <= sr.right; x++ ) |
---|
2018 | { |
---|
2019 | // find min. distortion position |
---|
2020 | m_cDistParam.cur.buf = piRef + x; |
---|
2021 | |
---|
2022 | uiSad = m_cDistParam.distFunc( m_cDistParam ); |
---|
2023 | |
---|
2024 | // motion cost |
---|
2025 | #if JVET_K0357_AMVR |
---|
2026 | uiSad += m_pcRdCost->getCostOfVectorWithPredictor( x, y, cStruct.imvShift ); |
---|
2027 | #else |
---|
2028 | uiSad += m_pcRdCost->getCostOfVectorWithPredictor( x, y ); |
---|
2029 | #endif |
---|
2030 | |
---|
2031 | if ( uiSad < uiSadBest ) |
---|
2032 | { |
---|
2033 | uiSadBest = uiSad; |
---|
2034 | iBestX = x; |
---|
2035 | iBestY = y; |
---|
2036 | m_cDistParam.maximumDistortionForEarlyExit = uiSad; |
---|
2037 | } |
---|
2038 | } |
---|
2039 | piRef += cStruct.iRefStride; |
---|
2040 | } |
---|
2041 | |
---|
2042 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
2043 | CHECK( rcMv.highPrec, "Unexpected high precision MV." ); |
---|
2044 | #endif |
---|
2045 | rcMv.set( iBestX, iBestY ); |
---|
2046 | |
---|
2047 | cStruct.uiBestSad = uiSadBest; // th for testing |
---|
2048 | #if JVET_K0357_AMVR |
---|
2049 | ruiSAD = uiSadBest - m_pcRdCost->getCostOfVectorWithPredictor( iBestX, iBestY, cStruct.imvShift ); |
---|
2050 | #else |
---|
2051 | ruiSAD = uiSadBest - m_pcRdCost->getCostOfVectorWithPredictor( iBestX, iBestY ); |
---|
2052 | #endif |
---|
2053 | return; |
---|
2054 | } |
---|
2055 | |
---|
2056 | |
---|
2057 | void InterSearch::xPatternSearchFast( const PredictionUnit& pu, |
---|
2058 | IntTZSearchStruct& cStruct, |
---|
2059 | Mv& rcMv, |
---|
2060 | Distortion& ruiSAD, |
---|
2061 | const Mv* const pIntegerMv2Nx2NPred ) |
---|
2062 | { |
---|
2063 | switch ( m_motionEstimationSearchMethod ) |
---|
2064 | { |
---|
2065 | case MESEARCH_DIAMOND: |
---|
2066 | xTZSearch ( pu, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred, false ); |
---|
2067 | break; |
---|
2068 | |
---|
2069 | case MESEARCH_SELECTIVE: |
---|
2070 | xTZSearchSelective( pu, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred ); |
---|
2071 | break; |
---|
2072 | |
---|
2073 | case MESEARCH_DIAMOND_ENHANCED: |
---|
2074 | xTZSearch ( pu, cStruct, rcMv, ruiSAD, pIntegerMv2Nx2NPred, true ); |
---|
2075 | break; |
---|
2076 | |
---|
2077 | case MESEARCH_FULL: // shouldn't get here. |
---|
2078 | default: |
---|
2079 | break; |
---|
2080 | } |
---|
2081 | } |
---|
2082 | |
---|
2083 | |
---|
2084 | void InterSearch::xTZSearch( const PredictionUnit& pu, |
---|
2085 | IntTZSearchStruct& cStruct, |
---|
2086 | Mv& rcMv, |
---|
2087 | Distortion& ruiSAD, |
---|
2088 | const Mv* const pIntegerMv2Nx2NPred, |
---|
2089 | const bool bExtendedSettings, |
---|
2090 | const bool bFastSettings) |
---|
2091 | { |
---|
2092 | const bool bUseRasterInFastMode = true; //toggle this to further reduce runtime |
---|
2093 | |
---|
2094 | const bool bUseAdaptiveRaster = bExtendedSettings; |
---|
2095 | const int iRaster = (bFastSettings && bUseRasterInFastMode) ? 8 : 5; |
---|
2096 | const bool bTestZeroVector = true && !bFastSettings; |
---|
2097 | const bool bTestZeroVectorStart = bExtendedSettings; |
---|
2098 | const bool bTestZeroVectorStop = false; |
---|
2099 | const bool bFirstSearchDiamond = true; // 1 = xTZ8PointDiamondSearch 0 = xTZ8PointSquareSearch |
---|
2100 | const bool bFirstCornersForDiamondDist1 = bExtendedSettings; |
---|
2101 | const bool bFirstSearchStop = m_pcEncCfg->getFastMEAssumingSmootherMVEnabled(); |
---|
2102 | const uint32_t uiFirstSearchRounds = bFastSettings ? (bUseRasterInFastMode?3:2) : 3; // first search stop X rounds after best match (must be >=1) |
---|
2103 | const bool bEnableRasterSearch = bFastSettings ? bUseRasterInFastMode : true; |
---|
2104 | const bool bAlwaysRasterSearch = bExtendedSettings; // true: BETTER but factor 2 slower |
---|
2105 | const bool bRasterRefinementEnable = false; // enable either raster refinement or star refinement |
---|
2106 | const bool bRasterRefinementDiamond = false; // 1 = xTZ8PointDiamondSearch 0 = xTZ8PointSquareSearch |
---|
2107 | const bool bRasterRefinementCornersForDiamondDist1 = bExtendedSettings; |
---|
2108 | const bool bStarRefinementEnable = true; // enable either star refinement or raster refinement |
---|
2109 | const bool bStarRefinementDiamond = true; // 1 = xTZ8PointDiamondSearch 0 = xTZ8PointSquareSearch |
---|
2110 | const bool bStarRefinementCornersForDiamondDist1 = bExtendedSettings; |
---|
2111 | const bool bStarRefinementStop = false || bFastSettings; |
---|
2112 | const uint32_t uiStarRefinementRounds = 2; // star refinement stop X rounds after best match (must be >=1) |
---|
2113 | const bool bNewZeroNeighbourhoodTest = bExtendedSettings; |
---|
2114 | |
---|
2115 | int iSearchRange = m_iSearchRange; |
---|
2116 | |
---|
2117 | clipMv( rcMv, pu.cu->lumaPos(), *pu.cs->sps ); |
---|
2118 | rcMv.divideByPowerOf2(2); |
---|
2119 | |
---|
2120 | // init TZSearchStruct |
---|
2121 | #if DISTORTION_TYPE_BUGFIX |
---|
2122 | cStruct.uiBestSad = std::numeric_limits<Distortion>::max(); |
---|
2123 | #else |
---|
2124 | cStruct.uiBestSad = MAX_UINT; |
---|
2125 | #endif |
---|
2126 | |
---|
2127 | // |
---|
2128 | m_cDistParam.maximumDistortionForEarlyExit = cStruct.uiBestSad; |
---|
2129 | m_pcRdCost->setDistParam( m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode ); |
---|
2130 | |
---|
2131 | // distortion |
---|
2132 | |
---|
2133 | |
---|
2134 | // set rcMv (Median predictor) as start point and as best point |
---|
2135 | xTZSearchHelp( cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 ); |
---|
2136 | |
---|
2137 | // test whether zero Mv is better start point than Median predictor |
---|
2138 | if ( bTestZeroVector ) |
---|
2139 | { |
---|
2140 | if ((rcMv.getHor() != 0 || rcMv.getVer() != 0) && |
---|
2141 | (0 != cStruct.iBestX || 0 != cStruct.iBestY)) |
---|
2142 | { |
---|
2143 | // only test 0-vector if not obviously previously tested. |
---|
2144 | xTZSearchHelp( cStruct, 0, 0, 0, 0 ); |
---|
2145 | } |
---|
2146 | } |
---|
2147 | |
---|
2148 | SearchRange& sr = cStruct.searchRange; |
---|
2149 | |
---|
2150 | if (pIntegerMv2Nx2NPred != 0) |
---|
2151 | { |
---|
2152 | Mv integerMv2Nx2NPred = *pIntegerMv2Nx2NPred; |
---|
2153 | integerMv2Nx2NPred <<= 2; |
---|
2154 | clipMv( integerMv2Nx2NPred, pu.cu->lumaPos(), *pu.cs->sps ); |
---|
2155 | integerMv2Nx2NPred.divideByPowerOf2(2); |
---|
2156 | |
---|
2157 | if ((rcMv != integerMv2Nx2NPred) && |
---|
2158 | (integerMv2Nx2NPred.getHor() != cStruct.iBestX || integerMv2Nx2NPred.getVer() != cStruct.iBestY)) |
---|
2159 | { |
---|
2160 | // only test integerMv2Nx2NPred if not obviously previously tested. |
---|
2161 | xTZSearchHelp( cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0); |
---|
2162 | } |
---|
2163 | } |
---|
2164 | { |
---|
2165 | // set search range |
---|
2166 | Mv currBestMv(cStruct.iBestX, cStruct.iBestY ); |
---|
2167 | currBestMv <<= 2; |
---|
2168 | xSetSearchRange( pu, currBestMv, m_iSearchRange>>(bFastSettings?1:0), sr ); |
---|
2169 | } |
---|
2170 | |
---|
2171 | // start search |
---|
2172 | int iDist = 0; |
---|
2173 | int iStartX = cStruct.iBestX; |
---|
2174 | int iStartY = cStruct.iBestY; |
---|
2175 | |
---|
2176 | const bool bBestCandidateZero = (cStruct.iBestX == 0) && (cStruct.iBestY == 0); |
---|
2177 | |
---|
2178 | // first search around best position up to now. |
---|
2179 | // The following works as a "subsampled/log" window search around the best candidate |
---|
2180 | for ( iDist = 1; iDist <= iSearchRange; iDist*=2 ) |
---|
2181 | { |
---|
2182 | if ( bFirstSearchDiamond == 1 ) |
---|
2183 | { |
---|
2184 | xTZ8PointDiamondSearch ( cStruct, iStartX, iStartY, iDist, bFirstCornersForDiamondDist1 ); |
---|
2185 | } |
---|
2186 | else |
---|
2187 | { |
---|
2188 | xTZ8PointSquareSearch ( cStruct, iStartX, iStartY, iDist ); |
---|
2189 | } |
---|
2190 | |
---|
2191 | if ( bFirstSearchStop && ( cStruct.uiBestRound >= uiFirstSearchRounds ) ) // stop criterion |
---|
2192 | { |
---|
2193 | break; |
---|
2194 | } |
---|
2195 | } |
---|
2196 | |
---|
2197 | if (!bNewZeroNeighbourhoodTest) |
---|
2198 | { |
---|
2199 | // test whether zero Mv is a better start point than Median predictor |
---|
2200 | if ( bTestZeroVectorStart && ((cStruct.iBestX != 0) || (cStruct.iBestY != 0)) ) |
---|
2201 | { |
---|
2202 | xTZSearchHelp( cStruct, 0, 0, 0, 0 ); |
---|
2203 | if ( (cStruct.iBestX == 0) && (cStruct.iBestY == 0) ) |
---|
2204 | { |
---|
2205 | // test its neighborhood |
---|
2206 | for ( iDist = 1; iDist <= iSearchRange; iDist*=2 ) |
---|
2207 | { |
---|
2208 | xTZ8PointDiamondSearch( cStruct, 0, 0, iDist, false ); |
---|
2209 | if ( bTestZeroVectorStop && (cStruct.uiBestRound > 0) ) // stop criterion |
---|
2210 | { |
---|
2211 | break; |
---|
2212 | } |
---|
2213 | } |
---|
2214 | } |
---|
2215 | } |
---|
2216 | } |
---|
2217 | else |
---|
2218 | { |
---|
2219 | // Test also zero neighbourhood but with half the range |
---|
2220 | // It was reported that the original (above) search scheme using bTestZeroVectorStart did not |
---|
2221 | // make sense since one would have already checked the zero candidate earlier |
---|
2222 | // and thus the conditions for that test would have not been satisfied |
---|
2223 | if (bTestZeroVectorStart == true && bBestCandidateZero != true) |
---|
2224 | { |
---|
2225 | for ( iDist = 1; iDist <= (iSearchRange >> 1); iDist*=2 ) |
---|
2226 | { |
---|
2227 | xTZ8PointDiamondSearch( cStruct, 0, 0, iDist, false ); |
---|
2228 | if ( bTestZeroVectorStop && (cStruct.uiBestRound > 2) ) // stop criterion |
---|
2229 | { |
---|
2230 | break; |
---|
2231 | } |
---|
2232 | } |
---|
2233 | } |
---|
2234 | } |
---|
2235 | |
---|
2236 | // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1 |
---|
2237 | if ( cStruct.uiBestDistance == 1 ) |
---|
2238 | { |
---|
2239 | cStruct.uiBestDistance = 0; |
---|
2240 | xTZ2PointSearch( cStruct ); |
---|
2241 | } |
---|
2242 | |
---|
2243 | // raster search if distance is too big |
---|
2244 | if (bUseAdaptiveRaster) |
---|
2245 | { |
---|
2246 | int iWindowSize = iRaster; |
---|
2247 | SearchRange localsr = sr; |
---|
2248 | |
---|
2249 | if (!(bEnableRasterSearch && ( ((int)(cStruct.uiBestDistance) >= iRaster)))) |
---|
2250 | { |
---|
2251 | iWindowSize ++; |
---|
2252 | localsr.left /= 2; |
---|
2253 | localsr.right /= 2; |
---|
2254 | localsr.top /= 2; |
---|
2255 | localsr.bottom /= 2; |
---|
2256 | } |
---|
2257 | cStruct.uiBestDistance = iWindowSize; |
---|
2258 | for ( iStartY = localsr.top; iStartY <= localsr.bottom; iStartY += iWindowSize ) |
---|
2259 | { |
---|
2260 | for ( iStartX = localsr.left; iStartX <= localsr.right; iStartX += iWindowSize ) |
---|
2261 | { |
---|
2262 | xTZSearchHelp( cStruct, iStartX, iStartY, 0, iWindowSize ); |
---|
2263 | } |
---|
2264 | } |
---|
2265 | } |
---|
2266 | else |
---|
2267 | { |
---|
2268 | if ( bEnableRasterSearch && ( ((int)(cStruct.uiBestDistance) >= iRaster) || bAlwaysRasterSearch ) ) |
---|
2269 | { |
---|
2270 | cStruct.uiBestDistance = iRaster; |
---|
2271 | for ( iStartY = sr.top; iStartY <= sr.bottom; iStartY += iRaster ) |
---|
2272 | { |
---|
2273 | for ( iStartX = sr.left; iStartX <= sr.right; iStartX += iRaster ) |
---|
2274 | { |
---|
2275 | xTZSearchHelp( cStruct, iStartX, iStartY, 0, iRaster ); |
---|
2276 | } |
---|
2277 | } |
---|
2278 | } |
---|
2279 | } |
---|
2280 | |
---|
2281 | // raster refinement |
---|
2282 | |
---|
2283 | if ( bRasterRefinementEnable && cStruct.uiBestDistance > 0 ) |
---|
2284 | { |
---|
2285 | while ( cStruct.uiBestDistance > 0 ) |
---|
2286 | { |
---|
2287 | iStartX = cStruct.iBestX; |
---|
2288 | iStartY = cStruct.iBestY; |
---|
2289 | if ( cStruct.uiBestDistance > 1 ) |
---|
2290 | { |
---|
2291 | iDist = cStruct.uiBestDistance >>= 1; |
---|
2292 | if ( bRasterRefinementDiamond == 1 ) |
---|
2293 | { |
---|
2294 | xTZ8PointDiamondSearch ( cStruct, iStartX, iStartY, iDist, bRasterRefinementCornersForDiamondDist1 ); |
---|
2295 | } |
---|
2296 | else |
---|
2297 | { |
---|
2298 | xTZ8PointSquareSearch ( cStruct, iStartX, iStartY, iDist ); |
---|
2299 | } |
---|
2300 | } |
---|
2301 | |
---|
2302 | // calculate only 2 missing points instead 8 points if cStruct.uiBestDistance == 1 |
---|
2303 | if ( cStruct.uiBestDistance == 1 ) |
---|
2304 | { |
---|
2305 | cStruct.uiBestDistance = 0; |
---|
2306 | if ( cStruct.ucPointNr != 0 ) |
---|
2307 | { |
---|
2308 | xTZ2PointSearch( cStruct ); |
---|
2309 | } |
---|
2310 | } |
---|
2311 | } |
---|
2312 | } |
---|
2313 | |
---|
2314 | // star refinement |
---|
2315 | if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 ) |
---|
2316 | { |
---|
2317 | while ( cStruct.uiBestDistance > 0 ) |
---|
2318 | { |
---|
2319 | iStartX = cStruct.iBestX; |
---|
2320 | iStartY = cStruct.iBestY; |
---|
2321 | cStruct.uiBestDistance = 0; |
---|
2322 | cStruct.ucPointNr = 0; |
---|
2323 | for ( iDist = 1; iDist < iSearchRange + 1; iDist*=2 ) |
---|
2324 | { |
---|
2325 | if ( bStarRefinementDiamond == 1 ) |
---|
2326 | { |
---|
2327 | xTZ8PointDiamondSearch ( cStruct, iStartX, iStartY, iDist, bStarRefinementCornersForDiamondDist1 ); |
---|
2328 | } |
---|
2329 | else |
---|
2330 | { |
---|
2331 | xTZ8PointSquareSearch ( cStruct, iStartX, iStartY, iDist ); |
---|
2332 | } |
---|
2333 | if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion |
---|
2334 | { |
---|
2335 | break; |
---|
2336 | } |
---|
2337 | } |
---|
2338 | |
---|
2339 | // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1 |
---|
2340 | if ( cStruct.uiBestDistance == 1 ) |
---|
2341 | { |
---|
2342 | cStruct.uiBestDistance = 0; |
---|
2343 | if ( cStruct.ucPointNr != 0 ) |
---|
2344 | { |
---|
2345 | xTZ2PointSearch( cStruct ); |
---|
2346 | } |
---|
2347 | } |
---|
2348 | } |
---|
2349 | } |
---|
2350 | |
---|
2351 | // write out best match |
---|
2352 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
2353 | CHECK( rcMv.highPrec, "Unexpected high precision MV." ); |
---|
2354 | #endif |
---|
2355 | rcMv.set( cStruct.iBestX, cStruct.iBestY ); |
---|
2356 | #if JVET_K0357_AMVR |
---|
2357 | ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY, cStruct.imvShift ); |
---|
2358 | #else |
---|
2359 | ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY ); |
---|
2360 | #endif |
---|
2361 | } |
---|
2362 | |
---|
2363 | |
---|
2364 | void InterSearch::xTZSearchSelective( const PredictionUnit& pu, |
---|
2365 | IntTZSearchStruct& cStruct, |
---|
2366 | Mv &rcMv, |
---|
2367 | Distortion &ruiSAD, |
---|
2368 | const Mv* const pIntegerMv2Nx2NPred ) |
---|
2369 | { |
---|
2370 | const bool bTestZeroVector = true; |
---|
2371 | const bool bEnableRasterSearch = true; |
---|
2372 | const bool bAlwaysRasterSearch = false; // 1: BETTER but factor 15x slower |
---|
2373 | const bool bStarRefinementEnable = true; // enable either star refinement or raster refinement |
---|
2374 | const bool bStarRefinementDiamond = true; // 1 = xTZ8PointDiamondSearch 0 = xTZ8PointSquareSearch |
---|
2375 | const bool bStarRefinementStop = false; |
---|
2376 | const uint32_t uiStarRefinementRounds = 2; // star refinement stop X rounds after best match (must be >=1) |
---|
2377 | const int iSearchRange = m_iSearchRange; |
---|
2378 | const int iSearchRangeInitial = m_iSearchRange >> 2; |
---|
2379 | const int uiSearchStep = 4; |
---|
2380 | const int iMVDistThresh = 8; |
---|
2381 | |
---|
2382 | int iStartX = 0; |
---|
2383 | int iStartY = 0; |
---|
2384 | int iDist = 0; |
---|
2385 | |
---|
2386 | clipMv( rcMv, pu.cu->lumaPos(), *pu.cs->sps ); |
---|
2387 | |
---|
2388 | rcMv.divideByPowerOf2(2); |
---|
2389 | |
---|
2390 | // init TZSearchStruct |
---|
2391 | #if DISTORTION_TYPE_BUGFIX |
---|
2392 | cStruct.uiBestSad = std::numeric_limits<Distortion>::max(); |
---|
2393 | #else |
---|
2394 | cStruct.uiBestSad = MAX_UINT; |
---|
2395 | #endif |
---|
2396 | cStruct.iBestX = 0; |
---|
2397 | cStruct.iBestY = 0; |
---|
2398 | |
---|
2399 | m_cDistParam.maximumDistortionForEarlyExit = cStruct.uiBestSad; |
---|
2400 | m_pcRdCost->setDistParam( m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, cStruct.subShiftMode ); |
---|
2401 | |
---|
2402 | |
---|
2403 | // set rcMv (Median predictor) as start point and as best point |
---|
2404 | xTZSearchHelp( cStruct, rcMv.getHor(), rcMv.getVer(), 0, 0 ); |
---|
2405 | |
---|
2406 | // test whether zero Mv is better start point than Median predictor |
---|
2407 | if ( bTestZeroVector ) |
---|
2408 | { |
---|
2409 | xTZSearchHelp( cStruct, 0, 0, 0, 0 ); |
---|
2410 | } |
---|
2411 | |
---|
2412 | SearchRange& sr = cStruct.searchRange; |
---|
2413 | |
---|
2414 | if ( pIntegerMv2Nx2NPred != 0 ) |
---|
2415 | { |
---|
2416 | Mv integerMv2Nx2NPred = *pIntegerMv2Nx2NPred; |
---|
2417 | integerMv2Nx2NPred <<= 2; |
---|
2418 | clipMv( integerMv2Nx2NPred, pu.cu->lumaPos(), *pu.cs->sps ); |
---|
2419 | integerMv2Nx2NPred.divideByPowerOf2(2); |
---|
2420 | |
---|
2421 | xTZSearchHelp( cStruct, integerMv2Nx2NPred.getHor(), integerMv2Nx2NPred.getVer(), 0, 0); |
---|
2422 | |
---|
2423 | } |
---|
2424 | { |
---|
2425 | // set search range |
---|
2426 | Mv currBestMv(cStruct.iBestX, cStruct.iBestY ); |
---|
2427 | currBestMv <<= 2; |
---|
2428 | xSetSearchRange( pu, currBestMv, m_iSearchRange, sr ); |
---|
2429 | } |
---|
2430 | |
---|
2431 | // Initial search |
---|
2432 | int iBestX = cStruct.iBestX; |
---|
2433 | int iBestY = cStruct.iBestY; |
---|
2434 | int iFirstSrchRngHorLeft = ((iBestX - iSearchRangeInitial) > sr.left) ? (iBestX - iSearchRangeInitial) : sr.left; |
---|
2435 | int iFirstSrchRngVerTop = ((iBestY - iSearchRangeInitial) > sr.top) ? (iBestY - iSearchRangeInitial) : sr.top; |
---|
2436 | int iFirstSrchRngHorRight = ((iBestX + iSearchRangeInitial) < sr.right) ? (iBestX + iSearchRangeInitial) : sr.right; |
---|
2437 | int iFirstSrchRngVerBottom = ((iBestY + iSearchRangeInitial) < sr.bottom) ? (iBestY + iSearchRangeInitial) : sr.bottom; |
---|
2438 | |
---|
2439 | for ( iStartY = iFirstSrchRngVerTop; iStartY <= iFirstSrchRngVerBottom; iStartY += uiSearchStep ) |
---|
2440 | { |
---|
2441 | for ( iStartX = iFirstSrchRngHorLeft; iStartX <= iFirstSrchRngHorRight; iStartX += uiSearchStep ) |
---|
2442 | { |
---|
2443 | xTZSearchHelp( cStruct, iStartX, iStartY, 0, 0 ); |
---|
2444 | xTZ8PointDiamondSearch ( cStruct, iStartX, iStartY, 1, false ); |
---|
2445 | xTZ8PointDiamondSearch ( cStruct, iStartX, iStartY, 2, false ); |
---|
2446 | } |
---|
2447 | } |
---|
2448 | |
---|
2449 | int iMaxMVDistToPred = (abs(cStruct.iBestX - iBestX) > iMVDistThresh || abs(cStruct.iBestY - iBestY) > iMVDistThresh); |
---|
2450 | |
---|
2451 | //full search with early exit if MV is distant from predictors |
---|
2452 | if ( bEnableRasterSearch && (iMaxMVDistToPred || bAlwaysRasterSearch) ) |
---|
2453 | { |
---|
2454 | for ( iStartY = sr.top; iStartY <= sr.bottom; iStartY += 1 ) |
---|
2455 | { |
---|
2456 | for ( iStartX = sr.left; iStartX <= sr.right; iStartX += 1 ) |
---|
2457 | { |
---|
2458 | xTZSearchHelp( cStruct, iStartX, iStartY, 0, 1 ); |
---|
2459 | } |
---|
2460 | } |
---|
2461 | } |
---|
2462 | //Smaller MV, refine around predictor |
---|
2463 | else if ( bStarRefinementEnable && cStruct.uiBestDistance > 0 ) |
---|
2464 | { |
---|
2465 | // start refinement |
---|
2466 | while ( cStruct.uiBestDistance > 0 ) |
---|
2467 | { |
---|
2468 | iStartX = cStruct.iBestX; |
---|
2469 | iStartY = cStruct.iBestY; |
---|
2470 | cStruct.uiBestDistance = 0; |
---|
2471 | cStruct.ucPointNr = 0; |
---|
2472 | for ( iDist = 1; iDist < iSearchRange + 1; iDist*=2 ) |
---|
2473 | { |
---|
2474 | if ( bStarRefinementDiamond == 1 ) |
---|
2475 | { |
---|
2476 | xTZ8PointDiamondSearch ( cStruct, iStartX, iStartY, iDist, false ); |
---|
2477 | } |
---|
2478 | else |
---|
2479 | { |
---|
2480 | xTZ8PointSquareSearch ( cStruct, iStartX, iStartY, iDist ); |
---|
2481 | } |
---|
2482 | if ( bStarRefinementStop && (cStruct.uiBestRound >= uiStarRefinementRounds) ) // stop criterion |
---|
2483 | { |
---|
2484 | break; |
---|
2485 | } |
---|
2486 | } |
---|
2487 | |
---|
2488 | // calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1 |
---|
2489 | if ( cStruct.uiBestDistance == 1 ) |
---|
2490 | { |
---|
2491 | cStruct.uiBestDistance = 0; |
---|
2492 | if ( cStruct.ucPointNr != 0 ) |
---|
2493 | { |
---|
2494 | xTZ2PointSearch( cStruct ); |
---|
2495 | } |
---|
2496 | } |
---|
2497 | } |
---|
2498 | } |
---|
2499 | |
---|
2500 | // write out best match |
---|
2501 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
2502 | CHECK( rcMv.highPrec, "Unexpected high precision MV." ); |
---|
2503 | #endif |
---|
2504 | rcMv.set( cStruct.iBestX, cStruct.iBestY ); |
---|
2505 | #if JVET_K0357_AMVR |
---|
2506 | ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY, cStruct.imvShift ); |
---|
2507 | #else |
---|
2508 | ruiSAD = cStruct.uiBestSad - m_pcRdCost->getCostOfVectorWithPredictor( cStruct.iBestX, cStruct.iBestY ); |
---|
2509 | #endif |
---|
2510 | } |
---|
2511 | |
---|
2512 | #if JVET_K0357_AMVR |
---|
2513 | void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct& cStruct, Mv& rcMv, Mv& rcMvPred, int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost, const AMVPInfo& amvpInfo, double fWeight) |
---|
2514 | { |
---|
2515 | |
---|
2516 | CHECK( pu.cu->imv == 0, "xPatternSearchIntRefine(): IMV not used."); |
---|
2517 | CHECK( amvpInfo.mvCand[riMVPIdx] != rcMvPred, "xPatternSearchIntRefine(): MvPred issue."); |
---|
2518 | |
---|
2519 | const SPS &sps = *pu.cs->sps; |
---|
2520 | m_pcRdCost->setDistParam( m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, 0, 1, m_pcEncCfg->getUseHADME() && !pu.cu->transQuantBypass ); |
---|
2521 | |
---|
2522 | // input MV rcMV has integer resolution |
---|
2523 | // -> shift it to QPEL |
---|
2524 | rcMv <<= 2; |
---|
2525 | // -> set MV scale for cost calculation to QPEL (0) |
---|
2526 | m_pcRdCost->setCostScale ( 0 ); |
---|
2527 | |
---|
2528 | Distortion uiDist, uiSATD = 0; |
---|
2529 | Distortion uiBestDist = std::numeric_limits<Distortion>::max(); |
---|
2530 | // subtract old MVP costs because costs for all newly tested MVPs are added in here |
---|
2531 | ruiBits -= m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS]; |
---|
2532 | |
---|
2533 | Mv cBestMv = rcMv; |
---|
2534 | Mv cBaseMvd[2]; |
---|
2535 | int iBestBits = 0; |
---|
2536 | int iBestMVPIdx = riMVPIdx; |
---|
2537 | int testPos[9][2] = { { 0, 0}, { -1, -1},{ -1, 0},{ -1, 1},{ 0, -1},{ 0, 1},{ 1, -1},{ 1, 0},{ 1, 1} }; |
---|
2538 | |
---|
2539 | |
---|
2540 | cBaseMvd[0] = (rcMv - amvpInfo.mvCand[0]); |
---|
2541 | cBaseMvd[1] = (rcMv - amvpInfo.mvCand[1]); |
---|
2542 | CHECK( (cBaseMvd[0].getHor() & 0x03) != 0 || (cBaseMvd[0].getVer() & 0x03) != 0 , "xPatternSearchIntRefine(): AMVP cand 0 Mvd issue."); |
---|
2543 | CHECK( (cBaseMvd[1].getHor() & 0x03) != 0 || (cBaseMvd[1].getVer() & 0x03) != 0 , "xPatternSearchIntRefine(): AMVP cand 1 Mvd issue."); |
---|
2544 | |
---|
2545 | roundMV(cBaseMvd[0], cStruct.imvShift); |
---|
2546 | roundMV(cBaseMvd[1], cStruct.imvShift); |
---|
2547 | |
---|
2548 | int mvOffset = 1 << cStruct.imvShift; |
---|
2549 | |
---|
2550 | // test best integer position and all 8 neighboring positions |
---|
2551 | for (int pos = 0; pos < 9; pos ++) |
---|
2552 | { |
---|
2553 | Mv cTestMv[2]; |
---|
2554 | // test both AMVP candidates for each position |
---|
2555 | for (int iMVPIdx = 0; iMVPIdx < amvpInfo.numCand; iMVPIdx++) |
---|
2556 | { |
---|
2557 | cTestMv[iMVPIdx].set(testPos[pos][0]*mvOffset, testPos[pos][1]*mvOffset); |
---|
2558 | cTestMv[iMVPIdx] += cBaseMvd[iMVPIdx]; |
---|
2559 | cTestMv[iMVPIdx] += amvpInfo.mvCand[iMVPIdx]; |
---|
2560 | |
---|
2561 | if ( iMVPIdx == 0 || cTestMv[0] != cTestMv[1]) |
---|
2562 | { |
---|
2563 | Mv cTempMV = cTestMv[iMVPIdx]; |
---|
2564 | clipMv(cTempMV, pu.cu->lumaPos(), sps); |
---|
2565 | |
---|
2566 | m_cDistParam.cur.buf = cStruct.piRefY + cStruct.iRefStride * (cTempMV.getVer() >> 2) + (cTempMV.getHor() >> 2); |
---|
2567 | uiDist = uiSATD = (Distortion) (m_cDistParam.distFunc( m_cDistParam ) * fWeight); |
---|
2568 | } |
---|
2569 | else |
---|
2570 | { |
---|
2571 | uiDist = uiSATD; |
---|
2572 | } |
---|
2573 | |
---|
2574 | int iMvBits = m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS]; |
---|
2575 | m_pcRdCost->setPredictor( amvpInfo.mvCand[iMVPIdx] ); |
---|
2576 | iMvBits += m_pcRdCost->getBitsOfVectorWithPredictor( cTestMv[iMVPIdx].getHor(), cTestMv[iMVPIdx].getVer(), cStruct.imvShift ); |
---|
2577 | uiDist += m_pcRdCost->getCostOfVectorWithPredictor( cTestMv[iMVPIdx].getHor(), cTestMv[iMVPIdx].getVer(), cStruct.imvShift ); |
---|
2578 | |
---|
2579 | if (uiDist < uiBestDist) |
---|
2580 | { |
---|
2581 | uiBestDist = uiDist; |
---|
2582 | cBestMv = cTestMv[iMVPIdx]; |
---|
2583 | iBestMVPIdx = iMVPIdx; |
---|
2584 | iBestBits = iMvBits; |
---|
2585 | } |
---|
2586 | } |
---|
2587 | } |
---|
2588 | |
---|
2589 | rcMv = cBestMv; |
---|
2590 | rcMvPred = amvpInfo.mvCand[iBestMVPIdx]; |
---|
2591 | riMVPIdx = iBestMVPIdx; |
---|
2592 | m_pcRdCost->setPredictor( rcMvPred ); |
---|
2593 | |
---|
2594 | ruiBits += iBestBits; |
---|
2595 | // taken from JEM 5.0 |
---|
2596 | // verify since it makes no sence to subtract Lamda*(Rmvd+Rmvpidx) from D+Lamda(Rmvd) |
---|
2597 | // this would take the rate for the MVP idx out of the cost calculation |
---|
2598 | // however this rate is always 1 so impact is small |
---|
2599 | ruiCost = uiBestDist - m_pcRdCost->getCost(iBestBits) + m_pcRdCost->getCost(ruiBits); |
---|
2600 | // taken from JEM 5.0 |
---|
2601 | // verify since it makes no sense to add rate for MVDs twicce |
---|
2602 | ruiBits += m_pcRdCost->getBitsOfVectorWithPredictor(rcMv.getHor(), rcMv.getVer(), cStruct.imvShift); |
---|
2603 | |
---|
2604 | return; |
---|
2605 | } |
---|
2606 | #endif |
---|
2607 | |
---|
2608 | void InterSearch::xPatternSearchFracDIF( |
---|
2609 | const PredictionUnit& pu, |
---|
2610 | RefPicList eRefPicList, |
---|
2611 | int iRefIdx, |
---|
2612 | IntTZSearchStruct& cStruct, |
---|
2613 | const Mv& rcMvInt, |
---|
2614 | Mv& rcMvHalf, |
---|
2615 | Mv& rcMvQter, |
---|
2616 | Distortion& ruiCost |
---|
2617 | ) |
---|
2618 | { |
---|
2619 | const bool bIsLosslessCoded = pu.cu->transQuantBypass; |
---|
2620 | |
---|
2621 | // Reference pattern initialization (integer scale) |
---|
2622 | int iOffset = rcMvInt.getHor() + rcMvInt.getVer() * cStruct.iRefStride; |
---|
2623 | CPelBuf cPatternRoi(cStruct.piRefY + iOffset, cStruct.iRefStride, *cStruct.pcPatternKey); |
---|
2624 | |
---|
2625 | |
---|
2626 | #if JVET_K0357_AMVR |
---|
2627 | if( cStruct.imvShift ) |
---|
2628 | { |
---|
2629 | m_pcRdCost->setDistParam( m_cDistParam, *cStruct.pcPatternKey, cStruct.piRefY + iOffset, cStruct.iRefStride, m_lumaClpRng.bd, COMPONENT_Y, 0, 1, m_pcEncCfg->getUseHADME() && !bIsLosslessCoded ); |
---|
2630 | ruiCost = m_cDistParam.distFunc( m_cDistParam ); |
---|
2631 | ruiCost += m_pcRdCost->getCostOfVectorWithPredictor( rcMvInt.getHor(), rcMvInt.getVer(), cStruct.imvShift ); |
---|
2632 | return; |
---|
2633 | } |
---|
2634 | #endif |
---|
2635 | |
---|
2636 | // Half-pel refinement |
---|
2637 | m_pcRdCost->setCostScale(1); |
---|
2638 | xExtDIFUpSamplingH ( &cPatternRoi ); |
---|
2639 | |
---|
2640 | rcMvHalf = rcMvInt; rcMvHalf <<= 1; // for mv-cost |
---|
2641 | Mv baseRefMv(0, 0); |
---|
2642 | ruiCost = xPatternRefinement(cStruct.pcPatternKey, baseRefMv, 2, rcMvHalf, !bIsLosslessCoded); |
---|
2643 | |
---|
2644 | // quarter-pel refinement |
---|
2645 | m_pcRdCost->setCostScale( 0 ); |
---|
2646 | xExtDIFUpSamplingQ ( &cPatternRoi, rcMvHalf ); |
---|
2647 | baseRefMv = rcMvHalf; |
---|
2648 | baseRefMv <<= 1; |
---|
2649 | |
---|
2650 | rcMvQter = rcMvInt; rcMvQter <<= 1; // for mv-cost |
---|
2651 | rcMvQter += rcMvHalf; rcMvQter <<= 1; |
---|
2652 | ruiCost = xPatternRefinement( cStruct.pcPatternKey, baseRefMv, 1, rcMvQter, !bIsLosslessCoded ); |
---|
2653 | } |
---|
2654 | |
---|
2655 | #if JEM_TOOLS || JVET_K_AFFINE |
---|
2656 | |
---|
2657 | void InterSearch::xPredAffineInterSearch( PredictionUnit& pu, |
---|
2658 | PelUnitBuf& origBuf, |
---|
2659 | int puIdx, |
---|
2660 | uint32_t& lastMode, |
---|
2661 | Distortion& affineCost, |
---|
2662 | #if JVET_K0220_ENC_CTRL |
---|
2663 | Mv hevcMv[2][33] |
---|
2664 | #else |
---|
2665 | Mv hevcMv[2][33], |
---|
2666 | bool bFastSkipBi |
---|
2667 | #endif |
---|
2668 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
2669 | , Mv mvAffine4Para[2][33][3] |
---|
2670 | , int refIdx4Para[2] |
---|
2671 | #endif |
---|
2672 | ) |
---|
2673 | { |
---|
2674 | const Slice &slice = *pu.cu->slice; |
---|
2675 | |
---|
2676 | affineCost = std::numeric_limits<Distortion>::max(); |
---|
2677 | |
---|
2678 | Mv cMvZero; |
---|
2679 | Mv aacMv[2][3]; |
---|
2680 | Mv cMvBi[2][3]; |
---|
2681 | Mv cMvTemp[2][33][3]; |
---|
2682 | |
---|
2683 | int iNumPredDir = slice.isInterP() ? 1 : 2; |
---|
2684 | |
---|
2685 | int mvNum = 2; |
---|
2686 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
2687 | mvNum = pu.cu->affineType ? 3 : 2; |
---|
2688 | #endif |
---|
2689 | |
---|
2690 | // Mvp |
---|
2691 | Mv cMvPred[2][33][3]; |
---|
2692 | Mv cMvPredBi[2][33][3]; |
---|
2693 | int aaiMvpIdxBi[2][33]; |
---|
2694 | int aaiMvpIdx[2][33]; |
---|
2695 | int aaiMvpNum[2][33]; |
---|
2696 | |
---|
2697 | AffineAMVPInfo aacAffineAMVPInfo[2][33]; |
---|
2698 | AffineAMVPInfo affiAMVPInfoTemp[2]; |
---|
2699 | |
---|
2700 | int iRefIdx[2]={0,0}; // If un-initialized, may cause SEGV in bi-directional prediction iterative stage. |
---|
2701 | int iRefIdxBi[2]; |
---|
2702 | |
---|
2703 | uint32_t uiMbBits[3] = {1, 1, 0}; |
---|
2704 | |
---|
2705 | int iRefStart, iRefEnd; |
---|
2706 | |
---|
2707 | PartSize ePartSize = pu.cu->partSize; |
---|
2708 | |
---|
2709 | int bestBiPRefIdxL1 = 0; |
---|
2710 | int bestBiPMvpL1 = 0; |
---|
2711 | #if DISTORTION_TYPE_BUGFIX |
---|
2712 | Distortion biPDistTemp = std::numeric_limits<Distortion>::max(); |
---|
2713 | #else |
---|
2714 | uint32_t biPDistTemp = MAX_INT; |
---|
2715 | #endif |
---|
2716 | |
---|
2717 | Distortion uiCost[2] = { std::numeric_limits<Distortion>::max(), std::numeric_limits<Distortion>::max() }; |
---|
2718 | Distortion uiCostBi = std::numeric_limits<Distortion>::max(); |
---|
2719 | Distortion uiCostTemp; |
---|
2720 | |
---|
2721 | uint32_t uiBits[3]; |
---|
2722 | uint32_t uiBitsTemp; |
---|
2723 | Distortion bestBiPDist = std::numeric_limits<Distortion>::max(); |
---|
2724 | |
---|
2725 | Distortion uiCostTempL0[MAX_NUM_REF]; |
---|
2726 | for (int iNumRef=0; iNumRef < MAX_NUM_REF; iNumRef++) |
---|
2727 | { |
---|
2728 | uiCostTempL0[iNumRef] = std::numeric_limits<Distortion>::max(); |
---|
2729 | } |
---|
2730 | #if DISTORTION_TYPE_BUGFIX |
---|
2731 | uint32_t uiBitsTempL0[MAX_NUM_REF]; |
---|
2732 | #else |
---|
2733 | Distortion uiBitsTempL0[MAX_NUM_REF]; |
---|
2734 | #endif |
---|
2735 | |
---|
2736 | Mv mvValidList1[4]; |
---|
2737 | int refIdxValidList1 = 0; |
---|
2738 | uint32_t bitsValidList1 = MAX_UINT; |
---|
2739 | #if DISTORTION_TYPE_BUGFIX |
---|
2740 | Distortion costValidList1 = std::numeric_limits<Distortion>::max(); |
---|
2741 | #else |
---|
2742 | uint32_t costValidList1 = MAX_UINT; |
---|
2743 | #endif |
---|
2744 | Mv mvHevc[3]; |
---|
2745 | |
---|
2746 | xGetBlkBits( ePartSize, slice.isInterP(), puIdx, lastMode, uiMbBits); |
---|
2747 | |
---|
2748 | pu.cu->affine = true; |
---|
2749 | pu.mergeFlag = false; |
---|
2750 | |
---|
2751 | // Uni-directional prediction |
---|
2752 | for ( int iRefList = 0; iRefList < iNumPredDir; iRefList++ ) |
---|
2753 | { |
---|
2754 | RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); |
---|
2755 | |
---|
2756 | for ( int iRefIdxTemp = 0; iRefIdxTemp < slice.getNumRefIdx(eRefPicList); iRefIdxTemp++ ) |
---|
2757 | { |
---|
2758 | // Get RefIdx bits |
---|
2759 | uiBitsTemp = uiMbBits[iRefList]; |
---|
2760 | if ( slice.getNumRefIdx(eRefPicList) > 1 ) |
---|
2761 | { |
---|
2762 | uiBitsTemp += iRefIdxTemp+1; |
---|
2763 | if ( iRefIdxTemp == slice.getNumRefIdx(eRefPicList)-1 ) |
---|
2764 | { |
---|
2765 | uiBitsTemp--; |
---|
2766 | } |
---|
2767 | } |
---|
2768 | |
---|
2769 | // Do Affine AMVP |
---|
2770 | xEstimateAffineAMVP( pu, affiAMVPInfoTemp[eRefPicList], origBuf, eRefPicList, iRefIdxTemp, cMvPred[iRefList][iRefIdxTemp], &biPDistTemp ); |
---|
2771 | aaiMvpIdx[iRefList][iRefIdxTemp] = pu.mvpIdx[eRefPicList]; |
---|
2772 | aaiMvpNum[iRefList][iRefIdxTemp] = pu.mvpNum[eRefPicList];; |
---|
2773 | #if JVET_K0185_AFFINE_6PARA_ENC // reuse refidx of 4-para |
---|
2774 | if ( pu.cu->affineType == AFFINEMODEL_6PARAM && refIdx4Para[iRefList] != iRefIdxTemp ) |
---|
2775 | { |
---|
2776 | xCopyAffineAMVPInfo( affiAMVPInfoTemp[eRefPicList], aacAffineAMVPInfo[iRefList][iRefIdxTemp] ); |
---|
2777 | continue; |
---|
2778 | } |
---|
2779 | #endif |
---|
2780 | |
---|
2781 | // set hevc ME result as start search position when it is best than mvp |
---|
2782 | for ( int i=0; i<3; i++ ) |
---|
2783 | { |
---|
2784 | mvHevc[i] = hevcMv[iRefList][iRefIdxTemp]; |
---|
2785 | } |
---|
2786 | PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
2787 | |
---|
2788 | #if DISTORTION_TYPE_BUGFIX |
---|
2789 | Distortion uiCandCost = xGetAffineTemplateCost(pu, origBuf, predBuf, mvHevc, aaiMvpIdx[iRefList][iRefIdxTemp], |
---|
2790 | AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp); |
---|
2791 | #else |
---|
2792 | uint32_t uiCandCost = xGetAffineTemplateCost( pu, origBuf, predBuf, mvHevc, aaiMvpIdx[iRefList][iRefIdxTemp], AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp ); |
---|
2793 | #endif |
---|
2794 | #if JVET_K0185_AFFINE_6PARA_ENC // use 4-parameter results as start point |
---|
2795 | if ( pu.cu->affineType == AFFINEMODEL_6PARAM ) |
---|
2796 | { |
---|
2797 | Mv mvFour[3]; |
---|
2798 | mvFour[0] = mvAffine4Para[iRefList][iRefIdxTemp][0]; |
---|
2799 | mvFour[1] = mvAffine4Para[iRefList][iRefIdxTemp][1]; |
---|
2800 | |
---|
2801 | int shift = MAX_CU_DEPTH; |
---|
2802 | int vx2 = (mvFour[0].getHor() << shift) - ((mvFour[1].getVer() - mvFour[0].getVer()) << (shift + g_aucLog2[pu.lheight()] - g_aucLog2[pu.lwidth()])); |
---|
2803 | int vy2 = (mvFour[0].getVer() << shift) + ((mvFour[1].getHor() - mvFour[0].getHor()) << (shift + g_aucLog2[pu.lheight()] - g_aucLog2[pu.lwidth()])); |
---|
2804 | vx2 >>= shift; |
---|
2805 | vy2 >>= shift; |
---|
2806 | mvFour[2] = Mv( vx2, vy2, true ); |
---|
2807 | mvFour[2].roundMV2SignalPrecision(); |
---|
2808 | |
---|
2809 | Distortion uiCandCostInherit = xGetAffineTemplateCost( pu, origBuf, predBuf, mvFour, aaiMvpIdx[iRefList][iRefIdxTemp], AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdxTemp ); |
---|
2810 | if ( uiCandCostInherit < uiCandCost ) |
---|
2811 | { |
---|
2812 | uiCandCost = uiCandCostInherit; |
---|
2813 | for ( int i = 0; i < 3; i++ ) |
---|
2814 | { |
---|
2815 | mvHevc[i] = mvFour[i]; |
---|
2816 | } |
---|
2817 | } |
---|
2818 | } |
---|
2819 | #endif |
---|
2820 | |
---|
2821 | if ( uiCandCost < biPDistTemp ) |
---|
2822 | { |
---|
2823 | ::memcpy( cMvTemp[iRefList][iRefIdxTemp], mvHevc, sizeof(Mv)*3 ); |
---|
2824 | } |
---|
2825 | else |
---|
2826 | { |
---|
2827 | ::memcpy( cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], sizeof(Mv)*3 ); |
---|
2828 | } |
---|
2829 | |
---|
2830 | // GPB list 1, save the best MvpIdx, RefIdx and Cost |
---|
2831 | if ( slice.getMvdL1ZeroFlag() && iRefList==1 && biPDistTemp < bestBiPDist ) |
---|
2832 | { |
---|
2833 | bestBiPDist = biPDistTemp; |
---|
2834 | bestBiPMvpL1 = aaiMvpIdx[iRefList][iRefIdxTemp]; |
---|
2835 | bestBiPRefIdxL1 = iRefIdxTemp; |
---|
2836 | } |
---|
2837 | |
---|
2838 | // Update bits |
---|
2839 | uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdx[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS]; |
---|
2840 | |
---|
2841 | if ( m_pcEncCfg->getFastMEForGenBLowDelayEnabled() && iRefList == 1 ) // list 1 |
---|
2842 | { |
---|
2843 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
2844 | if ( slice.getList1IdxToList0Idx( iRefIdxTemp ) >= 0 && (pu.cu->affineType != AFFINEMODEL_6PARAM || slice.getList1IdxToList0Idx( iRefIdxTemp ) == refIdx4Para[0]) ) |
---|
2845 | #else |
---|
2846 | if ( slice.getList1IdxToList0Idx( iRefIdxTemp ) >= 0 ) |
---|
2847 | #endif |
---|
2848 | { |
---|
2849 | int iList1ToList0Idx = slice.getList1IdxToList0Idx( iRefIdxTemp ); |
---|
2850 | ::memcpy( cMvTemp[1][iRefIdxTemp], cMvTemp[0][iList1ToList0Idx], sizeof(Mv)*3 ); |
---|
2851 | uiCostTemp = uiCostTempL0[iList1ToList0Idx]; |
---|
2852 | |
---|
2853 | uiCostTemp -= m_pcRdCost->getCost( uiBitsTempL0[iList1ToList0Idx] ); |
---|
2854 | for (int iVerIdx = 0; iVerIdx < mvNum; iVerIdx++) |
---|
2855 | { |
---|
2856 | m_pcRdCost->setPredictor( cMvPred[iRefList][iRefIdxTemp][iVerIdx] ); |
---|
2857 | const int shift = cMvTemp[1][iRefIdxTemp][iVerIdx].highPrec ? VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : 0; |
---|
2858 | #if JVET_K0337_AFFINE_MVD_PREDICTION |
---|
2859 | Mv secondPred; |
---|
2860 | if ( iVerIdx != 0 ) |
---|
2861 | { |
---|
2862 | secondPred = cMvPred[iRefList][iRefIdxTemp][iVerIdx] + (cMvTemp[1][iRefIdxTemp][0] - cMvPred[1][iRefIdxTemp][0]); |
---|
2863 | m_pcRdCost->setPredictor( secondPred ); |
---|
2864 | } |
---|
2865 | #endif |
---|
2866 | #if JVET_K0357_AMVR |
---|
2867 | uiBitsTemp += m_pcRdCost->getBitsOfVectorWithPredictor( cMvTemp[1][iRefIdxTemp][iVerIdx].getHor()>>shift, cMvTemp[1][iRefIdxTemp][iVerIdx].getVer()>>shift, 0 ); |
---|
2868 | #else |
---|
2869 | uiBitsTemp += m_pcRdCost->getBitsOfVectorWithPredictor( cMvTemp[1][iRefIdxTemp][iVerIdx].getHor() >> shift, cMvTemp[1][iRefIdxTemp][iVerIdx].getVer() >> shift ); |
---|
2870 | #endif |
---|
2871 | } |
---|
2872 | /*calculate the correct cost*/ |
---|
2873 | uiCostTemp += m_pcRdCost->getCost( uiBitsTemp ); |
---|
2874 | DTRACE( g_trace_ctx, D_COMMON, " (%d) uiCostTemp=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiCostTemp ); |
---|
2875 | } |
---|
2876 | else |
---|
2877 | { |
---|
2878 | xAffineMotionEstimation( pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp ); |
---|
2879 | } |
---|
2880 | } |
---|
2881 | else |
---|
2882 | { |
---|
2883 | xAffineMotionEstimation( pu, origBuf, eRefPicList, cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp ); |
---|
2884 | } |
---|
2885 | |
---|
2886 | // Set best AMVP Index |
---|
2887 | xCopyAffineAMVPInfo( affiAMVPInfoTemp[eRefPicList], aacAffineAMVPInfo[iRefList][iRefIdxTemp] ); |
---|
2888 | xCheckBestAffineMVP( pu, affiAMVPInfoTemp[eRefPicList], eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPred[iRefList][iRefIdxTemp], aaiMvpIdx[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp ); |
---|
2889 | |
---|
2890 | if ( iRefList == 0 ) |
---|
2891 | { |
---|
2892 | uiCostTempL0[iRefIdxTemp] = uiCostTemp; |
---|
2893 | uiBitsTempL0[iRefIdxTemp] = uiBitsTemp; |
---|
2894 | } |
---|
2895 | DTRACE( g_trace_ctx, D_COMMON, " (%d) uiCostTemp=%d, uiCost[iRefList]=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiCostTemp, uiCost[iRefList] ); |
---|
2896 | if ( uiCostTemp < uiCost[iRefList] ) |
---|
2897 | { |
---|
2898 | uiCost[iRefList] = uiCostTemp; |
---|
2899 | uiBits[iRefList] = uiBitsTemp; // storing for bi-prediction |
---|
2900 | |
---|
2901 | // set best motion |
---|
2902 | ::memcpy( aacMv[iRefList], cMvTemp[iRefList][iRefIdxTemp], sizeof(Mv) * 3 ); |
---|
2903 | iRefIdx[iRefList] = iRefIdxTemp; |
---|
2904 | } |
---|
2905 | |
---|
2906 | if ( iRefList == 1 && uiCostTemp < costValidList1 && slice.getList1IdxToList0Idx( iRefIdxTemp ) < 0 ) |
---|
2907 | { |
---|
2908 | costValidList1 = uiCostTemp; |
---|
2909 | bitsValidList1 = uiBitsTemp; |
---|
2910 | |
---|
2911 | // set motion |
---|
2912 | memcpy( mvValidList1, cMvTemp[iRefList][iRefIdxTemp], sizeof(Mv)*3 ); |
---|
2913 | refIdxValidList1 = iRefIdxTemp; |
---|
2914 | } |
---|
2915 | } // End refIdx loop |
---|
2916 | } // end Uni-prediction |
---|
2917 | |
---|
2918 | #if JVET_K0185_AFFINE_6PARA_ENC // save 4-parameter UNI-ME results |
---|
2919 | if ( pu.cu->affineType == AFFINEMODEL_4PARAM ) |
---|
2920 | { |
---|
2921 | ::memcpy( mvAffine4Para, cMvTemp, sizeof( cMvTemp ) ); |
---|
2922 | } |
---|
2923 | #endif |
---|
2924 | |
---|
2925 | // Bi-directional prediction |
---|
2926 | #if JVET_K0220_ENC_CTRL |
---|
2927 | if ( slice.isInterB() && !PU::isBipredRestriction(pu) ) |
---|
2928 | #else |
---|
2929 | if ( slice.isInterB() && !PU::isBipredRestriction(pu) && !bFastSkipBi ) |
---|
2930 | #endif |
---|
2931 | { |
---|
2932 | // Set as best list0 and list1 |
---|
2933 | iRefIdxBi[0] = iRefIdx[0]; |
---|
2934 | iRefIdxBi[1] = iRefIdx[1]; |
---|
2935 | |
---|
2936 | ::memcpy( cMvBi, aacMv, sizeof(aacMv) ); |
---|
2937 | ::memcpy( cMvPredBi, cMvPred, sizeof(cMvPred) ); |
---|
2938 | ::memcpy( aaiMvpIdxBi, aaiMvpIdx, sizeof(aaiMvpIdx) ); |
---|
2939 | |
---|
2940 | uint32_t uiMotBits[2]; |
---|
2941 | |
---|
2942 | if ( slice.getMvdL1ZeroFlag() ) // GPB, list 1 only use Mvp |
---|
2943 | { |
---|
2944 | xCopyAffineAMVPInfo( aacAffineAMVPInfo[1][bestBiPRefIdxL1], affiAMVPInfoTemp[REF_PIC_LIST_1] ); |
---|
2945 | pu.mvpIdx[REF_PIC_LIST_1] = bestBiPMvpL1; |
---|
2946 | aaiMvpIdxBi[1][bestBiPRefIdxL1] = bestBiPMvpL1; |
---|
2947 | |
---|
2948 | // Set Mv for list1 |
---|
2949 | Mv pcMvTemp[3] = { affiAMVPInfoTemp[REF_PIC_LIST_1].mvCandLT[bestBiPMvpL1], |
---|
2950 | affiAMVPInfoTemp[REF_PIC_LIST_1].mvCandRT[bestBiPMvpL1], |
---|
2951 | affiAMVPInfoTemp[REF_PIC_LIST_1].mvCandLB[bestBiPMvpL1] }; |
---|
2952 | ::memcpy( cMvPredBi[1][bestBiPRefIdxL1], pcMvTemp, sizeof(Mv)*3 ); |
---|
2953 | ::memcpy( cMvBi[1], pcMvTemp, sizeof(Mv)*3 ); |
---|
2954 | ::memcpy( cMvTemp[1][bestBiPRefIdxL1], pcMvTemp, sizeof(Mv)*3 ); |
---|
2955 | iRefIdxBi[1] = bestBiPRefIdxL1; |
---|
2956 | |
---|
2957 | // Get list1 prediction block |
---|
2958 | PU::setAllAffineMv( pu, cMvBi[1][0], cMvBi[1][1], cMvBi[1][2], REF_PIC_LIST_1 ); |
---|
2959 | pu.refIdx[REF_PIC_LIST_1] = iRefIdxBi[1]; |
---|
2960 | |
---|
2961 | PelUnitBuf predBufTmp = m_tmpPredStorage[REF_PIC_LIST_1].getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
2962 | motionCompensation( pu, predBufTmp, REF_PIC_LIST_1 ); |
---|
2963 | |
---|
2964 | // Update bits |
---|
2965 | uiMotBits[0] = uiBits[0] - uiMbBits[0]; |
---|
2966 | uiMotBits[1] = uiMbBits[1]; |
---|
2967 | |
---|
2968 | if( slice.getNumRefIdx(REF_PIC_LIST_1) > 1 ) |
---|
2969 | { |
---|
2970 | uiMotBits[1] += bestBiPRefIdxL1+1; |
---|
2971 | if( bestBiPRefIdxL1 == slice.getNumRefIdx(REF_PIC_LIST_1)-1 ) |
---|
2972 | { |
---|
2973 | uiMotBits[1]--; |
---|
2974 | } |
---|
2975 | } |
---|
2976 | uiMotBits[1] += m_auiMVPIdxCost[aaiMvpIdxBi[1][bestBiPRefIdxL1]][AMVP_MAX_NUM_CANDS]; |
---|
2977 | uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1]; |
---|
2978 | } |
---|
2979 | else |
---|
2980 | { |
---|
2981 | uiMotBits[0] = uiBits[0] - uiMbBits[0]; |
---|
2982 | uiMotBits[1] = uiBits[1] - uiMbBits[1]; |
---|
2983 | uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1]; |
---|
2984 | } |
---|
2985 | |
---|
2986 | // 4-times iteration (default) |
---|
2987 | int iNumIter = 4; |
---|
2988 | // fast encoder setting or GPB: only one iteration |
---|
2989 | if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || slice.getMvdL1ZeroFlag() ) |
---|
2990 | { |
---|
2991 | iNumIter = 1; |
---|
2992 | } |
---|
2993 | |
---|
2994 | for ( int iIter = 0; iIter < iNumIter; iIter++ ) |
---|
2995 | { |
---|
2996 | // Set RefList |
---|
2997 | int iRefList = iIter % 2; |
---|
2998 | if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 ) |
---|
2999 | { |
---|
3000 | if( uiCost[0] <= uiCost[1] ) |
---|
3001 | { |
---|
3002 | iRefList = 1; |
---|
3003 | } |
---|
3004 | else |
---|
3005 | { |
---|
3006 | iRefList = 0; |
---|
3007 | } |
---|
3008 | } |
---|
3009 | else if ( iIter == 0 ) |
---|
3010 | { |
---|
3011 | iRefList = 0; |
---|
3012 | } |
---|
3013 | |
---|
3014 | // First iterate, get prediction block of opposite direction |
---|
3015 | if( iIter == 0 && !slice.getMvdL1ZeroFlag() ) |
---|
3016 | { |
---|
3017 | PU::setAllAffineMv( pu, aacMv[1-iRefList][0], aacMv[1-iRefList][1], aacMv[1-iRefList][2], RefPicList(1-iRefList) ); |
---|
3018 | pu.refIdx[1-iRefList] = iRefIdx[1-iRefList]; |
---|
3019 | |
---|
3020 | PelUnitBuf predBufTmp = m_tmpPredStorage[1 - iRefList].getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
3021 | motionCompensation( pu, predBufTmp, RefPicList(1 - iRefList) ); |
---|
3022 | } |
---|
3023 | |
---|
3024 | RefPicList eRefPicList = ( iRefList ? REF_PIC_LIST_1 : REF_PIC_LIST_0 ); |
---|
3025 | |
---|
3026 | if ( slice.getMvdL1ZeroFlag() ) // GPB, fix List 1, search List 0 |
---|
3027 | { |
---|
3028 | iRefList = 0; |
---|
3029 | eRefPicList = REF_PIC_LIST_0; |
---|
3030 | } |
---|
3031 | |
---|
3032 | bool bChanged = false; |
---|
3033 | |
---|
3034 | iRefStart = 0; |
---|
3035 | iRefEnd = slice.getNumRefIdx(eRefPicList) - 1; |
---|
3036 | |
---|
3037 | for ( int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ ) |
---|
3038 | { |
---|
3039 | #if JVET_K0185_AFFINE_6PARA_ENC // reuse refidx of 4-para |
---|
3040 | if ( pu.cu->affineType == AFFINEMODEL_6PARAM && refIdx4Para[iRefList] != iRefIdxTemp ) |
---|
3041 | { |
---|
3042 | continue; |
---|
3043 | } |
---|
3044 | #endif |
---|
3045 | |
---|
3046 | // update bits |
---|
3047 | uiBitsTemp = uiMbBits[2] + uiMotBits[1-iRefList]; |
---|
3048 | if( slice.getNumRefIdx(eRefPicList) > 1 ) |
---|
3049 | { |
---|
3050 | uiBitsTemp += iRefIdxTemp+1; |
---|
3051 | if ( iRefIdxTemp == slice.getNumRefIdx(eRefPicList)-1 ) |
---|
3052 | { |
---|
3053 | uiBitsTemp--; |
---|
3054 | } |
---|
3055 | } |
---|
3056 | uiBitsTemp += m_auiMVPIdxCost[aaiMvpIdxBi[iRefList][iRefIdxTemp]][AMVP_MAX_NUM_CANDS]; |
---|
3057 | |
---|
3058 | // call Affine ME |
---|
3059 | xAffineMotionEstimation( pu, origBuf, eRefPicList, cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true ); |
---|
3060 | xCopyAffineAMVPInfo( aacAffineAMVPInfo[iRefList][iRefIdxTemp], affiAMVPInfoTemp[eRefPicList] ); |
---|
3061 | xCheckBestAffineMVP( pu, affiAMVPInfoTemp[eRefPicList], eRefPicList, cMvTemp[iRefList][iRefIdxTemp], cMvPredBi[iRefList][iRefIdxTemp], aaiMvpIdxBi[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp ); |
---|
3062 | |
---|
3063 | if ( uiCostTemp < uiCostBi ) |
---|
3064 | { |
---|
3065 | bChanged = true; |
---|
3066 | ::memcpy( cMvBi[iRefList], cMvTemp[iRefList][iRefIdxTemp], sizeof(Mv)*3 ); |
---|
3067 | iRefIdxBi[iRefList] = iRefIdxTemp; |
---|
3068 | |
---|
3069 | uiCostBi = uiCostTemp; |
---|
3070 | uiMotBits[iRefList] = uiBitsTemp - uiMbBits[2] - uiMotBits[1-iRefList]; |
---|
3071 | uiBits[2] = uiBitsTemp; |
---|
3072 | |
---|
3073 | if ( iNumIter != 1 ) // MC for next iter |
---|
3074 | { |
---|
3075 | // Set motion |
---|
3076 | PU::setAllAffineMv( pu, cMvBi[iRefList][0], cMvBi[iRefList][1], cMvBi[iRefList][2], eRefPicList ); |
---|
3077 | pu.refIdx[eRefPicList] = iRefIdxBi[eRefPicList]; |
---|
3078 | PelUnitBuf predBufTmp = m_tmpPredStorage[iRefList].getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
3079 | motionCompensation( pu, predBufTmp, eRefPicList ); |
---|
3080 | } |
---|
3081 | } |
---|
3082 | } // for loop-iRefIdxTemp |
---|
3083 | |
---|
3084 | if ( !bChanged ) |
---|
3085 | { |
---|
3086 | if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] ) |
---|
3087 | { |
---|
3088 | xCopyAffineAMVPInfo( aacAffineAMVPInfo[0][iRefIdxBi[0]], affiAMVPInfoTemp[REF_PIC_LIST_0] ); |
---|
3089 | xCheckBestAffineMVP( pu, affiAMVPInfoTemp[REF_PIC_LIST_0], REF_PIC_LIST_0, cMvBi[0], cMvPredBi[0][iRefIdxBi[0]], aaiMvpIdxBi[0][iRefIdxBi[0]], uiBits[2], uiCostBi ); |
---|
3090 | |
---|
3091 | if ( !slice.getMvdL1ZeroFlag() ) |
---|
3092 | { |
---|
3093 | xCopyAffineAMVPInfo( aacAffineAMVPInfo[1][iRefIdxBi[1]], affiAMVPInfoTemp[REF_PIC_LIST_1] ); |
---|
3094 | xCheckBestAffineMVP( pu, affiAMVPInfoTemp[REF_PIC_LIST_1], REF_PIC_LIST_1, cMvBi[1], cMvPredBi[1][iRefIdxBi[1]], aaiMvpIdxBi[1][iRefIdxBi[1]], uiBits[2], uiCostBi ); |
---|
3095 | } |
---|
3096 | } |
---|
3097 | break; |
---|
3098 | } |
---|
3099 | } // for loop-iter |
---|
3100 | } // if (B_SLICE) |
---|
3101 | |
---|
3102 | pu.mv [REF_PIC_LIST_0] = Mv(); |
---|
3103 | pu.mv [REF_PIC_LIST_1] = Mv(); |
---|
3104 | pu.mvd [REF_PIC_LIST_0] = cMvZero; |
---|
3105 | pu.mvd [REF_PIC_LIST_1] = cMvZero; |
---|
3106 | pu.refIdx[REF_PIC_LIST_0] = NOT_VALID; |
---|
3107 | pu.refIdx[REF_PIC_LIST_1] = NOT_VALID; |
---|
3108 | pu.mvpIdx[REF_PIC_LIST_0] = NOT_VALID; |
---|
3109 | pu.mvpIdx[REF_PIC_LIST_1] = NOT_VALID; |
---|
3110 | pu.mvpNum[REF_PIC_LIST_0] = NOT_VALID; |
---|
3111 | pu.mvpNum[REF_PIC_LIST_1] = NOT_VALID; |
---|
3112 | |
---|
3113 | for ( int verIdx = 0; verIdx < 3; verIdx++ ) |
---|
3114 | { |
---|
3115 | pu.mvdAffi[REF_PIC_LIST_0][verIdx] = cMvZero; |
---|
3116 | pu.mvdAffi[REF_PIC_LIST_1][verIdx] = cMvZero; |
---|
3117 | } |
---|
3118 | |
---|
3119 | // Set Motion Field |
---|
3120 | memcpy( aacMv[1], mvValidList1, sizeof(Mv)*3 ); |
---|
3121 | iRefIdx[1] = refIdxValidList1; |
---|
3122 | uiBits[1] = bitsValidList1; |
---|
3123 | uiCost[1] = costValidList1; |
---|
3124 | |
---|
3125 | // Affine ME result set |
---|
3126 | if ( uiCostBi <= uiCost[0] && uiCostBi <= uiCost[1] ) // Bi |
---|
3127 | { |
---|
3128 | lastMode = 2; |
---|
3129 | affineCost = uiCostBi; |
---|
3130 | |
---|
3131 | PU::setAllAffineMv( pu, cMvBi[0][0], cMvBi[0][1], cMvBi[0][2], REF_PIC_LIST_0 ); |
---|
3132 | PU::setAllAffineMv( pu, cMvBi[1][0], cMvBi[1][1], cMvBi[1][2], REF_PIC_LIST_1 ); |
---|
3133 | pu.refIdx[REF_PIC_LIST_0] = iRefIdxBi[0]; |
---|
3134 | pu.refIdx[REF_PIC_LIST_1] = iRefIdxBi[1]; |
---|
3135 | |
---|
3136 | for ( int verIdx = 0; verIdx < mvNum; verIdx++ ) |
---|
3137 | { |
---|
3138 | pu.mvdAffi[REF_PIC_LIST_0][verIdx] = cMvBi[0][verIdx] - cMvPredBi[0][iRefIdxBi[0]][verIdx]; |
---|
3139 | pu.mvdAffi[REF_PIC_LIST_1][verIdx] = cMvBi[1][verIdx] - cMvPredBi[1][iRefIdxBi[1]][verIdx]; |
---|
3140 | #if JVET_K0337_AFFINE_MVD_PREDICTION |
---|
3141 | if ( verIdx != 0 ) |
---|
3142 | { |
---|
3143 | pu.mvdAffi[0][verIdx] = pu.mvdAffi[0][verIdx] - pu.mvdAffi[0][0]; |
---|
3144 | pu.mvdAffi[1][verIdx] = pu.mvdAffi[1][verIdx] - pu.mvdAffi[1][0]; |
---|
3145 | } |
---|
3146 | #endif |
---|
3147 | } |
---|
3148 | |
---|
3149 | pu.interDir = 3; |
---|
3150 | |
---|
3151 | pu.mvpIdx[REF_PIC_LIST_0] = aaiMvpIdxBi[0][iRefIdxBi[0]]; |
---|
3152 | pu.mvpNum[REF_PIC_LIST_0] = aaiMvpNum[0][iRefIdxBi[0]]; |
---|
3153 | pu.mvpIdx[REF_PIC_LIST_1] = aaiMvpIdxBi[1][iRefIdxBi[1]]; |
---|
3154 | pu.mvpNum[REF_PIC_LIST_1] = aaiMvpNum[1][iRefIdxBi[1]]; |
---|
3155 | } |
---|
3156 | else if ( uiCost[0] <= uiCost[1] ) // List 0 |
---|
3157 | { |
---|
3158 | lastMode = 0; |
---|
3159 | affineCost = uiCost[0]; |
---|
3160 | |
---|
3161 | PU::setAllAffineMv( pu, aacMv[0][0], aacMv[0][1], aacMv[0][2], REF_PIC_LIST_0 ); |
---|
3162 | pu.refIdx[REF_PIC_LIST_0] = iRefIdx[0]; |
---|
3163 | |
---|
3164 | for ( int verIdx = 0; verIdx < mvNum; verIdx++ ) |
---|
3165 | { |
---|
3166 | pu.mvdAffi[REF_PIC_LIST_0][verIdx] = aacMv[0][verIdx] - cMvPred[0][iRefIdx[0]][verIdx]; |
---|
3167 | #if JVET_K0337_AFFINE_MVD_PREDICTION |
---|
3168 | if ( verIdx != 0 ) |
---|
3169 | { |
---|
3170 | pu.mvdAffi[0][verIdx] = pu.mvdAffi[0][verIdx] - pu.mvdAffi[0][0]; |
---|
3171 | } |
---|
3172 | #endif |
---|
3173 | } |
---|
3174 | pu.interDir = 1; |
---|
3175 | |
---|
3176 | pu.mvpIdx[REF_PIC_LIST_0] = aaiMvpIdx[0][iRefIdx[0]]; |
---|
3177 | pu.mvpNum[REF_PIC_LIST_0] = aaiMvpNum[0][iRefIdx[0]]; |
---|
3178 | } |
---|
3179 | else |
---|
3180 | { |
---|
3181 | lastMode = 1; |
---|
3182 | affineCost = uiCost[1]; |
---|
3183 | |
---|
3184 | PU::setAllAffineMv( pu, aacMv[1][0], aacMv[1][1], aacMv[1][2], REF_PIC_LIST_1 ); |
---|
3185 | pu.refIdx[REF_PIC_LIST_1] = iRefIdx[1]; |
---|
3186 | |
---|
3187 | for ( int verIdx = 0; verIdx < mvNum; verIdx++ ) |
---|
3188 | { |
---|
3189 | pu.mvdAffi[REF_PIC_LIST_1][verIdx] = aacMv[1][verIdx] - cMvPred[1][iRefIdx[1]][verIdx]; |
---|
3190 | #if JVET_K0337_AFFINE_MVD_PREDICTION |
---|
3191 | if ( verIdx != 0 ) |
---|
3192 | { |
---|
3193 | pu.mvdAffi[1][verIdx] = pu.mvdAffi[1][verIdx] - pu.mvdAffi[1][0]; |
---|
3194 | } |
---|
3195 | #endif |
---|
3196 | } |
---|
3197 | pu.interDir = 2; |
---|
3198 | |
---|
3199 | pu.mvpIdx[REF_PIC_LIST_1] = aaiMvpIdx[1][iRefIdx[1]]; |
---|
3200 | pu.mvpNum[REF_PIC_LIST_1] = aaiMvpNum[1][iRefIdx[1]]; |
---|
3201 | } |
---|
3202 | } |
---|
3203 | |
---|
3204 | void solveEqual( double** dEqualCoeff, int iOrder, double* dAffinePara ) |
---|
3205 | { |
---|
3206 | #if JVET_K_AFFINE_BUG_FIXES |
---|
3207 | for ( int k = 0; k < iOrder; k++ ) |
---|
3208 | { |
---|
3209 | dAffinePara[k] = 0.; |
---|
3210 | } |
---|
3211 | #endif |
---|
3212 | |
---|
3213 | // row echelon |
---|
3214 | for ( int i = 1; i < iOrder; i++ ) |
---|
3215 | { |
---|
3216 | // find column max |
---|
3217 | double temp = fabs(dEqualCoeff[i][i-1]); |
---|
3218 | int tempIdx = i; |
---|
3219 | for ( int j = i+1; j < iOrder+1; j++ ) |
---|
3220 | { |
---|
3221 | if ( fabs(dEqualCoeff[j][i-1]) > temp ) |
---|
3222 | { |
---|
3223 | temp = fabs(dEqualCoeff[j][i-1]); |
---|
3224 | tempIdx = j; |
---|
3225 | } |
---|
3226 | } |
---|
3227 | |
---|
3228 | // swap line |
---|
3229 | if ( tempIdx != i ) |
---|
3230 | { |
---|
3231 | for ( int j = 0; j < iOrder+1; j++ ) |
---|
3232 | { |
---|
3233 | dEqualCoeff[0][j] = dEqualCoeff[i][j]; |
---|
3234 | dEqualCoeff[i][j] = dEqualCoeff[tempIdx][j]; |
---|
3235 | dEqualCoeff[tempIdx][j] = dEqualCoeff[0][j]; |
---|
3236 | } |
---|
3237 | } |
---|
3238 | |
---|
3239 | // elimination first column |
---|
3240 | #if JVET_K_AFFINE_BUG_FIXES |
---|
3241 | if ( dEqualCoeff[i][i - 1] == 0. ) |
---|
3242 | { |
---|
3243 | return; |
---|
3244 | } |
---|
3245 | #endif |
---|
3246 | for ( int j = i+1; j < iOrder+1; j++ ) |
---|
3247 | { |
---|
3248 | for ( int k = i; k < iOrder+1; k++ ) |
---|
3249 | { |
---|
3250 | dEqualCoeff[j][k] = dEqualCoeff[j][k] - dEqualCoeff[i][k] * dEqualCoeff[j][i-1] / dEqualCoeff[i][i-1]; |
---|
3251 | } |
---|
3252 | } |
---|
3253 | } |
---|
3254 | |
---|
3255 | #if JVET_K_AFFINE_BUG_FIXES |
---|
3256 | if ( dEqualCoeff[iOrder][iOrder - 1] == 0. ) |
---|
3257 | { |
---|
3258 | return; |
---|
3259 | } |
---|
3260 | #endif |
---|
3261 | dAffinePara[iOrder-1] = dEqualCoeff[iOrder][iOrder] / dEqualCoeff[iOrder][iOrder-1]; |
---|
3262 | for ( int i = iOrder-2; i >= 0; i-- ) |
---|
3263 | { |
---|
3264 | #if JVET_K_AFFINE_BUG_FIXES |
---|
3265 | if ( dEqualCoeff[i + 1][i] == 0. ) |
---|
3266 | { |
---|
3267 | for ( int k = 0; k < iOrder; k++ ) |
---|
3268 | { |
---|
3269 | dAffinePara[k] = 0.; |
---|
3270 | } |
---|
3271 | return; |
---|
3272 | } |
---|
3273 | #endif |
---|
3274 | double temp = 0; |
---|
3275 | for ( int j = i+1; j < iOrder; j++ ) |
---|
3276 | { |
---|
3277 | temp += dEqualCoeff[i+1][j] * dAffinePara[j]; |
---|
3278 | } |
---|
3279 | dAffinePara[i] = ( dEqualCoeff[i+1][iOrder] - temp ) / dEqualCoeff[i+1][i]; |
---|
3280 | } |
---|
3281 | } |
---|
3282 | |
---|
3283 | void InterSearch::xCheckBestAffineMVP( PredictionUnit &pu, AffineAMVPInfo &affineAMVPInfo, RefPicList eRefPicList, Mv acMv[3], Mv acMvPred[3], int& riMVPIdx, uint32_t& ruiBits, Distortion& ruiCost ) |
---|
3284 | { |
---|
3285 | if ( affineAMVPInfo.numCand < 2 ) |
---|
3286 | { |
---|
3287 | return; |
---|
3288 | } |
---|
3289 | |
---|
3290 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3291 | int mvNum = pu.cu->affineType ? 3 : 2; |
---|
3292 | #endif |
---|
3293 | |
---|
3294 | m_pcRdCost->selectMotionLambda( pu.cu->transQuantBypass ); |
---|
3295 | m_pcRdCost->setCostScale ( 0 ); |
---|
3296 | |
---|
3297 | int iBestMVPIdx = riMVPIdx; |
---|
3298 | |
---|
3299 | // Get origin MV bits |
---|
3300 | int iOrgMvBits = 0; |
---|
3301 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3302 | for ( int iVerIdx = 0; iVerIdx < mvNum; iVerIdx++ ) |
---|
3303 | #else |
---|
3304 | for ( int iVerIdx=0; iVerIdx<2; iVerIdx++ ) |
---|
3305 | #endif |
---|
3306 | { |
---|
3307 | m_pcRdCost->setPredictor ( acMvPred[iVerIdx] ); |
---|
3308 | const int shift = acMv[iVerIdx].highPrec ? VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : 0; |
---|
3309 | |
---|
3310 | #if JVET_K0337_AFFINE_MVD_PREDICTION |
---|
3311 | Mv secondPred; |
---|
3312 | if ( iVerIdx != 0 ) |
---|
3313 | { |
---|
3314 | secondPred = acMvPred[iVerIdx] + (acMv[0] - acMvPred[0]); |
---|
3315 | m_pcRdCost->setPredictor( secondPred ); |
---|
3316 | } |
---|
3317 | #endif |
---|
3318 | #if JVET_K0357_AMVR |
---|
3319 | iOrgMvBits += m_pcRdCost->getBitsOfVectorWithPredictor( acMv[iVerIdx].getHor()>>shift, acMv[iVerIdx].getVer()>>shift, 0 ); |
---|
3320 | #else |
---|
3321 | iOrgMvBits += m_pcRdCost->getBitsOfVectorWithPredictor( acMv[iVerIdx].getHor() >> shift, acMv[iVerIdx].getVer() >> shift ); |
---|
3322 | #endif |
---|
3323 | } |
---|
3324 | iOrgMvBits += m_auiMVPIdxCost[riMVPIdx][AMVP_MAX_NUM_CANDS]; |
---|
3325 | |
---|
3326 | int iBestMvBits = iOrgMvBits; |
---|
3327 | for (int iMVPIdx = 0; iMVPIdx < affineAMVPInfo.numCand; iMVPIdx++) |
---|
3328 | { |
---|
3329 | if (iMVPIdx == riMVPIdx) |
---|
3330 | { |
---|
3331 | continue; |
---|
3332 | } |
---|
3333 | |
---|
3334 | int iMvBits = 0; |
---|
3335 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3336 | for ( int iVerIdx = 0; iVerIdx < mvNum; iVerIdx++ ) |
---|
3337 | #else |
---|
3338 | for ( int iVerIdx=0; iVerIdx<2; iVerIdx++ ) |
---|
3339 | #endif |
---|
3340 | { |
---|
3341 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3342 | m_pcRdCost->setPredictor( iVerIdx == 2 ? affineAMVPInfo.mvCandLB[iMVPIdx] : |
---|
3343 | (iVerIdx == 1 ? affineAMVPInfo.mvCandRT[iMVPIdx] : affineAMVPInfo.mvCandLT[iMVPIdx]) ); |
---|
3344 | #else |
---|
3345 | m_pcRdCost->setPredictor ( iVerIdx ? affineAMVPInfo.mvCandRT[iMVPIdx] : affineAMVPInfo.mvCandLT[iMVPIdx] ); |
---|
3346 | #endif |
---|
3347 | const int shift = acMv[iVerIdx].highPrec ? VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : 0; |
---|
3348 | |
---|
3349 | #if JVET_K0337_AFFINE_MVD_PREDICTION |
---|
3350 | Mv secondPred; |
---|
3351 | if ( iVerIdx != 0 ) |
---|
3352 | { |
---|
3353 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3354 | #if AFFINE_ENC_BUGFIX |
---|
3355 | secondPred = (iVerIdx == 1 ? affineAMVPInfo.mvCandRT[iMVPIdx] : affineAMVPInfo.mvCandLB[iMVPIdx]) + (acMv[0] - affineAMVPInfo.mvCandLT[iMVPIdx]); |
---|
3356 | #else |
---|
3357 | secondPred = (iVerIdx == 1 ? affineAMVPInfo.mvCandRT[iMVPIdx] : affineAMVPInfo.mvCandLT[iMVPIdx]) + (acMv[0] - affineAMVPInfo.mvCandLT[iMVPIdx]); |
---|
3358 | #endif |
---|
3359 | #else |
---|
3360 | secondPred = affineAMVPInfo.mvCandRT[iMVPIdx] + (acMv[0] - affineAMVPInfo.mvCandLT[iMVPIdx]); |
---|
3361 | #endif |
---|
3362 | m_pcRdCost->setPredictor( secondPred ); |
---|
3363 | } |
---|
3364 | #endif |
---|
3365 | #if JVET_K0357_AMVR |
---|
3366 | iMvBits += m_pcRdCost->getBitsOfVectorWithPredictor( acMv[iVerIdx].getHor()>>shift, acMv[iVerIdx].getVer()>>shift, 0 ); |
---|
3367 | #else |
---|
3368 | iMvBits += m_pcRdCost->getBitsOfVectorWithPredictor( acMv[iVerIdx].getHor() >> shift, acMv[iVerIdx].getVer() >> shift ); |
---|
3369 | #endif |
---|
3370 | } |
---|
3371 | iMvBits += m_auiMVPIdxCost[iMVPIdx][AMVP_MAX_NUM_CANDS]; |
---|
3372 | |
---|
3373 | if (iMvBits < iBestMvBits) |
---|
3374 | { |
---|
3375 | iBestMvBits = iMvBits; |
---|
3376 | iBestMVPIdx = iMVPIdx; |
---|
3377 | } |
---|
3378 | } |
---|
3379 | |
---|
3380 | if (iBestMVPIdx != riMVPIdx) // if changed |
---|
3381 | { |
---|
3382 | acMvPred[0] = affineAMVPInfo.mvCandLT[iBestMVPIdx]; |
---|
3383 | acMvPred[1] = affineAMVPInfo.mvCandRT[iBestMVPIdx]; |
---|
3384 | acMvPred[2] = affineAMVPInfo.mvCandLB[iBestMVPIdx]; |
---|
3385 | riMVPIdx = iBestMVPIdx; |
---|
3386 | uint32_t uiOrgBits = ruiBits; |
---|
3387 | ruiBits = uiOrgBits - iOrgMvBits + iBestMvBits; |
---|
3388 | ruiCost = (ruiCost - m_pcRdCost->getCost( uiOrgBits )) + m_pcRdCost->getCost( ruiBits ); |
---|
3389 | } |
---|
3390 | } |
---|
3391 | |
---|
3392 | void InterSearch::xAffineMotionEstimation( PredictionUnit& pu, |
---|
3393 | PelUnitBuf& origBuf, |
---|
3394 | RefPicList eRefPicList, |
---|
3395 | Mv acMvPred[3], |
---|
3396 | int iRefIdxPred, |
---|
3397 | Mv acMv[3], |
---|
3398 | uint32_t& ruiBits, |
---|
3399 | Distortion& ruiCost, |
---|
3400 | bool bBi ) |
---|
3401 | { |
---|
3402 | const int width = pu.Y().width; |
---|
3403 | const int height = pu.Y().height; |
---|
3404 | |
---|
3405 | const Picture* refPic = pu.cu->slice->getRefPic(eRefPicList, iRefIdxPred); |
---|
3406 | |
---|
3407 | // Set Origin YUV: pcYuv |
---|
3408 | PelUnitBuf* pBuf = &origBuf; |
---|
3409 | double fWeight = 1.0; |
---|
3410 | |
---|
3411 | PelUnitBuf origBufTmp = m_tmpStorageLCU.getBuf( UnitAreaRelative( *pu.cu, pu ) ); |
---|
3412 | |
---|
3413 | // if Bi, set to ( 2 * Org - ListX ) |
---|
3414 | if ( bBi ) |
---|
3415 | { |
---|
3416 | // NOTE: Other buf contains predicted signal from another direction |
---|
3417 | PelUnitBuf otherBuf = m_tmpPredStorage[1 - (int)eRefPicList].getBuf( UnitAreaRelative( *pu.cu, pu ) ); |
---|
3418 | origBufTmp.copyFrom(origBuf); |
---|
3419 | origBufTmp.removeHighFreq(otherBuf, m_pcEncCfg->getClipForBiPredMeEnabled(), pu.cu->slice->clpRngs()); |
---|
3420 | pBuf = &origBufTmp; |
---|
3421 | |
---|
3422 | fWeight = 0.5; |
---|
3423 | } |
---|
3424 | |
---|
3425 | // pred YUV |
---|
3426 | PelUnitBuf predBuf = m_tmpAffiStorage.getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
3427 | |
---|
3428 | // Set start Mv position, use input mv as started search mv |
---|
3429 | Mv acMvTemp[3]; |
---|
3430 | ::memcpy( acMvTemp, acMv, sizeof(Mv)*3 ); |
---|
3431 | acMvTemp[0].setHighPrec(); |
---|
3432 | acMvTemp[1].setHighPrec(); |
---|
3433 | acMvTemp[2].setHighPrec(); |
---|
3434 | |
---|
3435 | // Set delta mv |
---|
3436 | // malloc buffer |
---|
3437 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3438 | int iParaNum = pu.cu->affineType ? 7 : 5; |
---|
3439 | int affineParaNum = iParaNum - 1; |
---|
3440 | int mvNum = pu.cu->affineType ? 3 : 2; |
---|
3441 | #else |
---|
3442 | static const int iParaNum = 5; |
---|
3443 | #endif |
---|
3444 | double **pdEqualCoeff; |
---|
3445 | pdEqualCoeff = new double *[iParaNum]; |
---|
3446 | for ( int i = 0; i < iParaNum; i++ ) |
---|
3447 | { |
---|
3448 | pdEqualCoeff[i] = new double[iParaNum]; |
---|
3449 | } |
---|
3450 | |
---|
3451 | #if JVET_K0367_AFFINE_FIX_POINT |
---|
3452 | int64_t i64EqualCoeff[7][7]; |
---|
3453 | Pel *piError = m_tmpAffiError; |
---|
3454 | int *pdDerivate[2]; |
---|
3455 | #else |
---|
3456 | int *piError = m_tmpAffiError; |
---|
3457 | double *pdDerivate[2]; |
---|
3458 | #endif |
---|
3459 | pdDerivate[0] = m_tmpAffiDeri[0]; |
---|
3460 | pdDerivate[1] = m_tmpAffiDeri[1]; |
---|
3461 | |
---|
3462 | Distortion uiCostBest = std::numeric_limits<Distortion>::max(); |
---|
3463 | uint32_t uiBitsBest = 0; |
---|
3464 | |
---|
3465 | // do motion compensation with origin mv |
---|
3466 | clipMv( acMvTemp[0], pu.cu->lumaPos(), *pu.cs->sps ); |
---|
3467 | clipMv( acMvTemp[1], pu.cu->lumaPos(), *pu.cs->sps ); |
---|
3468 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3469 | if ( pu.cu->affineType == AFFINEMODEL_6PARAM ) |
---|
3470 | { |
---|
3471 | clipMv( acMvTemp[2], pu.cu->lumaPos(), *pu.cs->sps ); |
---|
3472 | } |
---|
3473 | #endif |
---|
3474 | #if !JVET_K_AFFINE_BUG_FIXES |
---|
3475 | int vx2 = - ( acMvTemp[1].getVer() - acMvTemp[0].getVer() ) * height / width + acMvTemp[0].getHor(); |
---|
3476 | int vy2 = ( acMvTemp[1].getHor() - acMvTemp[0].getHor() ) * height / width + acMvTemp[0].getVer(); |
---|
3477 | acMvTemp[2] = Mv( vx2, vy2, true ); |
---|
3478 | clipMv( acMvTemp[2], pu.cu->lumaPos(), *pu.cs->sps ); |
---|
3479 | #endif |
---|
3480 | xPredAffineBlk( COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cs->slice->clpRng( COMPONENT_Y ) ); |
---|
3481 | |
---|
3482 | // get error |
---|
3483 | uiCostBest = m_pcRdCost->getDistPart( predBuf.Y(), pBuf->Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, DF_HAD ); |
---|
3484 | |
---|
3485 | // get cost with mv |
---|
3486 | m_pcRdCost->setCostScale(0); |
---|
3487 | uiBitsBest = ruiBits; |
---|
3488 | DTRACE( g_trace_ctx, D_COMMON, " (%d) xx uiBitsBest=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiBitsBest ); |
---|
3489 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3490 | for ( int i = 0; i < mvNum; i++ ) |
---|
3491 | #else |
---|
3492 | for ( int i=0; i<2; i++ ) |
---|
3493 | #endif |
---|
3494 | { |
---|
3495 | DTRACE( g_trace_ctx, D_COMMON, "#mvPredForBits=(%d,%d) \n", acMvPred[i].getHor(), acMvPred[i].getVer() ); |
---|
3496 | m_pcRdCost->setPredictor( acMvPred[i] ); |
---|
3497 | DTRACE( g_trace_ctx, D_COMMON, "#mvForBits=(%d,%d) \n", acMvTemp[i].getHor(), acMvTemp[i].getVer() ); |
---|
3498 | |
---|
3499 | const int shift = acMvTemp[i].highPrec ? VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : 0; |
---|
3500 | #if JVET_K0337_AFFINE_MVD_PREDICTION |
---|
3501 | Mv secondPred; |
---|
3502 | if ( i != 0 ) |
---|
3503 | { |
---|
3504 | secondPred = acMvPred[i] + (acMvTemp[0] - acMvPred[0]); |
---|
3505 | m_pcRdCost->setPredictor( secondPred ); |
---|
3506 | } |
---|
3507 | #endif |
---|
3508 | #if JVET_K0357_AMVR |
---|
3509 | uiBitsBest += m_pcRdCost->getBitsOfVectorWithPredictor( acMvTemp[i].getHor()>>shift, acMvTemp[i].getVer()>>shift, 0 ); |
---|
3510 | #else |
---|
3511 | uiBitsBest += m_pcRdCost->getBitsOfVectorWithPredictor( acMvTemp[i].getHor() >> shift, acMvTemp[i].getVer() >> shift ); |
---|
3512 | #endif |
---|
3513 | DTRACE( g_trace_ctx, D_COMMON, " (%d) yy uiBitsBest=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiBitsBest ); |
---|
3514 | } |
---|
3515 | uiCostBest = (Distortion)( floor( fWeight * (double)uiCostBest ) + (double)m_pcRdCost->getCost( uiBitsBest ) ); |
---|
3516 | |
---|
3517 | DTRACE( g_trace_ctx, D_COMMON, " (%d) uiBitsBest=%d, uiCostBest=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiBitsBest, uiCostBest ); |
---|
3518 | |
---|
3519 | ::memcpy( acMv, acMvTemp, sizeof(Mv) * 3 ); |
---|
3520 | |
---|
3521 | const int bufStride = pBuf->Y().stride; |
---|
3522 | const int predBufStride = predBuf.Y().stride; |
---|
3523 | |
---|
3524 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3525 | int iIterTime; |
---|
3526 | if ( pu.cu->affineType == AFFINEMODEL_6PARAM ) |
---|
3527 | { |
---|
3528 | iIterTime = bBi ? 3 : 4; |
---|
3529 | } |
---|
3530 | else |
---|
3531 | { |
---|
3532 | iIterTime = bBi ? 3 : 5; |
---|
3533 | } |
---|
3534 | |
---|
3535 | if ( !pu.cu->cs->sps->getSpsNext().getUseAffineType() ) |
---|
3536 | { |
---|
3537 | iIterTime = bBi ? 5 : 7; |
---|
3538 | } |
---|
3539 | #else |
---|
3540 | int iIterTime = bBi ? 5 : 7; |
---|
3541 | #endif |
---|
3542 | for ( int iter=0; iter<iIterTime; iter++ ) // iterate loop |
---|
3543 | { |
---|
3544 | /********************************************************************************* |
---|
3545 | * use gradient to update mv |
---|
3546 | *********************************************************************************/ |
---|
3547 | // get Error Matrix |
---|
3548 | Pel* pOrg = pBuf->Y().buf; |
---|
3549 | Pel* pPred = predBuf.Y().buf; |
---|
3550 | for ( int j=0; j< height; j++ ) |
---|
3551 | { |
---|
3552 | for ( int i=0; i< width; i++ ) |
---|
3553 | { |
---|
3554 | piError[i + j * width] = pOrg[i] - pPred[i]; |
---|
3555 | } |
---|
3556 | pOrg += bufStride; |
---|
3557 | pPred += predBufStride; |
---|
3558 | } |
---|
3559 | |
---|
3560 | // sobel x direction |
---|
3561 | // -1 0 1 |
---|
3562 | // -2 0 2 |
---|
3563 | // -1 0 1 |
---|
3564 | pPred = predBuf.Y().buf; |
---|
3565 | #if JVET_K0367_AFFINE_FIX_POINT |
---|
3566 | m_HorizontalSobelFilter( pPred, predBufStride, pdDerivate[0], width, width, height ); |
---|
3567 | #else |
---|
3568 | for ( int j = 1; j < height-1; j++ ) |
---|
3569 | { |
---|
3570 | for ( int k = 1; k < width-1; k++ ) |
---|
3571 | { |
---|
3572 | int iCenter = j*predBufStride + k; |
---|
3573 | pdDerivate[0][j*width + k] = (double)( pPred[iCenter + 1 - predBufStride] - pPred[iCenter - 1 - predBufStride] |
---|
3574 | + ( pPred[iCenter + 1] << 1 ) - ( pPred[iCenter - 1] << 1 ) |
---|
3575 | + pPred[iCenter + 1 + predBufStride] - pPred[iCenter - 1 + predBufStride] ) / 8 ; |
---|
3576 | } |
---|
3577 | pdDerivate[0][ j*width ] = pdDerivate[0][ j*width + 1 ]; |
---|
3578 | pdDerivate[0][ j*width + width - 1 ] = pdDerivate[0][ j*width + width - 2 ]; |
---|
3579 | } |
---|
3580 | |
---|
3581 | pdDerivate[0][0] = pdDerivate[0][width+1]; |
---|
3582 | pdDerivate[0][width-1] = pdDerivate[0][width+width-2]; |
---|
3583 | pdDerivate[0][(height-1)*width] = pdDerivate[0][(height-2)*width+1]; |
---|
3584 | pdDerivate[0][(height-1)*width+width-1] = pdDerivate[0][(height-2)*width+width-2]; |
---|
3585 | |
---|
3586 | for ( int j = 1; j < width - 1; j++ ) |
---|
3587 | { |
---|
3588 | pdDerivate[0][j] = pdDerivate[0][width+j]; |
---|
3589 | pdDerivate[0][(height-1)*width+j] = pdDerivate[0][(height-2)*width+j]; |
---|
3590 | } |
---|
3591 | #endif |
---|
3592 | |
---|
3593 | // sobel y direction |
---|
3594 | // -1 -2 -1 |
---|
3595 | // 0 0 0 |
---|
3596 | // 1 2 1 |
---|
3597 | #if JVET_K0367_AFFINE_FIX_POINT |
---|
3598 | m_VerticalSobelFilter( pPred, predBufStride, pdDerivate[1], width, width, height ); |
---|
3599 | #else |
---|
3600 | for ( int k=1; k < width-1; k++ ) |
---|
3601 | { |
---|
3602 | for ( int j = 1; j < height-1; j++ ) |
---|
3603 | { |
---|
3604 | int iCenter = j*predBufStride + k; |
---|
3605 | pdDerivate[1][j*width + k] = (double)( pPred[iCenter + predBufStride - 1] - pPred[iCenter - predBufStride - 1] |
---|
3606 | + ( pPred[iCenter + predBufStride] << 1 ) - ( pPred[iCenter - predBufStride] << 1 ) |
---|
3607 | + pPred[iCenter + predBufStride + 1] - pPred[iCenter - predBufStride + 1] ) / 8; |
---|
3608 | } |
---|
3609 | pdDerivate[1][k] = pdDerivate[1][ width + k ]; |
---|
3610 | pdDerivate[1][ (height - 1) * width + k ] = pdDerivate[1][ (height - 2) * width + k ]; |
---|
3611 | } |
---|
3612 | |
---|
3613 | pdDerivate[1][0] = pdDerivate[1][width+1]; |
---|
3614 | pdDerivate[1][width-1] = pdDerivate[1][width + width-2]; |
---|
3615 | pdDerivate[1][(height-1)*width] = pdDerivate[1][(height-2)*width+1]; |
---|
3616 | pdDerivate[1][(height-1)*width+width-1] = pdDerivate[1][(height-2)*width+(width-2)]; |
---|
3617 | |
---|
3618 | for ( int j=1; j < height-1; j++ ) |
---|
3619 | { |
---|
3620 | pdDerivate[1][j*width] = pdDerivate[1][j*width+1]; |
---|
3621 | pdDerivate[1][j*width+width-1] = pdDerivate[1][j*width+width-2]; |
---|
3622 | } |
---|
3623 | #endif |
---|
3624 | |
---|
3625 | // solve delta x and y |
---|
3626 | #if JVET_K0367_AFFINE_FIX_POINT |
---|
3627 | for ( int row = 0; row < iParaNum; row++ ) |
---|
3628 | { |
---|
3629 | memset( &i64EqualCoeff[row][0], 0, iParaNum * sizeof( int64_t ) ); |
---|
3630 | } |
---|
3631 | |
---|
3632 | m_EqualCoeffComputer( piError, width, pdDerivate, width, i64EqualCoeff, width, height |
---|
3633 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3634 | , (pu.cu->affineType == AFFINEMODEL_6PARAM) |
---|
3635 | #else |
---|
3636 | , false |
---|
3637 | #endif |
---|
3638 | ); |
---|
3639 | |
---|
3640 | for ( int row = 0; row < iParaNum; row++ ) |
---|
3641 | { |
---|
3642 | for ( int i = 0; i < iParaNum; i++ ) |
---|
3643 | { |
---|
3644 | pdEqualCoeff[row][i] = (double)i64EqualCoeff[row][i]; |
---|
3645 | } |
---|
3646 | } |
---|
3647 | #else |
---|
3648 | for ( int m = 0; m != iParaNum; m++ ) |
---|
3649 | { |
---|
3650 | for ( int n = 0; n != iParaNum; n++ ) |
---|
3651 | { |
---|
3652 | pdEqualCoeff[m][n] = 0.0; |
---|
3653 | } |
---|
3654 | } |
---|
3655 | |
---|
3656 | for ( int j = 0; j != height; j++ ) |
---|
3657 | { |
---|
3658 | for ( int k = 0; k != width; k++ ) |
---|
3659 | { |
---|
3660 | int iIdx = j * width + k; |
---|
3661 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3662 | double dC[6]; |
---|
3663 | if ( pu.cu->affineType ) |
---|
3664 | { |
---|
3665 | dC[0] = pdDerivate[0][iIdx]; |
---|
3666 | dC[1] = k * pdDerivate[0][iIdx]; |
---|
3667 | dC[2] = pdDerivate[1][iIdx]; |
---|
3668 | dC[3] = k * pdDerivate[1][iIdx]; |
---|
3669 | dC[4] = j * pdDerivate[0][iIdx]; |
---|
3670 | dC[5] = j * pdDerivate[1][iIdx]; |
---|
3671 | } |
---|
3672 | else |
---|
3673 | { |
---|
3674 | dC[0] = pdDerivate[0][iIdx]; |
---|
3675 | dC[1] = k * pdDerivate[0][iIdx] + j * pdDerivate[1][iIdx]; |
---|
3676 | dC[2] = pdDerivate[1][iIdx]; |
---|
3677 | dC[3] = j * pdDerivate[0][iIdx] - k * pdDerivate[1][iIdx]; |
---|
3678 | } |
---|
3679 | |
---|
3680 | for ( int col = 0; col < affineParaNum; col++ ) |
---|
3681 | { |
---|
3682 | for ( int row = 0; row < affineParaNum; row++ ) |
---|
3683 | { |
---|
3684 | pdEqualCoeff[col + 1][row] += dC[col] * dC[row]; |
---|
3685 | } |
---|
3686 | pdEqualCoeff[col + 1][affineParaNum] += (double)(piError[iIdx] * dC[col]); |
---|
3687 | } |
---|
3688 | #else |
---|
3689 | double dC[4]; |
---|
3690 | dC[0] = pdDerivate[0][iIdx]; |
---|
3691 | dC[1] = k * pdDerivate[0][iIdx] + j * pdDerivate[1][iIdx]; |
---|
3692 | dC[2] = pdDerivate[1][iIdx]; |
---|
3693 | dC[3] = j * pdDerivate[0][iIdx] - k * pdDerivate[1][iIdx]; |
---|
3694 | |
---|
3695 | for ( int col=0; col<4; col++ ) |
---|
3696 | { |
---|
3697 | for ( int row=0; row<4; row++ ) |
---|
3698 | { |
---|
3699 | pdEqualCoeff[col+1][row] += dC[col] * dC[row]; |
---|
3700 | } |
---|
3701 | pdEqualCoeff[col+1][4] += (double)( piError[iIdx] * dC[col] ); |
---|
3702 | } |
---|
3703 | #endif |
---|
3704 | } |
---|
3705 | } |
---|
3706 | #endif |
---|
3707 | |
---|
3708 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3709 | double dAffinePara[6]; |
---|
3710 | double dDeltaMv[6]; |
---|
3711 | Mv acDeltaMv[3]; |
---|
3712 | |
---|
3713 | solveEqual( pdEqualCoeff, affineParaNum, dAffinePara ); |
---|
3714 | |
---|
3715 | // convert to delta mv |
---|
3716 | dDeltaMv[0] = dAffinePara[0]; |
---|
3717 | dDeltaMv[2] = dAffinePara[2]; |
---|
3718 | if ( pu.cu->affineType == AFFINEMODEL_6PARAM ) |
---|
3719 | { |
---|
3720 | dDeltaMv[1] = dAffinePara[1] * width + dAffinePara[0]; |
---|
3721 | dDeltaMv[3] = dAffinePara[3] * width + dAffinePara[2]; |
---|
3722 | dDeltaMv[4] = dAffinePara[4] * height + dAffinePara[0]; |
---|
3723 | dDeltaMv[5] = dAffinePara[5] * height + dAffinePara[2]; |
---|
3724 | } |
---|
3725 | else |
---|
3726 | { |
---|
3727 | dDeltaMv[1] = dAffinePara[1] * width + dAffinePara[0]; |
---|
3728 | dDeltaMv[3] = -dAffinePara[3] * width + dAffinePara[2]; |
---|
3729 | } |
---|
3730 | |
---|
3731 | acDeltaMv[0] = Mv( (int)(dDeltaMv[0] * 4 + SIGN( dDeltaMv[0] ) * 0.5) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, (int)(dDeltaMv[2] * 4 + SIGN( dDeltaMv[2] ) * 0.5) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, true ); |
---|
3732 | acDeltaMv[1] = Mv( (int)(dDeltaMv[1] * 4 + SIGN( dDeltaMv[1] ) * 0.5) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, (int)(dDeltaMv[3] * 4 + SIGN( dDeltaMv[3] ) * 0.5) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, true ); |
---|
3733 | |
---|
3734 | if ( pu.cu->affineType == AFFINEMODEL_6PARAM ) |
---|
3735 | { |
---|
3736 | acDeltaMv[2] = Mv( (int)(dDeltaMv[4] * 4 + SIGN( dDeltaMv[4] ) * 0.5) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, (int)(dDeltaMv[5] * 4 + SIGN( dDeltaMv[5] ) * 0.5) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, true ); |
---|
3737 | } |
---|
3738 | #else |
---|
3739 | double dAffinePara[4]; |
---|
3740 | solveEqual( pdEqualCoeff, 4, dAffinePara ); |
---|
3741 | |
---|
3742 | // convert to delta mv |
---|
3743 | double dDeltaMv[4]; |
---|
3744 | dDeltaMv[0] = dAffinePara[0]; |
---|
3745 | dDeltaMv[2] = dAffinePara[2]; |
---|
3746 | |
---|
3747 | dDeltaMv[1] = dAffinePara[1] * width + dAffinePara[0]; |
---|
3748 | dDeltaMv[3] = - dAffinePara[3] * width + dAffinePara[2]; |
---|
3749 | |
---|
3750 | Mv acDeltaMv[3]; |
---|
3751 | acDeltaMv[0] = Mv( (int)(dDeltaMv[0] * 4 + SIGN(dDeltaMv[0]) * 0.5 ) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, (int)(dDeltaMv[2] * 4 + SIGN(dDeltaMv[2]) * 0.5 ) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, true ); |
---|
3752 | acDeltaMv[1] = Mv( (int)(dDeltaMv[1] * 4 + SIGN(dDeltaMv[1]) * 0.5 ) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, (int)(dDeltaMv[3] * 4 + SIGN(dDeltaMv[3]) * 0.5 ) << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, true ); |
---|
3753 | #endif |
---|
3754 | |
---|
3755 | bool bAllZero = false; |
---|
3756 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3757 | for ( int i = 0; i < mvNum; i++ ) |
---|
3758 | #else |
---|
3759 | for ( int i=0; i<2; i++ ) |
---|
3760 | #endif |
---|
3761 | { |
---|
3762 | if ( acDeltaMv[i].getHor() != 0 || acDeltaMv[i].getVer() != 0 ) |
---|
3763 | { |
---|
3764 | bAllZero = false; |
---|
3765 | break; |
---|
3766 | } |
---|
3767 | bAllZero = true; |
---|
3768 | } |
---|
3769 | |
---|
3770 | if ( bAllZero ) |
---|
3771 | break; |
---|
3772 | |
---|
3773 | // do motion compensation with updated mv |
---|
3774 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3775 | for ( int i = 0; i < mvNum; i++ ) |
---|
3776 | #else |
---|
3777 | for ( int i=0; i<2; i++ ) |
---|
3778 | #endif |
---|
3779 | { |
---|
3780 | acMvTemp[i] += acDeltaMv[i]; |
---|
3781 | #if JVET_K_AFFINE_BUG_FIXES |
---|
3782 | acMvTemp[i].hor = Clip3( -32768, 32767, acMvTemp[i].hor ); |
---|
3783 | acMvTemp[i].ver = Clip3( -32768, 32767, acMvTemp[i].ver ); |
---|
3784 | acMvTemp[i].roundMV2SignalPrecision(); |
---|
3785 | #endif |
---|
3786 | clipMv(acMvTemp[i], pu.cu->lumaPos(), *pu.cs->sps); |
---|
3787 | } |
---|
3788 | #if !JVET_K_AFFINE_BUG_FIXES |
---|
3789 | int vx2, vy2; |
---|
3790 | vx2 = - ( acMvTemp[1].getVer() - acMvTemp[0].getVer() ) * height / width + acMvTemp[0].getHor(); |
---|
3791 | vy2 = ( acMvTemp[1].getHor() - acMvTemp[0].getHor() ) * height / width + acMvTemp[0].getVer(); |
---|
3792 | acMvTemp[2].set( vx2, vy2 ); |
---|
3793 | clipMv(acMvTemp[2], pu.cu->lumaPos(), *pu.cs->sps); |
---|
3794 | #endif |
---|
3795 | xPredAffineBlk( COMPONENT_Y, pu, refPic, acMvTemp, predBuf, false, pu.cu->slice->clpRng( COMPONENT_Y ) ); |
---|
3796 | |
---|
3797 | // get error |
---|
3798 | Distortion uiCostTemp = m_pcRdCost->getDistPart( predBuf.Y(), pBuf->Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, DF_HAD ); |
---|
3799 | DTRACE( g_trace_ctx, D_COMMON, " (%d) uiCostTemp=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiCostTemp ); |
---|
3800 | |
---|
3801 | // get cost with mv |
---|
3802 | m_pcRdCost->setCostScale(0); |
---|
3803 | uint32_t uiBitsTemp = ruiBits; |
---|
3804 | #if JVET_K0185_AFFINE_6PARA_ENC |
---|
3805 | for ( int i = 0; i < mvNum; i++ ) |
---|
3806 | #else |
---|
3807 | for ( int i=0; i<2; i++ ) |
---|
3808 | #endif |
---|
3809 | { |
---|
3810 | m_pcRdCost->setPredictor( acMvPred[i] ); |
---|
3811 | const int shift = acMvTemp[i].highPrec ? VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE : 0; |
---|
3812 | #if JVET_K0337_AFFINE_MVD_PREDICTION |
---|
3813 | Mv secondPred; |
---|
3814 | if ( i != 0 ) |
---|
3815 | { |
---|
3816 | secondPred = acMvPred[i] + (acMvTemp[0] - acMvPred[0]); |
---|
3817 | m_pcRdCost->setPredictor( secondPred ); |
---|
3818 | } |
---|
3819 | #endif |
---|
3820 | #if JVET_K0357_AMVR |
---|
3821 | uiBitsTemp += m_pcRdCost->getBitsOfVectorWithPredictor( acMvTemp[i].getHor()>>shift, acMvTemp[i].getVer()>>shift, 0 ); |
---|
3822 | #else |
---|
3823 | uiBitsTemp += m_pcRdCost->getBitsOfVectorWithPredictor( acMvTemp[i].getHor() >> shift, acMvTemp[i].getVer() >> shift ); |
---|
3824 | #endif |
---|
3825 | } |
---|
3826 | |
---|
3827 | uiCostTemp = (Distortion)( floor( fWeight * (double)uiCostTemp ) + (double)m_pcRdCost->getCost( uiBitsTemp ) ); |
---|
3828 | |
---|
3829 | // store best cost and mv |
---|
3830 | if ( uiCostTemp < uiCostBest ) |
---|
3831 | { |
---|
3832 | uiCostBest = uiCostTemp; |
---|
3833 | uiBitsBest = uiBitsTemp; |
---|
3834 | memcpy( acMv, acMvTemp, sizeof(Mv) * 3 ); |
---|
3835 | } |
---|
3836 | } |
---|
3837 | |
---|
3838 | // free buffer |
---|
3839 | for ( int i=0; i<iParaNum; i++ ) |
---|
3840 | delete []pdEqualCoeff[i]; |
---|
3841 | delete []pdEqualCoeff; |
---|
3842 | |
---|
3843 | ruiBits = uiBitsBest; |
---|
3844 | ruiCost = uiCostBest; |
---|
3845 | DTRACE( g_trace_ctx, D_COMMON, " (%d) uiBitsBest=%d, uiCostBest=%d\n", DTRACE_GET_COUNTER(g_trace_ctx,D_COMMON), uiBitsBest, uiCostBest ); |
---|
3846 | |
---|
3847 | } |
---|
3848 | |
---|
3849 | void InterSearch::xEstimateAffineAMVP( PredictionUnit& pu, |
---|
3850 | AffineAMVPInfo& affineAMVPInfo, |
---|
3851 | PelUnitBuf& origBuf, |
---|
3852 | RefPicList eRefPicList, |
---|
3853 | int iRefIdx, |
---|
3854 | Mv acMvPred[3], |
---|
3855 | Distortion* puiDistBiP ) |
---|
3856 | { |
---|
3857 | Mv bestMvLT, bestMvRT, bestMvLB; |
---|
3858 | int iBestIdx = 0; |
---|
3859 | Distortion uiBestCost = std::numeric_limits<Distortion>::max(); |
---|
3860 | |
---|
3861 | // Fill the MV Candidates |
---|
3862 | PU::fillAffineMvpCand( pu, eRefPicList, iRefIdx, affineAMVPInfo ); |
---|
3863 | CHECK( affineAMVPInfo.numCand == 0, "Assertion failed." ); |
---|
3864 | |
---|
3865 | PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) ); |
---|
3866 | |
---|
3867 | // initialize Mvp index & Mvp |
---|
3868 | iBestIdx = 0; |
---|
3869 | for( int i = 0 ; i < affineAMVPInfo.numCand; i++ ) |
---|
3870 | { |
---|
3871 | Mv mv[3] = { affineAMVPInfo.mvCandLT[i], affineAMVPInfo.mvCandRT[i], affineAMVPInfo.mvCandLB[i] }; |
---|
3872 | Mv mvTrace[3] = { affineAMVPInfo.mvCandLT[i], affineAMVPInfo.mvCandRT[i], affineAMVPInfo.mvCandLB[i] }; |
---|
3873 | mvTrace[0].setHighPrec(); |
---|
3874 | mvTrace[1].setHighPrec(); |
---|
3875 | mvTrace[2].setHighPrec(); |
---|
3876 | |
---|
3877 | Distortion uiTmpCost = xGetAffineTemplateCost( pu, origBuf, predBuf, mv, i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx ); |
---|
3878 | |
---|
3879 | if ( uiBestCost > uiTmpCost ) |
---|
3880 | { |
---|
3881 | uiBestCost = uiTmpCost; |
---|
3882 | bestMvLT = affineAMVPInfo.mvCandLT[i]; |
---|
3883 | bestMvRT = affineAMVPInfo.mvCandRT[i]; |
---|
3884 | bestMvLB = affineAMVPInfo.mvCandLB[i]; |
---|
3885 | iBestIdx = i; |
---|
3886 | *puiDistBiP = uiTmpCost; |
---|
3887 | } |
---|
3888 | } |
---|
3889 | |
---|
3890 | // Setting Best MVP |
---|
3891 | acMvPred[0] = bestMvLT; |
---|
3892 | acMvPred[1] = bestMvRT; |
---|
3893 | acMvPred[2] = bestMvLB; |
---|
3894 | |
---|
3895 | pu.mvpIdx[eRefPicList] = iBestIdx; |
---|
3896 | pu.mvpNum[eRefPicList] = affineAMVPInfo.numCand; |
---|
3897 | DTRACE( g_trace_ctx, D_COMMON, "#estAffi=%d \n", affineAMVPInfo.numCand ); |
---|
3898 | } |
---|
3899 | |
---|
3900 | void InterSearch::xCopyAffineAMVPInfo (AffineAMVPInfo& src, AffineAMVPInfo& dst) |
---|
3901 | { |
---|
3902 | dst.numCand = src.numCand; |
---|
3903 | DTRACE( g_trace_ctx, D_COMMON, " (%d) #copyAffi=%d \n", DTRACE_GET_COUNTER( g_trace_ctx, D_COMMON ), src.numCand ); |
---|
3904 | ::memcpy( dst.mvCandLT, src.mvCandLT, sizeof(Mv)*src.numCand ); |
---|
3905 | ::memcpy( dst.mvCandRT, src.mvCandRT, sizeof(Mv)*src.numCand ); |
---|
3906 | ::memcpy( dst.mvCandLB, src.mvCandLB, sizeof(Mv)*src.numCand ); |
---|
3907 | } |
---|
3908 | #endif |
---|
3909 | |
---|
3910 | |
---|
3911 | /** |
---|
3912 | * \brief Generate half-sample interpolated block |
---|
3913 | * |
---|
3914 | * \param pattern Reference picture ROI |
---|
3915 | * \param biPred Flag indicating whether block is for biprediction |
---|
3916 | */ |
---|
3917 | void InterSearch::xExtDIFUpSamplingH( CPelBuf* pattern ) |
---|
3918 | { |
---|
3919 | const ClpRng& clpRng = m_lumaClpRng; |
---|
3920 | int width = pattern->width; |
---|
3921 | int height = pattern->height; |
---|
3922 | int srcStride = pattern->stride; |
---|
3923 | |
---|
3924 | int intStride = width + 1; |
---|
3925 | int dstStride = width + 1; |
---|
3926 | Pel *intPtr; |
---|
3927 | Pel *dstPtr; |
---|
3928 | int filterSize = NTAPS_LUMA; |
---|
3929 | int halfFilterSize = (filterSize>>1); |
---|
3930 | const Pel *srcPtr = pattern->buf - halfFilterSize*srcStride - 1; |
---|
3931 | |
---|
3932 | const ChromaFormat chFmt = m_currChromaFormat; |
---|
3933 | |
---|
3934 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
3935 | m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[0][0], intStride, width + 1, height + filterSize, 0 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, chFmt, clpRng); |
---|
3936 | m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[2][0], intStride, width + 1, height + filterSize, 2 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, chFmt, clpRng); |
---|
3937 | |
---|
3938 | intPtr = m_filteredBlockTmp[0][0] + halfFilterSize * intStride + 1; |
---|
3939 | dstPtr = m_filteredBlock[0][0][0]; |
---|
3940 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 0, height + 0, 0 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
3941 | |
---|
3942 | intPtr = m_filteredBlockTmp[0][0] + (halfFilterSize - 1) * intStride + 1; |
---|
3943 | dstPtr = m_filteredBlock[2][0][0]; |
---|
3944 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 0, height + 1, 2 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
3945 | |
---|
3946 | intPtr = m_filteredBlockTmp[2][0] + halfFilterSize * intStride; |
---|
3947 | dstPtr = m_filteredBlock[0][2][0]; |
---|
3948 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 1, height + 0, 0 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
3949 | |
---|
3950 | intPtr = m_filteredBlockTmp[2][0] + (halfFilterSize - 1) * intStride; |
---|
3951 | dstPtr = m_filteredBlock[2][2][0]; |
---|
3952 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 1, height + 1, 2 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
3953 | #else |
---|
3954 | m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[0][0], intStride, width + 1, height + filterSize, 0, false, chFmt, clpRng); |
---|
3955 | m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, m_filteredBlockTmp[2][0], intStride, width + 1, height + filterSize, 2, false, chFmt, clpRng); |
---|
3956 | |
---|
3957 | intPtr = m_filteredBlockTmp[0][0] + halfFilterSize * intStride + 1; |
---|
3958 | dstPtr = m_filteredBlock[0][0][0]; |
---|
3959 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 0, height + 0, 0, false, true, chFmt, clpRng); |
---|
3960 | |
---|
3961 | intPtr = m_filteredBlockTmp[0][0] + (halfFilterSize - 1) * intStride + 1; |
---|
3962 | dstPtr = m_filteredBlock[2][0][0]; |
---|
3963 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 0, height + 1, 2, false, true, chFmt, clpRng); |
---|
3964 | |
---|
3965 | intPtr = m_filteredBlockTmp[2][0] + halfFilterSize * intStride; |
---|
3966 | dstPtr = m_filteredBlock[0][2][0]; |
---|
3967 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 1, height + 0, 0, false, true, chFmt, clpRng); |
---|
3968 | |
---|
3969 | intPtr = m_filteredBlockTmp[2][0] + (halfFilterSize - 1) * intStride; |
---|
3970 | dstPtr = m_filteredBlock[2][2][0]; |
---|
3971 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width + 1, height + 1, 2, false, true, chFmt, clpRng); |
---|
3972 | #endif |
---|
3973 | } |
---|
3974 | |
---|
3975 | |
---|
3976 | |
---|
3977 | |
---|
3978 | |
---|
3979 | /** |
---|
3980 | * \brief Generate quarter-sample interpolated blocks |
---|
3981 | * |
---|
3982 | * \param pattern Reference picture ROI |
---|
3983 | * \param halfPelRef Half-pel mv |
---|
3984 | * \param biPred Flag indicating whether block is for biprediction |
---|
3985 | */ |
---|
3986 | void InterSearch::xExtDIFUpSamplingQ( CPelBuf* pattern, Mv halfPelRef ) |
---|
3987 | { |
---|
3988 | const ClpRng& clpRng = m_lumaClpRng; |
---|
3989 | int width = pattern->width; |
---|
3990 | int height = pattern->height; |
---|
3991 | int srcStride = pattern->stride; |
---|
3992 | |
---|
3993 | Pel const* srcPtr; |
---|
3994 | int intStride = width + 1; |
---|
3995 | int dstStride = width + 1; |
---|
3996 | Pel *intPtr; |
---|
3997 | Pel *dstPtr; |
---|
3998 | int filterSize = NTAPS_LUMA; |
---|
3999 | |
---|
4000 | int halfFilterSize = (filterSize>>1); |
---|
4001 | |
---|
4002 | int extHeight = (halfPelRef.getVer() == 0) ? height + filterSize : height + filterSize-1; |
---|
4003 | |
---|
4004 | const ChromaFormat chFmt = m_currChromaFormat; |
---|
4005 | |
---|
4006 | // Horizontal filter 1/4 |
---|
4007 | srcPtr = pattern->buf - halfFilterSize * srcStride - 1; |
---|
4008 | intPtr = m_filteredBlockTmp[1][0]; |
---|
4009 | if (halfPelRef.getVer() > 0) |
---|
4010 | { |
---|
4011 | srcPtr += srcStride; |
---|
4012 | } |
---|
4013 | if (halfPelRef.getHor() >= 0) |
---|
4014 | { |
---|
4015 | srcPtr += 1; |
---|
4016 | } |
---|
4017 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4018 | m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 1 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, chFmt, clpRng); |
---|
4019 | #else |
---|
4020 | m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 1, false, chFmt, clpRng); |
---|
4021 | #endif |
---|
4022 | |
---|
4023 | // Horizontal filter 3/4 |
---|
4024 | srcPtr = pattern->buf - halfFilterSize*srcStride - 1; |
---|
4025 | intPtr = m_filteredBlockTmp[3][0]; |
---|
4026 | if (halfPelRef.getVer() > 0) |
---|
4027 | { |
---|
4028 | srcPtr += srcStride; |
---|
4029 | } |
---|
4030 | if (halfPelRef.getHor() > 0) |
---|
4031 | { |
---|
4032 | srcPtr += 1; |
---|
4033 | } |
---|
4034 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4035 | m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 3 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, chFmt, clpRng); |
---|
4036 | #else |
---|
4037 | m_if.filterHor(COMPONENT_Y, srcPtr, srcStride, intPtr, intStride, width, extHeight, 3, false, chFmt, clpRng); |
---|
4038 | #endif |
---|
4039 | |
---|
4040 | // Generate @ 1,1 |
---|
4041 | intPtr = m_filteredBlockTmp[1][0] + (halfFilterSize-1) * intStride; |
---|
4042 | dstPtr = m_filteredBlock[1][1][0]; |
---|
4043 | if (halfPelRef.getVer() == 0) |
---|
4044 | { |
---|
4045 | intPtr += intStride; |
---|
4046 | } |
---|
4047 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4048 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4049 | #else |
---|
4050 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, clpRng); |
---|
4051 | #endif |
---|
4052 | |
---|
4053 | // Generate @ 3,1 |
---|
4054 | intPtr = m_filteredBlockTmp[1][0] + (halfFilterSize-1) * intStride; |
---|
4055 | dstPtr = m_filteredBlock[3][1][0]; |
---|
4056 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4057 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4058 | #else |
---|
4059 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, clpRng); |
---|
4060 | #endif |
---|
4061 | |
---|
4062 | if (halfPelRef.getVer() != 0) |
---|
4063 | { |
---|
4064 | // Generate @ 2,1 |
---|
4065 | intPtr = m_filteredBlockTmp[1][0] + (halfFilterSize - 1) * intStride; |
---|
4066 | dstPtr = m_filteredBlock[2][1][0]; |
---|
4067 | if (halfPelRef.getVer() == 0) |
---|
4068 | { |
---|
4069 | intPtr += intStride; |
---|
4070 | } |
---|
4071 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4072 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4073 | #else |
---|
4074 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2, false, true, chFmt, clpRng); |
---|
4075 | #endif |
---|
4076 | |
---|
4077 | // Generate @ 2,3 |
---|
4078 | intPtr = m_filteredBlockTmp[3][0] + (halfFilterSize - 1) * intStride; |
---|
4079 | dstPtr = m_filteredBlock[2][3][0]; |
---|
4080 | if (halfPelRef.getVer() == 0) |
---|
4081 | { |
---|
4082 | intPtr += intStride; |
---|
4083 | } |
---|
4084 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4085 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4086 | #else |
---|
4087 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 2, false, true, chFmt, clpRng); |
---|
4088 | #endif |
---|
4089 | } |
---|
4090 | else |
---|
4091 | { |
---|
4092 | // Generate @ 0,1 |
---|
4093 | intPtr = m_filteredBlockTmp[1][0] + halfFilterSize * intStride; |
---|
4094 | dstPtr = m_filteredBlock[0][1][0]; |
---|
4095 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4096 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4097 | #else |
---|
4098 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0, false, true, chFmt, clpRng); |
---|
4099 | #endif |
---|
4100 | |
---|
4101 | // Generate @ 0,3 |
---|
4102 | intPtr = m_filteredBlockTmp[3][0] + halfFilterSize * intStride; |
---|
4103 | dstPtr = m_filteredBlock[0][3][0]; |
---|
4104 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4105 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4106 | #else |
---|
4107 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 0, false, true, chFmt, clpRng); |
---|
4108 | #endif |
---|
4109 | } |
---|
4110 | |
---|
4111 | if (halfPelRef.getHor() != 0) |
---|
4112 | { |
---|
4113 | // Generate @ 1,2 |
---|
4114 | intPtr = m_filteredBlockTmp[2][0] + (halfFilterSize - 1) * intStride; |
---|
4115 | dstPtr = m_filteredBlock[1][2][0]; |
---|
4116 | if (halfPelRef.getHor() > 0) |
---|
4117 | { |
---|
4118 | intPtr += 1; |
---|
4119 | } |
---|
4120 | if (halfPelRef.getVer() >= 0) |
---|
4121 | { |
---|
4122 | intPtr += intStride; |
---|
4123 | } |
---|
4124 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4125 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4126 | #else |
---|
4127 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, clpRng); |
---|
4128 | #endif |
---|
4129 | |
---|
4130 | // Generate @ 3,2 |
---|
4131 | intPtr = m_filteredBlockTmp[2][0] + (halfFilterSize - 1) * intStride; |
---|
4132 | dstPtr = m_filteredBlock[3][2][0]; |
---|
4133 | if (halfPelRef.getHor() > 0) |
---|
4134 | { |
---|
4135 | intPtr += 1; |
---|
4136 | } |
---|
4137 | if (halfPelRef.getVer() > 0) |
---|
4138 | { |
---|
4139 | intPtr += intStride; |
---|
4140 | } |
---|
4141 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4142 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4143 | #else |
---|
4144 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, clpRng); |
---|
4145 | #endif |
---|
4146 | } |
---|
4147 | else |
---|
4148 | { |
---|
4149 | // Generate @ 1,0 |
---|
4150 | intPtr = m_filteredBlockTmp[0][0] + (halfFilterSize - 1) * intStride + 1; |
---|
4151 | dstPtr = m_filteredBlock[1][0][0]; |
---|
4152 | if (halfPelRef.getVer() >= 0) |
---|
4153 | { |
---|
4154 | intPtr += intStride; |
---|
4155 | } |
---|
4156 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4157 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4158 | #else |
---|
4159 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, clpRng); |
---|
4160 | #endif |
---|
4161 | |
---|
4162 | // Generate @ 3,0 |
---|
4163 | intPtr = m_filteredBlockTmp[0][0] + (halfFilterSize - 1) * intStride + 1; |
---|
4164 | dstPtr = m_filteredBlock[3][0][0]; |
---|
4165 | if (halfPelRef.getVer() > 0) |
---|
4166 | { |
---|
4167 | intPtr += intStride; |
---|
4168 | } |
---|
4169 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4170 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4171 | #else |
---|
4172 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, clpRng); |
---|
4173 | #endif |
---|
4174 | } |
---|
4175 | |
---|
4176 | // Generate @ 1,3 |
---|
4177 | intPtr = m_filteredBlockTmp[3][0] + (halfFilterSize - 1) * intStride; |
---|
4178 | dstPtr = m_filteredBlock[1][3][0]; |
---|
4179 | if (halfPelRef.getVer() == 0) |
---|
4180 | { |
---|
4181 | intPtr += intStride; |
---|
4182 | } |
---|
4183 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4184 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4185 | #else |
---|
4186 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 1, false, true, chFmt, clpRng); |
---|
4187 | #endif |
---|
4188 | |
---|
4189 | // Generate @ 3,3 |
---|
4190 | intPtr = m_filteredBlockTmp[3][0] + (halfFilterSize - 1) * intStride; |
---|
4191 | dstPtr = m_filteredBlock[3][3][0]; |
---|
4192 | #if JEM_TOOLS || JVET_K0346 || JVET_K_AFFINE |
---|
4193 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3 << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE, false, true, chFmt, clpRng); |
---|
4194 | #else |
---|
4195 | m_if.filterVer(COMPONENT_Y, intPtr, intStride, dstPtr, dstStride, width, height, 3, false, true, chFmt, clpRng); |
---|
4196 | #endif |
---|
4197 | } |
---|
4198 | |
---|
4199 | |
---|
4200 | |
---|
4201 | |
---|
4202 | |
---|
4203 | //! set wp tables |
---|
4204 | void InterSearch::setWpScalingDistParam( int iRefIdx, RefPicList eRefPicListCur, Slice *pcSlice ) |
---|
4205 | { |
---|
4206 | if ( iRefIdx<0 ) |
---|
4207 | { |
---|
4208 | m_cDistParam.applyWeight = false; |
---|
4209 | return; |
---|
4210 | } |
---|
4211 | |
---|
4212 | WPScalingParam *wp0 , *wp1; |
---|
4213 | |
---|
4214 | m_cDistParam.applyWeight = ( pcSlice->getSliceType()==P_SLICE && pcSlice->testWeightPred() ) || ( pcSlice->getSliceType()==B_SLICE && pcSlice->testWeightBiPred() ) ; |
---|
4215 | |
---|
4216 | if ( !m_cDistParam.applyWeight ) |
---|
4217 | { |
---|
4218 | return; |
---|
4219 | } |
---|
4220 | |
---|
4221 | int iRefIdx0 = ( eRefPicListCur == REF_PIC_LIST_0 ) ? iRefIdx : (-1); |
---|
4222 | int iRefIdx1 = ( eRefPicListCur == REF_PIC_LIST_1 ) ? iRefIdx : (-1); |
---|
4223 | |
---|
4224 | getWpScaling( pcSlice, iRefIdx0, iRefIdx1, wp0 , wp1 ); |
---|
4225 | |
---|
4226 | if ( iRefIdx0 < 0 ) |
---|
4227 | { |
---|
4228 | wp0 = NULL; |
---|
4229 | } |
---|
4230 | if ( iRefIdx1 < 0 ) |
---|
4231 | { |
---|
4232 | wp1 = NULL; |
---|
4233 | } |
---|
4234 | |
---|
4235 | m_cDistParam.wpCur = NULL; |
---|
4236 | |
---|
4237 | if ( eRefPicListCur == REF_PIC_LIST_0 ) |
---|
4238 | { |
---|
4239 | m_cDistParam.wpCur = wp0; |
---|
4240 | } |
---|
4241 | else |
---|
4242 | { |
---|
4243 | m_cDistParam.wpCur = wp1; |
---|
4244 | } |
---|
4245 | } |
---|
4246 | |
---|
4247 | void InterSearch::xEncodeInterResidualQT(CodingStructure &cs, Partitioner &partitioner, const ComponentID &compID) |
---|
4248 | { |
---|
4249 | const UnitArea& currArea = partitioner.currArea(); |
---|
4250 | const TransformUnit &currTU = *cs.getTU(currArea.lumaPos(), partitioner.chType); |
---|
4251 | const CodingUnit &cu = *currTU.cu; |
---|
4252 | #if ENABLE_BMS |
---|
4253 | const unsigned currDepth = partitioner.currTrDepth; |
---|
4254 | |
---|
4255 | const bool bSubdiv = currDepth != currTU.depth; |
---|
4256 | #endif |
---|
4257 | |
---|
4258 | if (compID == MAX_NUM_TBLOCKS) // we are not processing a channel, instead we always recurse and code the CBFs |
---|
4259 | { |
---|
4260 | #if ENABLE_BMS |
---|
4261 | if( cs.pcv->noRQT ) |
---|
4262 | { |
---|
4263 | #if ENABLE_BMS |
---|
4264 | if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) ) |
---|
4265 | { |
---|
4266 | CHECK( !bSubdiv, "Not performing the implicit TU split" ); |
---|
4267 | } |
---|
4268 | else |
---|
4269 | #endif |
---|
4270 | CHECK( bSubdiv, "transformsplit not supported" ); |
---|
4271 | } |
---|
4272 | #endif |
---|
4273 | CHECK(CU::isIntra(cu), "Inter search provided with intra CU"); |
---|
4274 | |
---|
4275 | if( cu.chromaFormat != CHROMA_400 ) |
---|
4276 | { |
---|
4277 | #if ENABLE_BMS |
---|
4278 | const bool firstCbfOfCU = ( currDepth == 0 ); |
---|
4279 | { |
---|
4280 | if( firstCbfOfCU || TU::getCbfAtDepth( currTU, COMPONENT_Cb, currDepth - 1 ) ) |
---|
4281 | { |
---|
4282 | const bool chroma_cbf = TU::getCbfAtDepth( currTU, COMPONENT_Cb, currDepth ); |
---|
4283 | m_CABACEstimator->cbf_comp( cs, chroma_cbf, currArea.blocks[COMPONENT_Cb], currDepth ); |
---|
4284 | } |
---|
4285 | if( firstCbfOfCU || TU::getCbfAtDepth( currTU, COMPONENT_Cr, currDepth - 1 ) ) |
---|
4286 | { |
---|
4287 | const bool chroma_cbf = TU::getCbfAtDepth( currTU, COMPONENT_Cr, currDepth ); |
---|
4288 | #if JVET_K0072 |
---|
4289 | m_CABACEstimator->cbf_comp( cs, chroma_cbf, currArea.blocks[COMPONENT_Cr], currDepth, TU::getCbfAtDepth( currTU, COMPONENT_Cb, currDepth ) ); |
---|
4290 | #else |
---|
4291 | m_CABACEstimator->cbf_comp( cs, chroma_cbf, currArea.blocks[COMPONENT_Cr], currDepth ); |
---|
4292 | #endif |
---|
4293 | } |
---|
4294 | } |
---|
4295 | } |
---|
4296 | |
---|
4297 | if( !bSubdiv ) |
---|
4298 | { |
---|
4299 | m_CABACEstimator->cbf_comp( cs, TU::getCbfAtDepth( currTU, COMPONENT_Y, currDepth ), currArea.Y(), currDepth ); |
---|
4300 | } |
---|
4301 | #else |
---|
4302 | m_CABACEstimator->cbf_comp( cs, TU::getCbf( currTU, COMPONENT_Cb ), currArea.blocks[COMPONENT_Cb] ); |
---|
4303 | #if JVET_K0072 |
---|
4304 | m_CABACEstimator->cbf_comp( cs, TU::getCbf( currTU, COMPONENT_Cr ), currArea.blocks[COMPONENT_Cr], TU::getCbf( currTU, COMPONENT_Cb ) ); |
---|
4305 | #else |
---|
4306 | m_CABACEstimator->cbf_comp( cs, TU::getCbf( currTU, COMPONENT_Cr ), currArea.blocks[COMPONENT_Cr] ); |
---|
4307 | #endif |
---|
4308 | } |
---|
4309 | |
---|
4310 | m_CABACEstimator->cbf_comp( cs, TU::getCbf( currTU, COMPONENT_Y ), currArea.Y() ); |
---|
4311 | #endif |
---|
4312 | } |
---|
4313 | |
---|
4314 | #if ENABLE_BMS |
---|
4315 | if (!bSubdiv) |
---|
4316 | #endif |
---|
4317 | { |
---|
4318 | if (compID != MAX_NUM_TBLOCKS) // we have already coded the CBFs, so now we code coefficients |
---|
4319 | { |
---|
4320 | if( currArea.blocks[compID].valid() ) |
---|
4321 | { |
---|
4322 | if( TU::hasCrossCompPredInfo( currTU, compID ) ) |
---|
4323 | { |
---|
4324 | m_CABACEstimator->cross_comp_pred( currTU, compID ); |
---|
4325 | } |
---|
4326 | if( TU::getCbf( currTU, compID ) ) |
---|
4327 | { |
---|
4328 | m_CABACEstimator->residual_coding( currTU, compID ); |
---|
4329 | } |
---|
4330 | } |
---|
4331 | } |
---|
4332 | } |
---|
4333 | #if ENABLE_BMS |
---|
4334 | else |
---|
4335 | { |
---|
4336 | if( compID == MAX_NUM_TBLOCKS || TU::getCbfAtDepth( currTU, compID, currDepth ) ) |
---|
4337 | { |
---|
4338 | #if ENABLE_BMS |
---|
4339 | if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) ) |
---|
4340 | { |
---|
4341 | partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs ); |
---|
4342 | } |
---|
4343 | else |
---|
4344 | #endif |
---|
4345 | THROW( "Implicit TU split not available!" ); |
---|
4346 | |
---|
4347 | do |
---|
4348 | { |
---|
4349 | xEncodeInterResidualQT( cs, partitioner, compID ); |
---|
4350 | } while( partitioner.nextPart( cs ) ); |
---|
4351 | |
---|
4352 | partitioner.exitCurrSplit(); |
---|
4353 | } |
---|
4354 | } |
---|
4355 | #endif |
---|
4356 | #if JEM_TOOLS && !HM_EMT_NSST_AS_IN_JEM |
---|
4357 | |
---|
4358 | #if ENABLE_BMS |
---|
4359 | if( isLuma( compID ) && currDepth == 0 ) |
---|
4360 | #else |
---|
4361 | if( isLuma( compID ) ) |
---|
4362 | #endif |
---|
4363 | { |
---|
4364 | m_CABACEstimator->cu_emt_pertu_idx( cu ); |
---|
4365 | } |
---|
4366 | #endif |
---|
4367 | } |
---|
4368 | |
---|
4369 | void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &partitioner, Distortion *puiZeroDist /*= NULL*/) |
---|
4370 | { |
---|
4371 | const UnitArea& currArea = partitioner.currArea(); |
---|
4372 | const SPS &sps = *cs.sps; |
---|
4373 | const PPS &pps = *cs.pps; |
---|
4374 | const uint32_t numValidComp = getNumberValidComponents( sps.getChromaFormatIdc() ); |
---|
4375 | const uint32_t numTBlocks = getNumberValidTBlocks ( *cs.pcv ); |
---|
4376 | #if ENABLE_BMS |
---|
4377 | const unsigned currDepth = partitioner.currTrDepth; |
---|
4378 | |
---|
4379 | bool bCheckSplit = false, bCheckFull = false; |
---|
4380 | #if ENABLE_BMS |
---|
4381 | if( cs.pcv->noRQT ) |
---|
4382 | { |
---|
4383 | bCheckFull = !partitioner.canSplit( TU_MAX_TR_SPLIT, cs ); |
---|
4384 | bCheckSplit = !bCheckFull; |
---|
4385 | } |
---|
4386 | #endif |
---|
4387 | |
---|
4388 | // get temporary data |
---|
4389 | CodingStructure *csSplit = nullptr; |
---|
4390 | CodingStructure *csFull = nullptr; |
---|
4391 | if (bCheckSplit) |
---|
4392 | { |
---|
4393 | csSplit = &cs; |
---|
4394 | } |
---|
4395 | else if (bCheckFull) |
---|
4396 | { |
---|
4397 | csFull = &cs; |
---|
4398 | } |
---|
4399 | #else |
---|
4400 | bool bCheckFull = true; |
---|
4401 | CodingStructure *csFull = &cs; |
---|
4402 | #endif |
---|
4403 | |
---|
4404 | Distortion uiSingleDist = 0; |
---|
4405 | Distortion uiSingleDistComp [3] = { 0, 0, 0 }; |
---|
4406 | TCoeff uiAbsSum [3] = { 0, 0, 0 }; |
---|
4407 | |
---|
4408 | const TempCtx ctxStart ( m_CtxCache, m_CABACEstimator->getCtx() ); |
---|
4409 | TempCtx ctxBest ( m_CtxCache ); |
---|
4410 | |
---|
4411 | if (bCheckFull) |
---|
4412 | { |
---|
4413 | TransformUnit &tu = csFull->addTU(currArea, partitioner.chType); |
---|
4414 | #if ENABLE_BMS |
---|
4415 | tu.depth = currDepth; |
---|
4416 | #endif |
---|
4417 | #if JEM_TOOLS || JVET_K1000_SIMPLIFIED_EMT |
---|
4418 | tu.emtIdx = 0; |
---|
4419 | #endif |
---|
4420 | |
---|
4421 | double minCost [MAX_NUM_TBLOCKS]; |
---|
4422 | bool checkTransformSkip [MAX_NUM_TBLOCKS]; |
---|
4423 | |
---|
4424 | m_CABACEstimator->resetBits(); |
---|
4425 | |
---|
4426 | memset(m_pTempPel, 0, sizeof(Pel) * tu.Y().area()); // not necessary needed for inside of recursion (only at the beginning) |
---|
4427 | |
---|
4428 | for (uint32_t i = 0; i < numTBlocks; i++) |
---|
4429 | { |
---|
4430 | minCost[i] = MAX_DOUBLE; |
---|
4431 | } |
---|
4432 | |
---|
4433 | CodingStructure &saveCS = *m_pSaveCS[0]; |
---|
4434 | saveCS.pcv = cs.pcv; |
---|
4435 | saveCS.picture = cs.picture; |
---|
4436 | saveCS.area.repositionTo(currArea); |
---|
4437 | saveCS.clearTUs(); |
---|
4438 | |
---|
4439 | TransformUnit &bestTU = saveCS.addTU( currArea, partitioner.chType ); |
---|
4440 | |
---|
4441 | |
---|
4442 | for( uint32_t c = 0; c < numTBlocks; c++ ) |
---|
4443 | { |
---|
4444 | const ComponentID compID = ComponentID(c); |
---|
4445 | const CompArea& compArea = tu.blocks[compID]; |
---|
4446 | const int channelBitDepth = sps.getBitDepth(toChannelType(compID)); |
---|
4447 | |
---|
4448 | checkTransformSkip[compID] = false; |
---|
4449 | |
---|
4450 | if( !tu.blocks[compID].valid() ) |
---|
4451 | { |
---|
4452 | continue; |
---|
4453 | } |
---|
4454 | |
---|
4455 | checkTransformSkip[compID] = pps.getUseTransformSkip() && TU::hasTransformSkipFlag( *tu.cs, tu.blocks[compID] ) && !cs.isLossless; |
---|
4456 | #if JEM_TOOLS || JVET_K1000_SIMPLIFIED_EMT |
---|
4457 | if( isLuma(compID) ) |
---|
4458 | { |
---|
4459 | checkTransformSkip[compID] &= !tu.cu->emtFlag; |
---|
4460 | } |
---|
4461 | #endif |
---|
4462 | |
---|
4463 | const bool isCrossCPredictionAvailable = TU::hasCrossCompPredInfo( tu, compID ); |
---|
4464 | |
---|
4465 | int8_t preCalcAlpha = 0; |
---|
4466 | const CPelBuf lumaResi = csFull->getResiBuf(tu.Y()); |
---|
4467 | |
---|
4468 | if (isCrossCPredictionAvailable) |
---|
4469 | { |
---|
4470 | csFull->getResiBuf( compArea ).copyFrom( cs.getOrgResiBuf( compArea ) ); |
---|
4471 | preCalcAlpha = xCalcCrossComponentPredictionAlpha( tu, compID, m_pcEncCfg->getUseReconBasedCrossCPredictionEstimate() ); |
---|
4472 | } |
---|
4473 | |
---|
4474 | const int crossCPredictionModesToTest = preCalcAlpha != 0 ? 2 : 1; |
---|
4475 | #if JEM_TOOLS || JVET_K1000_SIMPLIFIED_EMT |
---|
4476 | const int numEmtTransformCandidates = isLuma(compID) && tu.cu->emtFlag && sps.getSpsNext().getUseInterEMT() ? 4 : 1; |
---|
4477 | const int numTransformCandidates = checkTransformSkip[compID] ? ( numEmtTransformCandidates + 1 ) : numEmtTransformCandidates; |
---|
4478 | #else |
---|
4479 | const int numTransformCandidates = checkTransformSkip[compID] ? 2 : 1; |
---|
4480 | #endif |
---|
4481 | int lastTransformModeIndex = numTransformCandidates - 1; //lastTransformModeIndex is the mode for transformSkip (if transformSkip is active) |
---|
4482 | const bool isOneMode = crossCPredictionModesToTest == 1 && numTransformCandidates == 1; |
---|
4483 | |
---|
4484 | bool isLastBest = isOneMode; |
---|
4485 | for( int transformMode = 0; transformMode < numTransformCandidates; transformMode++ ) |
---|
4486 | { |
---|
4487 | for( int crossCPredictionModeId = 0; crossCPredictionModeId < crossCPredictionModesToTest; crossCPredictionModeId++ ) |
---|
4488 | { |
---|
4489 | const bool isFirstMode = transformMode == 0 && crossCPredictionModeId == 0; |
---|
4490 | const bool isLastMode = ( transformMode + 1 ) == numTransformCandidates && ( crossCPredictionModeId + 1 ) == crossCPredictionModesToTest; |
---|
4491 | const bool bUseCrossCPrediction = crossCPredictionModeId != 0; |
---|
4492 | |
---|
4493 | // copy the original residual into the residual buffer |
---|
4494 | csFull->getResiBuf(compArea).copyFrom(cs.getOrgResiBuf(compArea)); |
---|
4495 | |
---|
4496 | m_CABACEstimator->getCtx() = ctxStart; |
---|
4497 | m_CABACEstimator->resetBits(); |
---|
4498 | |
---|
4499 | #if JEM_TOOLS || JVET_K1000_SIMPLIFIED_EMT |
---|
4500 | if( isLuma( compID ) ) tu.emtIdx = transformMode; |
---|
4501 | #endif |
---|
4502 | tu.transformSkip[compID] = checkTransformSkip[compID] && transformMode == lastTransformModeIndex; |
---|
4503 | tu.compAlpha[compID] = bUseCrossCPrediction ? preCalcAlpha : 0; |
---|
4504 | |
---|
4505 | const QpParam cQP(tu, compID); // note: uses tu.transformSkip[compID] |
---|
4506 | |
---|
4507 | #if RDOQ_CHROMA_LAMBDA |
---|
4508 | m_pcTrQuant->selectLambda(compID); |
---|
4509 | #endif |
---|
4510 | |
---|
4511 | TCoeff currAbsSum = 0; |
---|
4512 | uint64_t currCompFracBits = 0; |
---|
4513 | Distortion currCompDist = 0; |
---|
4514 | double currCompCost = 0; |
---|
4515 | uint64_t nonCoeffFracBits = 0; |
---|
4516 | Distortion nonCoeffDist = 0; |
---|
4517 | double nonCoeffCost = 0; |
---|
4518 | |
---|
4519 | if (bUseCrossCPrediction) |
---|
4520 | { |
---|
4521 | PelBuf resiBuf = csFull->getResiBuf( compArea ); |
---|
4522 | crossComponentPrediction( tu, compID, lumaResi, resiBuf, resiBuf, false ); |
---|
4523 | } |
---|
4524 | |
---|
4525 | m_pcTrQuant->transformNxN(tu, compID, cQP, currAbsSum, m_CABACEstimator->getCtx()); |
---|
4526 | |
---|
4527 | if (isFirstMode || (currAbsSum == 0)) |
---|
4528 | { |
---|
4529 | const CPelBuf zeroBuf(m_pTempPel, compArea); |
---|
4530 | const CPelBuf orgResi = csFull->getOrgResiBuf( compArea ); |
---|
4531 | |
---|
4532 | if (bUseCrossCPrediction) |
---|
4533 | { |
---|
4534 | PelBuf resi = csFull->getResiBuf( compArea ); |
---|
4535 | crossComponentPrediction( tu, compID, lumaResi, zeroBuf, resi, true ); |
---|
4536 | nonCoeffDist = m_pcRdCost->getDistPart( orgResi, resi, channelBitDepth, compID, DF_SSE ); |
---|
4537 | } |
---|
4538 | else |
---|
4539 | { |
---|
4540 | nonCoeffDist = m_pcRdCost->getDistPart( zeroBuf, orgResi, channelBitDepth, compID, DF_SSE ); // initialized with zero residual distortion |
---|
4541 | } |
---|
4542 | |
---|
4543 | #if JVET_K0072 |
---|
4544 | const bool prevCbf = ( compID == COMPONENT_Cr ? tu.cbf[COMPONENT_Cb] : false ); |
---|
4545 | #if ENABLE_BMS |
---|
4546 | m_CABACEstimator->cbf_comp( *csFull, false, compArea, currDepth, prevCbf ); |
---|
4547 | #else |
---|
4548 | m_CABACEstimator->cbf_comp( *csFull, false, compArea, prevCbf ); |
---|
4549 | #endif |
---|
4550 | #else |
---|
4551 | #if ENABLE_BMS |
---|
4552 | m_CABACEstimator->cbf_comp( *csFull, false, compArea, currDepth ); |
---|
4553 | #else |
---|
4554 | m_CABACEstimator->cbf_comp( *csFull, false, compArea ); |
---|
4555 | #endif |
---|
4556 | #endif |
---|
4557 | |
---|
4558 | if( isCrossCPredictionAvailable ) |
---|
4559 | { |
---|
4560 | m_CABACEstimator->cross_comp_pred( tu, compID ); |
---|
4561 | } |
---|
4562 | |
---|
4563 | nonCoeffFracBits = m_CABACEstimator->getEstFracBits(); |
---|
4564 | #if WCG_EXT |
---|
4565 | if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() ) |
---|
4566 | { |
---|
4567 | nonCoeffCost = m_pcRdCost->calcRdCost(nonCoeffFracBits, nonCoeffDist, false); |
---|
4568 | } |
---|
4569 | else |
---|
4570 | #endif |
---|
4571 | nonCoeffCost = m_pcRdCost->calcRdCost(nonCoeffFracBits, nonCoeffDist); |
---|
4572 | } |
---|
4573 | |
---|
4574 | if ((puiZeroDist != NULL) && isFirstMode) |
---|
4575 | { |
---|
4576 | *puiZeroDist += nonCoeffDist; // initialized with zero residual distortion |
---|
4577 | } |
---|
4578 | |
---|
4579 | if (currAbsSum > 0) //if non-zero coefficients are present, a residual needs to be derived for further prediction |
---|
4580 | { |
---|
4581 | if (isFirstMode) |
---|
4582 | { |
---|
4583 | m_CABACEstimator->getCtx() = ctxStart; |
---|
4584 | m_CABACEstimator->resetBits(); |
---|
4585 | } |
---|
4586 | |
---|
4587 | #if JVET_K0072 |
---|
4588 | const bool prevCbf = ( compID == COMPONENT_Cr ? tu.cbf[COMPONENT_Cb] : false ); |
---|
4589 | #if ENABLE_BMS |
---|
4590 | m_CABACEstimator->cbf_comp( *csFull, true, compArea, currDepth, prevCbf ); |
---|
4591 | #else |
---|
4592 | m_CABACEstimator->cbf_comp( *csFull, true, compArea, prevCbf ); |
---|
4593 | #endif |
---|
4594 | #else |
---|
4595 | #if ENABLE_BMS |
---|
4596 | m_CABACEstimator->cbf_comp( *csFull, true, compArea, currDepth ); |
---|
4597 | #else |
---|
4598 | m_CABACEstimator->cbf_comp( *csFull, true, compArea ); |
---|
4599 | #endif |
---|
4600 | #endif |
---|
4601 | |
---|
4602 | if( isCrossCPredictionAvailable ) |
---|
4603 | { |
---|
4604 | m_CABACEstimator->cross_comp_pred( tu, compID ); |
---|
4605 | } |
---|
4606 | m_CABACEstimator->residual_coding( tu, compID ); |
---|
4607 | |
---|
4608 | currCompFracBits = m_CABACEstimator->getEstFracBits(); |
---|
4609 | |
---|
4610 | PelBuf resiBuf = csFull->getResiBuf(compArea); |
---|
4611 | CPelBuf orgResiBuf = csFull->getOrgResiBuf(compArea); |
---|
4612 | |
---|
4613 | m_pcTrQuant->invTransformNxN(tu, compID, resiBuf, cQP); |
---|
4614 | |
---|
4615 | #if JEM_TOOLS |
---|
4616 | if( cs.sps->getSpsNext().getUseBIF() && isLuma(compID) && (tu.cu->qp > 17) && (16 > std::min(tu.lumaSize().width, tu.lumaSize().height) ) ) |
---|
4617 | { |
---|
4618 | const CPelBuf predBuf = csFull->getPredBuf(compArea); |
---|
4619 | m_bilateralFilter->bilateralFilterInter( resiBuf, predBuf, tu.cu->qp, cs.slice->clpRng( COMPONENT_Y ) ); |
---|
4620 | } |
---|
4621 | |
---|
4622 | #endif |
---|
4623 | if (bUseCrossCPrediction) |
---|
4624 | { |
---|
4625 | crossComponentPrediction( tu, compID, lumaResi, resiBuf, resiBuf, true ); |
---|
4626 | } |
---|
4627 | |
---|
4628 | currCompDist = m_pcRdCost->getDistPart(orgResiBuf, resiBuf, channelBitDepth, compID, DF_SSE); |
---|
4629 | |
---|
4630 | #if WCG_EXT |
---|
4631 | currCompCost = m_pcRdCost->calcRdCost(currCompFracBits, currCompDist, false); |
---|
4632 | #else |
---|
4633 | currCompCost = m_pcRdCost->calcRdCost(currCompFracBits, currCompDist); |
---|
4634 | #endif |
---|
4635 | |
---|
4636 | if (csFull->isLossless) |
---|
4637 | { |
---|
4638 | nonCoeffCost = MAX_DOUBLE; |
---|
4639 | } |
---|
4640 | } |
---|
4641 | else if( ( transformMode == lastTransformModeIndex ) && checkTransformSkip[compID] && !bUseCrossCPrediction ) |
---|
4642 | { |
---|
4643 | currCompCost = MAX_DOUBLE; |
---|
4644 | } |
---|
4645 | else |
---|
4646 | { |
---|
4647 | currCompFracBits = nonCoeffFracBits; |
---|
4648 | currCompDist = nonCoeffDist; |
---|
4649 | currCompCost = nonCoeffCost; |
---|
4650 | |
---|
4651 | tu.cbf[compID] = 0; |
---|
4652 | } |
---|
4653 | |
---|
4654 | // evaluate |
---|
4655 | if( ( currCompCost < minCost[compID] ) || ( transformMode == lastTransformModeIndex && checkTransformSkip[compID] && currCompCost == minCost[compID] ) ) |
---|
4656 | { |
---|
4657 | // copy component |
---|
4658 | if (isFirstMode && ((nonCoeffCost < currCompCost) || (currAbsSum == 0))) // check for forced null |
---|
4659 | { |
---|
4660 | tu.getCoeffs( compID ).fill( 0 ); |
---|
4661 | csFull->getResiBuf( compArea ).fill( 0 ); |
---|
4662 | tu.cbf[compID] = 0; |
---|
4663 | |
---|
4664 | currAbsSum = 0; |
---|
4665 | currCompFracBits = nonCoeffFracBits; |
---|
4666 | currCompDist = nonCoeffDist; |
---|
4667 | currCompCost = nonCoeffCost; |
---|
4668 | } |
---|
4669 | |
---|
4670 | uiAbsSum[compID] = currAbsSum; |
---|
4671 | uiSingleDistComp[compID] = currCompDist; |
---|
4672 | minCost[compID] = currCompCost; |
---|
4673 | |
---|
4674 | if (uiAbsSum[compID] == 0) |
---|
4675 | { |
---|
4676 | if (bUseCrossCPrediction) |
---|
4677 | { |
---|
4678 | const CPelBuf zeroBuf( m_pTempPel, compArea ); |
---|
4679 | PelBuf resiBuf = csFull->getResiBuf( compArea ); |
---|
4680 | |
---|
4681 | crossComponentPrediction( tu, compID, lumaResi, zeroBuf, resiBuf, true ); |
---|
4682 | } |
---|
4683 | } |
---|
4684 | |
---|
4685 | if( !isLastMode ) |
---|
4686 | { |
---|
4687 | bestTU.copyComponentFrom( tu, compID ); |
---|
4688 | saveCS.getResiBuf( compArea ).copyFrom( csFull->getResiBuf( compArea ) ); |
---|
4689 | } |
---|
4690 | |
---|
4691 | isLastBest = isLastMode; |
---|
4692 | } |
---|
4693 | } |
---|
4694 | } |
---|
4695 | |
---|
4696 | if( !isLastBest ) |
---|
4697 | { |
---|
4698 | // copy component |
---|
4699 | tu.copyComponentFrom( bestTU, compID ); |
---|
4700 | csFull->getResiBuf( compArea ).copyFrom( saveCS.getResiBuf( compArea ) ); |
---|
4701 | } |
---|
4702 | } // component loop |
---|
4703 | |
---|
4704 | m_CABACEstimator->getCtx() = ctxStart; |
---|
4705 | m_CABACEstimator->resetBits(); |
---|
4706 | |
---|
4707 | static const ComponentID cbf_getComp[3] = { COMPONENT_Cb, COMPONENT_Cr, COMPONENT_Y }; |
---|
4708 | for( unsigned c = 0; c < numTBlocks; c++) |
---|
4709 | { |
---|
4710 | const ComponentID compID = cbf_getComp[c]; |
---|
4711 | if( tu.blocks[compID].valid() ) |
---|
4712 | { |
---|
4713 | #if ENABLE_BMS |
---|
4714 | #if JVET_K0072 |
---|
4715 | const bool prevCbf = ( compID == COMPONENT_Cr ? TU::getCbfAtDepth( tu, COMPONENT_Cb, currDepth ) : false ); |
---|
4716 | m_CABACEstimator->cbf_comp( *csFull, TU::getCbfAtDepth( tu, compID, currDepth ), tu.blocks[compID], currDepth, prevCbf ); |
---|
4717 | #else |
---|
4718 | m_CABACEstimator->cbf_comp( *csFull, TU::getCbfAtDepth( tu, compID, currDepth ), tu.blocks[compID], currDepth ); |
---|
4719 | #endif |
---|
4720 | #else |
---|
4721 | #if JVET_K0072 |
---|
4722 | const bool prevCbf = ( compID == COMPONENT_Cr ? TU::getCbf( tu, COMPONENT_Cb ) : false ); |
---|
4723 | m_CABACEstimator->cbf_comp( *csFull, TU::getCbf( tu, compID ), tu.blocks[compID], prevCbf ); |
---|
4724 | #else |
---|
4725 | m_CABACEstimator->cbf_comp( *csFull, TU::getCbf( tu, compID ), tu.blocks[compID] ); |
---|
4726 | #endif |
---|
4727 | #endif |
---|
4728 | } |
---|
4729 | } |
---|
4730 | |
---|
4731 | for (uint32_t ch = 0; ch < numValidComp; ch++) |
---|
4732 | { |
---|
4733 | const ComponentID compID = ComponentID(ch); |
---|
4734 | |
---|
4735 | if (tu.blocks[compID].valid()) |
---|
4736 | { |
---|
4737 | if( cs.pps->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag() && isChroma(compID) && uiAbsSum[COMPONENT_Y] ) |
---|
4738 | { |
---|
4739 | m_CABACEstimator->cross_comp_pred( tu, compID ); |
---|
4740 | } |
---|
4741 | if( TU::getCbf( tu, compID ) ) |
---|
4742 | { |
---|
4743 | m_CABACEstimator->residual_coding( tu, compID ); |
---|
4744 | } |
---|
4745 | uiSingleDist += uiSingleDistComp[compID]; |
---|
4746 | } |
---|
4747 | } |
---|
4748 | |
---|
4749 | csFull->fracBits += m_CABACEstimator->getEstFracBits(); |
---|
4750 | csFull->dist += uiSingleDist; |
---|
4751 | #if WCG_EXT |
---|
4752 | if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() ) |
---|
4753 | { |
---|
4754 | csFull->cost = m_pcRdCost->calcRdCost(csFull->fracBits, csFull->dist, false); |
---|
4755 | } |
---|
4756 | else |
---|
4757 | #endif |
---|
4758 | csFull->cost = m_pcRdCost->calcRdCost(csFull->fracBits, csFull->dist); |
---|
4759 | } // check full |
---|
4760 | #if ENABLE_BMS |
---|
4761 | |
---|
4762 | // code sub-blocks |
---|
4763 | if( bCheckSplit ) |
---|
4764 | { |
---|
4765 | if( bCheckFull ) |
---|
4766 | { |
---|
4767 | m_CABACEstimator->getCtx() = ctxStart; |
---|
4768 | } |
---|
4769 | |
---|
4770 | #if ENABLE_BMS |
---|
4771 | if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) ) |
---|
4772 | { |
---|
4773 | partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs ); |
---|
4774 | } |
---|
4775 | else |
---|
4776 | #endif |
---|
4777 | THROW( "Implicit TU split not available!" ); |
---|
4778 | |
---|
4779 | do |
---|
4780 | { |
---|
4781 | xEstimateInterResidualQT(*csSplit, partitioner, bCheckFull ? nullptr : puiZeroDist); |
---|
4782 | |
---|
4783 | csSplit->cost = m_pcRdCost->calcRdCost( csSplit->fracBits, csSplit->dist ); |
---|
4784 | #if JEM_TOOLS || JVET_K1000_SIMPLIFIED_EMT |
---|
4785 | if( csFull && csSplit->cost >= csFull->cost && m_pcEncCfg->getFastInterEMT() ) |
---|
4786 | { |
---|
4787 | break; |
---|
4788 | } |
---|
4789 | #endif |
---|
4790 | } while( partitioner.nextPart( *csSplit ) ); |
---|
4791 | |
---|
4792 | partitioner.exitCurrSplit(); |
---|
4793 | |
---|
4794 | unsigned anyCbfSet = 0; |
---|
4795 | unsigned compCbf[3] = { 0, 0, 0 }; |
---|
4796 | |
---|
4797 | #if JEM_TOOLS || JVET_K1000_SIMPLIFIED_EMT |
---|
4798 | bool isSplit = bCheckFull ? false : true; |
---|
4799 | if( !bCheckFull || ( csSplit->cost < csFull->cost && m_pcEncCfg->getFastInterEMT() ) || !m_pcEncCfg->getFastInterEMT() ) |
---|
4800 | #else |
---|
4801 | if( !bCheckFull ) |
---|
4802 | #endif |
---|
4803 | { |
---|
4804 | for( auto &currTU : csSplit->traverseTUs( currArea, partitioner.chType ) ) |
---|
4805 | { |
---|
4806 | for( unsigned ch = 0; ch < numTBlocks; ch++ ) |
---|
4807 | { |
---|
4808 | compCbf[ ch ] |= ( TU::getCbfAtDepth( currTU, ComponentID(ch), currDepth + 1 ) ? 1 : 0 ); |
---|
4809 | } |
---|
4810 | } |
---|
4811 | |
---|
4812 | { |
---|
4813 | |
---|
4814 | for( auto &currTU : csSplit->traverseTUs( currArea, partitioner.chType ) ) |
---|
4815 | { |
---|
4816 | TU::setCbfAtDepth ( currTU, COMPONENT_Y, currDepth, compCbf[ COMPONENT_Y ] ); |
---|
4817 | if( currArea.chromaFormat != CHROMA_400 ) |
---|
4818 | { |
---|
4819 | TU::setCbfAtDepth ( currTU, COMPONENT_Cb, currDepth, compCbf[ COMPONENT_Cb ] ); |
---|
4820 | TU::setCbfAtDepth ( currTU, COMPONENT_Cr, currDepth, compCbf[ COMPONENT_Cr ] ); |
---|
4821 | } |
---|
4822 | } |
---|
4823 | |
---|
4824 | anyCbfSet = compCbf[ COMPONENT_Y ]; |
---|
4825 | if( currArea.chromaFormat != CHROMA_400 ) |
---|
4826 | { |
---|
4827 | anyCbfSet |= compCbf[ COMPONENT_Cb ]; |
---|
4828 | anyCbfSet |= compCbf[ COMPONENT_Cr ]; |
---|
4829 | } |
---|
4830 | } |
---|
4831 | |
---|
4832 | m_CABACEstimator->getCtx() = ctxStart; |
---|
4833 | m_CABACEstimator->resetBits(); |
---|
4834 | |
---|
4835 | // when compID isn't a channel, code Cbfs: |
---|
4836 | xEncodeInterResidualQT( *csSplit, partitioner, MAX_NUM_TBLOCKS ); |
---|
4837 | for (uint32_t ch = 0; ch < numValidComp; ch++) |
---|
4838 | { |
---|
4839 | xEncodeInterResidualQT( *csSplit, partitioner, ComponentID( ch ) ); |
---|
4840 | } |
---|
4841 | |
---|
4842 | csSplit->fracBits = m_CABACEstimator->getEstFracBits(); |
---|
4843 | csSplit->cost = m_pcRdCost->calcRdCost(csSplit->fracBits, csSplit->dist); |
---|
4844 | |
---|
4845 | if( bCheckFull && anyCbfSet && csSplit->cost < csFull->cost ) |
---|
4846 | { |
---|
4847 | cs.useSubStructure( *csSplit, partitioner.chType, currArea, false, false, false, true ); |
---|
4848 | cs.cost = csSplit->cost; |
---|
4849 | #if JEM_TOOLS |
---|
4850 | isSplit = true; |
---|
4851 | #endif |
---|
4852 | } |
---|
4853 | } |
---|
4854 | |
---|
4855 | #if JEM_TOOLS || JVET_K1000_SIMPLIFIED_EMT |
---|
4856 | if( ( !isSplit && m_pcEncCfg->getFastInterEMT() ) || ( !m_pcEncCfg->getFastInterEMT() && !( !bCheckFull || ( anyCbfSet && csSplit->cost < csFull->cost ) ) ) ) |
---|
4857 | #else |
---|
4858 | if( !( !bCheckFull || ( anyCbfSet && csSplit->cost < csFull->cost ) ) ) |
---|
4859 | #endif |
---|
4860 | { |
---|
4861 | CHECK( !bCheckFull, "Error!" ); |
---|
4862 | cs.useSubStructure( *csFull, partitioner.chType, currArea, false, false, false, true ); |
---|
4863 | cs.cost = csFull->cost; |
---|
4864 | m_CABACEstimator->getCtx() = ctxBest; |
---|
4865 | } |
---|
4866 | |
---|
4867 | if( csSplit && csFull ) |
---|
4868 | { |
---|
4869 | csSplit->releaseIntermediateData(); |
---|
4870 | csFull ->releaseIntermediateData(); |
---|
4871 | } |
---|
4872 | } |
---|
4873 | #endif |
---|
4874 | } |
---|
4875 | |
---|
4876 | void InterSearch::encodeResAndCalcRdInterCU(CodingStructure &cs, Partitioner &partitioner, const bool &skipResidual) |
---|
4877 | { |
---|
4878 | CodingUnit &cu = *cs.getCU( partitioner.chType ); |
---|
4879 | |
---|
4880 | const ChromaFormat format = cs.area.chromaFormat;; |
---|
4881 | const int numValidComponents = getNumberValidComponents(format); |
---|
4882 | const SPS &sps = *cs.sps; |
---|
4883 | const PPS &pps = *cs.pps; |
---|
4884 | |
---|
4885 | if( skipResidual ) // No residual coding : SKIP mode |
---|
4886 | { |
---|
4887 | cu.skip = true; |
---|
4888 | cu.rootCbf = false; |
---|
4889 | cs.getResiBuf().fill(0); |
---|
4890 | #if JEM_TOOLS |
---|
4891 | if( sps.getSpsNext().getUseAClip() ) |
---|
4892 | { |
---|
4893 | cs.getRecoBuf().copyClip( cs.getPredBuf(), cs.slice->getClpRngs() ); |
---|
4894 | } |
---|
4895 | else |
---|
4896 | #endif |
---|
4897 | { |
---|
4898 | cs.getRecoBuf().copyFrom(cs.getPredBuf() ); |
---|
4899 | } |
---|
4900 | |
---|
4901 | |
---|
4902 | // add an empty TU |
---|
4903 | cs.addTU(cs.area, partitioner.chType); |
---|
4904 | |
---|
4905 | Distortion distortion = 0; |
---|
4906 | |
---|
4907 | for (int comp = 0; comp < numValidComponents; comp++) |
---|
4908 | { |
---|
4909 | const ComponentID compID = ComponentID(comp); |
---|
4910 | |
---|
4911 | CPelBuf reco = cs.getRecoBuf (compID); |
---|
4912 | CPelBuf org = cs.getOrgBuf (compID); |
---|
4913 | #if WCG_EXT |
---|
4914 | if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() ) |
---|
4915 | { |
---|
4916 | const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] ); |
---|
4917 | distortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma ); |
---|
4918 | } |
---|
4919 | else |
---|
4920 | #endif |
---|
4921 | distortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE ); |
---|
4922 | } |
---|
4923 | |
---|
4924 | m_CABACEstimator->resetBits(); |
---|
4925 | |
---|
4926 | if( pps.getTransquantBypassEnabledFlag() ) |
---|
4927 | { |
---|
4928 | m_CABACEstimator->cu_transquant_bypass_flag( cu ); |
---|
4929 | } |
---|
4930 | |
---|
4931 | PredictionUnit &pu = *cs.getPU( partitioner.chType ); |
---|
4932 | |
---|
4933 | m_CABACEstimator->cu_skip_flag ( cu ); |
---|
4934 | #if JEM_TOOLS |
---|
4935 | m_CABACEstimator->fruc_mrg_mode ( pu ); |
---|
4936 | m_CABACEstimator->affine_flag ( cu ); |
---|
4937 | #endif |
---|
4938 | #if !JEM_TOOLS && JVET_K_AFFINE |
---|
4939 | m_CABACEstimator->affine_flag( cu ); |
---|
4940 | #endif |
---|
4941 | m_CABACEstimator->merge_idx ( pu ); |
---|
4942 | #if !HM_LIC_MERGE_SKIP_AS_IN_JEM && JEM_TOOLS |
---|
4943 | m_CABACEstimator->cu_lic_flag ( cu ); |
---|
4944 | #endif |
---|
4945 | |
---|
4946 | |
---|
4947 | cs.dist = distortion; |
---|
4948 | cs.fracBits = m_CABACEstimator->getEstFracBits(); |
---|
4949 | cs.cost = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist); |
---|
4950 | |
---|
4951 | return; |
---|
4952 | } |
---|
4953 | |
---|
4954 | // Residual coding. |
---|
4955 | cs.getResiBuf().copyFrom (cs.getOrgBuf()); |
---|
4956 | cs.getResiBuf().subtract (cs.getPredBuf()); |
---|
4957 | |
---|
4958 | Distortion zeroDistortion = 0; |
---|
4959 | |
---|
4960 | #if JEM_TOOLS |
---|
4961 | if( m_pcEncCfg->getUseAClipEnc() ) |
---|
4962 | { |
---|
4963 | PelUnitBuf resi = cs.getResiBuf(); |
---|
4964 | resi.smoothWithRef( cs.getOrgBuf(), cs.slice->clpRngs() ); |
---|
4965 | } |
---|
4966 | |
---|
4967 | #endif |
---|
4968 | const TempCtx ctxStart( m_CtxCache, m_CABACEstimator->getCtx() ); |
---|
4969 | |
---|
4970 | cs.getOrgResiBuf().copyFrom(cs.getResiBuf()); |
---|
4971 | |
---|
4972 | xEstimateInterResidualQT(cs, partitioner, &zeroDistortion); |
---|
4973 | |
---|
4974 | TransformUnit &firstTU = *cs.getTU( partitioner.chType ); |
---|
4975 | |
---|
4976 | cu.rootCbf = false; |
---|
4977 | m_CABACEstimator->resetBits(); |
---|
4978 | m_CABACEstimator->rqt_root_cbf( cu ); |
---|
4979 | const uint64_t zeroFracBits = m_CABACEstimator->getEstFracBits(); |
---|
4980 | double zeroCost; |
---|
4981 | { |
---|
4982 | #if WCG_EXT |
---|
4983 | if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() ) |
---|
4984 | { |
---|
4985 | zeroCost = cs.isLossless ? ( cs.cost + 1 ) : m_pcRdCost->calcRdCost( zeroFracBits, zeroDistortion, false ); |
---|
4986 | } |
---|
4987 | else |
---|
4988 | #endif |
---|
4989 | zeroCost = cs.isLossless ? ( cs.cost + 1 ) : m_pcRdCost->calcRdCost( zeroFracBits, zeroDistortion ); |
---|
4990 | } |
---|
4991 | |
---|
4992 | const int numValidTBlocks = ::getNumberValidTBlocks( *cs.pcv ); |
---|
4993 | for (uint32_t i = 0; i < numValidTBlocks; i++) |
---|
4994 | { |
---|
4995 | cu.rootCbf |= TU::getCbf( firstTU, ComponentID( i ) ); |
---|
4996 | } |
---|
4997 | |
---|
4998 | // ------------------------------------------------------- |
---|
4999 | // If a block full of 0's is efficient, then just use 0's. |
---|
5000 | // The costs at this point do not include header bits. |
---|
5001 | |
---|
5002 | if (zeroCost < cs.cost || !cu.rootCbf) |
---|
5003 | { |
---|
5004 | cu.rootCbf = false; |
---|
5005 | |
---|
5006 | cs.clearTUs(); |
---|
5007 | |
---|
5008 | // add a new "empty" TU spanning the whole CU |
---|
5009 | TransformUnit& tu = cs.addTU(cu, partitioner.chType); |
---|
5010 | |
---|
5011 | for (int comp = 0; comp < numValidComponents; comp++) |
---|
5012 | { |
---|
5013 | tu.rdpcm[comp] = RDPCM_OFF; |
---|
5014 | } |
---|
5015 | cu.firstTU = cu.lastTU = &tu; |
---|
5016 | } |
---|
5017 | |
---|
5018 | |
---|
5019 | // all decisions now made. Fully encode the CU, including the headers: |
---|
5020 | m_CABACEstimator->getCtx() = ctxStart; |
---|
5021 | |
---|
5022 | uint64_t finalFracBits = xGetSymbolFracBitsInter( cs, partitioner ); |
---|
5023 | // we've now encoded the CU, and so have a valid bit cost |
---|
5024 | if (!cu.rootCbf) |
---|
5025 | { |
---|
5026 | cs.getResiBuf().fill(0); // Clear the residual image, if we didn't code it. |
---|
5027 | } |
---|
5028 | |
---|
5029 | cs.getRecoBuf().reconstruct(cs.getPredBuf(), cs.getResiBuf(), cs.slice->clpRngs()); |
---|
5030 | |
---|
5031 | // update with clipped distortion and cost (previously unclipped reconstruction values were used) |
---|
5032 | Distortion finalDistortion = 0; |
---|
5033 | |
---|
5034 | for (int comp = 0; comp < numValidComponents; comp++) |
---|
5035 | { |
---|
5036 | const ComponentID compID = ComponentID(comp); |
---|
5037 | |
---|
5038 | CPelBuf reco = cs.getRecoBuf (compID); |
---|
5039 | CPelBuf org = cs.getOrgBuf (compID); |
---|
5040 | |
---|
5041 | #if WCG_EXT |
---|
5042 | if( m_pcEncCfg->getLumaLevelToDeltaQPMapping().isEnabled() ) |
---|
5043 | { |
---|
5044 | const CPelBuf orgLuma = cs.getOrgBuf( cs.area.blocks[COMPONENT_Y] ); |
---|
5045 | finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE_WTD, &orgLuma ); |
---|
5046 | } |
---|
5047 | else |
---|
5048 | #endif |
---|
5049 | { |
---|
5050 | finalDistortion += m_pcRdCost->getDistPart( org, reco, sps.getBitDepth( toChannelType( compID ) ), compID, DF_SSE ); |
---|
5051 | } |
---|
5052 | } |
---|
5053 | |
---|
5054 | cs.dist = finalDistortion; |
---|
5055 | cs.fracBits = finalFracBits; |
---|
5056 | cs.cost = m_pcRdCost->calcRdCost(cs.fracBits, cs.dist); |
---|
5057 | |
---|
5058 | CHECK(cs.tus.size() == 0, "No TUs present"); |
---|
5059 | } |
---|
5060 | |
---|
5061 | uint64_t InterSearch::xGetSymbolFracBitsInter(CodingStructure &cs, Partitioner &partitioner) |
---|
5062 | { |
---|
5063 | uint64_t fracBits = 0; |
---|
5064 | CodingUnit &cu = *cs.getCU( partitioner.chType ); |
---|
5065 | |
---|
5066 | m_CABACEstimator->resetBits(); |
---|
5067 | |
---|
5068 | if( cu.partSize == SIZE_2Nx2N && cu.firstPU->mergeFlag && !cu.rootCbf ) |
---|
5069 | { |
---|
5070 | cu.skip = true; |
---|
5071 | |
---|
5072 | if( cs.pps->getTransquantBypassEnabledFlag() ) |
---|
5073 | { |
---|
5074 | m_CABACEstimator->cu_transquant_bypass_flag( cu ); |
---|
5075 | } |
---|
5076 | |
---|
5077 | m_CABACEstimator->cu_skip_flag ( cu ); |
---|
5078 | #if JEM_TOOLS |
---|
5079 | m_CABACEstimator->fruc_mrg_mode ( *cu.firstPU ); |
---|
5080 | m_CABACEstimator->affine_flag ( cu ); |
---|
5081 | #endif |
---|
5082 | #if !JEM_TOOLS && JVET_K_AFFINE |
---|
5083 | m_CABACEstimator->affine_flag ( cu ); |
---|
5084 | #endif |
---|
5085 | m_CABACEstimator->merge_idx ( *cu.firstPU ); |
---|
5086 | #if JEM_TOOLS |
---|
5087 | m_CABACEstimator->cu_lic_flag ( cu ); |
---|
5088 | #endif |
---|
5089 | fracBits += m_CABACEstimator->getEstFracBits(); |
---|
5090 | } |
---|
5091 | else |
---|
5092 | { |
---|
5093 | CHECK( cu.skip, "Skip flag has to be off at this point!" ); |
---|
5094 | |
---|
5095 | if( cs.pps->getTransquantBypassEnabledFlag() ) |
---|
5096 | { |
---|
5097 | m_CABACEstimator->cu_transquant_bypass_flag( cu ); |
---|
5098 | } |
---|
5099 | |
---|
5100 | m_CABACEstimator->cu_skip_flag( cu ); |
---|
5101 | m_CABACEstimator->pred_mode ( cu ); |
---|
5102 | m_CABACEstimator->cu_pred_data( cu ); |
---|
5103 | CUCtx cuCtx; |
---|
5104 | cuCtx.isDQPCoded = true; |
---|
5105 | cuCtx.isChromaQpAdjCoded = true; |
---|
5106 | m_CABACEstimator->cu_residual ( cu, partitioner, cuCtx ); |
---|
5107 | fracBits += m_CABACEstimator->getEstFracBits(); |
---|
5108 | } |
---|
5109 | |
---|
5110 | return fracBits; |
---|
5111 | } |
---|
5112 | |
---|
5113 | |
---|