1 /*
2 * Copyright (c) 2017-2018, 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 mhw_vdbox_mfx_interface.cpp
24 //! \brief MHW interface for constructing MFX commands for the Vdbox engine
25 //! \details Defines the interfaces for constructing MHW Vdbox MFX commands across all platforms
26 //!
27
28 #include "mhw_vdbox_mfx_interface.h"
29
30 const uint8_t MhwVdboxMfxInterface::m_mpeg2QuantMatrixScan[64] =
31 {
32 // Inverse Zig-Zag scan pattern
33 0, 1, 5, 6, 14, 15, 27, 28,
34 2, 4, 7, 13, 16, 26, 29, 42,
35 3, 8, 12, 17, 25, 30, 41, 43,
36 9, 11, 18, 24, 31, 40, 44, 53,
37 10, 19, 23, 32, 39, 45, 52, 54,
38 20, 22, 33, 38, 46, 51, 55, 60,
39 21, 34, 37, 47, 50, 56, 59, 61,
40 35, 36, 48, 49, 57, 58, 62, 63
41 };
42
43 const uint16_t MhwVdboxMfxInterface::m_mpeg2DefaultIntraQuantizerMatrix[64] =
44 {
45 8, 16, 19, 22, 26, 27, 29, 34,
46 16, 16, 22, 24, 27, 29, 34, 37,
47 19, 22, 26, 27, 29, 34, 34, 38,
48 22, 22, 26, 27, 29, 34, 37, 40,
49 22, 26, 27, 29, 32, 35, 40, 48,
50 26, 27, 29, 32, 35, 40, 48, 58,
51 26, 27, 29, 34, 38, 46, 56, 69,
52 27, 29, 35, 38, 46, 56, 69, 83
53 };
54
55 const uint16_t MhwVdboxMfxInterface::m_mpeg2DefaultNonIntraQuantizerMatrix[64] =
56 {
57 16, 16, 16, 16, 16, 16, 16, 16,
58 16, 16, 16, 16, 16, 16, 16, 16,
59 16, 16, 16, 16, 16, 16, 16, 16,
60 16, 16, 16, 16, 16, 16, 16, 16,
61 16, 16, 16, 16, 16, 16, 16, 16,
62 16, 16, 16, 16, 16, 16, 16, 16,
63 16, 16, 16, 16, 16, 16, 16, 16,
64 16, 16, 16, 16, 16, 16, 16, 16
65 };
66
67 const uint32_t MhwVdboxMfxInterface::m_mpeg2SliceDeltaQPMax[4] =
68 {
69 0x02040608, 0x01020304, 0x01020304, 0x01010202
70 };
71
72 const uint32_t MhwVdboxMfxInterface::m_mpeg2InitSliceDeltaQPMin[4] =
73 {
74 0x81828384, 0x81828384, 0x81828384, 0x81828384
75 };
76
77 const uint32_t MhwVdboxMfxInterface::m_mpeg2FrameBitrateMinMax[4] =
78 {
79 0x00010000, 0x00010000, 0x00010000, 0x00010000
80 };
81
82 const uint32_t MhwVdboxMfxInterface::m_mpeg2FrameBitrateMinMaxDelta[4] =
83 {
84 0x00010000, 0x00010000, 0x00010000, 0x00010000
85 };
86
87 const uint8_t MhwVdboxMfxInterface::m_columnScan4x4[16] =
88 {
89 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15
90 };
91
92 const uint8_t MhwVdboxMfxInterface::m_columnScan8x8[64] =
93 {
94 0, 8, 16, 24, 32, 40, 48, 56, 1, 9, 17, 25, 33, 41, 49, 57,
95 2, 10, 18, 26, 34, 42, 50, 58, 3, 11, 19, 27, 35, 43, 51, 59,
96 4, 12, 20, 28, 36, 44, 52, 60, 5, 13, 21, 29, 37, 45, 53, 61,
97 6, 14, 22, 30, 38, 46, 54, 62, 7, 15, 23, 31, 39, 47, 55, 63
98 };
99
100 const MhwVdboxMfxInterface::AvcSliceType MhwVdboxMfxInterface::m_AvcBsdSliceType[10] =
101 {
102 MhwVdboxMfxInterface::avcSliceP,
103 MhwVdboxMfxInterface::avcSliceB,
104 MhwVdboxMfxInterface::avcSliceI,
105 MhwVdboxMfxInterface::avcSliceP,
106 MhwVdboxMfxInterface::avcSliceI,
107 MhwVdboxMfxInterface::avcSliceP,
108 MhwVdboxMfxInterface::avcSliceB,
109 MhwVdboxMfxInterface::avcSliceI,
110 MhwVdboxMfxInterface::avcSliceP,
111 MhwVdboxMfxInterface::avcSliceI
112 };
113
MhwVdboxMfxInterface(PMOS_INTERFACE osInterface,MhwMiInterface * miInterface,MhwCpInterface * cpInterface,bool decodeInUse)114 MhwVdboxMfxInterface::MhwVdboxMfxInterface(
115 PMOS_INTERFACE osInterface,
116 MhwMiInterface *miInterface,
117 MhwCpInterface *cpInterface,
118 bool decodeInUse)
119 {
120 MHW_FUNCTION_ENTER;
121
122 m_osInterface = osInterface;
123 m_MiInterface = miInterface;
124 m_cpInterface = cpInterface;
125 m_decodeInUse = decodeInUse;
126
127 MHW_ASSERT(m_osInterface);
128 MHW_ASSERT(m_MiInterface);
129 MHW_ASSERT(m_cpInterface);
130
131 m_waTable = osInterface->pfnGetWaTable(osInterface);
132 m_skuTable = osInterface->pfnGetSkuTable(osInterface);
133 m_osInterface->pfnGetPlatform(m_osInterface, &m_platform);
134 m_maxVdboxIndex = MEDIA_IS_SKU(m_skuTable, FtrVcs2) ? MHW_VDBOX_NODE_2 : MHW_VDBOX_NODE_1;
135
136 if (m_osInterface->bUsesGfxAddress)
137 {
138 AddResourceToCmd = Mhw_AddResourceToCmd_GfxAddress;
139 }
140 else // bUsesPatchList
141 {
142 AddResourceToCmd = Mhw_AddResourceToCmd_PatchList;
143 }
144
145 MEDIA_ENGINE_INFO mediaSysInfo;
146 MOS_ZeroMemory(&mediaSysInfo, sizeof(MEDIA_ENGINE_INFO));
147 MOS_STATUS eStatus = osInterface->pfnGetMediaEngineInfo(osInterface, mediaSysInfo);
148 if (eStatus == MOS_STATUS_SUCCESS && (!MEDIA_IS_SKU(m_skuTable, FtrWithSlimVdbox) || m_decodeInUse))
149 {
150 m_numVdbox = (uint8_t)(mediaSysInfo.VDBoxInfo.NumberOfVDBoxEnabled);
151 }
152 else
153 {
154 m_numVdbox = 1;
155 }
156 }
157
CalcAvcImgStateMinMaxBitrate(MHW_VDBOX_AVC_IMG_BITRATE_PARAMS & params)158 void MhwVdboxMfxInterface::CalcAvcImgStateMinMaxBitrate(
159 MHW_VDBOX_AVC_IMG_BITRATE_PARAMS& params)
160 {
161 // Set this to New mode (= 1) - FrameBitRateMaxUnit and FrameBitRateMinUnit are in new mode (32byte/4Kb)
162 params.frameBitRateMaxUnitMode = params.frameBitRateMinUnitMode = 1;
163
164 // Set this to Kilo Byte (= 1) - FrameBitRateMax and FrameBitRateMin are in units of 4KBytes when FrameBitrateMaxUnitMode and FrameBitRateMinUnitMode are set to 1
165 params.frameBitRateMaxUnit = params.frameBitRateMinUnit = 1;
166
167 // We have 14 bits available when FrameBitRateMaxUnitMode is set to 1, so set it to max value
168 params.frameBitRateMax = (1 << 14) - 1;
169
170 // Set this to min available value
171 params.frameBitRateMin = 0;
172
173 // Set frame bitrate max and min delta to 0
174 params.frameBitRateMaxDelta = params.frameBitRateMinDelta = 0;
175
176 return;
177 }
178
GetViewOrder(PMHW_VDBOX_AVC_DPB_PARAMS params,uint32_t currIdx,uint32_t list)179 uint32_t MhwVdboxMfxInterface::GetViewOrder(
180 PMHW_VDBOX_AVC_DPB_PARAMS params,
181 uint32_t currIdx,
182 uint32_t list)
183 {
184 MHW_CHK_NULL_RETURN(params);
185
186 auto avcPicParams = params->pAvcPicParams;
187 auto mvcExtPicParams = params->pMvcExtPicParams;
188 auto avcRefList = params->ppAvcRefList;
189
190 // No need to check if bottom field since only progressive is supported
191 int32_t currPOC = avcPicParams->CurrFieldOrderCnt[0];
192 uint32_t numRefs = (list == LIST_0) ? mvcExtPicParams->NumInterViewRefsL0 : mvcExtPicParams->NumInterViewRefsL1;
193 uint32_t viewOrder = 0xF;
194 uint32_t currRef = params->pAvcPicIdx[currIdx].ucPicIdx;
195
196 if (params->pAvcPicIdx[currIdx].bValid &&
197 avcRefList[currRef]->bUsedAsInterViewRef &&
198 (currPOC == avcRefList[currRef]->iFieldOrderCnt[0]))
199 {
200 for (uint32_t i = 0; i < numRefs; i++)
201 {
202 if (mvcExtPicParams->ViewIDList[currIdx] == mvcExtPicParams->InterViewRefList[list][i])
203 {
204 viewOrder = mvcExtPicParams->ViewIDList[currIdx];
205 break;
206 }
207 }
208 }
209
210 return viewOrder;
211 }
212
IsVc1IPicture(const CODEC_PICTURE & picture,bool isFirstField,uint16_t picType)213 bool MhwVdboxMfxInterface::IsVc1IPicture(
214 const CODEC_PICTURE& picture,
215 bool isFirstField,
216 uint16_t picType)
217 {
218 bool isI = false;
219
220 if (CodecHal_PictureIsField(picture))
221 {
222 if (picType == vc1IIField)
223 {
224 // I/I frame
225 isI = true;
226 }
227 else if (picType == vc1IPField)
228 {
229 // I/P frame
230 isI = isFirstField;
231 }
232 else if (picType == vc1PIField)
233 {
234 // P/I frame
235 isI = (!isFirstField);
236 }
237 }
238 else
239 {
240 isI = (picType == vc1IFrame);
241 }
242
243 return isI;
244 }
245
IsVc1PPicture(const CODEC_PICTURE & picture,bool isFirstField,uint16_t picType)246 bool MhwVdboxMfxInterface::IsVc1PPicture(
247 const CODEC_PICTURE& picture,
248 bool isFirstField,
249 uint16_t picType)
250 {
251 bool isP = false;
252
253 if (CodecHal_PictureIsField(picture))
254 {
255 if (picType == vc1PPField)
256 {
257 // P/P frame
258 isP = true;
259 }
260 else if (picType == vc1IPField)
261 {
262 // I/P frame
263 isP = (!isFirstField);
264 }
265 else if (picType == vc1PIField)
266 {
267 // P/I frame
268 isP = isFirstField;
269 }
270 }
271 else
272 {
273 isP = (picType == vc1PFrame);
274 }
275
276 return isP;
277 }
278
IsVc1BPicture(const CODEC_PICTURE & picture,bool isFirstField,uint16_t picType)279 bool MhwVdboxMfxInterface::IsVc1BPicture(
280 const CODEC_PICTURE& picture,
281 bool isFirstField,
282 uint16_t picType)
283 {
284 bool isB = false;
285
286 if (CodecHal_PictureIsField(picture))
287 {
288 if (picType == vc1BBIField)
289 {
290 // B/BI frame
291 isB = isFirstField;
292 }
293 else if (picType == vc1BIBField)
294 {
295 // BI/B frame
296 isB = (!isFirstField);
297 }
298 else if (picType == vc1BBField)
299 {
300 // BI/BI frame
301 isB = true;
302 }
303 }
304 else
305 {
306 isB = (picType == vc1BFrame);
307 }
308
309 return isB;
310 }
311
IsVc1BIPicture(const CODEC_PICTURE & picture,bool isFirstField,uint16_t picType)312 bool MhwVdboxMfxInterface::IsVc1BIPicture(
313 const CODEC_PICTURE& picture,
314 bool isFirstField,
315 uint16_t picType)
316 {
317 bool isBI = false;
318
319 if (CodecHal_PictureIsField(picture))
320 {
321 if (picType == vc1BBIField)
322 {
323 // B/BI frame
324 isBI = (!isFirstField);
325 }
326 else if (picType == vc1BIBField)
327 {
328 // BI/B frame
329 isBI = isFirstField;
330 }
331 else if (picType == vc1BIBIField)
332 {
333 // BI/BI frame
334 isBI = true;
335 }
336 }
337 else
338 {
339 isBI = (picType == vc1BIFrame);
340 }
341
342 return isBI;
343 }
344
AddMfxAvcImgCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_IMG_PARAMS params)345 MOS_STATUS MhwVdboxMfxInterface::AddMfxAvcImgCmd(
346 PMOS_COMMAND_BUFFER cmdBuffer,
347 PMHW_BATCH_BUFFER batchBuffer,
348 PMHW_VDBOX_AVC_IMG_PARAMS params)
349 {
350 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
351
352 MHW_FUNCTION_ENTER;
353
354 if (m_decodeInUse)
355 {
356 MHW_MI_CHK_STATUS(AddMfxDecodeAvcImgCmd(cmdBuffer, batchBuffer, params));
357 }
358 else
359 {
360 MHW_MI_CHK_STATUS(AddMfxEncodeAvcImgCmd(cmdBuffer, batchBuffer, params));
361 }
362
363 return eStatus;
364 }
365
AddMfxAvcWeightOffset(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS params)366 MOS_STATUS MhwVdboxMfxInterface::AddMfxAvcWeightOffset(
367 PMOS_COMMAND_BUFFER cmdBuffer,
368 PMHW_BATCH_BUFFER batchBuffer,
369 PMHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS params)
370 {
371 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
372
373 MHW_FUNCTION_ENTER;
374
375 if (m_decodeInUse)
376 {
377 MHW_MI_CHK_STATUS(AddMfxDecodeAvcWeightOffset(cmdBuffer, batchBuffer, params));
378 }
379 else
380 {
381 MHW_MI_CHK_STATUS(AddMfxEncodeAvcWeightOffset(cmdBuffer, batchBuffer, params));
382 }
383
384 return eStatus;
385 }
386
AddMfxAvcSlice(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)387 MOS_STATUS MhwVdboxMfxInterface::AddMfxAvcSlice(
388 PMOS_COMMAND_BUFFER cmdBuffer,
389 PMHW_BATCH_BUFFER batchBuffer,
390 PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)
391 {
392 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
393
394 MHW_FUNCTION_ENTER;
395
396 if (m_decodeInUse)
397 {
398 MHW_MI_CHK_STATUS(AddMfxDecodeAvcSlice(cmdBuffer, batchBuffer, avcSliceState));
399 }
400 else
401 {
402 MHW_MI_CHK_STATUS(AddMfxEncodeAvcSlice(cmdBuffer, batchBuffer, avcSliceState));
403 }
404
405 return eStatus;
406 }
407
AddMfxMpeg2PicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_MPEG2_PIC_STATE params)408 MOS_STATUS MhwVdboxMfxInterface::AddMfxMpeg2PicCmd(
409 PMOS_COMMAND_BUFFER cmdBuffer,
410 PMHW_VDBOX_MPEG2_PIC_STATE params)
411 {
412 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
413
414 MHW_FUNCTION_ENTER;
415
416 if (m_decodeInUse)
417 {
418 MHW_MI_CHK_STATUS(AddMfxDecodeMpeg2PicCmd(cmdBuffer, params));
419 }
420 else
421 {
422 MHW_MI_CHK_STATUS(AddMfxEncodeMpeg2PicCmd(cmdBuffer, params));
423 }
424
425 return eStatus;
426 }
427
AddMfxVp8PicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VP8_PIC_STATE params)428 MOS_STATUS MhwVdboxMfxInterface::AddMfxVp8PicCmd(
429 PMOS_COMMAND_BUFFER cmdBuffer,
430 PMHW_VDBOX_VP8_PIC_STATE params)
431 {
432 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
433
434 MHW_FUNCTION_ENTER;
435
436 if (m_decodeInUse)
437 {
438 MHW_MI_CHK_STATUS(AddMfxDecodeVp8PicCmd(cmdBuffer, params));
439 }
440 else
441 {
442 MHW_MI_CHK_STATUS(AddMfxEncodeVp8PicCmd(cmdBuffer, params));
443 }
444
445 return eStatus;
446 }
447
GetJpegDecodeFormat(MOS_FORMAT format)448 MHW_VDBOX_DECODE_JPEG_FORMAT_CODE MhwVdboxMfxInterface::GetJpegDecodeFormat(MOS_FORMAT format)
449 {
450 switch (format)
451 {
452 case Format_NV12:
453 return MHW_VDBOX_DECODE_JPEG_FORMAT_NV12;
454 case Format_UYVY:
455 return MHW_VDBOX_DECODE_JPEG_FORMAT_UYVY;
456 case Format_YUY2:
457 return MHW_VDBOX_DECODE_JPEG_FORMAT_YUY2;
458 default:
459 return MHW_VDBOX_DECODE_JPEG_FORMAT_SEPARATE_PLANE;
460 }
461
462 return MHW_VDBOX_DECODE_JPEG_FORMAT_SEPARATE_PLANE;
463 }
464
IsVPlanePresent(MOS_FORMAT format)465 bool MhwVdboxMfxInterface::IsVPlanePresent(MOS_FORMAT format)
466 {
467 switch (format)
468 {
469 case Format_NV12:
470 case Format_NV11:
471 case Format_P208:
472 case Format_IMC1:
473 case Format_IMC3:
474 case Format_YUY2:
475 case Format_YUYV:
476 case Format_YVYU:
477 case Format_UYVY:
478 case Format_VYUY:
479 case Format_422H:
480 case Format_422V:
481 // Adding RGB formats because RGB is treated like YUV for JPEG encode and decode
482 case Format_RGBP:
483 case Format_BGRP:
484 case Format_A8R8G8B8:
485 case Format_X8R8G8B8:
486 case Format_A8B8G8R8:
487 case Format_411P:
488 case Format_411R:
489 case Format_444P:
490 case Format_IMC2:
491 case Format_IMC4:
492 return true;
493 default:
494 return false;
495 }
496 }
497
MosToMediaStateFormat(MOS_FORMAT format)498 uint32_t MhwVdboxMfxInterface::MosToMediaStateFormat(MOS_FORMAT format)
499 {
500 switch (format)
501 {
502 case Format_A8R8G8B8:
503 case Format_X8R8G8B8:
504 case Format_A8B8G8R8:
505 return MHW_MEDIASTATE_SURFACEFORMAT_R8G8B8A8_UNORM;
506 case Format_422H:
507 case Format_422V:
508 return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_422_8;
509 case Format_AYUV:
510 case Format_AUYV:
511 return MHW_MEDIASTATE_SURFACEFORMAT_A8Y8U8V8_UNORM;
512 case Format_NV12:
513 case Format_NV11:
514 case Format_P208:
515 case Format_IMC1:
516 case Format_IMC3:
517 return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_420_8;
518 case Format_400P:
519 case Format_P8:
520 return MHW_MEDIASTATE_SURFACEFORMAT_Y8_UNORM;
521 case Format_411P:
522 case Format_411R:
523 return MHW_MEDIASTATE_SURFACEFORMAT_PLANAR_411_8;
524 case Format_UYVY:
525 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPY;
526 case Format_YVYU:
527 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPUV;
528 case Format_VYUY:
529 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_SWAPUVY;
530 case Format_YUY2:
531 case Format_YUYV:
532 case Format_444P:
533 case Format_IMC2:
534 case Format_IMC4:
535 default:
536 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_NORMAL;
537 }
538
539 return MHW_MEDIASTATE_SURFACEFORMAT_YCRCB_NORMAL;
540 }
541
GetJpegHorizontalSamplingFactorForY(CodecEncodeJpegInputSurfaceFormat format)542 uint32_t MhwVdboxMfxInterface::GetJpegHorizontalSamplingFactorForY(
543 CodecEncodeJpegInputSurfaceFormat format)
544 {
545 uint32_t horizontalSamplingFactor = 1;
546
547 if (format == codechalJpegY8)
548 {
549 horizontalSamplingFactor = 1;
550 }
551 else if (format == codechalJpegNV12)
552 {
553 horizontalSamplingFactor = 2;
554 }
555 else if (format == codechalJpegUYVY || format == codechalJpegYUY2)
556 {
557 horizontalSamplingFactor = 2;
558 }
559 else if (format == codechalJpegRGB)
560 {
561 horizontalSamplingFactor = 1;
562 }
563
564 return horizontalSamplingFactor;
565 }
566
GetJpegVerticalSamplingFactorForY(CodecEncodeJpegInputSurfaceFormat format)567 uint32_t MhwVdboxMfxInterface::GetJpegVerticalSamplingFactorForY(
568 CodecEncodeJpegInputSurfaceFormat format)
569 {
570 uint32_t verticalSamplingFactor = 1;
571
572 if (format == codechalJpegY8)
573 {
574 verticalSamplingFactor = 1;
575 }
576 else if (format == codechalJpegNV12)
577 {
578 verticalSamplingFactor = 2;
579 }
580 else if (format == codechalJpegRGB ||
581 format == codechalJpegUYVY ||
582 format == codechalJpegYUY2)
583 {
584 verticalSamplingFactor = 1;
585 }
586
587 return verticalSamplingFactor;
588 }
589