1 /*
2 * Copyright (c) 2014-2019, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file codechal_encode_sfc.cpp
24 //! \brief Implements the encode interface extension for CSC via VEBox/SFC.
25 //! \details Downsampling in this case is supported by the VEBox fixed function HW unit.
26 //!
27
28 #include "codechal_encode_sfc.h"
29 #include "codechal_encoder_base.h"
30 #include "hal_oca_interface.h"
31
32 #define CODECHAL_IS_BT601_CSPACE(format) \
33 ( (format == MHW_CSpace_BT601) || \
34 (format == MHW_CSpace_xvYCC601) || \
35 (format == MHW_CSpace_BT601Gray) || \
36 (format == MHW_CSpace_BT601_FullRange) || \
37 (format == MHW_CSpace_BT601Gray_FullRange) )
38
39 #define CODECHAL_IS_BT709_CSPACE(format) \
40 ( (format == MHW_CSpace_BT709) || \
41 (format == MHW_CSpace_xvYCC709) || \
42 (format == MHW_CSpace_BT709_FullRange) )
43
44 // Generic YUV to RGB conversion matrix from BT.601 standard
45 const float CODECHAL_CSC_BT601_YUV_RGB[9] =
46 {
47 1.000000f, 0.000000f, 1.402000f,
48 1.000000f, -0.344136f, -0.714136f,
49 1.000000f, 1.772000f, 0.000000f
50 };
51
52 // Generic YUV to RGB conversion matrix from BT.709 standard
53 const float CODECHAL_CSC_BT709_YUV_RGB[9] =
54 {
55 1.000000f, 0.000000f, 1.574800f,
56 1.000000f, -0.187324f, -0.468124f,
57 1.000000f, 1.855600f, 0.000000f
58 };
59
60 // Generic RGB to YUV conversion matrix from BT.601 standard
61 const float CODECHAL_CSC_BT601_RGB_YUV[9] =
62 {
63 0.299000f, 0.587000f, 0.114000f,
64 -0.168736f, -0.331264f, 0.500000f,
65 0.500000f, -0.418688f, -0.081312f
66 };
67
68 // Generic RGB to YUV conversion matrix from BT.709 standard
69 const float CODECHAL_CSC_BT709_RGB_YUV[9] =
70 {
71 0.212600f, 0.715200f, 0.072200f,
72 -0.114572f, -0.385428f, 0.500000f,
73 0.500000f, -0.454153f, -0.045847f
74 };
75
76 // BT2020 RGB to Non-constant YUV conversion matrix from R-REC-BT.2020-1-201406-I!!PDF-E.pdf
77 const float CODECHAL_CSC_BT2020_RGB_YUV[9] =
78 {
79 0.262700f, 0.678000f, 0.059300f, // Y
80 -0.139630f, -0.360370f, 0.500000f, // U
81 0.500000f, -0.459786f, -0.040214f // V
82 };
83
84 // BT2020 Non-constant YUV to RGB conversion matrix from R-REC-BT.2020-1-201406-I!!PDF-E.pdf
85 const float CODECHAL_CSC_BT2020_YUV_RGB[9] =
86 {
87 1.000000f, 0.000000f, 1.474600f, //R
88 1.000000f, -0.164553f, -0.571353f, //G
89 1.000000f, 1.881400f, 0.000000f //B
90 };
91
~CodecHalEncodeSfc()92 CodecHalEncodeSfc::~CodecHalEncodeSfc()
93 {
94 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
95
96 CODECHAL_ENCODE_FUNCTION_ENTER;
97
98 // pVeboxInterface->pfnDestroy() will be called in CodecHal_HwDestroy(), no need to destroy here
99
100 FreeResources();
101 }
102
IsCspace(MHW_CSPACE srcCspace,MHW_CSPACE dstCspace)103 bool CodecHalEncodeSfc::IsCspace(MHW_CSPACE srcCspace, MHW_CSPACE dstCspace)
104 {
105 switch (dstCspace)
106 {
107 case MHW_CSpace_RGB:
108 return (srcCspace == MHW_CSpace_sRGB ||
109 srcCspace == MHW_CSpace_stRGB);
110
111 case MHW_CSpace_YUV:
112 return (srcCspace == MHW_CSpace_BT709 ||
113 srcCspace == MHW_CSpace_BT601 ||
114 srcCspace == MHW_CSpace_BT601_FullRange ||
115 srcCspace == MHW_CSpace_BT709_FullRange ||
116 srcCspace == MHW_CSpace_xvYCC709 ||
117 srcCspace == MHW_CSpace_xvYCC601);
118
119 case MHW_CSpace_Gray:
120 return (srcCspace == MHW_CSpace_BT601Gray ||
121 srcCspace == MHW_CSpace_BT601Gray_FullRange);
122
123 case MHW_CSpace_Any:
124 return (srcCspace != MHW_CSpace_None);
125
126 case MHW_CSpace_BT2020:
127 return (srcCspace == MHW_CSpace_BT2020 ||
128 srcCspace == MHW_CSpace_BT2020_FullRange);
129
130 case MHW_CSpace_BT2020_RGB:
131 return (srcCspace == MHW_CSpace_BT2020_RGB ||
132 srcCspace == MHW_CSpace_BT2020_stRGB);
133
134 default:
135 return (srcCspace == dstCspace);
136 }
137
138 return false;
139 }
140
GetRgbRangeAndOffset(MHW_CSPACE srcCspace,float * rgbOffset,float * rgbExcursion)141 bool CodecHalEncodeSfc::GetRgbRangeAndOffset(
142 MHW_CSPACE srcCspace,
143 float *rgbOffset,
144 float *rgbExcursion)
145 {
146 bool ret = true;
147
148 switch (srcCspace)
149 {
150 case MHW_CSpace_sRGB:
151 case MHW_CSpace_BT2020_RGB:
152 *rgbOffset = 0.0f;
153 *rgbExcursion = 255.0f;
154 break;
155
156 case MHW_CSpace_stRGB:
157 case MHW_CSpace_BT2020_stRGB:
158 *rgbOffset = 16.0f;
159 *rgbExcursion = 219.0f;
160 break;
161
162 default:
163 ret = false;
164 break;
165 }
166
167 return ret;
168 }
169
GetYuvRangeAndOffset(MHW_CSPACE srcCspace,float * lumaOffset,float * lumaExcursion,float * chromaZero,float * chromaExcursion)170 bool CodecHalEncodeSfc::GetYuvRangeAndOffset(
171 MHW_CSPACE srcCspace,
172 float *lumaOffset,
173 float *lumaExcursion,
174 float *chromaZero,
175 float *chromaExcursion)
176 {
177 bool ret = true;
178
179 switch (srcCspace)
180 {
181 case MHW_CSpace_BT601_FullRange:
182 case MHW_CSpace_BT709_FullRange:
183 case MHW_CSpace_BT601Gray_FullRange:
184 case MHW_CSpace_BT2020_FullRange:
185 *lumaOffset = 0.0f;
186 *lumaExcursion = 255.0f;
187 *chromaZero = 128.0f;
188 *chromaExcursion = 255.0f;
189 break;
190
191 case MHW_CSpace_BT601:
192 case MHW_CSpace_BT709:
193 case MHW_CSpace_xvYCC601: // since matrix is the same as 601, use the same range
194 case MHW_CSpace_xvYCC709: // since matrix is the same as 709, use the same range
195 case MHW_CSpace_BT601Gray:
196 case MHW_CSpace_BT2020:
197 *lumaOffset = 16.0f;
198 *lumaExcursion = 219.0f;
199 *chromaZero = 128.0f;
200 *chromaExcursion = 224.0f;
201 break;
202
203 default:
204 ret = false;
205 break;
206 }
207
208 return ret;
209 }
210
CalcYuvToRgbMatrix(MHW_CSPACE srcCspace,MHW_CSPACE dstCspace,float * transferMatrix,float * outMatrix)211 bool CodecHalEncodeSfc::CalcYuvToRgbMatrix(
212 MHW_CSPACE srcCspace, // [in] YUV Color space
213 MHW_CSPACE dstCspace, // [in] RGB Color space
214 float *transferMatrix, // [in] Transfer matrix (3x3)
215 float *outMatrix) // [out] Conversion matrix (3x4)
216 {
217 bool ret = true;
218 float lumaOffset, lumaExcursion, chromaZero, chromaExcursion;
219 float rgbOffset, rgbExcursion;
220
221 ret = GetRgbRangeAndOffset(dstCspace, &rgbOffset, &rgbExcursion);
222 if (ret)
223 {
224 ret = GetYuvRangeAndOffset(srcCspace, &lumaOffset, &lumaExcursion, &chromaZero, &chromaExcursion);
225 }
226 if (ret)
227 {
228
229 // after + (3x3)(3x3)
230 outMatrix[0] = transferMatrix[0] * rgbExcursion / lumaExcursion;
231 outMatrix[4] = transferMatrix[3] * rgbExcursion / lumaExcursion;
232 outMatrix[8] = transferMatrix[6] * rgbExcursion / lumaExcursion;
233 outMatrix[1] = transferMatrix[1] * rgbExcursion / chromaExcursion;
234 outMatrix[5] = transferMatrix[4] * rgbExcursion / chromaExcursion;
235 outMatrix[9] = transferMatrix[7] * rgbExcursion / chromaExcursion;
236 outMatrix[2] = transferMatrix[2] * rgbExcursion / chromaExcursion;
237 outMatrix[6] = transferMatrix[5] * rgbExcursion / chromaExcursion;
238 outMatrix[10] = transferMatrix[8] * rgbExcursion / chromaExcursion;
239
240 // (3x1) - (3x3)(3x3)(3x1)
241 outMatrix[3] = rgbOffset - (outMatrix[0] * lumaOffset + outMatrix[1] * chromaZero + outMatrix[2] * chromaZero);
242 outMatrix[7] = rgbOffset - (outMatrix[4] * lumaOffset + outMatrix[5] * chromaZero + outMatrix[6] * chromaZero);
243 outMatrix[11] = rgbOffset - (outMatrix[8] * lumaOffset + outMatrix[9] * chromaZero + outMatrix[10] * chromaZero);
244 }
245 return ret;
246 }
247
CalcRgbToYuvMatrix(MHW_CSPACE srcCspace,MHW_CSPACE dstCspace,float * transferMatrix,float * outMatrix)248 bool CodecHalEncodeSfc::CalcRgbToYuvMatrix(
249 MHW_CSPACE srcCspace, // [in] RGB Color space
250 MHW_CSPACE dstCspace, // [in] YUV Color space
251 float *transferMatrix, // [in] Transfer matrix (3x3)
252 float *outMatrix) // [out] Conversion matrix (3x4)
253 {
254 bool ret = true;
255 float lumaOffset, lumaExcursion, chromaZero, chromaExcursion;
256 float rgbOffset, rgbExcursion;
257
258 ret = GetRgbRangeAndOffset(srcCspace, &rgbOffset, &rgbExcursion);
259 if (ret)
260 {
261 ret = GetYuvRangeAndOffset(dstCspace, &lumaOffset, &lumaExcursion, &chromaZero, &chromaExcursion);
262 }
263 if (ret)
264 {
265 // multiplication of + onwards
266 outMatrix[0] = transferMatrix[0] * lumaExcursion / rgbExcursion;
267 outMatrix[1] = transferMatrix[1] * lumaExcursion / rgbExcursion;
268 outMatrix[2] = transferMatrix[2] * lumaExcursion / rgbExcursion;
269 outMatrix[4] = transferMatrix[3] * chromaExcursion / rgbExcursion;
270 outMatrix[5] = transferMatrix[4] * chromaExcursion / rgbExcursion;
271 outMatrix[6] = transferMatrix[5] * chromaExcursion / rgbExcursion;
272 outMatrix[8] = transferMatrix[6] * chromaExcursion / rgbExcursion;
273 outMatrix[9] = transferMatrix[7] * chromaExcursion / rgbExcursion;
274 outMatrix[10] = transferMatrix[8] * chromaExcursion / rgbExcursion;
275
276 // before +
277 outMatrix[3] = lumaOffset - lumaExcursion * rgbOffset / rgbExcursion;
278 outMatrix[7] = chromaZero;
279 outMatrix[11] = chromaZero;
280 }
281 return ret;
282 }
283
GetCSCMatrix(MHW_CSPACE srcCspace,MHW_CSPACE dstCspace,float * cscMatrix)284 void CodecHalEncodeSfc::GetCSCMatrix(
285 MHW_CSPACE srcCspace, // [in] Source Color space
286 MHW_CSPACE dstCspace, // [in] Destination Color space
287 float *cscMatrix) // [out] CSC matrix to use
288 {
289 int32_t i;
290
291 // BT601/709 YUV to sRGB/stRGB conversion
292 if (IsCspace(srcCspace, MHW_CSpace_YUV))
293 {
294 if(IsCspace(dstCspace, MHW_CSpace_RGB))
295 {
296 if (CODECHAL_IS_BT601_CSPACE(srcCspace))
297 {
298 CalcYuvToRgbMatrix(srcCspace, dstCspace, (float *) CODECHAL_CSC_BT601_YUV_RGB, cscMatrix);
299 }
300 else // if (IS_BT709_CSPACE(srcCspace))
301 {
302 CalcYuvToRgbMatrix(srcCspace, dstCspace, (float *) CODECHAL_CSC_BT709_YUV_RGB, cscMatrix);
303 }
304 }
305 }
306 // sRGB/stRGB to BT601/709 YUV conversion
307 else if (IsCspace(srcCspace, MHW_CSpace_RGB))
308 {
309 if (IsCspace(dstCspace, MHW_CSpace_YUV))
310 {
311 if (CODECHAL_IS_BT601_CSPACE(dstCspace))
312 {
313 CalcRgbToYuvMatrix(srcCspace, dstCspace, (float *)CODECHAL_CSC_BT601_RGB_YUV, cscMatrix);
314 }
315 else // if (IS_BT709_CSPACE(srcCspace))
316 {
317 CalcRgbToYuvMatrix(srcCspace, dstCspace, (float *)CODECHAL_CSC_BT709_RGB_YUV, cscMatrix);
318 }
319 }
320 }
321 // BT2020 YUV to RGB conversion
322 else if (IsCspace(srcCspace, MHW_CSpace_BT2020))
323 {
324 if (IsCspace(dstCspace, MHW_CSpace_BT2020_RGB))
325 {
326 CalcYuvToRgbMatrix(srcCspace, dstCspace, (float *)CODECHAL_CSC_BT2020_YUV_RGB, cscMatrix);
327 }
328 }
329 // BT2020 RGB to YUV conversion
330 else if (IsCspace(srcCspace, MHW_CSpace_BT2020_RGB))
331 {
332 if (IsCspace(dstCspace, MHW_CSpace_BT2020))
333 {
334 CalcRgbToYuvMatrix(srcCspace, dstCspace, (float *)CODECHAL_CSC_BT2020_RGB_YUV, cscMatrix);
335 }
336 }
337 else
338 {
339 CODECHAL_ENCODE_ASSERTMESSAGE("Not supported color space conversion(from %d to %d)", srcCspace, dstCspace);
340 }
341
342 CODECHAL_ENCODE_NORMALMESSAGE("");
343 for(i = 0; i < 3; i++)
344 {
345 CODECHAL_ENCODE_NORMALMESSAGE("%f\t%f\t%f\t%f",
346 cscMatrix[4 * i],
347 cscMatrix[4 * i + 1],
348 cscMatrix[4 * i + 2],
349 cscMatrix[4 * i + 3]);
350 }
351 }
352
GetCscMatrix(MHW_CSPACE srcCspace,MHW_CSPACE dstCspace,float * cscCoeff,float * cscInOffset,float * cscOutOffset)353 void CodecHalEncodeSfc::GetCscMatrix(
354 MHW_CSPACE srcCspace, // [in] Source Cspace
355 MHW_CSPACE dstCspace, // [in] Destination Cspace
356 float *cscCoeff, // [out] [3x3] Coefficients matrix
357 float *cscInOffset, // [out] [3x1] Input Offset matrix
358 float *cscOutOffset) // [out] [3x1] Output Offset matrix
359 {
360 float cscMatrix[12];
361 int32_t i;
362
363 GetCSCMatrix(
364 srcCspace,
365 dstCspace,
366 cscMatrix);
367
368 // Copy [3x3] into Coeff
369 for (i = 0; i < 3; i++)
370 {
371 MOS_SecureMemcpy(
372 &cscCoeff[i*3],
373 sizeof(float) * 3,
374 &cscMatrix[i*4],
375 sizeof(float) * 3);
376 }
377
378 // Get the input offsets
379 switch(srcCspace)
380 {
381 case MHW_CSpace_BT601:
382 case MHW_CSpace_BT601Gray:
383 case MHW_CSpace_xvYCC601:
384 case MHW_CSpace_BT709:
385 case MHW_CSpace_xvYCC709:
386 cscInOffset[0] = -16.0F;
387 cscInOffset[1] = -128.0F;
388 cscInOffset[2] = -128.0F;
389 break;
390
391 case MHW_CSpace_BT601_FullRange:
392 case MHW_CSpace_BT601Gray_FullRange:
393 case MHW_CSpace_BT709_FullRange:
394 cscInOffset[0] = 0.0F;
395 cscInOffset[1] = -128.0F;
396 cscInOffset[2] = -128.0F;
397 break;
398
399 case MHW_CSpace_sRGB:
400 cscInOffset[0] = 0.0F;
401 cscInOffset[1] = 0.0F;
402 cscInOffset[2] = 0.0F;
403 break;
404
405 case MHW_CSpace_stRGB:
406 cscInOffset[0] = -16.0F;
407 cscInOffset[1] = -16.0F;
408 cscInOffset[2] = -16.0F;
409 break;
410
411 //BT2020 YUV->RGB
412 case MHW_CSpace_BT2020:
413 cscInOffset[0] = -16.0F;
414 cscInOffset[1] = -128.0F;
415 cscInOffset[2] = -128.0F;
416 break;
417
418 case MHW_CSpace_BT2020_FullRange:
419 cscInOffset[0] = 0.0F;
420 cscInOffset[1] = -128.0F;
421 cscInOffset[2] = -128.0F;
422 break;
423
424 //BT2020 RGB->YUV
425 case MHW_CSpace_BT2020_RGB:
426 cscInOffset[0] = 0.0F;
427 cscInOffset[1] = 0.0F;
428 cscInOffset[2] = 0.0F;
429 break;
430
431 //BT2020 RGB->YUV
432 case MHW_CSpace_BT2020_stRGB:
433 cscInOffset[0] = -16.0F;
434 cscInOffset[1] = -16.0F;
435 cscInOffset[2] = -16.0F;
436 break;
437
438 default:
439 CODECHAL_PUBLIC_ASSERTMESSAGE("Unsupported Input ColorSpace for Vebox.");
440 }
441
442 // Get the output offsets
443 switch(dstCspace)
444 {
445 case MHW_CSpace_BT601:
446 case MHW_CSpace_BT601Gray:
447 case MHW_CSpace_xvYCC601:
448 case MHW_CSpace_BT709:
449 case MHW_CSpace_xvYCC709:
450 cscOutOffset[0] = 16.0F;
451 cscOutOffset[1] = 128.0F;
452 cscOutOffset[2] = 128.0F;
453 break;
454
455 case MHW_CSpace_BT601_FullRange:
456 case MHW_CSpace_BT601Gray_FullRange:
457 case MHW_CSpace_BT709_FullRange:
458 cscOutOffset[0] = 0.0F;
459 cscOutOffset[1] = 128.0F;
460 cscOutOffset[2] = 128.0F;
461 break;
462
463 case MHW_CSpace_sRGB:
464 cscOutOffset[0] = 0.0F;
465 cscOutOffset[1] = 0.0F;
466 cscOutOffset[2] = 0.0F;
467 break;
468
469 case MHW_CSpace_stRGB:
470 cscOutOffset[0] = 16.0F;
471 cscOutOffset[1] = 16.0F;
472 cscOutOffset[2] = 16.0F;
473 break;
474
475 //BT2020 RGB->YUV
476 case MHW_CSpace_BT2020:
477 cscOutOffset[0] = 16.0F;
478 cscOutOffset[1] = 128.0F;
479 cscOutOffset[2] = 128.0F;
480 break;
481
482 case MHW_CSpace_BT2020_FullRange:
483 cscOutOffset[0] = 0.0F;
484 cscOutOffset[1] = 128.0F;
485 cscOutOffset[2] = 128.0F;
486 break;
487
488 case MHW_CSpace_BT2020_RGB:
489 cscOutOffset[0] = 0.0F;
490 cscOutOffset[1] = 0.0F;
491 cscOutOffset[2] = 0.0F;
492 break;
493
494 case MHW_CSpace_BT2020_stRGB:
495 cscOutOffset[0] = 16.0F;
496 cscOutOffset[1] = 16.0F;
497 cscOutOffset[2] = 16.0F;
498 break;
499
500 default:
501 CODECHAL_PUBLIC_ASSERTMESSAGE("Unsupported Output ColorSpace for Vebox.");
502 }
503 }
504
AllocateResources()505 MOS_STATUS CodecHalEncodeSfc::AllocateResources()
506 {
507 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
508 uint32_t ycoeffTableSize;
509 uint32_t uvcoeffTableSize;
510 int32_t size;
511 char* ptr;
512 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
513
514 CODECHAL_ENCODE_FUNCTION_ENTER;
515
516 CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface);
517
518 // Allocate AVS line buffer
519 if (Mos_ResourceIsNull(&m_resAvsLineBuffer))
520 {
521 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
522 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
523 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
524 allocParamsForBufferLinear.Format = Format_Buffer;
525 allocParamsForBufferLinear.dwBytes = MOS_ROUNDUP_DIVIDE(m_inputSurface->dwHeight, 8) * 5 * MHW_SFC_CACHELINE_SIZE;
526
527 allocParamsForBufferLinear.pBufName = "SfcAvsLineBuffer";
528
529 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource(
530 m_osInterface,
531 &allocParamsForBufferLinear,
532 &m_resAvsLineBuffer));
533 }
534
535 //Initialize AVS parameters, try to do once
536 if (m_scaling && !m_avsParams.piYCoefsX)
537 {
538 m_avsParams.Format = Format_None;
539 m_avsParams.fScaleX = 0.0F;
540 m_avsParams.fScaleY = 0.0F;
541 m_avsParams.piYCoefsX = nullptr;
542
543 ycoeffTableSize = POLYPHASE_Y_COEFFICIENT_TABLE_SIZE_G9;
544 uvcoeffTableSize = POLYPHASE_UV_COEFFICIENT_TABLE_SIZE_G9;
545
546 size = (ycoeffTableSize + uvcoeffTableSize) * 2;
547
548 ptr = (char*)MOS_AllocAndZeroMemory(size);
549 CODECHAL_ENCODE_CHK_NULL_RETURN(ptr);
550
551 m_avsParams.piYCoefsX = (int32_t*)ptr;
552
553 ptr += ycoeffTableSize;
554 m_avsParams.piUVCoefsX = (int32_t*)ptr;
555
556 ptr += uvcoeffTableSize;
557 m_avsParams.piYCoefsY = (int32_t*)ptr;
558
559 ptr += ycoeffTableSize;
560 m_avsParams.piUVCoefsY = (int32_t*)ptr;
561 }
562
563 return eStatus;
564 }
565
FreeResources()566 MOS_STATUS CodecHalEncodeSfc::FreeResources()
567 {
568 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
569
570 CODECHAL_ENCODE_FUNCTION_ENTER;
571
572 CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface);
573
574 // Free AVS Line Buffer
575 m_osInterface->pfnFreeResource(m_osInterface, &m_resAvsLineBuffer);
576
577 // Free resLaceOrAceOrRgbHistogram
578 m_osInterface->pfnFreeResource(m_osInterface, &m_resLaceOrAceOrRgbHistogram);
579
580 // Free resStatisticsOutput
581 m_osInterface->pfnFreeResource(m_osInterface, &m_resStatisticsOutput);
582
583 // Free buffers in AVS parameters
584 MOS_FreeMemory(m_avsParams.piYCoefsX);
585 m_avsParams.piYCoefsX = nullptr;
586
587 return eStatus;
588 }
589
SetVeboxStateParams(PMHW_VEBOX_STATE_CMD_PARAMS params)590 MOS_STATUS CodecHalEncodeSfc::SetVeboxStateParams(
591 PMHW_VEBOX_STATE_CMD_PARAMS params)
592 {
593 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
594
595 CODECHAL_ENCODE_FUNCTION_ENTER;
596
597 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
598
599 params->bNoUseVeboxHeap = 0;
600
601 params->VeboxMode.ColorGamutExpansionEnable = 0;
602 params->VeboxMode.ColorGamutCompressionEnable = 0;
603 // On SKL, GlobalIECP must be enabled when the output pipe is Vebox or SFC
604 params->VeboxMode.GlobalIECPEnable = 1;
605 params->VeboxMode.DNEnable = 0;
606 params->VeboxMode.DIEnable = 0;
607 params->VeboxMode.DNDIFirstFrame = 0;
608 params->VeboxMode.DIOutputFrames = 0;
609 params->VeboxMode.PipeSynchronizeDisable = 0;
610 params->VeboxMode.DemosaicEnable = 0;
611 params->VeboxMode.VignetteEnable = 0;
612 params->VeboxMode.AlphaPlaneEnable = 0;
613 params->VeboxMode.HotPixelFilteringEnable = 0;
614 // 0-both slices enabled 1-Slice 0 enabled 2-Slice 1 enabled
615 // On SKL GT3 and GT4, there are 2 Veboxes. But only Vebox0 can be used,Vebox1 cannot be used
616 params->VeboxMode.SingleSliceVeboxEnable = 1;
617 params->VeboxMode.LACECorrectionEnable = 0;
618 params->VeboxMode.DisableEncoderStatistics = 1;
619 params->VeboxMode.DisableTemporalDenoiseFilter = 1;
620 params->VeboxMode.SinglePipeIECPEnable = 0;
621 params->VeboxMode.SFCParallelWriteEnable = 0;
622 params->VeboxMode.ScalarMode = 0;
623 params->VeboxMode.ForwardGammaCorrectionEnable = 0;
624
625 return eStatus;
626 }
627
SetVeboxSurfaceStateParams(PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS params)628 MOS_STATUS CodecHalEncodeSfc::SetVeboxSurfaceStateParams(
629 PMHW_VEBOX_SURFACE_STATE_CMD_PARAMS params)
630 {
631 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
632
633 CODECHAL_ENCODE_FUNCTION_ENTER;
634
635 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
636
637 // Initialize SurfInput
638 params->SurfInput.bActive = true;
639 params->SurfInput.Format = m_inputSurface->Format;
640 params->SurfInput.dwWidth = m_inputSurface->dwWidth;
641 params->SurfInput.dwHeight = m_inputSurface->dwHeight;
642 params->SurfInput.dwPitch = m_inputSurface->dwPitch;
643 params->SurfInput.TileType = m_inputSurface->TileType;
644 params->SurfInput.TileModeGMM = m_inputSurface->TileModeGMM;
645 params->SurfInput.bGMMTileEnabled = m_inputSurface->bGMMTileEnabled;
646 params->SurfInput.dwYoffset = m_inputSurface->YPlaneOffset.iYOffset;
647 params->SurfInput.pOsResource = &m_inputSurface->OsResource;
648 params->SurfInput.rcMaxSrc.left = m_inputSurfaceRegion.X;
649 params->SurfInput.rcMaxSrc.top = m_inputSurfaceRegion.Y;
650 params->SurfInput.rcMaxSrc.right = m_inputSurfaceRegion.X + m_inputSurfaceRegion.Width;
651 params->SurfInput.rcMaxSrc.bottom = m_inputSurfaceRegion.Y + m_inputSurfaceRegion.Height;
652
653 // Initialize SurfSTMM
654 params->SurfSTMM.dwPitch = m_inputSurface->dwPitch;
655
656 params->bDIEnable = false;
657 params->bOutputValid = (m_veboxOutputSurface != nullptr) ? true : false;
658
659 return eStatus;
660 }
661
SetVeboxDiIecpParams(PMHW_VEBOX_DI_IECP_CMD_PARAMS params)662 MOS_STATUS CodecHalEncodeSfc::SetVeboxDiIecpParams(
663 PMHW_VEBOX_DI_IECP_CMD_PARAMS params)
664 {
665 uint32_t width;
666 uint32_t height;
667 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear;
668 uint32_t size = 0, sizeLace = 0, sizeNoLace = 0;
669 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
670 MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
671
672 CODECHAL_ENCODE_FUNCTION_ENTER;
673
674 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
675
676 height = m_inputSurface->dwHeight;
677 width = m_inputSurface->dwWidth;
678
679 params->dwStartingX = 0;
680 params->dwEndingX = width - 1;
681 params->dwCurrInputSurfOffset = m_inputSurface->dwOffset;
682 params->pOsResCurrInput = &m_inputSurface->OsResource;
683 params->CurrInputSurfCtrl.Value = 0; //Keep it here untill VPHAL moving to new CMD definition and remove this parameter definition.
684
685 CodecHalGetResourceInfo(
686 m_osInterface,
687 m_inputSurface);
688
689 m_osInterface->pfnGetMemoryCompressionMode(m_osInterface, &m_inputSurface->OsResource, &mmcMode);
690 if (mmcMode &&
691 (m_inputSurface->TileType == MOS_TILE_Y ||
692 m_inputSurface->TileType == MOS_TILE_YS))
693 {
694 m_inputSurface->bCompressible = true;
695 m_inputSurface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
696 }
697 else
698 {
699 m_inputSurface->CompressionMode = MOS_MMC_DISABLED;
700 }
701
702 params->CurInputSurfMMCState = (MOS_MEMCOMP_STATE)(m_inputSurface->CompressionMode);
703
704 // Allocate Resource to avoid Page Fault issue since HW will access it
705 if (Mos_ResourceIsNull(&m_resLaceOrAceOrRgbHistogram))
706 {
707 size = CODECHAL_SFC_VEBOX_RGB_HISTOGRAM_SIZE;
708
709 sizeLace = MOS_ROUNDUP_DIVIDE(height, 64) *
710 MOS_ROUNDUP_DIVIDE(width, 64) *
711 CODECHAL_SFC_VEBOX_LACE_HISTOGRAM_256_BIN_PER_BLOCK;
712
713 sizeNoLace = CODECHAL_SFC_VEBOX_ACE_HISTOGRAM_SIZE_PER_FRAME_PER_SLICE *
714 CODECHAL_SFC_NUM_FRAME_PREVIOUS_CURRENT *
715 CODECHAL_SFC_VEBOX_MAX_SLICES;
716
717 size += MOS_MAX(sizeLace, sizeNoLace);
718
719 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
720 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
721 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
722 allocParamsForBufferLinear.Format = Format_Buffer;
723 allocParamsForBufferLinear.dwBytes = size;
724 allocParamsForBufferLinear.pBufName = "ResLaceOrAceOrRgbHistogram";
725
726 m_osInterface->pfnAllocateResource(
727 m_osInterface,
728 &allocParamsForBufferLinear,
729 &m_resLaceOrAceOrRgbHistogram);
730 }
731
732 params->pOsResLaceOrAceOrRgbHistogram = &m_resLaceOrAceOrRgbHistogram;
733
734 // Allocate Resource to avoid Page Fault issue since HW will access it
735 if (Mos_ResourceIsNull(&m_resStatisticsOutput))
736 {
737 width = MOS_ALIGN_CEIL(width, 64);
738 height = MOS_ROUNDUP_DIVIDE(height, 4) + MOS_ROUNDUP_DIVIDE(CODECHAL_SFC_VEBOX_STATISTICS_SIZE * sizeof(uint32_t), width);
739 size = width * height;
740
741 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS));
742 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER;
743 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR;
744 allocParamsForBufferLinear.Format = Format_Buffer;
745 allocParamsForBufferLinear.dwBytes = size;
746 allocParamsForBufferLinear.pBufName = "ResStatisticsOutput";
747
748 m_osInterface->pfnAllocateResource(
749 m_osInterface,
750 &allocParamsForBufferLinear,
751 &m_resStatisticsOutput);
752 }
753
754 params->pOsResStatisticsOutput = &m_resStatisticsOutput;
755
756 return eStatus;
757 }
758
VeboxSetIecpParams(PMHW_VEBOX_IECP_PARAMS mhwVeboxIecpParams)759 MOS_STATUS CodecHalEncodeSfc::VeboxSetIecpParams(
760 PMHW_VEBOX_IECP_PARAMS mhwVeboxIecpParams)
761 {
762 // Calculate matrix if not done so before. CSC is expensive!
763 if ((m_cscInputCspace != m_inputSurfaceColorSpace) ||
764 (m_cscOutputCspace != m_outputSurfaceColorSpace))
765 {
766 float fTemp[3];
767
768 // Get the matrix to use for conversion
769 GetCscMatrix(
770 m_inputSurfaceColorSpace,
771 m_outputSurfaceColorSpace,
772 m_cscCoeff,
773 m_cscInOffset,
774 m_cscOutOffset);
775
776 // Vebox CSC converts RGB input to YUV for SFC
777 // Vebox only supports A8B8G8R8 input, swap the 1st and 3rd
778 // columns of the transfer matrix for A8R8G8B8 and X8R8G8B8
779 // This only happens when SFC output is used
780 if ((m_inputSurface->Format == Format_A8R8G8B8) ||
781 (m_inputSurface->Format == Format_X8R8G8B8))
782 {
783 fTemp[0] = m_cscCoeff[0];
784 fTemp[1] = m_cscCoeff[3];
785 fTemp[2] = m_cscCoeff[6];
786
787 m_cscCoeff[0] = m_cscCoeff[2];
788 m_cscCoeff[3] = m_cscCoeff[5];
789 m_cscCoeff[6] = m_cscCoeff[8];
790
791 m_cscCoeff[2] = fTemp[0];
792 m_cscCoeff[5] = fTemp[1];
793 m_cscCoeff[8] = fTemp[2];
794 }
795 }
796 // Store it for next BLT
797 m_cscInputCspace = m_inputSurfaceColorSpace;
798 m_cscOutputCspace = m_outputSurfaceColorSpace;
799 CODECHAL_ENCODE_VERBOSEMESSAGE("Input color space: %d, output color space: %d",
800 m_cscInputCspace, m_cscOutputCspace);
801
802 // copy into MHW parameters
803
804 mhwVeboxIecpParams->ColorSpace = m_inputSurfaceColorSpace;
805 mhwVeboxIecpParams->dstFormat = m_sfcOutputSurface->Format;
806 mhwVeboxIecpParams->srcFormat = m_inputSurface->Format;
807 mhwVeboxIecpParams->bCSCEnable = m_veboxCsc;
808 mhwVeboxIecpParams->pfCscCoeff = m_cscCoeff;
809 mhwVeboxIecpParams->pfCscInOffset = m_cscInOffset;
810 mhwVeboxIecpParams->pfCscOutOffset = m_cscOutOffset;
811 //mhwVeboxIecpParams->bAlphaEnable = m_alphaEnable; ??
812 //mhwVeboxIecpParams->wAlphaValue = m_alphaValue;
813
814 return MOS_STATUS_SUCCESS;
815 }
816
SetSfcStateParams(PMHW_SFC_INTERFACE sfcInterface,PMHW_SFC_STATE_PARAMS params,PMHW_SFC_OUT_SURFACE_PARAMS outSurfaceParams)817 MOS_STATUS CodecHalEncodeSfc::SetSfcStateParams(
818 PMHW_SFC_INTERFACE sfcInterface,
819 PMHW_SFC_STATE_PARAMS params,
820 PMHW_SFC_OUT_SURFACE_PARAMS outSurfaceParams)
821 {
822 uint16_t widthAlignUnit;
823 uint16_t heightAlignUnit;
824 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
825
826 CODECHAL_ENCODE_FUNCTION_ENTER;
827
828 CODECHAL_ENCODE_CHK_NULL_RETURN(sfcInterface);
829 CODECHAL_ENCODE_CHK_NULL_RETURN(m_inputSurface);
830 CODECHAL_ENCODE_CHK_NULL_RETURN(m_sfcOutputSurface);
831 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
832
833 params->sfcPipeMode = MEDIASTATE_SFC_PIPE_VE_TO_SFC;
834 params->dwAVSFilterMode = MEDIASTATE_SFC_AVS_FILTER_8x8;
835 params->dwVDVEInputOrderingMode = MEDIASTATE_SFC_INPUT_ORDERING_VE_4x8;
836
837 params->dwInputChromaSubSampling = MEDIASTATE_SFC_CHROMA_SUBSAMPLING_444;
838
839 // Adjust SFC input surface alignment.
840 // As VEBOX doesn't do scaling, input size equals to output size
841 // For the VEBOX output to SFC, width is multiple of 16 and height is multiple of 4
842 widthAlignUnit = sfcInterface->m_veWidthAlignment;
843 heightAlignUnit = sfcInterface->m_veHeightAlignment;
844
845 params->dwInputFrameWidth = MOS_ALIGN_CEIL(m_inputSurface->dwWidth, widthAlignUnit);
846 params->dwInputFrameHeight = MOS_ALIGN_CEIL(m_inputSurface->dwHeight, heightAlignUnit);
847
848 params->dwChromaDownSamplingMode = MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_444TO420;
849 params->bAVSChromaUpsamplingEnable = m_scaling;
850
851 if ((params->fAVSXScalingRatio > 1.0F) || (params->fAVSYScalingRatio > 1.0F))
852 {
853 params->bBypassXAdaptiveFilter = false;
854 params->bBypassYAdaptiveFilter = false;
855 }
856 else
857 {
858 params->bBypassXAdaptiveFilter = true;
859 params->bBypassYAdaptiveFilter = true;
860 }
861
862 params->fChromaSubSamplingXSiteOffset = 0.0F;
863 params->fChromaSubSamplingYSiteOffset = 0.0F;
864
865 widthAlignUnit = 1;
866 heightAlignUnit = 1;
867
868 switch(m_sfcOutputSurface->Format)
869 {
870 case Format_NV12:
871 case Format_P010:
872 widthAlignUnit = 2;
873 heightAlignUnit = 2;
874 break;
875 case Format_YUY2:
876 case Format_UYVY:
877 widthAlignUnit = 2;
878 break;
879 default:
880 break;
881 }
882
883 // Default to Horizontal Left, Vertical Top
884 params->dwChromaDownSamplingHorizontalCoef = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ?
885 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 :
886 ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ?
887 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 :
888 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
889
890 params->dwChromaDownSamplingVerticalCoef = (m_chromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ?
891 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_4_OVER_8 :
892 ((m_chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ?
893 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_8_OVER_8 :
894 MEDIASTATE_SFC_CHROMA_DOWNSAMPLING_COEF_0_OVER_8);
895
896 outSurfaceParams->dwWidth = m_sfcOutputSurface->dwWidth;
897 outSurfaceParams->dwHeight = m_sfcOutputSurface->dwHeight;
898 outSurfaceParams->dwPitch = m_sfcOutputSurface->dwPitch;
899 outSurfaceParams->TileType = m_sfcOutputSurface->TileType;
900 outSurfaceParams->TileModeGMM = m_sfcOutputSurface->TileModeGMM;
901 outSurfaceParams->bGMMTileEnabled = m_sfcOutputSurface->bGMMTileEnabled;
902 outSurfaceParams->ChromaSiting = m_chromaSiting;
903 outSurfaceParams->dwUYoffset = m_sfcOutputSurface->UPlaneOffset.iYOffset;
904
905 params->dwOutputFrameWidth = MOS_ALIGN_CEIL(m_sfcOutputSurface->dwWidth, widthAlignUnit);
906 params->dwOutputFrameHeight = MOS_ALIGN_CEIL(m_sfcOutputSurface->dwHeight, heightAlignUnit);
907 params->OutputFrameFormat = m_sfcOutputSurface->Format;
908 params->dwOutputSurfaceOffset = m_sfcOutputSurface->dwOffset;
909 params->pOsResOutputSurface = &m_sfcOutputSurface->OsResource;
910 params->pOsResAVSLineBuffer = &m_resAvsLineBuffer;
911
912 params->dwSourceRegionHeight = MOS_ALIGN_FLOOR(m_inputSurfaceRegion.Height, heightAlignUnit);
913 params->dwSourceRegionWidth = MOS_ALIGN_FLOOR(m_inputSurfaceRegion.Width, widthAlignUnit);
914 params->dwSourceRegionVerticalOffset = MOS_ALIGN_CEIL(m_inputSurfaceRegion.Y, heightAlignUnit);
915 params->dwSourceRegionHorizontalOffset = MOS_ALIGN_CEIL(m_inputSurfaceRegion.X, widthAlignUnit);
916 params->dwScaledRegionHeight = MOS_UF_ROUND(m_scaleY * params->dwSourceRegionHeight);
917 params->dwScaledRegionWidth = MOS_UF_ROUND(m_scaleX * params->dwSourceRegionWidth);
918 params->dwScaledRegionVerticalOffset = MOS_ALIGN_FLOOR(m_outputSurfaceRegion.Y, heightAlignUnit);
919 params->dwScaledRegionHorizontalOffset = MOS_ALIGN_FLOOR(m_outputSurfaceRegion.X, widthAlignUnit);
920 params->fAVSXScalingRatio = m_scaleX;
921 params->fAVSYScalingRatio = m_scaleY;
922
923 params->fAlphaPixel = 1.0F;
924 params->bColorFillEnable = m_colorFill;
925 params->bCSCEnable = m_CSC;
926
927 // ARGB8,ABGR10,A16B16G16R16,VYUY and YVYU output format need to enable swap
928 if (m_sfcOutputSurface->Format == Format_X8R8G8B8 ||
929 m_sfcOutputSurface->Format == Format_A8R8G8B8 ||
930 m_sfcOutputSurface->Format == Format_R10G10B10A2 ||
931 m_sfcOutputSurface->Format == Format_A16B16G16R16 ||
932 m_sfcOutputSurface->Format == Format_VYUY ||
933 m_sfcOutputSurface->Format == Format_YVYU)
934 {
935 params->bRGBASwapEnable = true;
936 }
937 else
938 {
939 params->bRGBASwapEnable = false;
940 }
941
942
943 // CodecHal does not support SFC rotation
944 params->RotationMode = MHW_ROTATION_IDENTITY;
945
946 // For downsampling, expect output surface to be MMC disabled
947 // For Jpeg, the only usage is CSC and the output surface format is RGB8, so also disable MMC
948 params->bMMCEnable = false;
949 params->MMCMode = MOS_MMC_DISABLED;
950
951 return eStatus;
952 }
953
SetSfcAvsStateParams(PMHW_SFC_INTERFACE sfcInterface)954 MOS_STATUS CodecHalEncodeSfc::SetSfcAvsStateParams(
955 PMHW_SFC_INTERFACE sfcInterface)
956 {
957 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
958 PMHW_SFC_AVS_STATE mhwSfcAvsState;
959
960 CODECHAL_ENCODE_FUNCTION_ENTER;
961
962 CODECHAL_ENCODE_CHK_NULL_RETURN(sfcInterface);
963 CODECHAL_ENCODE_CHK_NULL_RETURN(m_inputSurface);
964
965 mhwSfcAvsState = &m_avsState;
966
967 if (m_chromaSiting == MHW_CHROMA_SITING_NONE)
968 {
969 m_chromaSiting = MHW_CHROMA_SITING_HORZ_LEFT | MHW_CHROMA_SITING_VERT_CENTER;
970 }
971
972 mhwSfcAvsState->dwInputHorizontalSiting = (m_chromaSiting & MHW_CHROMA_SITING_HORZ_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 :
973 ((m_chromaSiting & MHW_CHROMA_SITING_HORZ_RIGHT) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 :
974 SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
975
976 mhwSfcAvsState->dwInputVerticalSitting = (m_chromaSiting & MHW_CHROMA_SITING_VERT_CENTER) ? SFC_AVS_INPUT_SITING_COEF_4_OVER_8 :
977 ((m_chromaSiting & MHW_CHROMA_SITING_VERT_BOTTOM) ? SFC_AVS_INPUT_SITING_COEF_8_OVER_8 :
978 SFC_AVS_INPUT_SITING_COEF_0_OVER_8);
979
980 CODECHAL_ENCODE_CHK_STATUS_RETURN(sfcInterface->SetSfcSamplerTable(
981 &m_lumaTable,
982 &m_chromaTable,
983 &m_avsParams,
984 m_inputSurface->Format,
985 m_scaleX,
986 m_scaleY,
987 m_chromaSiting,
988 true,
989 0,
990 0));
991 return eStatus;
992 }
993
SetSfcIefStateParams(PMHW_SFC_IEF_STATE_PARAMS params)994 MOS_STATUS CodecHalEncodeSfc::SetSfcIefStateParams(
995 PMHW_SFC_IEF_STATE_PARAMS params)
996 {
997 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
998
999 CODECHAL_ENCODE_FUNCTION_ENTER;
1000
1001 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1002
1003 params->bIEFEnable = false;
1004 params->bCSCEnable = true;
1005
1006 params->pfCscCoeff = m_cscCoeff;
1007 params->pfCscInOffset = m_cscInOffset;
1008 params->pfCscOutOffset = m_cscOutOffset;
1009
1010 return eStatus;
1011 }
1012
Initialize(CodechalHwInterface * hwInterface,PMOS_INTERFACE osInterface)1013 MOS_STATUS CodecHalEncodeSfc::Initialize(
1014 CodechalHwInterface *hwInterface,
1015 PMOS_INTERFACE osInterface)
1016 {
1017
1018 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1019
1020 CODECHAL_ENCODE_FUNCTION_ENTER;
1021
1022 CODECHAL_ENCODE_CHK_NULL_RETURN(hwInterface);
1023 CODECHAL_ENCODE_CHK_NULL_RETURN(hwInterface->GetVeboxInterface());
1024 CODECHAL_ENCODE_CHK_NULL_RETURN(osInterface);
1025
1026 m_hwInterface = hwInterface;
1027 m_osInterface = osInterface;
1028
1029 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetVeboxInterface()->CreateHeap());
1030
1031 // Create VEBOX Context
1032 MOS_GPUCTX_CREATOPTIONS createOption;
1033 //
1034 // VeboxgpuContext could be created from both VP and Codec.
1035 // If there is no such as a GPU context it will create a new one and set the GPU component ID.
1036 // If there has been a valid GPU context it won�t create another one anymore and the component ID won�t be updated either.
1037 // Therefore if a codec veboxgpu context creation happens earlier than a vp veboxgpu context creation and set its component ID to MOS_GPU_COMPONENT_ENCODE,
1038 // VPBLT callstack would index a GpuAppTaskEvent of MOS_GPU_COMPONENT_ENCODE.
1039 //
1040 MOS_COMPONENT originalComponent = m_osInterface->Component;
1041 m_osInterface->Component = COMPONENT_VPCommon;
1042
1043 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
1044 m_osInterface,
1045 MOS_GPU_CONTEXT_VEBOX,
1046 MOS_GPU_NODE_VE,
1047 &createOption));
1048
1049 m_osInterface->Component = originalComponent;
1050
1051 // Register Vebox GPU context with the Batch Buffer completion event
1052 // Ignore if creation fails
1053 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
1054 m_osInterface,
1055 MOS_GPU_CONTEXT_VEBOX));
1056
1057 return eStatus;
1058 }
1059
SetParams(CODECHAL_ENCODE_SFC_PARAMS * params)1060 MOS_STATUS CodecHalEncodeSfc::SetParams(
1061 CODECHAL_ENCODE_SFC_PARAMS* params)
1062 {
1063 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1064
1065 CODECHAL_ENCODE_FUNCTION_ENTER;
1066
1067 CODECHAL_ENCODE_CHK_NULL_RETURN(params);
1068 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pInputSurface);
1069 CODECHAL_ENCODE_CHK_NULL_RETURN(params->pOutputSurface);
1070
1071 m_inputSurface = params->pInputSurface;
1072 // Vebox o/p should not be written to memory for SFC, VeboxOutputSurface should be nullptr
1073 m_veboxOutputSurface = nullptr;
1074 m_sfcOutputSurface = params->pOutputSurface;
1075
1076 // no scaling.
1077 m_scaling = false;
1078 m_colorFill = false;
1079
1080 // No CSC for SFC pipe
1081 m_veboxCsc = true;
1082
1083 m_scaleX = 1.0;
1084 m_scaleY = 1.0;
1085 m_chromaSiting = params->uiChromaSitingType;
1086
1087 eStatus = MOS_SecureMemcpy(&m_inputSurfaceRegion,
1088 sizeof(m_inputSurfaceRegion),
1089 ¶ms->rcInputSurfaceRegion,
1090 sizeof(params->rcInputSurfaceRegion));
1091
1092 eStatus = MOS_SecureMemcpy(&m_outputSurfaceRegion,
1093 sizeof(m_outputSurfaceRegion),
1094 ¶ms->rcOutputSurfaceRegion,
1095 sizeof(params->rcOutputSurfaceRegion));
1096
1097 CODECHAL_ENCODE_CHK_STATUS_RETURN(AllocateResources());
1098
1099 return eStatus;
1100 }
1101
AddSfcCommands(PMHW_SFC_INTERFACE sfcInterface,PMOS_COMMAND_BUFFER cmdBuffer)1102 MOS_STATUS CodecHalEncodeSfc::AddSfcCommands(
1103 PMHW_SFC_INTERFACE sfcInterface,
1104 PMOS_COMMAND_BUFFER cmdBuffer)
1105 {
1106 MHW_SFC_LOCK_PARAMS sfcLockParams;
1107 MHW_SFC_STATE_PARAMS sfcStateParams;
1108 MHW_SFC_OUT_SURFACE_PARAMS sfcOutSurfaceParams;
1109 MHW_SFC_IEF_STATE_PARAMS sfcIefStateParams;
1110 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1111
1112 CODECHAL_ENCODE_FUNCTION_ENTER;
1113
1114 CODECHAL_ENCODE_CHK_NULL_RETURN(sfcInterface);
1115 CODECHAL_ENCODE_CHK_NULL_RETURN(cmdBuffer);
1116
1117 MOS_ZeroMemory(&sfcLockParams, sizeof(sfcLockParams));
1118
1119 sfcLockParams.sfcPipeMode = MhwSfcInterface::SFC_PIPE_MODE_VEBOX;
1120 sfcLockParams.bOutputToMemory = false;
1121
1122 MOS_ZeroMemory(&sfcStateParams, sizeof(sfcStateParams));
1123 MOS_ZeroMemory(&sfcOutSurfaceParams, sizeof(sfcOutSurfaceParams));
1124 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSfcStateParams(sfcInterface, &sfcStateParams, &sfcOutSurfaceParams));
1125
1126 CODECHAL_ENCODE_CHK_STATUS_RETURN(sfcInterface->AddSfcLock(cmdBuffer, &sfcLockParams));
1127 CODECHAL_ENCODE_CHK_STATUS_RETURN(sfcInterface->AddSfcState(cmdBuffer, &sfcStateParams, &sfcOutSurfaceParams));
1128
1129 if (m_scaling)
1130 {
1131 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSfcAvsStateParams(sfcInterface));
1132 CODECHAL_ENCODE_CHK_STATUS_RETURN(sfcInterface->AddSfcAvsState(cmdBuffer, &m_avsState));
1133 CODECHAL_ENCODE_CHK_STATUS_RETURN(sfcInterface->AddSfcAvsLumaTable(cmdBuffer, &m_lumaTable));
1134 CODECHAL_ENCODE_CHK_STATUS_RETURN(sfcInterface->AddSfcAvsChromaTable(cmdBuffer, &m_chromaTable));
1135 }
1136
1137 if (m_CSC)
1138 {
1139 MOS_ZeroMemory(&sfcIefStateParams, sizeof(sfcIefStateParams));
1140 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetSfcIefStateParams(&sfcIefStateParams));
1141 CODECHAL_ENCODE_CHK_STATUS_RETURN(sfcInterface->AddSfcIefState(cmdBuffer, &sfcIefStateParams));
1142 }
1143
1144 CODECHAL_ENCODE_CHK_STATUS_RETURN(sfcInterface->AddSfcFrameStart(cmdBuffer, MhwSfcInterface::SFC_PIPE_MODE_VEBOX));
1145
1146 return eStatus;
1147 }
1148
RenderStart(CodechalEncoderState * encoder)1149 MOS_STATUS CodecHalEncodeSfc::RenderStart(
1150 CodechalEncoderState* encoder)
1151 {
1152 MHW_VEBOX_STATE_CMD_PARAMS veboxStateCmdParams;
1153 MHW_VEBOX_SURFACE_STATE_CMD_PARAMS veboxSurfaceStateCmdParams;
1154 MHW_VEBOX_DI_IECP_CMD_PARAMS veboxDiIecpCmdParams;
1155 MHW_VEBOX_IECP_PARAMS veboxIecpParams;
1156 MHW_VEBOX_SURFACE_CNTL_PARAMS veboxSurfCntlParams;
1157 MhwVeboxInterface *veboxInterface;
1158 PMHW_SFC_INTERFACE sfcInterface;
1159 MhwMiInterface *miInterface;
1160 PMOS_CONTEXT pOsContext = nullptr;
1161 MHW_MI_MMIOREGISTERS *mmioVeboxRegisters = nullptr;
1162 MOS_COMMAND_BUFFER cmdBuffer;
1163 bool requestFrameTracking;
1164 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1165
1166 CODECHAL_ENCODE_FUNCTION_ENTER;
1167
1168 CODECHAL_ENCODE_CHK_NULL_RETURN(m_hwInterface);
1169 CODECHAL_ENCODE_CHK_NULL_RETURN(m_osInterface);
1170 CODECHAL_ENCODE_CHK_NULL_RETURN(pOsContext = m_osInterface->pOsContext);
1171 CODECHAL_ENCODE_CHK_NULL_RETURN(encoder);
1172 CODECHAL_ENCODE_CHK_NULL_RETURN(sfcInterface = m_hwInterface->GetSfcInterface());
1173 CODECHAL_ENCODE_CHK_NULL_RETURN(veboxInterface = m_hwInterface->GetVeboxInterface());
1174 CODECHAL_ENCODE_CHK_NULL_RETURN(miInterface = m_hwInterface->GetMiInterface());
1175 CODECHAL_ENCODE_CHK_NULL_RETURN(mmioVeboxRegisters = miInterface->GetMmioRegisters());
1176
1177 // Switch GPU context to VEBOX
1178 m_osInterface->pfnSetGpuContext(m_osInterface, MOS_GPU_CONTEXT_VEBOX);
1179 // Reset allocation list and house keeping
1180 m_osInterface->pfnResetOsStates(m_osInterface);
1181
1182 // Send command buffer header at the beginning
1183 MOS_ZeroMemory(&cmdBuffer, sizeof(MOS_COMMAND_BUFFER));
1184 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
1185
1186 // the first task?
1187 requestFrameTracking = false;
1188 CODECHAL_ENCODE_CHK_STATUS_RETURN(encoder->SendPrologWithFrameTracking(&cmdBuffer, requestFrameTracking));
1189
1190 // If m_pollingSyncEnabled is set, insert HW semaphore to wait for external
1191 // raw surface processing to complete, before start CSC. Once the marker in
1192 // raw surface is overwritten by external operation, HW semaphore will be
1193 // signalled and CSC will start. This is to reduce SW latency between
1194 // external raw surface processing and CSC, in usages like remote gaming.
1195 if (encoder->m_pollingSyncEnabled)
1196 {
1197 MHW_MI_SEMAPHORE_WAIT_PARAMS miSemaphoreWaitParams;
1198 MOS_ZeroMemory((&miSemaphoreWaitParams), sizeof(miSemaphoreWaitParams));
1199 miSemaphoreWaitParams.presSemaphoreMem = &m_inputSurface->OsResource;
1200 miSemaphoreWaitParams.dwResourceOffset = encoder->m_syncMarkerOffset;
1201 miSemaphoreWaitParams.bPollingWaitMode = true;
1202 miSemaphoreWaitParams.dwSemaphoreData = encoder->m_syncMarkerValue;
1203 miSemaphoreWaitParams.CompareOperation = MHW_MI_SAD_NOT_EQUAL_SDD;
1204 CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiSemaphoreWaitCmd(&cmdBuffer, &miSemaphoreWaitParams));
1205 }
1206
1207 // Setup cmd prameters
1208 MOS_ZeroMemory(&veboxStateCmdParams, sizeof(veboxStateCmdParams));
1209 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetVeboxStateParams(&veboxStateCmdParams));
1210
1211 MOS_ZeroMemory(&veboxSurfaceStateCmdParams, sizeof(veboxSurfaceStateCmdParams));
1212 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetVeboxSurfaceStateParams(&veboxSurfaceStateCmdParams));
1213
1214 MOS_ZeroMemory(&veboxDiIecpCmdParams, sizeof(veboxDiIecpCmdParams));
1215 CODECHAL_ENCODE_CHK_STATUS_RETURN(SetVeboxDiIecpParams(&veboxDiIecpCmdParams));
1216
1217 MOS_ZeroMemory(&veboxSurfCntlParams, sizeof(veboxSurfCntlParams));
1218 veboxSurfCntlParams.bIsCompressed = m_inputSurface->bIsCompressed;
1219 veboxSurfCntlParams.CompressionMode = m_inputSurface->CompressionMode;
1220 CODECHAL_ENCODE_CHK_STATUS_RETURN(veboxInterface->AddVeboxSurfaceControlBits(
1221 &veboxSurfCntlParams,
1222 (uint32_t *)&(veboxDiIecpCmdParams.CurrInputSurfCtrl.Value)));
1223
1224 // get csc matrix
1225 MOS_ZeroMemory(&veboxIecpParams, sizeof(veboxIecpParams));
1226 CODECHAL_ENCODE_CHK_STATUS_RETURN(VeboxSetIecpParams(&veboxIecpParams));
1227
1228 // send matrix into heap
1229 CODECHAL_ENCODE_CHK_STATUS_RETURN(veboxInterface->AddVeboxIecpState(
1230 &veboxIecpParams));
1231
1232 // send Vebox and SFC cmds
1233 CODECHAL_ENCODE_CHK_STATUS_RETURN(veboxInterface->AddVeboxState(&cmdBuffer, &veboxStateCmdParams, 0));
1234
1235 CODECHAL_ENCODE_CHK_STATUS_RETURN(veboxInterface->AddVeboxSurfaces( &cmdBuffer, &veboxSurfaceStateCmdParams));
1236
1237 CODECHAL_ENCODE_CHK_STATUS_RETURN(AddSfcCommands(sfcInterface, &cmdBuffer));
1238
1239 HalOcaInterface::OnDispatch(cmdBuffer, *pOsContext, *miInterface, *mmioVeboxRegisters);
1240
1241 CODECHAL_ENCODE_CHK_STATUS_RETURN(veboxInterface->AddVeboxDiIecp(&cmdBuffer, &veboxDiIecpCmdParams));
1242
1243 // If m_pollingSyncEnabled is set, write the marker to source surface for next MI_SEMAPHORE_WAIT to check.
1244 if (encoder->m_pollingSyncEnabled)
1245 {
1246 MHW_MI_STORE_DATA_PARAMS storeDataParams;
1247 storeDataParams.pOsResource = &m_inputSurface->OsResource;
1248 storeDataParams.dwResourceOffset = encoder->m_syncMarkerOffset;
1249 storeDataParams.dwValue = encoder->m_syncMarkerValue;
1250 CODECHAL_ENCODE_CHK_STATUS_RETURN(miInterface->AddMiStoreDataImmCmd(&cmdBuffer, &storeDataParams));
1251 }
1252
1253 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_hwInterface->GetMiInterface()->AddMiBatchBufferEnd(
1254 &cmdBuffer,
1255 nullptr));
1256
1257 CODECHAL_DEBUG_TOOL(CODECHAL_ENCODE_CHK_STATUS_RETURN(encoder->GetDebugInterface()->DumpCmdBuffer(
1258 &cmdBuffer,
1259 CODECHAL_MEDIA_STATE_CSC_DS_COPY,
1260 nullptr)));
1261
1262 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1263 HalOcaInterface::On1stLevelBBEnd(cmdBuffer, *m_osInterface->pOsContext);
1264
1265 CODECHAL_ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1266 m_osInterface,
1267 &cmdBuffer,
1268 encoder->m_videoContextUsesNullHw));
1269
1270 return eStatus;
1271 }
1272