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