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
9 #include "EbDefinitions.h"
10 #include "EbSystemResourceManager.h"
11 #include "EbPictureControlSet.h"
12 #include "EbSequenceControlSet.h"
13 #include "EbPictureBufferDesc.h"
14 #include "EbErrorCodes.h"
15 #include "EbErrorHandling.h"
16
17 #include "EbResourceCoordinationProcess.h"
18
19 #include "EbResourceCoordinationResults.h"
20 #include "EbReferenceObject.h"
21 #include "EbUtility.h"
22
ResourceCoordinationContextDctor(EB_PTR p)23 static void ResourceCoordinationContextDctor(EB_PTR p)
24 {
25 ResourceCoordinationContext_t *obj = (ResourceCoordinationContext_t*)p;
26 EB_FREE_ARRAY(obj->sequenceControlSetActiveArray);
27 EB_FREE_ARRAY(obj->pictureNumberArray);
28 }
29
30 /************************************************
31 * Resource Coordination Context Constructor
32 ************************************************/
ResourceCoordinationContextCtor(ResourceCoordinationContext_t * contextPtr,EbFifo_t * inputBufferFifoPtr,EbFifo_t * resourceCoordinationResultsOutputFifoPtr,EbFifo_t ** pictureControlSetFifoPtrArray,EbSequenceControlSetInstance_t ** sequenceControlSetInstanceArray,EbFifo_t * sequenceControlSetEmptyFifoPtr,EbCallback_t ** appCallbackPtrArray,EB_U32 * computeSegmentsTotalCountArray,EB_U32 encodeInstancesTotalCount)33 EB_ERRORTYPE ResourceCoordinationContextCtor(
34 ResourceCoordinationContext_t *contextPtr,
35 EbFifo_t *inputBufferFifoPtr,
36 EbFifo_t *resourceCoordinationResultsOutputFifoPtr,
37 EbFifo_t **pictureControlSetFifoPtrArray,
38 EbSequenceControlSetInstance_t **sequenceControlSetInstanceArray,
39 EbFifo_t *sequenceControlSetEmptyFifoPtr,
40 EbCallback_t **appCallbackPtrArray,
41 EB_U32 *computeSegmentsTotalCountArray,
42 EB_U32 encodeInstancesTotalCount)
43 {
44 contextPtr->dctor = ResourceCoordinationContextDctor;
45 contextPtr->inputBufferFifoPtr = inputBufferFifoPtr;
46 contextPtr->resourceCoordinationResultsOutputFifoPtr = resourceCoordinationResultsOutputFifoPtr;
47 contextPtr->pictureControlSetFifoPtrArray = pictureControlSetFifoPtrArray;
48 contextPtr->sequenceControlSetInstanceArray = sequenceControlSetInstanceArray;
49 contextPtr->sequenceControlSetEmptyFifoPtr = sequenceControlSetEmptyFifoPtr;
50 contextPtr->appCallbackPtrArray = appCallbackPtrArray;
51 contextPtr->computeSegmentsTotalCountArray = computeSegmentsTotalCountArray;
52 contextPtr->encodeInstancesTotalCount = encodeInstancesTotalCount;
53
54 // Allocate SequenceControlSetActiveArray
55 EB_CALLOC_ARRAY(contextPtr->sequenceControlSetActiveArray, contextPtr->encodeInstancesTotalCount);
56
57 // Picture Stats
58 EB_CALLOC_ARRAY(contextPtr->pictureNumberArray, contextPtr->encodeInstancesTotalCount);
59
60 return EB_ErrorNone;
61 }
62
63 //******************************************************************************//
64 // Modify the Enc mode based on the buffer Status
65 // Inputs: TargetSpeed, Status of the SCbuffer
66 // Output: EncMod
67 //******************************************************************************//
SpeedBufferControl(ResourceCoordinationContext_t * contextPtr,PictureParentControlSet_t * pictureControlSetPtr,SequenceControlSet_t * sequenceControlSetPtr)68 static void SpeedBufferControl(
69 ResourceCoordinationContext_t *contextPtr,
70 PictureParentControlSet_t *pictureControlSetPtr,
71 SequenceControlSet_t *sequenceControlSetPtr)
72 {
73
74 EB_U64 cursTimeSeconds = 0;
75 EB_U64 cursTimeuSeconds = 0;
76 double overallDuration = 0.0;
77 double instDuration = 0.0;
78 EB_S8 encoderModeDelta = 0;
79 EB_S64 inputFramesCount = 0;
80 EB_S8 changeCond = 0;
81 EB_S64 targetFps = (sequenceControlSetPtr->staticConfig.injectorFrameRate >> 16);
82
83
84 EB_S64 bufferTrshold1 = SC_FRAMES_INTERVAL_T1;
85 EB_S64 bufferTrshold2 = SC_FRAMES_INTERVAL_T2;
86 EB_S64 bufferTrshold3 = SC_FRAMES_INTERVAL_T3;
87 EB_S64 bufferTrshold4 = MAX(SC_FRAMES_INTERVAL_T1, targetFps);
88 EbBlockOnMutex(sequenceControlSetPtr->encodeContextPtr->scBufferMutex);
89
90 if (sequenceControlSetPtr->encodeContextPtr->scFrameIn == 0) {
91 EbHevcStartTime((uint64_t*)&contextPtr->firstInPicArrivedTimeSeconds, (uint64_t*)&contextPtr->firstInPicArrivedTimeuSeconds);
92 }
93 else if (sequenceControlSetPtr->encodeContextPtr->scFrameIn == SC_FRAMES_TO_IGNORE) {
94 contextPtr->startFlag = EB_TRUE;
95 }
96
97 // Compute duration since the start of the encode and since the previous checkpoint
98 EbHevcFinishTime((uint64_t*)&cursTimeSeconds, (uint64_t*)&cursTimeuSeconds);
99
100 EbHevcComputeOverallElapsedTimeMs(
101 contextPtr->firstInPicArrivedTimeSeconds,
102 contextPtr->firstInPicArrivedTimeuSeconds,
103 cursTimeSeconds,
104 cursTimeuSeconds,
105 &overallDuration);
106
107 EbHevcComputeOverallElapsedTimeMs(
108 contextPtr->prevsTimeSeconds,
109 contextPtr->prevsTimeuSeconds,
110 cursTimeSeconds,
111 cursTimeuSeconds,
112 &instDuration);
113
114 inputFramesCount = (EB_S64)overallDuration *(sequenceControlSetPtr->staticConfig.injectorFrameRate >> 16) / 1000;
115 sequenceControlSetPtr->encodeContextPtr->scBuffer = inputFramesCount - sequenceControlSetPtr->encodeContextPtr->scFrameIn;
116
117 encoderModeDelta = 0;
118
119 // Check every bufferTsshold1 for the changes (previousFrameInCheck1 variable)
120 if ((sequenceControlSetPtr->encodeContextPtr->scFrameIn > contextPtr->previousFrameInCheck1 + bufferTrshold1 && sequenceControlSetPtr->encodeContextPtr->scFrameIn >= SC_FRAMES_TO_IGNORE)) {
121 // Go to a slower mode based on the fullness and changes of the buffer
122 if (sequenceControlSetPtr->encodeContextPtr->scBuffer < bufferTrshold4 && (contextPtr->prevEncModeDelta >-1 || (contextPtr->prevEncModeDelta < 0 && sequenceControlSetPtr->encodeContextPtr->scFrameIn > contextPtr->previousModeChangeFrameIn + bufferTrshold4 * 2))) {
123 if (contextPtr->previousBufferCheck1 > sequenceControlSetPtr->encodeContextPtr->scBuffer + bufferTrshold1) {
124 encoderModeDelta += -1;
125 changeCond = 2;
126 }
127 else if (contextPtr->previousModeChangeBuffer > bufferTrshold1 + sequenceControlSetPtr->encodeContextPtr->scBuffer && sequenceControlSetPtr->encodeContextPtr->scBuffer < bufferTrshold1) {
128 encoderModeDelta += -1;
129 changeCond = 4;
130 }
131 }
132
133 // Go to a faster mode based on the fullness and changes of the buffer
134 if (sequenceControlSetPtr->encodeContextPtr->scBuffer >bufferTrshold1 + contextPtr->previousBufferCheck1) {
135 encoderModeDelta += +1;
136 changeCond = 1;
137 }
138 else if (sequenceControlSetPtr->encodeContextPtr->scBuffer > bufferTrshold1 + contextPtr->previousModeChangeBuffer) {
139 encoderModeDelta += +1;
140 changeCond = 3;
141 }
142
143 // Update the encode mode based on the fullness of the buffer
144 // If previous ChangeCond was the same, double the threshold2
145 if (sequenceControlSetPtr->encodeContextPtr->scBuffer > bufferTrshold3 &&
146 (contextPtr->prevChangeCond != 7 || sequenceControlSetPtr->encodeContextPtr->scFrameIn > contextPtr->previousModeChangeFrameIn + bufferTrshold2 * 2) &&
147 sequenceControlSetPtr->encodeContextPtr->scBuffer > contextPtr->previousModeChangeBuffer) {
148 encoderModeDelta += 1;
149 changeCond = 7;
150 }
151 encoderModeDelta = CLIP3(-1, 1, encoderModeDelta);
152 sequenceControlSetPtr->encodeContextPtr->encMode = (EB_ENC_MODE)CLIP3(ENC_MODE_0, sequenceControlSetPtr->maxEncMode, (EB_S8)sequenceControlSetPtr->encodeContextPtr->encMode + encoderModeDelta);
153
154 // Update previous stats
155 contextPtr->previousFrameInCheck1 = sequenceControlSetPtr->encodeContextPtr->scFrameIn;
156 contextPtr->previousBufferCheck1 = sequenceControlSetPtr->encodeContextPtr->scBuffer;
157
158 if (encoderModeDelta) {
159 contextPtr->previousModeChangeBuffer = sequenceControlSetPtr->encodeContextPtr->scBuffer;
160 contextPtr->previousModeChangeFrameIn = sequenceControlSetPtr->encodeContextPtr->scFrameIn;
161 contextPtr->prevEncModeDelta = encoderModeDelta;
162 }
163 }
164
165 // Check every bufferTrshold2 for the changes (previousFrameInCheck2 variable)
166 if ((sequenceControlSetPtr->encodeContextPtr->scFrameIn > contextPtr->previousFrameInCheck2 + bufferTrshold2 && sequenceControlSetPtr->encodeContextPtr->scFrameIn >= SC_FRAMES_TO_IGNORE)) {
167 encoderModeDelta = 0;
168
169 // if no change in the encoder mode and buffer is low enough and level is not increasing, switch to a slower encoder mode
170 // If previous ChangeCond was the same, double the threshold2
171 if (encoderModeDelta == 0 && sequenceControlSetPtr->encodeContextPtr->scFrameIn > contextPtr->previousModeChangeFrameIn + bufferTrshold2 &&
172 (contextPtr->prevChangeCond != 8 || sequenceControlSetPtr->encodeContextPtr->scFrameIn > contextPtr->previousModeChangeFrameIn + bufferTrshold2 * 2) &&
173 ((sequenceControlSetPtr->encodeContextPtr->scBuffer - contextPtr->previousModeChangeBuffer < (bufferTrshold4 / 3)) || contextPtr->previousModeChangeBuffer == 0) &&
174 sequenceControlSetPtr->encodeContextPtr->scBuffer < bufferTrshold3) {
175 encoderModeDelta = -1;
176 changeCond = 8;
177 }
178
179 encoderModeDelta = CLIP3(-1, 1, encoderModeDelta);
180 sequenceControlSetPtr->encodeContextPtr->encMode = (EB_ENC_MODE)CLIP3(ENC_MODE_0, sequenceControlSetPtr->maxEncMode, (EB_S8)sequenceControlSetPtr->encodeContextPtr->encMode + encoderModeDelta);
181 // Update previous stats
182 contextPtr->previousFrameInCheck2 = sequenceControlSetPtr->encodeContextPtr->scFrameIn;
183
184 if (encoderModeDelta) {
185 contextPtr->previousModeChangeBuffer = sequenceControlSetPtr->encodeContextPtr->scBuffer;
186 contextPtr->previousModeChangeFrameIn = sequenceControlSetPtr->encodeContextPtr->scFrameIn;
187 contextPtr->prevEncModeDelta = encoderModeDelta;
188 }
189
190 }
191 // Check every SC_FRAMES_INTERVAL_SPEED frames for the speed calculation (previousFrameInCheck3 variable)
192 if (contextPtr->startFlag || (sequenceControlSetPtr->encodeContextPtr->scFrameIn > contextPtr->previousFrameInCheck3 + SC_FRAMES_INTERVAL_SPEED && sequenceControlSetPtr->encodeContextPtr->scFrameIn >= SC_FRAMES_TO_IGNORE)) {
193 if (contextPtr->startFlag) {
194 contextPtr->curSpeed = (EB_U64)(sequenceControlSetPtr->encodeContextPtr->scFrameOut - 0) * 1000 / (EB_U64)(overallDuration);
195 }
196 else {
197 if (instDuration != 0)
198 contextPtr->curSpeed = (EB_U64)(sequenceControlSetPtr->encodeContextPtr->scFrameOut - contextPtr->prevFrameOut) * 1000 / (EB_U64)(instDuration);
199 }
200 contextPtr->startFlag = EB_FALSE;
201
202 // Update previous stats
203 contextPtr->previousFrameInCheck3 = sequenceControlSetPtr->encodeContextPtr->scFrameIn;
204 contextPtr->prevsTimeSeconds = cursTimeSeconds;
205 contextPtr->prevsTimeuSeconds = cursTimeuSeconds;
206 contextPtr->prevFrameOut = sequenceControlSetPtr->encodeContextPtr->scFrameOut;
207
208 }
209 else if (sequenceControlSetPtr->encodeContextPtr->scFrameIn < SC_FRAMES_TO_IGNORE && (overallDuration != 0)) {
210 contextPtr->curSpeed = (EB_U64)(sequenceControlSetPtr->encodeContextPtr->scFrameOut - 0) * 1000 / (EB_U64)(overallDuration);
211 }
212
213 if (changeCond) {
214 contextPtr->prevChangeCond = changeCond;
215 }
216 sequenceControlSetPtr->encodeContextPtr->scFrameIn++;
217 if (sequenceControlSetPtr->encodeContextPtr->scFrameIn >= SC_FRAMES_TO_IGNORE) {
218 contextPtr->averageEncMod += sequenceControlSetPtr->encodeContextPtr->encMode;
219 }
220 else {
221 contextPtr->averageEncMod = 0;
222 }
223
224 // Set the encoder level
225 pictureControlSetPtr->encMode = sequenceControlSetPtr->encodeContextPtr->encMode;
226
227 EbReleaseMutex(sequenceControlSetPtr->encodeContextPtr->scBufferMutex);
228
229 contextPtr->prevEncMod = sequenceControlSetPtr->encodeContextPtr->encMode;
230 }
231
232
233
234 /******************************************************
235 * Derive Pre-Analysis settings for OQ
236 Input : encoder mode and tune
237 Output : Pre-Analysis signal(s)
238 ******************************************************/
SignalDerivationPreAnalysisOq(SequenceControlSet_t * sequenceControlSetPtr,PictureParentControlSet_t * pictureControlSetPtr)239 static EB_ERRORTYPE SignalDerivationPreAnalysisOq(
240 SequenceControlSet_t *sequenceControlSetPtr,
241 PictureParentControlSet_t *pictureControlSetPtr) {
242
243 EB_ERRORTYPE return_error = EB_ErrorNone;
244
245 EB_U8 inputResolution = sequenceControlSetPtr->inputResolution;
246
247
248 // Derive Noise Detection Method
249 if (inputResolution == INPUT_SIZE_4K_RANGE) {
250 if (pictureControlSetPtr->encMode <= ENC_MODE_3) {
251 pictureControlSetPtr->noiseDetectionMethod = NOISE_DETECT_FULL_PRECISION;
252 }
253 else {
254 pictureControlSetPtr->noiseDetectionMethod = NOISE_DETECT_HALF_PRECISION;
255 }
256 }
257 else if (inputResolution == INPUT_SIZE_1080p_RANGE) {
258 if (pictureControlSetPtr->encMode <= ENC_MODE_3) {
259 pictureControlSetPtr->noiseDetectionMethod = NOISE_DETECT_FULL_PRECISION;
260 }
261 else {
262 pictureControlSetPtr->noiseDetectionMethod = NOISE_DETECT_QUARTER_PRECISION;
263 }
264 }
265 else {
266 pictureControlSetPtr->noiseDetectionMethod = NOISE_DETECT_FULL_PRECISION;
267 }
268
269
270 // Derive Noise Detection Threshold
271 if (pictureControlSetPtr->encMode <= ENC_MODE_3) {
272 pictureControlSetPtr->noiseDetectionTh = 0;
273 }
274 else if (pictureControlSetPtr->encMode <= ENC_MODE_8) {
275 if (inputResolution <= INPUT_SIZE_1080p_RANGE) {
276 pictureControlSetPtr->noiseDetectionTh = 1;
277 }
278 else {
279 pictureControlSetPtr->noiseDetectionTh = 0;
280 }
281 }
282 else{
283 pictureControlSetPtr->noiseDetectionTh = 1;
284 }
285
286 EB_U8 hmeMeLevel = pictureControlSetPtr->encMode;
287
288 EB_U32 inputRatio = sequenceControlSetPtr->lumaWidth / sequenceControlSetPtr->lumaHeight;
289 EB_U8 resolutionIndex = inputResolution <= INPUT_SIZE_576p_RANGE_OR_LOWER ? 0 : // 480P
290 (inputResolution <= INPUT_SIZE_1080i_RANGE && inputRatio < 2) ? 1 : // 720P
291 (inputResolution <= INPUT_SIZE_1080i_RANGE && inputRatio > 3) ? 2 : // 1080I
292 (inputResolution <= INPUT_SIZE_1080p_RANGE) ? 3 : // 1080I
293 4; // 4K
294
295 // Derive HME Flag
296 if (sequenceControlSetPtr->staticConfig.useDefaultMeHme)
297 pictureControlSetPtr->enableHmeFlag = EB_TRUE;
298 else
299 pictureControlSetPtr->enableHmeFlag = sequenceControlSetPtr->staticConfig.enableHmeFlag;
300 pictureControlSetPtr->enableHmeLevel0Flag = EnableHmeLevel0FlagOq[resolutionIndex][hmeMeLevel];
301 pictureControlSetPtr->enableHmeLevel1Flag = EnableHmeLevel1FlagOq[resolutionIndex][hmeMeLevel];
302 pictureControlSetPtr->enableHmeLevel2Flag = EnableHmeLevel2FlagOq[resolutionIndex][hmeMeLevel];
303
304 pictureControlSetPtr->enableDenoiseSrcFlag = EB_FALSE;
305
306 if (pictureControlSetPtr->encMode <= ENC_MODE_7) {
307 pictureControlSetPtr->disableVarianceFlag = EB_FALSE;
308 }
309 else if (pictureControlSetPtr->encMode <= ENC_MODE_8) {
310 if (inputResolution == INPUT_SIZE_4K_RANGE) {
311 pictureControlSetPtr->disableVarianceFlag = EB_TRUE;
312 }
313 else {
314 pictureControlSetPtr->disableVarianceFlag = EB_FALSE;
315 }
316 }
317 else {
318 pictureControlSetPtr->disableVarianceFlag = EB_TRUE;
319 }
320
321 return return_error;
322 }
323
324
325
326 /***************************************
327 * ResourceCoordination Kernel
328 ***************************************/
ResourceCoordinationKernel(void * inputPtr)329 void* ResourceCoordinationKernel(void *inputPtr)
330 {
331 ResourceCoordinationContext_t *contextPtr = (ResourceCoordinationContext_t*) inputPtr;
332
333 EbObjectWrapper_t *pictureControlSetWrapperPtr;
334
335 PictureParentControlSet_t *pictureControlSetPtr;
336
337 SequenceControlSet_t *sequenceControlSetPtr;
338
339 EbObjectWrapper_t *ebInputWrapperPtr;
340 EB_BUFFERHEADERTYPE *ebInputPtr;
341 EbObjectWrapper_t *outputWrapperPtr;
342 ResourceCoordinationResults_t *outputResultsPtr;
343
344 EbObjectWrapper_t *inputPictureWrapperPtr;
345 EbPictureBufferDesc_t *inputPicturePtr;
346 EbObjectWrapper_t *referencePictureWrapperPtr;
347
348 EB_U32 instanceIndex;
349
350 EB_BOOL endOfSequenceFlag = EB_FALSE;
351
352 EB_BOOL is16BitInput;
353
354 EB_U32 inputSize = 0;
355 EbObjectWrapper_t *prevPictureControlSetWrapperPtr = 0;
356 EB_U32 chromaFormat = EB_YUV420;
357 EB_U32 subWidthCMinus1 = 1;
358 EB_U32 subHeightCMinus1 = 1;
359
360 for(;;) {
361
362 // Tie instanceIndex to zero for now...
363 instanceIndex = 0;
364
365 // Get the Next Input Buffer [BLOCKING]
366 EbGetFullObject(
367 contextPtr->inputBufferFifoPtr,
368 &ebInputWrapperPtr);
369 EB_CHECK_END_OBJ(ebInputWrapperPtr);
370 ebInputPtr = (EB_BUFFERHEADERTYPE*) ebInputWrapperPtr->objectPtr;
371
372 sequenceControlSetPtr = contextPtr->sequenceControlSetInstanceArray[instanceIndex]->sequenceControlSetPtr;
373
374 // Get source video bit depth
375 is16BitInput = (EB_BOOL)(sequenceControlSetPtr->staticConfig.encoderBitDepth > EB_8BIT);
376
377 chromaFormat = sequenceControlSetPtr->chromaFormatIdc;
378 subWidthCMinus1 = (chromaFormat == EB_YUV444 ? 1 : 2) - 1;
379 subHeightCMinus1 = (chromaFormat >= EB_YUV422 ? 1 : 2) - 1;
380 // If config changes occured since the last picture began encoding, then
381 // prepare a new sequenceControlSetPtr containing the new changes and update the state
382 // of the previous Active SequenceControlSet
383 EbBlockOnMutex(contextPtr->sequenceControlSetInstanceArray[instanceIndex]->configMutex);
384 if (contextPtr->sequenceControlSetInstanceArray[instanceIndex]->encodeContextPtr->initialPicture) {
385 inputSize = sequenceControlSetPtr->lumaWidth * sequenceControlSetPtr->lumaHeight;
386
387 // HDR BT2020
388 if (sequenceControlSetPtr->staticConfig.videoUsabilityInfo)
389 {
390 AppVideoUsabilityInfo_t *vuiPtr = sequenceControlSetPtr->videoUsabilityInfoPtr;
391
392 if (sequenceControlSetPtr->staticConfig.highDynamicRangeInput && is16BitInput){
393 vuiPtr->aspectRatioInfoPresentFlag = EB_TRUE;
394 vuiPtr->overscanInfoPresentFlag = EB_FALSE;
395
396 vuiPtr->videoSignalTypePresentFlag = EB_TRUE;
397 vuiPtr->videoFormat = 5;
398 vuiPtr->videoFullRangeFlag = EB_FALSE;
399
400 vuiPtr->colorDescriptionPresentFlag = EB_TRUE;
401 vuiPtr->colorPrimaries = 9; // BT2020
402 vuiPtr->transferCharacteristics = 16; // SMPTE ST2048
403 vuiPtr->matrixCoeffs = 9;
404
405 vuiPtr->chromaLocInfoPresentFlag = EB_TRUE;
406 vuiPtr->chromaSampleLocTypeTopField = 2;
407 vuiPtr->chromaSampleLocTypeBottomField = 2;
408 }
409
410 vuiPtr->vuiTimingInfoPresentFlag = EB_TRUE;
411 if (sequenceControlSetPtr->staticConfig.frameRateDenominator != 0 && sequenceControlSetPtr->staticConfig.frameRateNumerator != 0) {
412 vuiPtr->vuiTimeScale = (sequenceControlSetPtr->staticConfig.frameRateNumerator);
413 vuiPtr->vuiNumUnitsInTick = sequenceControlSetPtr->staticConfig.frameRateDenominator;
414 }
415 else {
416 vuiPtr->vuiTimeScale = (sequenceControlSetPtr->staticConfig.frameRate) > 1000 ? (sequenceControlSetPtr->staticConfig.frameRate) : (sequenceControlSetPtr->staticConfig.frameRate)<<16;
417 vuiPtr->vuiNumUnitsInTick = 1 << 16;
418 }
419
420 }
421 // Get empty SequenceControlSet [BLOCKING]
422 EbGetEmptyObject(
423 contextPtr->sequenceControlSetEmptyFifoPtr,
424 &contextPtr->sequenceControlSetActiveArray[instanceIndex]);
425
426 // Copy the contents of the active SequenceControlSet into the new empty SequenceControlSet
427 CopySequenceControlSet(
428 (SequenceControlSet_t*) contextPtr->sequenceControlSetActiveArray[instanceIndex]->objectPtr,
429 sequenceControlSetPtr);
430
431 }
432 EbReleaseMutex(contextPtr->sequenceControlSetInstanceArray[instanceIndex]->configMutex);
433 if (sequenceControlSetPtr->staticConfig.rateControlMode) {
434 // Sequence Control Set is released by Rate Control after passing through MDC->MD->ENCDEC->Packetization->RateControl
435 // ,in the PictureManager after receiving the reference and in PictureManager after receiving the feedback
436 EbObjectIncLiveCount(
437 contextPtr->sequenceControlSetActiveArray[instanceIndex],
438 3);
439 }
440 else {
441 // Sequence Control Set is released by Rate Control after passing through MDC->MD->ENCDEC->Packetization->RateControl
442 // and in the PictureManager
443 EbObjectIncLiveCount(
444 contextPtr->sequenceControlSetActiveArray[instanceIndex],
445 2);
446
447 }
448 // Set the current SequenceControlSet
449 sequenceControlSetPtr = (SequenceControlSet_t*) contextPtr->sequenceControlSetActiveArray[instanceIndex]->objectPtr;
450
451 //Move to pcs init stage
452 //InitTileInfo(sequenceControlSetPtr);
453
454 sequenceControlSetPtr->pictureWidthInLcu = (EB_U8)((sequenceControlSetPtr->lumaWidth + sequenceControlSetPtr->lcuSize - 1) / sequenceControlSetPtr->lcuSize);
455 sequenceControlSetPtr->pictureHeightInLcu = (EB_U8)((sequenceControlSetPtr->lumaHeight + sequenceControlSetPtr->lcuSize - 1) / sequenceControlSetPtr->lcuSize);
456 sequenceControlSetPtr->lcuTotalCount = sequenceControlSetPtr->pictureWidthInLcu * sequenceControlSetPtr->pictureHeightInLcu;
457
458 // Init LCU Params
459 if (contextPtr->sequenceControlSetInstanceArray[instanceIndex]->encodeContextPtr->initialPicture) {
460 DeriveInputResolution(
461 sequenceControlSetPtr,
462 inputSize);
463
464 LcuParamsInit(sequenceControlSetPtr);
465 }
466
467 //Get a New ParentPCS where we will hold the new inputPicture
468 EbGetEmptyObject(
469 contextPtr->pictureControlSetFifoPtrArray[instanceIndex],
470 &pictureControlSetWrapperPtr);
471
472 // Parent PCS is released by the Rate Control after passing through MDC->MD->ENCDEC->Packetization
473 EbObjectIncLiveCount(
474 pictureControlSetWrapperPtr,
475 2);
476
477 pictureControlSetPtr = (PictureParentControlSet_t*) pictureControlSetWrapperPtr->objectPtr;
478
479 pictureControlSetPtr->pPcsWrapperPtr = pictureControlSetWrapperPtr;
480
481 // Set the Encoder mode
482 pictureControlSetPtr->encMode = sequenceControlSetPtr->staticConfig.encMode;
483
484 // Keep track of the previous input for the ZZ SADs computation
485 pictureControlSetPtr->previousPictureControlSetWrapperPtr = (contextPtr->sequenceControlSetInstanceArray[instanceIndex]->encodeContextPtr->initialPicture) ?
486 pictureControlSetWrapperPtr :
487 sequenceControlSetPtr->encodeContextPtr->previousPictureControlSetWrapperPtr;
488
489 sequenceControlSetPtr->encodeContextPtr->previousPictureControlSetWrapperPtr = pictureControlSetWrapperPtr;
490
491 // Copy data from the buffer to the input frame
492 // *Note - Assumes 4:2:0 planar
493 inputPictureWrapperPtr = NULL;
494 inputPicturePtr = NULL;
495
496 // assign the input picture
497 pictureControlSetPtr->enhancedPicturePtr = (EbPictureBufferDesc_t*)ebInputPtr->pBuffer;
498 // start latency measure as soon as we copy input picture from buffer
499 pictureControlSetPtr->startTimeSeconds = 0;
500 pictureControlSetPtr->startTimeuSeconds = 0;
501
502 EbHevcStartTime((uint64_t*)&pictureControlSetPtr->startTimeSeconds, (uint64_t*)&pictureControlSetPtr->startTimeuSeconds);
503
504 inputPicturePtr = pictureControlSetPtr->enhancedPicturePtr;
505
506 // Setup new input picture buffer
507 inputPicturePtr->bitDepth = sequenceControlSetPtr->inputBitdepth;
508 inputPicturePtr->originX = sequenceControlSetPtr->leftPadding;
509
510 inputPicturePtr->originY = sequenceControlSetPtr->topPadding;
511
512 inputPicturePtr->maxWidth = sequenceControlSetPtr->maxInputLumaWidth;
513 inputPicturePtr->maxHeight = sequenceControlSetPtr->maxInputLumaHeight;
514 inputPicturePtr->lumaSize =
515 ((sequenceControlSetPtr->maxInputLumaWidth - sequenceControlSetPtr->maxInputPadRight) + sequenceControlSetPtr->leftPadding + sequenceControlSetPtr->rightPadding) *
516 ((sequenceControlSetPtr->maxInputLumaHeight - sequenceControlSetPtr->maxInputPadBottom) + sequenceControlSetPtr->topPadding + sequenceControlSetPtr->botPadding);
517 inputPicturePtr->chromaSize = inputPicturePtr->lumaSize >> (3 - chromaFormat);
518
519 inputPicturePtr->width = sequenceControlSetPtr->lumaWidth;
520 inputPicturePtr->height = sequenceControlSetPtr->lumaHeight;
521 inputPicturePtr->strideY = sequenceControlSetPtr->lumaWidth + sequenceControlSetPtr->leftPadding + sequenceControlSetPtr->rightPadding;
522 inputPicturePtr->strideCb = inputPicturePtr->strideCr = inputPicturePtr->strideY >> subWidthCMinus1;
523
524 inputPicturePtr->strideBitIncY = inputPicturePtr->strideY;
525 inputPicturePtr->strideBitIncCb = inputPicturePtr->strideCb;
526 inputPicturePtr->strideBitIncCr = inputPicturePtr->strideCr;
527
528 pictureControlSetPtr->ebInputPtr = ebInputPtr;
529 pictureControlSetPtr->ebInputWrapperPtr = ebInputWrapperPtr;
530
531 endOfSequenceFlag = (ebInputPtr->nFlags & EB_BUFFERFLAG_EOS) ? EB_TRUE : EB_FALSE;
532
533 pictureControlSetPtr->sequenceControlSetWrapperPtr = contextPtr->sequenceControlSetActiveArray[instanceIndex];
534 pictureControlSetPtr->inputPictureWrapperPtr = inputPictureWrapperPtr;
535
536 // Set Picture Control Flags
537 pictureControlSetPtr->idrFlag = sequenceControlSetPtr->encodeContextPtr->initialPicture || (ebInputPtr->sliceType == EB_IDR_PICTURE);
538 pictureControlSetPtr->craFlag = (ebInputPtr->sliceType == EB_I_PICTURE) ? EB_TRUE : EB_FALSE;
539 pictureControlSetPtr->sceneChangeFlag = EB_FALSE;
540
541 pictureControlSetPtr->qpOnTheFly = EB_FALSE;
542
543 //pictureControlSetPtr->lcuTotalCount = sequenceControlSetPtr->lcuTotalCount;
544
545 if (sequenceControlSetPtr->staticConfig.speedControlFlag) {
546 SpeedBufferControl(
547 contextPtr,
548 pictureControlSetPtr,
549 sequenceControlSetPtr);
550 }
551 else {
552 pictureControlSetPtr->encMode = (EB_ENC_MODE)sequenceControlSetPtr->staticConfig.encMode;
553 }
554
555 // Set the SCD Mode
556 sequenceControlSetPtr->scdMode = sequenceControlSetPtr->staticConfig.sceneChangeDetection == 0 ?
557 SCD_MODE_0 :
558 SCD_MODE_1 ;
559
560 SignalDerivationPreAnalysisOq(
561 sequenceControlSetPtr,
562 pictureControlSetPtr);
563
564 // Rate Control
565 // Set the ME Distortion and OIS Historgrams to zero
566 if (sequenceControlSetPtr->staticConfig.rateControlMode){
567 EB_MEMSET(pictureControlSetPtr->meDistortionHistogram, 0, NUMBER_OF_SAD_INTERVALS*sizeof(EB_U16));
568 EB_MEMSET(pictureControlSetPtr->oisDistortionHistogram, 0, NUMBER_OF_INTRA_SAD_INTERVALS*sizeof(EB_U16));
569 }
570 pictureControlSetPtr->fullLcuCount = 0;
571
572 if (sequenceControlSetPtr->staticConfig.useQpFile == 1){
573 pictureControlSetPtr->qpOnTheFly = EB_TRUE;
574 if (ebInputPtr->qpValue > 51)
575 CHECK_REPORT_ERROR_NC(contextPtr->sequenceControlSetInstanceArray[instanceIndex]->encodeContextPtr->appCallbackPtr, EB_ENC_RES_COORD_InvalidQP);
576 pictureControlSetPtr->pictureQp = (EB_U8)ebInputPtr->qpValue;
577 }
578 else {
579 pictureControlSetPtr->qpOnTheFly = EB_FALSE;
580 pictureControlSetPtr->pictureQp = (EB_U8)sequenceControlSetPtr->qp;
581 }
582
583 // Picture Stats
584 pictureControlSetPtr->pictureNumber = contextPtr->pictureNumberArray[instanceIndex]++;
585
586 #if DEADLOCK_DEBUG
587 if ((pictureControlSetPtr->pictureNumber >= MIN_POC) && (pictureControlSetPtr->pictureNumber <= MAX_POC))
588 if (!endOfSequenceFlag)
589 SVT_LOG("POC %lu RESCOOR IN \n", pictureControlSetPtr->pictureNumber);
590 #endif
591 // Set the picture structure: 0: progressive, 1: top, 2: bottom
592 pictureControlSetPtr->pictStruct = sequenceControlSetPtr->interlacedVideo == EB_FALSE ?
593 PROGRESSIVE_PICT_STRUCT :
594 pictureControlSetPtr->pictureNumber % 2 == 0 ?
595 TOP_FIELD_PICT_STRUCT :
596 BOTTOM_FIELD_PICT_STRUCT ;
597
598 sequenceControlSetPtr->encodeContextPtr->initialPicture = EB_FALSE;
599
600 // Get Empty Reference Picture Object
601 EbGetEmptyObject(
602 sequenceControlSetPtr->encodeContextPtr->paReferencePicturePoolFifoPtr,
603 &referencePictureWrapperPtr);
604
605 pictureControlSetPtr->paReferencePictureWrapperPtr = referencePictureWrapperPtr;
606
607 // Note: the PPCS and its PA reference picture will be released in both EncDec and RateControl kernels.
608 // Give the new Reference a nominal liveCount of 2
609 EbObjectIncLiveCount(
610 pictureControlSetPtr->paReferencePictureWrapperPtr,
611 2);
612
613 // Get Empty Output Results Object
614 // Note: record the PCS object into output of the Resource Coordination process for EOS frame(s).
615 // Because EbH265GetPacket() can get the encoded bit stream only if Packetization process has
616 // posted the buffer as its result, and the buffer belonging to a PCS object is recorded in
617 // the Initial Rate Control process. So need to record the PCS object immediately once the
618 // 1st frame is EOS, to make it go through the whole encoding kernels.
619 if (((pictureControlSetPtr->pictureNumber > 0) && (prevPictureControlSetWrapperPtr != (EbObjectWrapper_t*)EB_NULL)) ||
620 endOfSequenceFlag) {
621 if (prevPictureControlSetWrapperPtr && prevPictureControlSetWrapperPtr->objectPtr)
622 ((PictureParentControlSet_t *)prevPictureControlSetWrapperPtr->objectPtr)->endOfSequenceFlag = endOfSequenceFlag;
623
624 EbGetEmptyObject(
625 contextPtr->resourceCoordinationResultsOutputFifoPtr,
626 &outputWrapperPtr);
627 outputResultsPtr = (ResourceCoordinationResults_t *)outputWrapperPtr->objectPtr;
628 if (endOfSequenceFlag && (pictureControlSetPtr->pictureNumber == 0)) {
629 ((PictureParentControlSet_t *)pictureControlSetWrapperPtr->objectPtr)->endOfSequenceFlag = endOfSequenceFlag;
630 outputResultsPtr->pictureControlSetWrapperPtr = pictureControlSetWrapperPtr;
631 } else
632 outputResultsPtr->pictureControlSetWrapperPtr = prevPictureControlSetWrapperPtr;
633
634 // Post the finished Results Object
635 EbPostFullObject(outputWrapperPtr);
636 #if DEADLOCK_DEBUG
637 if ((((PictureParentControlSet_t *)outputResultsPtr->pictureControlSetWrapperPtr->objectPtr)->pictureNumber >= MIN_POC) &&
638 (((PictureParentControlSet_t *)outputResultsPtr->pictureControlSetWrapperPtr->objectPtr)->pictureNumber <= MAX_POC))
639 SVT_LOG("POC %lu RESCOOR OUT \n", ((PictureParentControlSet_t *)outputResultsPtr->pictureControlSetWrapperPtr->objectPtr)->pictureNumber);
640 #endif
641 }
642
643 prevPictureControlSetWrapperPtr = pictureControlSetWrapperPtr;
644
645 if (sequenceControlSetPtr->staticConfig.segmentOvEnabled) {
646 EB_MEMCPY(pictureControlSetPtr->segmentOvArray, ebInputPtr->segmentOvPtr, sizeof(SegmentOverride_t) * sequenceControlSetPtr->lcuTotalCount);
647 }
648 }
649
650 return EB_NULL;
651 }
652