1 /*
2 * Copyright(c) 2018 Intel Corporation
3 * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 */
5
6 #include <stdlib.h>
7 #include <string.h>
8 #include "EbUtility.h"
9
10 #include "EbModeDecisionProcess.h"
11
12 #include "EbLambdaRateTables.h"
13 #include "EbTransforms.h"
14
ModeDecisionContextDctor(EB_PTR p)15 static void ModeDecisionContextDctor(EB_PTR p)
16 {
17 ModeDecisionContext_t* obj = (ModeDecisionContext_t*)p;
18 EB_FREE(obj->transformInnerArrayPtr);
19 if (obj->isMdRateEstimationPtrOwner) {
20 EB_FREE(obj->mdRateEstimationPtr);
21 }
22 EB_FREE_ARRAY(obj->fastCandidateArray);
23 EB_FREE_ARRAY(obj->fastCandidatePtrArray);
24 EB_DELETE(obj->transQuantBuffersPtr);
25 if(obj->isCabacCostOwner)
26 EB_FREE(obj->CabacCost);
27 EB_FREE_ARRAY(obj->fastCostArray);
28 EB_FREE_ARRAY(obj->fullCostArray);
29 EB_FREE_ARRAY(obj->fullCostSkipPtr);
30 EB_FREE_ARRAY(obj->fullCostMergePtr);
31 EB_DELETE_PTR_ARRAY(obj->candidateBufferPtrArray, MODE_DECISION_CANDIDATE_BUFFER_MAX_COUNT);
32 EB_DELETE(obj->interPredictionContext);
33 EB_DELETE(obj->predictionBuffer);
34 EB_DELETE(obj->intraRefPtr);
35 EB_DELETE(obj->mcpContext);
36 EB_DELETE(obj->pillarReconBuffer);
37 EB_DELETE(obj->mdReconBuffer);
38 EB_FREE(obj->mdPicLcuDetect);
39 }
40
41 /******************************************************
42 * Mode Decision Context Constructor
43 ******************************************************/
ModeDecisionContextCtor(ModeDecisionContext_t * contextPtr,EbFifo_t * modeDecisionConfigurationInputFifoPtr,EbFifo_t * modeDecisionOutputFifoPtr,EB_BOOL is16bit)44 EB_ERRORTYPE ModeDecisionContextCtor(
45 ModeDecisionContext_t *contextPtr,
46 EbFifo_t *modeDecisionConfigurationInputFifoPtr,
47 EbFifo_t *modeDecisionOutputFifoPtr,
48 EB_BOOL is16bit)
49 {
50 EB_U32 bufferIndex;
51 EB_U32 candidateIndex;
52 contextPtr->dctor = ModeDecisionContextDctor;
53
54 // Input/Output System Resource Manager FIFOs
55 contextPtr->modeDecisionConfigurationInputFifoPtr = modeDecisionConfigurationInputFifoPtr;
56 contextPtr->modeDecisionOutputFifoPtr = modeDecisionOutputFifoPtr;
57
58 // Trasform Scratch Memory
59 EB_MALLOC(contextPtr->transformInnerArrayPtr, 3120); //refer to EbInvTransform_SSE2.as. case 32x32
60
61 // MD rate Estimation tables
62 EB_MALLOC(contextPtr->mdRateEstimationPtr, sizeof(MdRateEstimationContext_t));
63 contextPtr->isMdRateEstimationPtrOwner = EB_TRUE;
64
65 // Fast Candidate Array
66 EB_MALLOC_ARRAY(contextPtr->fastCandidateArray, MODE_DECISION_CANDIDATE_MAX_COUNT);
67 EB_MALLOC_ARRAY(contextPtr->fastCandidatePtrArray, MODE_DECISION_CANDIDATE_MAX_COUNT);
68
69 for(candidateIndex = 0; candidateIndex < MODE_DECISION_CANDIDATE_MAX_COUNT; ++candidateIndex) {
70 contextPtr->fastCandidatePtrArray[candidateIndex] = &contextPtr->fastCandidateArray[candidateIndex];
71 contextPtr->fastCandidatePtrArray[candidateIndex]->mdRateEstimationPtr = contextPtr->mdRateEstimationPtr;
72 }
73
74 // Transform and Quantization Buffers
75 EB_NEW(
76 contextPtr->transQuantBuffersPtr,
77 EbTransQuantBuffersCtor);
78
79 // Cabac cost
80 EB_MALLOC(contextPtr->CabacCost, sizeof(CabacCost_t));
81 contextPtr->isCabacCostOwner = EB_TRUE;
82
83 // Cost Arrays
84 EB_MALLOC_ARRAY(contextPtr->fastCostArray, MODE_DECISION_CANDIDATE_BUFFER_MAX_COUNT);
85 EB_MALLOC_ARRAY(contextPtr->fullCostArray, MODE_DECISION_CANDIDATE_BUFFER_MAX_COUNT);
86 EB_MALLOC_ARRAY(contextPtr->fullCostSkipPtr, MODE_DECISION_CANDIDATE_BUFFER_MAX_COUNT);
87 EB_MALLOC_ARRAY(contextPtr->fullCostMergePtr, MODE_DECISION_CANDIDATE_BUFFER_MAX_COUNT);
88
89 // Candidate Buffers
90 EB_ALLOC_PTR_ARRAY(contextPtr->candidateBufferPtrArray, MODE_DECISION_CANDIDATE_BUFFER_MAX_COUNT);
91
92 for(bufferIndex = 0; bufferIndex < MODE_DECISION_CANDIDATE_BUFFER_MAX_COUNT; ++bufferIndex) {
93 EB_NEW(
94 contextPtr->candidateBufferPtrArray[bufferIndex],
95 ModeDecisionCandidateBufferCtor,
96 MAX_LCU_SIZE,
97 EB_8BIT,
98 &(contextPtr->fastCostArray[bufferIndex]),
99 &(contextPtr->fullCostArray[bufferIndex]),
100 &(contextPtr->fullCostSkipPtr[bufferIndex]),
101 &(contextPtr->fullCostMergePtr[bufferIndex]));
102 }
103
104 // Inter Prediction Context
105 EB_NEW(
106 contextPtr->interPredictionContext,
107 InterPredictionContextCtor,
108 MAX_LCU_SIZE,
109 MAX_LCU_SIZE,
110 is16bit);
111
112 // Prediction Buffer
113 {
114 EbPictureBufferDescInitData_t initData;
115
116 initData.bufferEnableMask = PICTURE_BUFFER_DESC_LUMA_MASK;
117 initData.maxWidth = MAX_LCU_SIZE;
118 initData.maxHeight = MAX_LCU_SIZE;
119 initData.bitDepth = EB_8BIT;
120 initData.colorFormat = EB_YUV420;
121 initData.leftPadding = 0;
122 initData.rightPadding = 0;
123 initData.topPadding = 0;
124 initData.botPadding = 0;
125 initData.splitMode = EB_FALSE;
126
127 EB_NEW(
128 contextPtr->predictionBuffer,
129 EbPictureBufferDescCtor,
130 (EB_PTR)&initData);
131 }
132
133 // Intra Reference Samples
134 EB_NEW(
135 contextPtr->intraRefPtr,
136 IntraReferenceSamplesCtor,
137 EB_YUV420);
138
139 // MCP Context
140 EB_NEW(
141 contextPtr->mcpContext,
142 MotionCompensationPredictionContextCtor,
143 MAX_LCU_SIZE,
144 MAX_LCU_SIZE,
145 is16bit);
146
147 {
148 EbPictureBufferDescInitData_t initData;
149
150 initData.bufferEnableMask = PICTURE_BUFFER_DESC_FULL_MASK;
151 initData.maxWidth = MAX_LCU_SIZE;
152 initData.maxHeight = MAX_LCU_SIZE;
153 initData.bitDepth = EB_8BIT;
154 initData.colorFormat = EB_YUV420;
155 initData.leftPadding = 0;
156 initData.rightPadding = 0;
157 initData.topPadding = 0;
158 initData.botPadding = 0;
159 initData.splitMode = EB_FALSE;
160
161 EB_NEW(
162 contextPtr->pillarReconBuffer,
163 EbPictureBufferDescCtor,
164 (EB_PTR)&initData);
165
166 EB_NEW(
167 contextPtr->mdReconBuffer,
168 EbPictureBufferDescCtor,
169 (EB_PTR)&initData);
170 }
171
172 EB_CALLOC(contextPtr->mdPicLcuDetect, 1, sizeof(LcuBasedDetectors_t));
173
174 return EB_ErrorNone;
175 }
176
177
178
lambdaAssignLowDelay(PictureParentControlSet_t * pictureControlSetPtr,EB_U32 * fastLambda,EB_U32 * fullLambda,EB_U32 * fastChromaLambda,EB_U32 * fullChromaLambda,EB_U32 * fullChromaLambdaSao,EB_U8 qp,EB_U8 chromaQp)179 extern void lambdaAssignLowDelay(
180 PictureParentControlSet_t *pictureControlSetPtr,
181 EB_U32 *fastLambda,
182 EB_U32 *fullLambda,
183 EB_U32 *fastChromaLambda,
184 EB_U32 *fullChromaLambda,
185 EB_U32 *fullChromaLambdaSao,
186 EB_U8 qp,
187 EB_U8 chromaQp)
188
189 {
190
191 if (pictureControlSetPtr->temporalLayerIndex == 0) {
192
193 *fastLambda = lambdaModeDecisionLdSad[qp];
194 *fastChromaLambda = lambdaModeDecisionLdSad[qp];
195 *fullLambda = lambdaModeDecisionLdSse[qp];
196 *fullChromaLambda = lambdaModeDecisionLdSse[qp];
197 *fullChromaLambdaSao = lambdaModeDecisionLdSse[chromaQp];
198
199 }
200 else { // Hierarchical postions 1, 2, 3, 4, 5
201
202 *fastLambda = lambdaModeDecisionLdSadQpScaling[qp];
203 *fastChromaLambda = lambdaModeDecisionLdSadQpScaling[qp];
204 *fullLambda = lambdaModeDecisionLdSseQpScaling[qp];
205 *fullChromaLambda = lambdaModeDecisionLdSseQpScaling[qp];
206 *fullChromaLambdaSao = lambdaModeDecisionLdSseQpScaling[chromaQp];
207 }
208
209 }
210
lambdaAssignRandomAccess(PictureParentControlSet_t * pictureControlSetPtr,EB_U32 * fastLambda,EB_U32 * fullLambda,EB_U32 * fastChromaLambda,EB_U32 * fullChromaLambda,EB_U32 * fullChromaLambdaSao,EB_U8 qp,EB_U8 chromaQp)211 void lambdaAssignRandomAccess(
212 PictureParentControlSet_t *pictureControlSetPtr,
213 EB_U32 *fastLambda,
214 EB_U32 *fullLambda,
215 EB_U32 *fastChromaLambda,
216 EB_U32 *fullChromaLambda,
217 EB_U32 *fullChromaLambdaSao,
218 EB_U8 qp,
219 EB_U8 chromaQp)
220
221 {
222 if (pictureControlSetPtr->temporalLayerIndex == 0) {
223
224 *fastLambda = lambdaModeDecisionRaSadBase[qp];
225 *fastChromaLambda = lambdaModeDecisionRaSadBase[qp];
226 *fullLambda = lambdaModeDecisionRaSseBase[qp];
227 *fullChromaLambda = lambdaModeDecisionRaSseBase[qp];
228 *fullChromaLambdaSao = lambdaModeDecisionRaSseBase[chromaQp];
229
230 }
231 else if (pictureControlSetPtr->isUsedAsReferenceFlag) {
232
233 *fastLambda = lambdaModeDecisionRaSadRefNonBase[qp];
234 *fastChromaLambda = lambdaModeDecisionRaSadRefNonBase[qp];
235 *fullLambda = lambdaModeDecisionRaSseRefNonBase[qp];
236 *fullChromaLambda = lambdaModeDecisionRaSseRefNonBase[qp];
237 *fullChromaLambdaSao = lambdaModeDecisionRaSseRefNonBase[chromaQp];
238 }
239 else {
240
241 *fastLambda = lambdaModeDecisionRaSadNonRef[qp];
242 *fastChromaLambda = lambdaModeDecisionRaSadNonRef[qp];
243 *fullLambda = lambdaModeDecisionRaSseNonRef[qp];
244 *fullChromaLambda = lambdaModeDecisionRaSseNonRef[qp];
245 *fullChromaLambdaSao = lambdaModeDecisionRaSseNonRef[chromaQp];
246 }
247
248 }
249
EbHevcLambdaAssignISlice(PictureParentControlSet_t * pictureControlSetPtr,EB_U32 * fastLambda,EB_U32 * fullLambda,EB_U32 * fastChromaLambda,EB_U32 * fullChromaLambda,EB_U32 * fullChromaLambdaSao,EB_U8 qp,EB_U8 chromaQp)250 void EbHevcLambdaAssignISlice(
251 PictureParentControlSet_t *pictureControlSetPtr,
252 EB_U32 *fastLambda,
253 EB_U32 *fullLambda,
254 EB_U32 *fastChromaLambda,
255 EB_U32 *fullChromaLambda,
256 EB_U32 *fullChromaLambdaSao,
257 EB_U8 qp,
258 EB_U8 chromaQp)
259
260 {
261
262 if (pictureControlSetPtr->temporalLayerIndex == 0) {
263
264 *fastLambda = lambdaModeDecisionISliceSad[qp];
265 *fastChromaLambda = lambdaModeDecisionISliceSad[qp];
266 *fullLambda = lambdaModeDecisionISliceSse[qp];
267 *fullChromaLambda = lambdaModeDecisionISliceSse[qp];
268 *fullChromaLambdaSao = lambdaModeDecisionISliceSse[chromaQp];
269
270 }
271 else {
272
273 }
274
275 }
276 const EB_LAMBDA_ASSIGN_FUNC lambdaAssignmentFunctionTable[4] = {
277 lambdaAssignLowDelay, // low delay P
278 lambdaAssignLowDelay, // low delay B
279 lambdaAssignRandomAccess, // Random Access
280 EbHevcLambdaAssignISlice // I_SLICE
281 };
282
ProductResetModeDecision(ModeDecisionContext_t * contextPtr,PictureControlSet_t * pictureControlSetPtr,SequenceControlSet_t * sequenceControlSetPtr)283 void ProductResetModeDecision(
284 ModeDecisionContext_t *contextPtr,
285 PictureControlSet_t *pictureControlSetPtr,
286 SequenceControlSet_t *sequenceControlSetPtr)
287 {
288 EB_PICTURE sliceType;
289 MdRateEstimationContext_t *mdRateEstimationArray;
290
291 // SAO
292 pictureControlSetPtr->saoFlag[0] = EB_TRUE;
293 pictureControlSetPtr->saoFlag[1] = EB_TRUE;
294
295 // QP
296 contextPtr->qp = pictureControlSetPtr->pictureQp;
297 // Asuming cb and cr offset to be the same for chroma QP in both slice and pps for lambda computation
298
299 EB_U8 qpScaled = CLIP3(MIN_QP_VALUE, MAX_CHROMA_MAP_QP_VALUE, (EB_S32)(contextPtr->qp + pictureControlSetPtr->cbQpOffset + pictureControlSetPtr->sliceCbQpOffset));
300 contextPtr->chromaQp = MapChromaQp(qpScaled);
301
302 if (pictureControlSetPtr->sliceType == EB_I_PICTURE && pictureControlSetPtr->temporalId == 0){
303
304 (*lambdaAssignmentFunctionTable[3])(
305 pictureControlSetPtr->ParentPcsPtr,
306 &contextPtr->fastLambda,
307 &contextPtr->fullLambda,
308 &contextPtr->fastChromaLambda,
309 &contextPtr->fullChromaLambda,
310 &contextPtr->fullChromaLambdaSao,
311 contextPtr->qp,
312 contextPtr->chromaQp);
313 }
314 else{
315 (*lambdaAssignmentFunctionTable[sequenceControlSetPtr->staticConfig.predStructure])(
316 pictureControlSetPtr->ParentPcsPtr,
317 &contextPtr->fastLambda,
318 &contextPtr->fullLambda,
319 &contextPtr->fastChromaLambda,
320 &contextPtr->fullChromaLambda,
321 &contextPtr->fullChromaLambdaSao,
322 contextPtr->qp,
323 contextPtr->chromaQp);
324 }
325 // Configure the number of candidate buffers to search at each depth
326
327 // 64x64 CU
328 contextPtr->bufferDepthIndexStart[0] = 0;
329 contextPtr->bufferDepthIndexWidth[0] = 5; // 4 NFL + 1 for temporary data
330
331 // 32x32 CU
332 contextPtr->bufferDepthIndexStart[1] = contextPtr->bufferDepthIndexStart[0] + contextPtr->bufferDepthIndexWidth[0];
333 contextPtr->bufferDepthIndexWidth[1] = 8; // 4 NFL + 3 MPM + 1 for temporary data
334
335 // 16x16 CU
336 contextPtr->bufferDepthIndexStart[2] = contextPtr->bufferDepthIndexStart[1] + contextPtr->bufferDepthIndexWidth[1];
337 contextPtr->bufferDepthIndexWidth[2] = 8; // 4 NFL + 3 MPM + 1 for temporary data
338
339 // 8x8 CU
340 contextPtr->bufferDepthIndexStart[3] = contextPtr->bufferDepthIndexStart[2] + contextPtr->bufferDepthIndexWidth[2];
341 contextPtr->bufferDepthIndexWidth[3] = 8; // 4 NFL + 3 MPM + 1 for temporary data
342
343 // 4x4 CU
344 contextPtr->bufferDepthIndexStart[4] = contextPtr->bufferDepthIndexStart[3] + contextPtr->bufferDepthIndexWidth[3];
345 contextPtr->bufferDepthIndexWidth[4] = 5; // 4 NFL + 1 for temporary data
346
347 // Slice Type
348 sliceType =
349 (pictureControlSetPtr->ParentPcsPtr->idrFlag == EB_TRUE) ? EB_I_PICTURE :
350 pictureControlSetPtr->sliceType;
351
352 // Increment the MD Rate Estimation array pointer to point to the right address based on the QP and slice type
353
354 /* Note(CHKN) : Rate estimation will use FrameQP even when Qp modulation is ON */
355
356 mdRateEstimationArray = (MdRateEstimationContext_t*)sequenceControlSetPtr->encodeContextPtr->mdRateEstimationArray;
357 mdRateEstimationArray += sliceType * TOTAL_NUMBER_OF_QP_VALUES + contextPtr->qp;
358
359 // Reset MD rate Estimation table to initial values by copying from mdRateEstimationArray
360 if (contextPtr->isMdRateEstimationPtrOwner) {
361 contextPtr->isMdRateEstimationPtrOwner = EB_FALSE;
362 EB_FREE(contextPtr->mdRateEstimationPtr);
363 }
364 contextPtr->mdRateEstimationPtr = mdRateEstimationArray;
365
366 EB_U32 candidateIndex;
367 for (candidateIndex = 0; candidateIndex < MODE_DECISION_CANDIDATE_MAX_COUNT; ++candidateIndex) {
368 contextPtr->fastCandidatePtrArray[candidateIndex]->mdRateEstimationPtr = mdRateEstimationArray;
369 }
370
371 // TMVP Map Writer Pointer
372 if (pictureControlSetPtr->ParentPcsPtr->isUsedAsReferenceFlag == EB_TRUE)
373 contextPtr->referenceObjectWritePtr = (EbReferenceObject_t*)pictureControlSetPtr->ParentPcsPtr->referencePictureWrapperPtr->objectPtr;
374 else
375 contextPtr->referenceObjectWritePtr = (EbReferenceObject_t*)EB_NULL;
376
377 // Reset CABAC Contexts
378 contextPtr->coeffEstEntropyCoderPtr = pictureControlSetPtr->coeffEstEntropyCoderPtr;
379
380 return;
381 }
382
ConfigureChroma(PictureControlSet_t * pictureControlSetPtr,ModeDecisionContext_t * contextPtr,LargestCodingUnit_t * lcuPtr)383 void ConfigureChroma(
384 PictureControlSet_t *pictureControlSetPtr,
385 ModeDecisionContext_t *contextPtr,
386 LargestCodingUnit_t *lcuPtr) {
387
388 EB_U32 lcuAddr = lcuPtr->index;
389 EB_U32 lcuEdgeNum = pictureControlSetPtr->ParentPcsPtr->edgeResultsPtr[lcuAddr].edgeBlockNum;
390 LcuStat_t *lcuStatPtr = &(pictureControlSetPtr->ParentPcsPtr->lcuStatArray[lcuAddr]);
391
392 lcuPtr->chromaEncodeMode = CHROMA_MODE_FULL;
393
394 EB_BOOL chromaCond0 = lcuStatPtr->stationaryEdgeOverTimeFlag;
395 EB_BOOL chromaCond1 = pictureControlSetPtr->ParentPcsPtr->lcuHomogeneousAreaArray[lcuAddr] && lcuStatPtr->cuStatArray[0].highChroma;
396 EB_BOOL chromaCond2 = !lcuStatPtr->cuStatArray[0].highLuma;
397 EB_BOOL chromaCond3 = ((pictureControlSetPtr->ParentPcsPtr->grassPercentageInPicture > 60) || (lcuPtr->auraStatus == AURA_STATUS_1) || (pictureControlSetPtr->ParentPcsPtr->isPan));
398
399 // 0: Full Search Chroma for All
400 // 1: Best Search Chroma for All LCUs; Chroma OFF if I_SLICE, Chroma for only MV_Merge if P/B_SLICE
401 // 2: Full vs. Best Swicth Method 0: chromaCond0 || chromaCond1 || chromaCond2
402 // 3: Full vs. Best Swicth Method 1: chromaCond0 || chromaCond1
403 // 4: Full vs. Best Swicth Method 2: chromaCond2 || chromaCond3
404 // 5: Full vs. Best Swicth Method 3: chromaCond0
405 // If INTRA Close Loop, then the switch modes (2,3,4,5) are not supported as reference samples for Chroma compensation will be a mix of source samples and reconstructed samples
406
407 if (contextPtr->chromaLevel == 0) {
408 lcuPtr->chromaEncodeMode = CHROMA_MODE_FULL;
409 }
410 else if (contextPtr->chromaLevel == 1) {
411 lcuPtr->chromaEncodeMode = CHROMA_MODE_BEST;
412 }
413 else if (contextPtr->chromaLevel == 2) {
414 lcuPtr->chromaEncodeMode = (chromaCond0 || chromaCond1 || chromaCond2) ?
415 (EB_U8)CHROMA_MODE_FULL :
416 (EB_U8)CHROMA_MODE_BEST;
417 }
418 else if (contextPtr->chromaLevel == 3) {
419 lcuPtr->chromaEncodeMode = (chromaCond0 || chromaCond1) ?
420 (EB_U8)CHROMA_MODE_FULL :
421 (EB_U8)CHROMA_MODE_BEST;
422 }
423 else if (contextPtr->chromaLevel == 4) {
424 lcuPtr->chromaEncodeMode = chromaCond2 || chromaCond3 ?
425 (EB_U8)CHROMA_MODE_FULL :
426 (EB_U8)CHROMA_MODE_BEST;
427 }
428 else {
429 lcuPtr->chromaEncodeMode = chromaCond0 ?
430 (EB_U8)CHROMA_MODE_FULL :
431 (EB_U8)CHROMA_MODE_BEST;
432 }
433
434 // hack disable chroma search for P422/444 for known error
435 if (lcuPtr->chromaEncodeMode == CHROMA_MODE_FULL && pictureControlSetPtr->colorFormat >= EB_YUV422) {
436 lcuPtr->chromaEncodeMode = CHROMA_MODE_BEST;
437 }
438
439 contextPtr->useChromaInformationInFastLoop = (lcuEdgeNum > 0 || lcuPtr->chromaEncodeMode == CHROMA_MODE_FULL) ? 1 : 0;
440
441 contextPtr->useChromaInformationInFullLoop = (lcuPtr->chromaEncodeMode == CHROMA_MODE_FULL) ? 1 : 0;
442
443 if (lcuPtr->chromaEncodeMode == CHROMA_MODE_BEST) {
444 contextPtr->useChromaInformationInFastLoop = 0;
445 contextPtr->useChromaInformationInFullLoop = 0;
446 }
447
448 contextPtr->use4x4ChromaInformationInFullLoop = contextPtr->useChromaInformationInFullLoop && lcuPtr->intra4x4SearchMethod == INTRA4x4_INLINE_SEARCH && contextPtr->intraMdOpenLoopFlag == EB_FALSE ? EB_TRUE : EB_FALSE;
449 }
450
451
DeriveIntraInterBiasFlag(SequenceControlSet_t * sequenceControlSetPtr,PictureControlSet_t * pictureControlSetPtr,ModeDecisionContext_t * contextPtr,LargestCodingUnit_t * lcuPtr)452 void DeriveIntraInterBiasFlag(
453 SequenceControlSet_t *sequenceControlSetPtr,
454 PictureControlSet_t *pictureControlSetPtr,
455 ModeDecisionContext_t *contextPtr,
456 LargestCodingUnit_t *lcuPtr) {
457
458
459 EB_U32 lcuAddr = lcuPtr->index;
460 LcuStat_t *lcuStatPtr = &(pictureControlSetPtr->ParentPcsPtr->lcuStatArray[lcuAddr]);
461
462 contextPtr->useIntraInterBias = EB_FALSE;
463
464 if (sequenceControlSetPtr->staticConfig.improveSharpness) {
465
466 contextPtr->useIntraInterBias = EB_TRUE;
467
468 if (lcuPtr->pictureControlSetPtr->sceneCaracteristicId == EB_FRAME_CARAC_2) {
469 if (lcuPtr->pictureControlSetPtr->ParentPcsPtr->lcuCmplxContrastArray[lcuAddr]) {
470 contextPtr->useIntraInterBias = EB_FALSE;
471 }
472 }
473
474 if (lcuPtr->pictureControlSetPtr->sceneCaracteristicId == EB_FRAME_CARAC_1) {
475 if (lcuPtr->pictureControlSetPtr->ParentPcsPtr->edgeResultsPtr[lcuAddr].edgeBlockNum) {
476 contextPtr->useIntraInterBias = EB_FALSE;
477 }
478 }
479
480 if (lcuStatPtr->stationaryEdgeOverTimeFlag)
481 contextPtr->useIntraInterBias = EB_FALSE;
482
483 if (pictureControlSetPtr->ParentPcsPtr->picNoiseClass >= PIC_NOISE_CLASS_3_1) {
484
485 contextPtr->useIntraInterBias = EB_FALSE;
486 }
487
488 if (pictureControlSetPtr->ParentPcsPtr->yMean[lcuAddr][RASTER_SCAN_CU_INDEX_64x64] < TH_BIAS_DARK_LCU) {
489 contextPtr->useIntraInterBias = EB_FALSE;
490 }
491
492 }
493
494 if (sequenceControlSetPtr->inputResolution < INPUT_SIZE_4K_RANGE) {
495 contextPtr->useIntraInterBias = EB_FALSE;
496 }
497 }
498
ProductConfigurePicLcuMdDetectors(PictureControlSet_t * pictureControlSetPtr,ModeDecisionContext_t * contextPtr,LargestCodingUnit_t * lcuPtr)499 void ProductConfigurePicLcuMdDetectors(
500 PictureControlSet_t *pictureControlSetPtr,
501 ModeDecisionContext_t *contextPtr,
502 LargestCodingUnit_t *lcuPtr)
503
504 {
505
506 LcuBasedDetectors_t *mdPicLcuDetect = contextPtr->mdPicLcuDetect;
507 EB_U8 index;
508 EB_U16 lcuAddr = lcuPtr->index;
509 LcuStat_t *lcuStatPtr = &(pictureControlSetPtr->ParentPcsPtr->lcuStatArray[lcuAddr]);
510 PictureParentControlSet_t *ppcsPtr = pictureControlSetPtr->ParentPcsPtr;
511
512
513 mdPicLcuDetect->intraInterCond1 = (ppcsPtr->grassPercentageInPicture > 60 && lcuPtr->auraStatus == AURA_STATUS_1) || ppcsPtr->failingMotionLcuFlag[lcuAddr] ? EB_FALSE : EB_TRUE;
514 mdPicLcuDetect->intraInterCond2 = (ppcsPtr->lcuFlatNoiseArray[lcuAddr] &&
515 ppcsPtr->similarColocatedLcuArrayAllLayers[lcuAddr] == EB_TRUE &&
516 (ppcsPtr->failingMotionLcuFlag[lcuAddr] || ppcsPtr->similarColocatedLcuArray[lcuAddr] || ppcsPtr->temporalLayerIndex > 0)) ? EB_TRUE : EB_FALSE;
517
518
519 mdPicLcuDetect->intraInterCond3 = EB_FALSE;
520
521 EB_U8 cuUseRefSrc = (pictureControlSetPtr->ParentPcsPtr->useSrcRef);
522
523 if (pictureControlSetPtr->temporalLayerIndex == 0 || cuUseRefSrc) {
524 if (pictureControlSetPtr->ParentPcsPtr->isLcuHomogeneousOverTime[lcuAddr] &&
525 pictureControlSetPtr->ParentPcsPtr->edgeResultsPtr[lcuAddr].edgeBlockNum == 0
526 && (!lcuStatPtr->cuStatArray[0].skinArea) && (!ppcsPtr->failingMotionLcuFlag[lcuAddr]) && (ppcsPtr->lcuFlatNoiseArray[lcuAddr])) {
527
528 mdPicLcuDetect->intraInterCond3 = EB_TRUE;
529 }
530 }
531
532
533 if (ppcsPtr->lcuHomogeneousAreaArray[lcuAddr] || (&(lcuStatPtr->cuStatArray[0]))->grassArea)
534
535 mdPicLcuDetect->biPredCond1 = EB_TRUE;
536 else
537 mdPicLcuDetect->biPredCond1 = EB_FALSE;
538
539 // AntiContouring Threasholds
540 for (index = 0; index < 4; index++) {
541 mdPicLcuDetect->enableContouringQCUpdateFlag32x32[index] =
542 (ppcsPtr->lcuYSrcEnergyCuArray[lcuPtr->index][index + 1] == 0 ||
543 ppcsPtr->lcuYSrcMeanCuArray[lcuPtr->index][index + 1] > ANTI_CONTOURING_LUMA_T2 ||
544 ppcsPtr->lcuYSrcMeanCuArray[lcuPtr->index][index + 1] < ANTI_CONTOURING_LUMA_T1) ? 0 :
545 (ppcsPtr->lcuYSrcEnergyCuArray[lcuPtr->index][index + 1] < ((32 * 32)*C1_TRSHLF_N / C1_TRSHLF_D)) ? 1 :
546 (ppcsPtr->lcuYSrcEnergyCuArray[lcuPtr->index][index + 1] < ((32 * 32)*C2_TRSHLF_N / C2_TRSHLF_D)) ? 2 : 0;
547 }
548 }
549
550
ConfigureMpm(ModeDecisionContext_t * contextPtr)551 void ConfigureMpm(
552 ModeDecisionContext_t *contextPtr)
553 {
554 if (contextPtr->restrictIntraGlobalMotion) {
555 contextPtr->mpmSearch = EB_FALSE;
556 }
557 else if (contextPtr->mpmLevel == 0) {
558 contextPtr->mpmSearch = EB_TRUE;
559 contextPtr->mpmSearchCandidate = MAX_MPM_CANDIDATES;
560 }
561 else if (contextPtr->mpmLevel == 1) {
562 contextPtr->mpmSearch = EB_TRUE;
563 contextPtr->mpmSearchCandidate = 1;
564 }
565 else {
566 contextPtr->mpmSearch = EB_FALSE;
567 }
568 }
569
570 /******************************************************
571 * Derive the INTRA4x4 Search Method:
572 Input : INTRA4x4 Level, Partitioning Method
573 Output : INTRA4x4 Search: in-line or as refinement or off
574 ************************************************/
DeriveIntra4x4SearchMethod(PictureControlSet_t * pictureControlSetPtr,ModeDecisionContext_t * contextPtr,LargestCodingUnit_t * lcuPtr)575 void DeriveIntra4x4SearchMethod(
576 PictureControlSet_t *pictureControlSetPtr,
577 ModeDecisionContext_t *contextPtr,
578 LargestCodingUnit_t *lcuPtr) {
579
580 if (pictureControlSetPtr->ParentPcsPtr->lcuFlatNoiseArray[lcuPtr->index] == EB_FALSE) {
581
582 // Set INTRA4x4 Search Level
583 // Level Settings
584 // 0 INLINE if not BDP, refinment otherwise
585 // 1 REFINMENT
586 // 2 OFF
587 if (contextPtr->intra4x4Level == 0) {
588 if ((pictureControlSetPtr->ParentPcsPtr->depthMode == PICT_FULL85_DEPTH_MODE ||
589 pictureControlSetPtr->ParentPcsPtr->depthMode == PICT_FULL84_DEPTH_MODE ||
590 (pictureControlSetPtr->ParentPcsPtr->depthMode == PICT_LCU_SWITCH_DEPTH_MODE && (pictureControlSetPtr->ParentPcsPtr->lcuMdModeArray[lcuPtr->index] == LCU_FULL85_DEPTH_MODE || pictureControlSetPtr->ParentPcsPtr->lcuMdModeArray[lcuPtr->index] == LCU_FULL84_DEPTH_MODE)))) {
591 lcuPtr->intra4x4SearchMethod = INTRA4x4_INLINE_SEARCH;
592 }
593 else {
594 lcuPtr->intra4x4SearchMethod = INTRA4x4_REFINEMENT_SEARCH;
595 }
596 }
597 else if (contextPtr->intra4x4Level == 1) {
598 lcuPtr->intra4x4SearchMethod = INTRA4x4_REFINEMENT_SEARCH;
599 }
600 else {
601 lcuPtr->intra4x4SearchMethod = INTRA4x4_OFF;
602 }
603
604 }
605 else {
606 lcuPtr->intra4x4SearchMethod = INTRA4x4_OFF;
607 }
608 }
609
610 /******************************************************
611 * Derive the Depth Refinment level used in MD and BDP
612 Output : depth Refinment
613 ******************************************************/
DeriveDepthRefinment(PictureControlSet_t * pictureControlSetPtr,ModeDecisionContext_t * contextPtr,LargestCodingUnit_t * lcuPtr)614 void DeriveDepthRefinment(
615 PictureControlSet_t *pictureControlSetPtr,
616 ModeDecisionContext_t *contextPtr,
617 LargestCodingUnit_t *lcuPtr) {
618
619 EB_U32 lcuAddr = lcuPtr->index;
620 LcuStat_t *lcuStatPtr = &(pictureControlSetPtr->ParentPcsPtr->lcuStatArray[lcuAddr]);
621
622 EB_U8 stationaryEdgeOverTimeFlag = lcuStatPtr->stationaryEdgeOverTimeFlag;
623
624 contextPtr->depthRefinment = 0;
625
626 // S-LOGO
627 if (stationaryEdgeOverTimeFlag > 0) {
628 if (lcuStatPtr->lowDistLogo)
629 contextPtr->depthRefinment = 1;
630 else
631 contextPtr->depthRefinment = 2;
632 }
633
634
635 if (pictureControlSetPtr->ParentPcsPtr->highDarkLowLightAreaDensityFlag && pictureControlSetPtr->ParentPcsPtr->temporalLayerIndex > 0 && pictureControlSetPtr->ParentPcsPtr->sharpEdgeLcuFlag[lcuAddr] && !pictureControlSetPtr->ParentPcsPtr->similarColocatedLcuArrayAllLayers[lcuAddr]) {
636 contextPtr->depthRefinment = 2;
637 }
638
639 if ((pictureControlSetPtr->ParentPcsPtr->sliceType != EB_I_PICTURE && (pictureControlSetPtr->ParentPcsPtr->logoPicFlag) &&
640 pictureControlSetPtr->ParentPcsPtr->edgeResultsPtr[lcuAddr].edgeBlockNum)) {
641 contextPtr->depthRefinment = 2;
642 }
643 }
644
645 /******************************************************
646 * Mode Decision Configure LCU
647 ******************************************************/
ModeDecisionConfigureLcu(ModeDecisionContext_t * contextPtr,LargestCodingUnit_t * lcuPtr,PictureControlSet_t * pictureControlSetPtr,SequenceControlSet_t * sequenceControlSetPtr,EB_U8 pictureQp,EB_U8 lcuQp)648 void ModeDecisionConfigureLcu(
649 ModeDecisionContext_t *contextPtr,
650 LargestCodingUnit_t *lcuPtr,
651 PictureControlSet_t *pictureControlSetPtr,
652 SequenceControlSet_t *sequenceControlSetPtr,
653 EB_U8 pictureQp,
654 EB_U8 lcuQp)
655
656 {
657 // Load INTRA4x4 Settings (should be before CHROMA)
658 DeriveIntra4x4SearchMethod(
659 pictureControlSetPtr,
660 contextPtr,
661 lcuPtr);
662
663 // Load Chroma Settings
664 ConfigureChroma(
665 pictureControlSetPtr,
666 contextPtr,
667 lcuPtr);
668
669 // Load MPM Settings
670 ConfigureMpm(
671 contextPtr);
672
673 // Derive Depth Refinment Fla
674 DeriveDepthRefinment(
675 pictureControlSetPtr,
676 contextPtr,
677 lcuPtr);
678
679 ProductConfigurePicLcuMdDetectors(
680 pictureControlSetPtr,
681 contextPtr,
682 lcuPtr);
683
684 DeriveIntraInterBiasFlag(
685 sequenceControlSetPtr,
686 pictureControlSetPtr,
687 contextPtr,
688 lcuPtr);
689
690 if (sequenceControlSetPtr->staticConfig.rateControlMode == 0 && sequenceControlSetPtr->staticConfig.improveSharpness == 0 && sequenceControlSetPtr->staticConfig.segmentOvEnabled == 0) {
691 contextPtr->qp = (EB_U8)pictureQp;
692 lcuPtr->qp = (EB_U8)contextPtr->qp;
693 }
694 //RC is on
695 else {
696 contextPtr->qp = (EB_U8) lcuQp;
697 }
698
699 // Asuming cb and cr offset to be the same for chroma QP in both slice and pps for lambda computation
700
701 EB_U8 qpScaled = CLIP3((EB_S8)MIN_QP_VALUE, (EB_S8)MAX_CHROMA_MAP_QP_VALUE, (EB_S8)(contextPtr->qp + pictureControlSetPtr->cbQpOffset + pictureControlSetPtr->sliceCbQpOffset));
702 contextPtr->chromaQp = MapChromaQp(qpScaled);
703
704 /* Note(CHKN) : when Qp modulation varies QP on a sub-LCU(CU) basis, Lamda has to change based on Cu->QP , and then this code has to move inside the CU loop in MD */
705
706 // Lambda Assignement
707 if(pictureControlSetPtr->sliceType == EB_I_PICTURE && pictureControlSetPtr->temporalId == 0){
708
709 (*lambdaAssignmentFunctionTable[3])(
710 pictureControlSetPtr->ParentPcsPtr,
711 &contextPtr->fastLambda,
712 &contextPtr->fullLambda,
713 &contextPtr->fastChromaLambda,
714 &contextPtr->fullChromaLambda,
715 &contextPtr->fullChromaLambdaSao,
716 contextPtr->qp,
717 contextPtr->chromaQp);
718 }
719 else{
720
721 // Change lambda QP for 4K 5L and 6L
722 EB_U8 lambdaQp = contextPtr->qp;
723
724 (*lambdaAssignmentFunctionTable[sequenceControlSetPtr->staticConfig.predStructure])(
725 pictureControlSetPtr->ParentPcsPtr,
726 &contextPtr->fastLambda,
727 &contextPtr->fullLambda,
728 &contextPtr->fastChromaLambda,
729 &contextPtr->fullChromaLambda,
730 &contextPtr->fullChromaLambdaSao,
731 lambdaQp,
732 contextPtr->chromaQp);
733 }
734
735 return;
736 }
737