1 /*
2 * Copyright(c) 2018 Intel Corporation
3 * SPDX - License - Identifier: BSD - 2 - Clause - Patent
4 */
5 
6 #include <stdlib.h>
7 
8 #include "EbDefinitions.h"
9 #include "EbSequenceControlSet.h"
10 
EbSequenceControlSetDctor(EB_PTR p)11 static void EbSequenceControlSetDctor(EB_PTR p)
12 {
13     SequenceControlSet_t *obj = (SequenceControlSet_t*)p;
14     EB_FREE_ARRAY(obj->lcuParamsArray);
15     EB_DELETE(obj->videoUsabilityInfoPtr);
16 }
17 
18 /**************************************************************************************************
19     General notes on how Sequence Control Sets (SCS) are used.
20 
21     SequenceControlSetInstance
22         is the master copy that interacts with the API in real-time.  When a
23         change happens, the changeFlag is signaled so that appropriate action can
24         be taken.  There is one scsInstance per stream/encode instance.  The scsInstance
25         owns the encodeContext
26 
27     encodeContext
28         has context type variables (i.e. non-config) that keep track of global parameters.
29 
30     SequenceControlSets
31         general SCSs are controled by a system resource manager.  They are kept completely
32         separate from the instances.  In general there is one active SCS at a time.  When the
33         changeFlag is signaled, the old active SCS is no longer used for new input pictures.
34         A fresh copy of the scsInstance is made to a new SCS, which becomes the active SCS.  The
35         old SCS will eventually be released back into the SCS pool when its current pictures are
36         finished encoding.
37 
38     Motivations
39         The whole reason for this structure is due to the nature of the pipeline.  We have to
40         take great care not to have pipeline mismanagement.  Once an object enters use in the
41         pipeline, it cannot be changed on the fly or you will have pipeline coherency problems.
42  ***************************************************************************************************/
EbSequenceControlSetCtor(SequenceControlSet_t * sequenceControlSetPtr,EB_PTR objectInitDataPtr)43 EB_ERRORTYPE EbSequenceControlSetCtor(
44     SequenceControlSet_t *sequenceControlSetPtr,
45     EB_PTR objectInitDataPtr)
46 {
47     sequenceControlSetPtr->dctor = EbSequenceControlSetDctor;
48     EbSequenceControlSetInitData_t *scsInitData = (EbSequenceControlSetInitData_t*) objectInitDataPtr;
49     sequenceControlSetPtr->staticConfig.qp = 32;
50 
51     // Segments
52     for(EB_U32 layerIndex=0; layerIndex < MAX_TEMPORAL_LAYERS; ++layerIndex) {
53         sequenceControlSetPtr->meSegmentColumnCountArray[layerIndex] = 1;
54         sequenceControlSetPtr->meSegmentRowCountArray[layerIndex]    = 1;
55         sequenceControlSetPtr->encDecSegmentColCountArray[layerIndex] = 1;
56         sequenceControlSetPtr->encDecSegmentRowCountArray[layerIndex]  = 1;
57         sequenceControlSetPtr->tileGroupColCountArray[layerIndex] = 1;
58         sequenceControlSetPtr->tileGroupRowCountArray[layerIndex] = 1;
59     }
60 
61     // Encode Context
62     if(scsInitData != EB_NULL) {
63         sequenceControlSetPtr->encodeContextPtr                             = scsInitData->encodeContextPtr;
64     }
65 
66     // Profile & ID
67     sequenceControlSetPtr->chromaFormatIdc                                  = EB_YUV420;
68     sequenceControlSetPtr->maxTemporalLayers                                = 1;
69 
70     sequenceControlSetPtr->bitsForPictureOrderCount                         = 16;
71 
72     sequenceControlSetPtr->encoderBitDepth                                  = 8;
73 
74     // Bitdepth
75     sequenceControlSetPtr->inputBitdepth                                    = EB_8BIT;
76     sequenceControlSetPtr->outputBitdepth                                   = EB_8BIT;
77 
78     // GOP Structure
79     sequenceControlSetPtr->maxRefCount                                      = 1;
80 
81     // LCU
82     sequenceControlSetPtr->lcuSize                                          = 64;
83     sequenceControlSetPtr->maxLcuDepth                                      = 3;
84 
85     sequenceControlSetPtr->generalProgressiveSourceFlag                     = 1;
86 
87     // temporal mvp enable flag
88     sequenceControlSetPtr->enableTmvpSps                                    = 1;
89 
90     // Strong Intra Smoothing
91     sequenceControlSetPtr->enableStrongIntraSmoothing                       = EB_TRUE;
92 
93     // Rate Control
94     sequenceControlSetPtr->targetBitrate                                    = 0x1000;
95     sequenceControlSetPtr->availableBandwidth                               = 0x1000;
96 
97     // Quantization
98     sequenceControlSetPtr->qp                                               = 20;
99 
100     // Mv merge
101     sequenceControlSetPtr->mvMergeTotalCount                                = 5;
102 
103     // Initialize vui parameters
104     EB_NEW(
105         sequenceControlSetPtr->videoUsabilityInfoPtr,
106         EbVideoUsabilityInfoCtor);
107 
108     return EB_ErrorNone;
109 }
110 
EbSequenceControlSetCreator(EB_PTR * objectDblPtr,EB_PTR objectInitDataPtr)111 EB_ERRORTYPE EbSequenceControlSetCreator(
112     EB_PTR  *objectDblPtr,
113     EB_PTR   objectInitDataPtr)
114 {
115     SequenceControlSet_t* obj;
116 
117     *objectDblPtr = NULL;
118     EB_NEW(obj, EbSequenceControlSetCtor, objectInitDataPtr);
119     *objectDblPtr = obj;
120 
121     return EB_ErrorNone;
122 }
123 
124 /************************************************
125  * Sequence Control Set Copy
126  ************************************************/
CopySequenceControlSet(SequenceControlSet_t * dst,SequenceControlSet_t * src)127 EB_ERRORTYPE CopySequenceControlSet(
128     SequenceControlSet_t *dst,
129     SequenceControlSet_t *src)
130 {
131     AppVideoUsabilityInfo_t *videoUsabilityInfoPtr = dst->videoUsabilityInfoPtr;
132     size_t sizeCopy = (size_t)((EB_U64)(&dst->pictureControlSetPoolInitCount) -
133                                (EB_U64)(&dst->staticConfig));
134 
135     EB_MEMCPY(&dst->staticConfig, &src->staticConfig, sizeCopy);
136 
137     dst->videoUsabilityInfoPtr = videoUsabilityInfoPtr;
138     EbVideoUsabilityInfoCopy(
139         dst->videoUsabilityInfoPtr,
140         src->videoUsabilityInfoPtr);
141 
142     dst->enableDenoiseFlag = src->enableDenoiseFlag;
143     dst->maxEncMode        = src->maxEncMode;
144 
145     EB_MEMCPY(&dst->activeParameterSet, &src->activeParameterSet, sizeof(AppActiveparameterSetSei_t));
146 
147     return EB_ErrorNone;
148 }
149 
EbSequenceControlSetInstanceDctor(EB_PTR p)150 static void EbSequenceControlSetInstanceDctor(EB_PTR p)
151 {
152     EbSequenceControlSetInstance_t* obj = (EbSequenceControlSetInstance_t*)p;
153     EB_DELETE(obj->encodeContextPtr);
154     EB_DELETE(obj->sequenceControlSetPtr);
155     EB_DESTROY_MUTEX(obj->configMutex);
156 }
157 
EbSequenceControlSetInstanceCtor(EbSequenceControlSetInstance_t * objectPtr)158 EB_ERRORTYPE EbSequenceControlSetInstanceCtor(
159     EbSequenceControlSetInstance_t *objectPtr)
160 {
161     EbSequenceControlSetInitData_t scsInitData;
162     objectPtr->dctor = EbSequenceControlSetInstanceDctor;
163 
164     EB_NEW(
165         objectPtr->encodeContextPtr,
166         EncodeContextCtor,
167         EB_NULL);
168     scsInitData.encodeContextPtr = objectPtr->encodeContextPtr;
169 
170     EB_NEW(
171         objectPtr->sequenceControlSetPtr,
172         EbSequenceControlSetCtor,
173         (void *) &scsInitData);
174 
175     EB_CREATE_MUTEX(objectPtr->configMutex);
176 
177     return EB_ErrorNone;
178 }
179 
LcuParamsInit(SequenceControlSet_t * sequenceControlSetPtr)180 EB_ERRORTYPE LcuParamsInit(
181 	SequenceControlSet_t *sequenceControlSetPtr) {
182 
183 	EB_ERRORTYPE return_error = EB_ErrorNone;
184 	EB_U16	lcuIndex;
185 	EB_U16	rasterScanCuIndex;
186 
187 	EB_U8   pictureLcuWidth  = sequenceControlSetPtr->pictureWidthInLcu;
188 	EB_U8	pictureLcuHeight = sequenceControlSetPtr->pictureHeightInLcu;
189 
190     EB_MALLOC_ARRAY(sequenceControlSetPtr->lcuParamsArray, pictureLcuWidth * pictureLcuHeight);
191 
192 	for (lcuIndex = 0; lcuIndex < pictureLcuWidth * pictureLcuHeight; ++lcuIndex) {
193 		sequenceControlSetPtr->lcuParamsArray[lcuIndex].horizontalIndex = (EB_U8)(lcuIndex % pictureLcuWidth);
194 		sequenceControlSetPtr->lcuParamsArray[lcuIndex].verticalIndex   = (EB_U8)(lcuIndex / pictureLcuWidth);
195         sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX         = sequenceControlSetPtr->lcuParamsArray[lcuIndex].horizontalIndex * sequenceControlSetPtr->lcuSize;
196 		sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY         = sequenceControlSetPtr->lcuParamsArray[lcuIndex].verticalIndex * sequenceControlSetPtr->lcuSize;
197 
198 		sequenceControlSetPtr->lcuParamsArray[lcuIndex].width = (EB_U8)(((sequenceControlSetPtr->lumaWidth - sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX)  < sequenceControlSetPtr->lcuSize) ?
199 			sequenceControlSetPtr->lumaWidth - sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX :
200 			sequenceControlSetPtr->lcuSize);
201 
202 		sequenceControlSetPtr->lcuParamsArray[lcuIndex].height = (EB_U8)(((sequenceControlSetPtr->lumaHeight - sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY) < sequenceControlSetPtr->lcuSize) ?
203 			sequenceControlSetPtr->lumaHeight - sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY :
204 			sequenceControlSetPtr->lcuSize);
205 
206 		sequenceControlSetPtr->lcuParamsArray[lcuIndex].isCompleteLcu = (EB_U8)(((sequenceControlSetPtr->lcuParamsArray[lcuIndex].width == sequenceControlSetPtr->lcuSize) && (sequenceControlSetPtr->lcuParamsArray[lcuIndex].height == sequenceControlSetPtr->lcuSize)) ?
207 			1 :
208 			0);
209 
210 		sequenceControlSetPtr->lcuParamsArray[lcuIndex].isEdgeLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX < sequenceControlSetPtr->lcuSize) ||
211 			(sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY < sequenceControlSetPtr->lcuSize) ||
212 			(sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX > sequenceControlSetPtr->lumaWidth - sequenceControlSetPtr->lcuSize) ||
213 			(sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY > sequenceControlSetPtr->lumaHeight - sequenceControlSetPtr->lcuSize) ? 1 : 0;
214 
215 
216         EB_U8 potentialLogoLcu = 0;
217 
218         // 4K
219         /*__ 14 __         __ 14__*/
220         ///////////////////////////
221         //		 |		  |		 //
222         //		 8		  8		 //
223         //___14_ |		  |_14___//
224         //						 //
225         //						 //
226         //-----------------------// |
227         //						 // 8
228         ///////////////////////////	|
229 
230         // 1080p/720P
231         /*__ 7 __          __ 7__*/
232         ///////////////////////////
233         //		 |		  |		 //
234         //		 4		  4		 //
235         //___7__ |		  |__7___//
236         //						 //
237         //						 //
238         //-----------------------// |
239         //						 // 4
240         ///////////////////////////	|
241 
242         // 480P
243         /*__ 3 __          __ 3__*/
244         ///////////////////////////
245         //		 |		  |		 //
246         //		 2		  2		 //
247         //___3__ |		  |__3___//
248         //						 //
249         //						 //
250         //-----------------------// |
251         //						 // 2
252         ///////////////////////////	|
253         if (sequenceControlSetPtr->inputResolution <= INPUT_SIZE_576p_RANGE_OR_LOWER){
254             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX >= (sequenceControlSetPtr->lumaWidth - (3 * sequenceControlSetPtr->lcuSize))) && (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY < 2 * sequenceControlSetPtr->lcuSize) ? 1 : potentialLogoLcu;
255             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX <  ((3 * sequenceControlSetPtr->lcuSize))) && (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY < 2 * sequenceControlSetPtr->lcuSize) ? 1 : potentialLogoLcu;
256             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY >= (sequenceControlSetPtr->lumaHeight - (2 * sequenceControlSetPtr->lcuSize))) ? 1 : potentialLogoLcu;
257 
258         }
259         else
260         if (sequenceControlSetPtr->inputResolution < INPUT_SIZE_4K_RANGE){
261             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX >= (sequenceControlSetPtr->lumaWidth - (7 * sequenceControlSetPtr->lcuSize))) && (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY < 4 * sequenceControlSetPtr->lcuSize) ? 1 : potentialLogoLcu;
262             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX <  ((7 * sequenceControlSetPtr->lcuSize))) && (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY < 4 * sequenceControlSetPtr->lcuSize) ? 1 : potentialLogoLcu;
263             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY >= (sequenceControlSetPtr->lumaHeight - (4 * sequenceControlSetPtr->lcuSize))) ? 1 : potentialLogoLcu;
264 
265         }
266         else{
267 
268             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX >= (sequenceControlSetPtr->lumaWidth - (14 * sequenceControlSetPtr->lcuSize))) && (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY < 8 * sequenceControlSetPtr->lcuSize) ? 1 : potentialLogoLcu;
269             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX < ((14 * sequenceControlSetPtr->lcuSize))) && (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY < 8 * sequenceControlSetPtr->lcuSize) ? 1 : potentialLogoLcu;
270             potentialLogoLcu = (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY >= (sequenceControlSetPtr->lumaHeight - (8 * sequenceControlSetPtr->lcuSize))) ? 1 : potentialLogoLcu;
271 
272         }
273         sequenceControlSetPtr->lcuParamsArray[lcuIndex].potentialLogoLcu = potentialLogoLcu;
274 
275 		for (rasterScanCuIndex = RASTER_SCAN_CU_INDEX_64x64; rasterScanCuIndex <= RASTER_SCAN_CU_INDEX_8x8_63; rasterScanCuIndex++) {
276 
277 			sequenceControlSetPtr->lcuParamsArray[lcuIndex].rasterScanCuValidity[rasterScanCuIndex] = ((sequenceControlSetPtr->lcuParamsArray[lcuIndex].originX + RASTER_SCAN_CU_X[rasterScanCuIndex] + RASTER_SCAN_CU_SIZE[rasterScanCuIndex] > sequenceControlSetPtr->lumaWidth ) || (sequenceControlSetPtr->lcuParamsArray[lcuIndex].originY + RASTER_SCAN_CU_Y[rasterScanCuIndex] + RASTER_SCAN_CU_SIZE[rasterScanCuIndex] > sequenceControlSetPtr->lumaHeight)) ?
278 				EB_FALSE :
279 				EB_TRUE;
280 		}
281 	}
282 
283     //ConfigureTiles(sequenceControlSetPtr);
284 
285 	return return_error;
286 }
287 
DeriveInputResolution(SequenceControlSet_t * sequenceControlSetPtr,EB_U32 inputSize)288 extern EB_ERRORTYPE DeriveInputResolution(
289 	SequenceControlSet_t *sequenceControlSetPtr,
290 	EB_U32				  inputSize) {
291 	EB_ERRORTYPE return_error = EB_ErrorNone;
292 
293 	sequenceControlSetPtr->inputResolution = (inputSize < INPUT_SIZE_1080i_TH) ?
294 		INPUT_SIZE_576p_RANGE_OR_LOWER :
295 		(inputSize < INPUT_SIZE_1080p_TH) ?
296 			INPUT_SIZE_1080i_RANGE :
297 			(inputSize < INPUT_SIZE_4K_TH) ?
298 				INPUT_SIZE_1080p_RANGE :
299 				INPUT_SIZE_4K_RANGE;
300 
301 	return return_error;
302 }
303 
304