1 /*
2 * Copyright (c) 2011-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 codechal_decoder.cpp
24 //! \brief Implements the decode interface for CodecHal.
25 //! \details The decode interface is further sub-divided by standard, this file is for the base interface which is shared by all decode standards.
26 //!
27
28 #include "codechal_decoder.h"
29 #include "codechal_secure_decode_interface.h"
30 #include "mos_solo_generic.h"
31 #include "codechal_debug.h"
32 #include "codechal_decode_histogram.h"
33
34 #ifdef _HEVC_DECODE_SUPPORTED
35 #include "codechal_decode_hevc.h"
36 #endif
37
38 #ifdef _VP9_DECODE_SUPPORTED
39 #include "codechal_decode_vp9.h"
40 #endif
41
42 #ifdef _HYBRID_HEVC_DECODE_SUPPORTED
43 #include "codechal_decode_hybrid_hevc.h"
44 #endif
45
46 #ifdef _HYBRID_VP9_DECODE_SUPPORTED
47 #include "codechal_decode_hybrid_vp9.h"
48 #endif
49
50 #ifdef _AVC_DECODE_SUPPORTED
51 #include "codechal_decode_avc.h"
52 #endif
53
54 #ifdef _JPEG_DECODE_SUPPORTED
55 #include "codechal_decode_jpeg.h"
56 #endif
57
58 #ifdef _VC1_DECODE_SUPPORTED
59 #include "codechal_decode_vc1.h"
60 #endif
61
62 #ifdef _VP8_DECODE_SUPPORTED
63 #include "codechal_decode_vp8.h"
64 #endif
65
66 #ifdef _MPEG2_DECODE_SUPPORTED
67 #include "codechal_decode_mpeg2.h"
68 #endif
69
70 #if USE_CODECHAL_DEBUG_TOOL
71 #include <sstream>
72 #include <fstream>
73 #include "codechal_debug.h"
74 #endif
75
AllocateBuffer(PMOS_RESOURCE resource,uint32_t size,const char * name,bool initialize,uint8_t value,bool bPersistent)76 MOS_STATUS CodechalDecode::AllocateBuffer(
77 PMOS_RESOURCE resource,
78 uint32_t size,
79 const char *name,
80 bool initialize,
81 uint8_t value,
82 bool bPersistent)
83 {
84 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
85
86 CODECHAL_DECODE_FUNCTION_ENTER;
87
88 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
89 CODECHAL_DECODE_CHK_NULL_RETURN(resource);
90
91 MOS_ALLOC_GFXRES_PARAMS allocParams;
92 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
93 allocParams.Type = MOS_GFXRES_BUFFER;
94 allocParams.TileType = MOS_TILE_LINEAR;
95 allocParams.Format = Format_Buffer;
96 allocParams.dwBytes = size;
97 allocParams.pBufName = name;
98 allocParams.bIsPersistent = bPersistent;
99
100 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
101 m_osInterface,
102 &allocParams,
103 resource),
104 "Failed to allocate %s.", name);
105
106 if (initialize)
107 {
108 CodechalResLock ResourceLock(m_osInterface, resource);
109 auto data = (uint8_t*)ResourceLock.Lock(CodechalResLock::writeOnly);
110 CODECHAL_DECODE_CHK_NULL_RETURN(data);
111
112 MOS_FillMemory(data, size, value);
113 }
114
115 return eStatus;
116 }
117
AllocateSurface(PMOS_SURFACE surface,uint32_t width,uint32_t height,const char * name,MOS_FORMAT format,bool isCompressible)118 MOS_STATUS CodechalDecode::AllocateSurface(
119 PMOS_SURFACE surface,
120 uint32_t width,
121 uint32_t height,
122 const char *name,
123 MOS_FORMAT format,
124 bool isCompressible)
125 {
126 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
127
128 CODECHAL_DECODE_FUNCTION_ENTER;
129
130 CODECHAL_DECODE_CHK_NULL_RETURN(m_osInterface);
131 CODECHAL_DECODE_CHK_NULL_RETURN(surface);
132
133 MOS_ALLOC_GFXRES_PARAMS allocParams;
134 MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
135 allocParams.Type = MOS_GFXRES_2D;
136 allocParams.TileType = MOS_TILE_Y;
137 allocParams.Format = format;
138 allocParams.dwWidth = width;
139 allocParams.dwHeight = height;
140 allocParams.dwArraySize = 1;
141 allocParams.pBufName = name;
142 allocParams.bIsCompressible = isCompressible;
143
144 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(m_osInterface->pfnAllocateResource(
145 m_osInterface,
146 &allocParams,
147 &surface->OsResource),
148 "Failed to allocate %s.", name);
149
150 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
151 m_osInterface,
152 surface));
153
154 return eStatus;
155 }
156
HucCopy(PMOS_COMMAND_BUFFER cmdBuffer,PMOS_RESOURCE src,PMOS_RESOURCE dst,uint32_t copyLength,uint32_t copyInputOffset,uint32_t copyOutputOffset)157 MOS_STATUS CodechalDecode::HucCopy(
158 PMOS_COMMAND_BUFFER cmdBuffer,
159 PMOS_RESOURCE src,
160 PMOS_RESOURCE dst,
161 uint32_t copyLength,
162 uint32_t copyInputOffset,
163 uint32_t copyOutputOffset)
164 {
165 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
166
167 CODECHAL_DECODE_FUNCTION_ENTER;
168
169 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
170 CODECHAL_DECODE_CHK_NULL_RETURN(src);
171 CODECHAL_DECODE_CHK_NULL_RETURN(dst);
172
173 CodechalHucStreamoutParams hucStreamOutParams;
174 MOS_ZeroMemory(&hucStreamOutParams, sizeof(hucStreamOutParams));
175
176 // Ind Obj Addr command
177 hucStreamOutParams.dataBuffer = src;
178 hucStreamOutParams.dataSize = copyLength + copyInputOffset;
179 hucStreamOutParams.dataOffset = MOS_ALIGN_FLOOR(copyInputOffset, MHW_PAGE_SIZE);
180 hucStreamOutParams.streamOutObjectBuffer = dst;
181 hucStreamOutParams.streamOutObjectSize = copyLength + copyOutputOffset;
182 hucStreamOutParams.streamOutObjectOffset = MOS_ALIGN_FLOOR(copyOutputOffset, MHW_PAGE_SIZE);
183
184 // Stream object params
185 hucStreamOutParams.indStreamInLength = copyLength;
186 hucStreamOutParams.inputRelativeOffset = copyInputOffset - hucStreamOutParams.dataOffset;
187 hucStreamOutParams.outputRelativeOffset = copyOutputOffset - hucStreamOutParams.streamOutObjectOffset;
188
189 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->PerformHucStreamOut(
190 &hucStreamOutParams,
191 cmdBuffer));
192
193 return eStatus;
194 }
195
LinearToYTiledAddress(uint32_t x,uint32_t y,uint32_t pitch)196 uint32_t CodechalDecode::LinearToYTiledAddress(
197 uint32_t x,
198 uint32_t y,
199 uint32_t pitch)
200 {
201 uint32_t tileW = 128;
202 uint32_t tileH = 32;
203
204 uint32_t tileSize = tileW * tileH;
205
206 uint32_t rowSize = (pitch / tileW) * tileSize;
207
208 uint32_t xOffWithinTile = x % tileW;
209 uint32_t yOffWithinTile = y % tileH;
210
211 uint32_t tileNumberInX = x / tileW;
212 uint32_t tileNumberInY = y / tileH;
213
214 uint32_t tileOffset =
215 rowSize * tileNumberInY +
216 tileSize * tileNumberInX +
217 tileH * 16 * (xOffWithinTile / 16) +
218 yOffWithinTile * 16 +
219 (xOffWithinTile % 16);
220
221 return tileOffset;
222 }
223
CodechalDecode(CodechalHwInterface * hwInterface,CodechalDebugInterface * debugInterface,PCODECHAL_STANDARD_INFO standardInfo)224 CodechalDecode::CodechalDecode (
225 CodechalHwInterface *hwInterface,
226 CodechalDebugInterface *debugInterface,
227 PCODECHAL_STANDARD_INFO standardInfo):
228 Codechal(hwInterface, debugInterface)
229 {
230 CODECHAL_DECODE_FUNCTION_ENTER;
231
232 MOS_ZeroMemory(&m_dummyReference, sizeof(MOS_SURFACE));
233
234 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface);
235 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface->GetOsInterface());
236 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface->GetMiInterface());
237 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(hwInterface->GetCpInterface());
238 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(standardInfo);
239
240 m_mfxInterface = hwInterface->GetMfxInterface();
241 m_hcpInterface = hwInterface->GetHcpInterface();
242 m_hucInterface = hwInterface->GetHucInterface();
243 m_vdencInterface = hwInterface->GetVdencInterface();
244 m_miInterface = hwInterface->GetMiInterface();
245 m_cpInterface = hwInterface->GetCpInterface();
246
247 PLATFORM platform;
248 m_osInterface->pfnGetPlatform(m_osInterface, &platform);
249 m_waTable = m_osInterface->pfnGetWaTable(m_osInterface);
250 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_waTable);
251 m_skuTable = m_osInterface->pfnGetSkuTable(m_osInterface);
252 CODECHAL_DECODE_CHK_NULL_NO_STATUS_RETURN(m_skuTable);
253
254 m_mode = standardInfo->Mode;
255 m_isHybridDecoder = standardInfo->bIsHybridCodec ? true : false;
256 }
257
SetGpuCtxCreatOption(CodechalSetting * codecHalSetting)258 MOS_STATUS CodechalDecode::SetGpuCtxCreatOption(
259 CodechalSetting * codecHalSetting)
260 {
261 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
262
263 MOS_UNUSED(codecHalSetting);
264
265 m_gpuCtxCreatOpt = MOS_New(MOS_GPUCTX_CREATOPTIONS);
266 CODECHAL_DECODE_CHK_NULL_RETURN(m_gpuCtxCreatOpt);
267
268 return eStatus;
269 }
270
CreateGpuContexts(CodechalSetting * codecHalSettings)271 MOS_STATUS CodechalDecode::CreateGpuContexts(
272 CodechalSetting *codecHalSettings)
273 {
274 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
275
276 CODECHAL_DECODE_CHK_NULL_RETURN(codecHalSettings);
277
278 MHW_VDBOX_GPUNODE_LIMIT gpuNodeLimit;
279 gpuNodeLimit.bHuCInUse = false;
280 gpuNodeLimit.bHcpInUse = m_hcpInUse;
281 gpuNodeLimit.bSfcInUse = IsSfcInUse(codecHalSettings);
282
283 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mfxInterface->FindGpuNodeToUse(
284 &gpuNodeLimit));
285
286 m_videoGpuNode = (MOS_GPU_NODE)(gpuNodeLimit.dwGpuNodeToUse);
287
288 CODECHAL_UPDATE_VDBOX_USER_FEATURE(m_videoGpuNode);
289 CodecHalDecodeMapGpuNodeToGpuContex(m_videoGpuNode, m_videoContext, false);
290
291 CODECHAL_DECODE_CHK_STATUS_RETURN(SetGpuCtxCreatOption(codecHalSettings));
292 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnCreateGpuContext(
293 m_osInterface,
294 m_videoContext,
295 m_videoGpuNode,
296 m_gpuCtxCreatOpt));
297
298 // Create Video2 Context for MPEG2 WA and JPEG incomplete bitstream & VP9 / HEVC DRC support
299 // For decode device, we use VDBOX0 always for the WA context
300 // For AVC,VC1,VP9, use WA context for huc stream out copy
301 if (Mos_Solo_IsInUse(m_osInterface))
302 {
303 Mos_Solo_DecodeMapGpuNodeToGpuContex(MOS_GPU_NODE_VIDEO, m_videoContextForWa, true, false);
304 }
305 else
306 {
307 CodecHalDecodeMapGpuNodeToGpuContex(MOS_GPU_NODE_VIDEO, m_videoContextForWa, true);
308 }
309
310 MOS_GPUCTX_CREATOPTIONS createOption;
311 eStatus = (MOS_STATUS)m_osInterface->pfnCreateGpuContext(
312 m_osInterface,
313 m_videoContextForWa,
314 MOS_GPU_NODE_VIDEO,
315 &createOption);
316
317 if (eStatus != MOS_STATUS_SUCCESS)
318 {
319 // use context Video1. It should be valid
320 if (Mos_Solo_IsInUse(m_osInterface))
321 {
322 Mos_Solo_DecodeMapGpuNodeToGpuContex(MOS_GPU_NODE_VIDEO, m_videoContextForWa, false, false);
323 }
324 else
325 {
326 CodecHalDecodeMapGpuNodeToGpuContex(MOS_GPU_NODE_VIDEO, m_videoContextForWa, false);
327 }
328 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnIsGpuContextValid(
329 m_osInterface,
330 m_videoContextForWa));
331 }
332
333 // Do not need to create render context here, it will be created by standard specific decoder
334
335 return eStatus;
336 }
337
338 // Decoder Public Interface Functions
Allocate(CodechalSetting * codecHalSettings)339 MOS_STATUS CodechalDecode::Allocate (CodechalSetting * codecHalSettings)
340 {
341 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
342
343 CODECHAL_DECODE_FUNCTION_ENTER;
344
345 CODECHAL_DECODE_CHK_STATUS_RETURN(Codechal::Allocate(codecHalSettings));
346
347 m_standard = codecHalSettings->standard;
348 m_mode = codecHalSettings->mode;
349 m_disableDecodeSyncLock = codecHalSettings->disableDecodeSyncLock ? true : false;
350 m_disableLockForTranscode = MEDIA_IS_WA(m_waTable, WaDisableLockForTranscodePerf);
351
352 // register cp params via codechal_Setting
353 m_cpInterface->RegisterParams(codecHalSettings->GetCpParams());
354
355 {
356 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
357 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
358 userFeatureData.u32Data = MOS_STATUS_REPORT_DEFAULT;
359 userFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE;
360 MOS_UserFeature_ReadValue_ID(
361 nullptr,
362 __MEDIA_USER_FEATURE_VALUE_STATUS_REPORTING_ENABLE_ID,
363 &userFeatureData);
364 m_statusQueryReportingEnabled = (userFeatureData.u32Data) ? true : false;
365
366 #if (_DEBUG || _RELEASE_INTERNAL)
367 if (m_statusQueryReportingEnabled)
368 {
369 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
370 MOS_UserFeature_ReadValue_ID(
371 nullptr,
372 __MEDIA_USER_FEATURE_VALUE_STREAM_OUT_ENABLE_ID,
373 &userFeatureData);
374 m_streamOutEnabled = (userFeatureData.u32Data) ? true : false;
375
376 }
377
378 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
379 MOS_UserFeature_ReadValue_ID(
380 nullptr,
381 __MEDIA_USER_FEATURE_VALUE_PERF_PROFILER_FE_BE_TIMING,
382 &userFeatureData);
383 m_perfFEBETimingEnabled = userFeatureData.bData;
384
385 #endif // _DEBUG || _RELEASE_INTERNAL
386 }
387
388 //#if (_DEBUG || _RELEASE_INTERNAL)
389 //#ifdef _MD5_DEBUG_SUPPORTED
390 // {
391 // // For multi-thread decoder case, MD5 kernel will share the same context with hybrid decoder.
392 // // And it will be initialized in decoder worker thread function.
393 // if ((!m_isHybridDecoder || (m_isHybridDecoder && !IsFrameMTEnabled())) &&
394 // m_debugInterface != nullptr)
395 // {
396 // CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgInitMD5Context(
397 // m_debugInterface,
398 // nullptr));
399 // if (m_debugInterface->pMD5Context)
400 // {
401 // m_debugInterface->bMD5DDIThreadExecute = true;
402 // }
403 // }
404 // }
405 //#endif // _MD5_DEBUG_SUPPORTED
406 //#endif // _DEBUG || _RELEASE_INTERNAL
407
408 // Set decoder running flag to OS context so that VPP driver can query this flag and use
409 // this flag to decide if disable VPP DNDI feature in VEBOX for power saving.
410 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetHybridDecoderRunningFlag(
411 m_osInterface,
412 m_isHybridDecoder));
413
414 // eStatus Query reporting
415 if (m_statusQueryReportingEnabled)
416 {
417 uint32_t statusBufferSize = sizeof(CodechalDecodeStatus) * CODECHAL_DECODE_STATUS_NUM + sizeof(uint32_t) * 2;
418
419 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
420 &m_decodeStatusBuf.m_statusBuffer,
421 statusBufferSize,
422 "StatusQueryBuffer"),
423 "Failed to allocate decode eStatus buffer.");
424
425 MOS_LOCK_PARAMS lockFlagsNoOverWrite;
426 MOS_ZeroMemory(&lockFlagsNoOverWrite, sizeof(MOS_LOCK_PARAMS));
427 lockFlagsNoOverWrite.WriteOnly = 1;
428 lockFlagsNoOverWrite.NoOverWrite = 1;
429
430 uint8_t *data = (uint8_t *)m_osInterface->pfnLockResource(
431 m_osInterface,
432 &m_decodeStatusBuf.m_statusBuffer,
433 &lockFlagsNoOverWrite);
434
435 MOS_ZeroMemory(data, statusBufferSize);
436 m_decodeStatusBuf.m_data = (uint32_t *)data;
437 m_decodeStatusBuf.m_decodeStatus = (CodechalDecodeStatus *)(data + sizeof(uint32_t) * 2);
438 m_decodeStatusBuf.m_currIndex = 0;
439 m_decodeStatusBuf.m_firstIndex = 0;
440 m_decodeStatusBuf.m_swStoreData = 1;
441
442 m_decodeStatusBuf.m_storeDataOffset = 0;
443 m_decodeStatusBuf.m_decErrorStatusOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_mmioErrorStatusReg);
444 m_decodeStatusBuf.m_decFrameCrcOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_mmioFrameCrcReg);
445 m_decodeStatusBuf.m_decMBCountOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_mmioMBCountReg);
446 m_decodeStatusBuf.m_csEngineIdOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_mmioCsEngineIdReg);
447 m_decodeStatusBuf.m_hucErrorStatus2MaskOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_hucErrorStatus2);
448 m_decodeStatusBuf.m_hucErrorStatus2RegOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_hucErrorStatus2) + sizeof(uint32_t);
449 m_decodeStatusBuf.m_hucErrorStatusMaskOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_hucErrorStatus);
450 m_decodeStatusBuf.m_hucErrorStatusRegOffset = CODECHAL_OFFSETOF(CodechalDecodeStatus, m_hucErrorStatus) + sizeof(uint32_t);
451
452 // Set IMEM Loaded bit (in DW1) to 1 by default in the first status buffer
453 // This bit will be changed later after storing register
454 if (m_hucInterface)
455 {
456 m_decodeStatusBuf.m_decodeStatus->m_hucErrorStatus2 = (uint64_t)m_hucInterface->GetHucStatus2ImemLoadedMask() << 32;
457 }
458
459 //if kernels are used update the media state heap with status pointers to keep track of when buffers are done
460 if (m_hwInterface->GetRenderInterface() != nullptr &&
461 m_hwInterface->GetRenderInterface()->m_stateHeapInterface != nullptr)
462 {
463 PMHW_STATE_HEAP_INTERFACE pStateHeapInterface =
464 m_hwInterface->GetRenderInterface()->m_stateHeapInterface;
465
466 CODECHAL_DECODE_CHK_STATUS_RETURN(pStateHeapInterface->pfnSetCmdBufStatusPtr(
467 pStateHeapInterface,
468 m_decodeStatusBuf.m_data));
469 }
470
471 // StreamOut Buffer Allocation
472 if (m_streamOutEnabled)
473 {
474 uint32_t numMacroblocks =
475 (codecHalSettings->height / CODECHAL_MACROBLOCK_HEIGHT) *
476 (codecHalSettings->width / CODECHAL_MACROBLOCK_WIDTH);
477 uint32_t streamOutBufSize = MOS_ALIGN_CEIL(numMacroblocks * CODEC_SIZE_MFX_STREAMOUT_DATA, 64);
478
479 m_streamOutCurrBufIdx = 0;
480
481 for (auto i = 0; i < CODECHAL_DECODE_NUM_STREAM_OUT_BUFFERS; i++)
482 {
483 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
484 &(m_streamOutBuffer[i]),
485 streamOutBufSize,
486 "StreamOutBuffer",
487 true,
488 0),
489 "Failed to allocate streamout buffer.");
490
491 m_streamOutCurrStatusIdx[i] = CODECHAL_DECODE_STATUS_NUM;
492 }
493 }
494 }
495
496 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(AllocateBuffer(
497 &m_predicationBuffer,
498 sizeof(uint32_t),
499 "PredicationBuffer",
500 true,
501 0),
502 "Failed to allocate predication buffer.");
503
504 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateStandard(codecHalSettings));
505
506 if(!m_isHybridDecoder)
507 {
508 // Create Video Contexts
509 CODECHAL_DECODE_CHK_STATUS_RETURN(CreateGpuContexts(codecHalSettings));
510 // Set Vdbox index in use
511 m_vdboxIndex = (m_videoGpuNode == MOS_GPU_NODE_VIDEO2)? MHW_VDBOX_NODE_2 : MHW_VDBOX_NODE_1;
512
513 // Set FrameCrc reg offset
514 if (m_standard == CODECHAL_HEVC)
515 {
516 m_hcpFrameCrcRegOffset = m_hcpInterface->GetMmioRegisters(m_vdboxIndex)->hcpFrameCrcRegOffset;
517 }
518 }
519
520 if (!m_mmc)
521 {
522 m_mmc = MOS_New(CodecHalMmcState, m_hwInterface);
523 }
524
525 m_secureDecoder = Create_SecureDecodeInterface(codecHalSettings, m_hwInterface);
526
527 #ifdef _DECODE_PROCESSING_SUPPORTED
528 m_downsamplingHinted = codecHalSettings->downsamplingHinted ? true : false;
529 if (CodecHalIsEnableFieldScaling(codecHalSettings->codecFunction, m_standard, m_downsamplingHinted))
530 {
531 CODECHAL_DECODE_CHK_NULL_RETURN(m_fieldScalingInterface);
532 CODECHAL_DECODE_CHK_STATUS_RETURN(m_fieldScalingInterface->InitializeKernelState(
533 this,
534 m_hwInterface,
535 m_osInterface));
536 }
537 #endif
538
539 m_renderContextUsesNullHw = m_useNullHw[m_renderContext];
540 if(!m_isHybridDecoder)
541 {
542 m_videoContextUsesNullHw = m_useNullHw[m_videoContext];
543 m_videoContextForWaUsesNullHw = m_useNullHw[m_videoContextForWa];
544
545 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnRegisterBBCompleteNotifyEvent(
546 m_osInterface,
547 m_videoContext));
548 }
549
550 if (!m_perfProfiler)
551 {
552 m_perfProfiler = MediaPerfProfiler::Instance();
553 CODECHAL_DECODE_CHK_NULL_RETURN(m_perfProfiler);
554
555 CODECHAL_DECODE_CHK_STATUS_RETURN(m_perfProfiler->Initialize((void*)this, m_osInterface));
556 }
557
558 return eStatus;
559 }
560
AllocateRefSurfaces(uint32_t allocWidth,uint32_t allocHeight,MOS_FORMAT format)561 MOS_STATUS CodechalDecode::AllocateRefSurfaces(
562 uint32_t allocWidth,
563 uint32_t allocHeight,
564 MOS_FORMAT format)
565 {
566 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
567
568 CODECHAL_DECODE_FUNCTION_ENTER;
569
570 if (allocWidth == 0 || allocHeight == 0)
571 {
572 CODECHAL_DECODE_ASSERTMESSAGE("Invalid Downsampling Reference Frame Width or Height !");
573 return MOS_STATUS_INVALID_PARAMETER;
574 }
575
576 m_refSurfaces = (MOS_SURFACE*)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE) * m_refFrmCnt);
577 CODECHAL_DECODE_CHK_NULL_RETURN(m_refSurfaces);
578
579 CODECHAL_DEBUG_TOOL(
580 m_downsampledSurfaces = (MOS_SURFACE*)MOS_AllocAndZeroMemory(m_refFrmCnt * sizeof(MOS_SURFACE));
581 )
582
583 for (uint32_t i = 0; i < m_refFrmCnt; i++)
584 {
585 eStatus = AllocateSurface(
586 &m_refSurfaces[i],
587 allocWidth,
588 allocHeight,
589 "DownsamplingRefSurface",
590 format,
591 CodecHalMmcState::IsMmcEnabled());
592
593 if (eStatus != MOS_STATUS_SUCCESS)
594 {
595 CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate decode downsampling reference surface.");
596 DeallocateRefSurfaces();
597 return eStatus;
598 }
599 }
600
601 return MOS_STATUS_SUCCESS;
602 }
603
RefSurfacesResize(uint32_t frameIdx,uint32_t width,uint32_t height,MOS_FORMAT format)604 MOS_STATUS CodechalDecode::RefSurfacesResize(
605 uint32_t frameIdx,
606 uint32_t width,
607 uint32_t height,
608 MOS_FORMAT format)
609 {
610 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
611 CODECHAL_DECODE_FUNCTION_ENTER;
612
613 if (m_refSurfaces[frameIdx].dwWidth == 0 || m_refSurfaces[frameIdx].dwHeight == 0)
614 {
615 CODECHAL_DECODE_ASSERTMESSAGE("Invalid Downsampling Reference Frame Width or Height !");
616 return MOS_STATUS_INVALID_PARAMETER;
617 }
618
619 DeallocateSpecificRefSurfaces(frameIdx);
620
621 eStatus = AllocateSurface(
622 &m_refSurfaces[frameIdx],
623 width,
624 height,
625 "DownsamplingRefSurface",
626 format,
627 CodecHalMmcState::IsMmcEnabled());
628
629 if (eStatus != MOS_STATUS_SUCCESS)
630 {
631 CODECHAL_DECODE_ASSERTMESSAGE("Failed to allocate decode downsampling reference surface.");
632 DeallocateRefSurfaces();
633 return eStatus;
634 }
635
636 return MOS_STATUS_SUCCESS;
637 }
638
DeallocateSpecificRefSurfaces(uint32_t frameIdx)639 void CodechalDecode::DeallocateSpecificRefSurfaces(uint32_t frameIdx)
640 {
641 CODECHAL_DECODE_FUNCTION_ENTER;
642
643 if (m_refSurfaces != nullptr && frameIdx != 0)
644 {
645 if (!Mos_ResourceIsNull(&m_refSurfaces[frameIdx].OsResource))
646 {
647 m_osInterface->pfnFreeResource(
648 m_osInterface,
649 &m_refSurfaces[frameIdx].OsResource);
650 }
651 }
652 }
653
DeallocateRefSurfaces()654 void CodechalDecode::DeallocateRefSurfaces()
655 {
656 CODECHAL_DECODE_FUNCTION_ENTER;
657
658 if (m_refSurfaces != nullptr && m_refFrmCnt != 0)
659 {
660 CODECHAL_DEBUG_TOOL(
661 MOS_FreeMemAndSetNull(m_downsampledSurfaces);
662 )
663
664 for (uint32_t i = 0; i < m_refFrmCnt; i++)
665 {
666 if (!Mos_ResourceIsNull(&m_refSurfaces[i].OsResource))
667 {
668 m_osInterface->pfnFreeResource(
669 m_osInterface,
670 &m_refSurfaces[i].OsResource);
671 }
672 }
673
674 MOS_FreeMemory(m_refSurfaces);
675 m_refSurfaces = nullptr;
676 }
677 }
678
SetDummyReference()679 MOS_STATUS CodechalDecode::SetDummyReference()
680 {
681 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
682
683 if (MEDIA_IS_WA(m_waTable, WaDummyReference))
684 {
685 // If can't find valid dummy reference, create one or use current decode output surface
686 if (Mos_ResourceIsNull(&m_dummyReference.OsResource))
687 {
688 // If MMC enabled
689 if (m_mmc != nullptr && m_mmc->IsMmcEnabled() &&
690 !m_mmc->IsMmcExtensionEnabled() &&
691 m_decodeParams.m_destSurface->bIsCompressed)
692 {
693 if (m_mode == CODECHAL_DECODE_MODE_HEVCVLD)
694 {
695 eStatus = AllocateSurface(
696 &m_dummyReference,
697 m_decodeParams.m_destSurface->dwWidth,
698 m_decodeParams.m_destSurface->dwHeight,
699 "dummy reference resource",
700 m_decodeParams.m_destSurface->Format,
701 m_decodeParams.m_destSurface->bIsCompressed);
702
703 if (eStatus != MOS_STATUS_SUCCESS)
704 {
705 CODECHAL_DECODE_ASSERTMESSAGE("Failed to create dummy reference!");
706 return eStatus;
707 }
708 else
709 {
710 m_dummyReferenceStatus = CODECHAL_DUMMY_REFERENCE_ALLOCATED;
711 CODECHAL_DECODE_VERBOSEMESSAGE("Dummy reference is created!");
712 }
713 }
714 }
715 else // Use decode output surface as dummy reference
716 {
717 m_dummyReference.OsResource = m_decodeParams.m_destSurface->OsResource;
718 m_dummyReferenceStatus = CODECHAL_DUMMY_REFERENCE_DEST_SURFACE;
719 }
720 }
721 }
722
723 return eStatus;
724 }
725
~CodechalDecode()726 CodechalDecode::~CodechalDecode()
727 {
728 CODECHAL_DECODE_FUNCTION_ENTER;
729
730 Delete_SecureDecodeInterface(m_secureDecoder);
731 m_secureDecoder = nullptr;
732
733 if (m_mmc)
734 {
735 MOS_Delete(m_mmc);
736 m_mmc = nullptr;
737 }
738
739 // Destroy decode histogram
740 if (m_decodeHistogram != nullptr)
741 {
742 MOS_Delete(m_decodeHistogram);
743 m_decodeHistogram = nullptr;
744 }
745
746 if (MEDIA_IS_SKU(m_skuTable, FtrVcs2) && (m_videoGpuNode < MOS_GPU_NODE_MAX))
747 {
748 // Destroy decode video node association
749 m_osInterface->pfnDestroyVideoNodeAssociation(m_osInterface, m_videoGpuNode);
750 }
751
752 if (m_statusQueryReportingEnabled)
753 {
754 m_osInterface->pfnUnlockResource(
755 m_osInterface,
756 &(m_decodeStatusBuf.m_statusBuffer));
757
758 m_osInterface->pfnFreeResource(
759 m_osInterface,
760 &(m_decodeStatusBuf.m_statusBuffer));
761
762 if (m_streamOutEnabled)
763 {
764 for (auto i = 0; i < CODECHAL_DECODE_NUM_STREAM_OUT_BUFFERS; i++)
765 {
766 m_osInterface->pfnFreeResource(
767 m_osInterface,
768 &(m_streamOutBuffer[i]));
769 }
770 }
771 }
772
773 if (m_gpuCtxCreatOpt)
774 {
775 MOS_Delete(m_gpuCtxCreatOpt);
776 }
777
778 m_osInterface->pfnFreeResource(
779 m_osInterface,
780 &m_predicationBuffer);
781
782 DeallocateRefSurfaces();
783
784 #ifdef _DECODE_PROCESSING_SUPPORTED
785 if (CodecHalIsEnableFieldScaling(CODECHAL_FUNCTION_DECODE, m_standard, m_downsamplingHinted))
786 {
787 if (m_fieldScalingInterface != nullptr)
788 {
789 MOS_Delete(m_fieldScalingInterface);
790 m_fieldScalingInterface = nullptr;
791 }
792 }
793 #endif
794
795 if (m_perfProfiler)
796 {
797 MediaPerfProfiler::Destroy(m_perfProfiler, (void*)this, m_osInterface);
798 m_perfProfiler = nullptr;
799 }
800
801 if (m_dummyReferenceStatus == CODECHAL_DUMMY_REFERENCE_ALLOCATED &&
802 !Mos_ResourceIsNull(&m_dummyReference.OsResource))
803 {
804 m_osInterface->pfnFreeResource(m_osInterface, &m_dummyReference.OsResource);
805 }
806 }
807
CalcRequestedSpace(uint32_t & requestedSize,uint32_t & additionalSizeNeeded,uint32_t & requestedPatchListSize)808 void CodechalDecode::CalcRequestedSpace(
809 uint32_t &requestedSize,
810 uint32_t &additionalSizeNeeded,
811 uint32_t &requestedPatchListSize)
812 {
813 requestedSize = m_commandBufferSizeNeeded +
814 (m_standardDecodeSizeNeeded * (m_decodeParams.m_numSlices + 1));
815 requestedPatchListSize = m_commandPatchListSizeNeeded +
816 (m_standardDecodePatchListSizeNeeded * (m_decodeParams.m_numSlices + 1));
817 additionalSizeNeeded = COMMAND_BUFFER_RESERVED_SPACE;
818 }
819
VerifySpaceAvailable()820 MOS_STATUS CodechalDecode::VerifySpaceAvailable ()
821 {
822 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
823
824 CODECHAL_DECODE_FUNCTION_ENTER;
825
826 uint32_t requestedSize = 0, additionalSizeNeeded = 0, requestedPatchListSize = 0;
827 CalcRequestedSpace(requestedSize, additionalSizeNeeded, requestedPatchListSize);
828
829 uint32_t primRequestedSize = RequestedSpaceSize(requestedSize);
830
831 // Try a maximum of 3 attempts to request the required sizes from OS
832 // OS could reset the sizes if necessary, therefore, requires to re-verify
833 for (auto i = 0; i < 3; i++)
834 {
835 if (m_osInterface->bUsesPatchList || MEDIA_IS_SKU(m_skuTable, FtrMediaPatchless))
836 {
837 eStatus = (MOS_STATUS)m_osInterface->pfnVerifyPatchListSize(
838 m_osInterface,
839 requestedPatchListSize);
840
841 if (eStatus != MOS_STATUS_SUCCESS)
842 {
843 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->ResizeCommandBufferAndPatchList(
844 0,
845 requestedPatchListSize));
846 }
847 }
848
849 eStatus = (MOS_STATUS)m_osInterface->pfnVerifyCommandBufferSize(
850 m_osInterface,
851 primRequestedSize,
852 0);
853
854 if (eStatus == MOS_STATUS_SUCCESS)
855 {
856 break;
857 }
858 else
859 {
860 CODECHAL_DECODE_CHK_STATUS_RETURN(m_hwInterface->ResizeCommandBufferAndPatchList(
861 primRequestedSize + additionalSizeNeeded,
862 0));
863 }
864 }
865
866 CODECHAL_DECODE_CHK_STATUS_RETURN(VerifyExtraSpace(requestedSize, additionalSizeNeeded));
867
868 return eStatus;
869 }
870
EndFrame()871 MOS_STATUS CodechalDecode::EndFrame ()
872 {
873 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
874
875 CODECHAL_DECODE_FUNCTION_ENTER;
876
877 CODECHAL_DEBUG_TOOL(
878 CodechalDecodeStatusReport * decodeStatusReport;
879 auto tempSurfNum = m_debugInterface->m_decodeSurfDumpFrameNum; // to handle BB_END data not written case
880 uint16_t preIndex = m_debugInterface->m_preIndex;
881 uint32_t numReportsAvailable = (m_decodeStatusBuf.m_currIndex - preIndex) & (CODECHAL_DECODE_STATUS_NUM - 1);
882 CODECHAL_DECODE_VERBOSEMESSAGE("NumReportsAvailable = %d", numReportsAvailable);
883
884 for (uint32_t i = 0; i < numReportsAvailable; i++) {
885 uint16_t index = (m_debugInterface->m_preIndex + i) % CODECHAL_DECODE_STATUS_NUM;
886 decodeStatusReport =
887 &(m_decodeStatusBuf.m_decodeStatus[index].m_decodeStatusReport);
888
889 // record SurfDumpFrameNum to handle BB_END data not written case
890 if (CodecHal_PictureIsFrame(decodeStatusReport->m_currDecodedPic) ||
891 CodecHal_PictureIsInterlacedFrame(decodeStatusReport->m_currDecodedPic) ||
892 decodeStatusReport->m_secondField)
893 {
894 tempSurfNum++;
895 }
896
897 if (m_standard == CODECHAL_HEVC &&
898 m_isHybridDecoder &&
899 (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrReferenceSurfaces)|| m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeOutputSurface)))
900 {
901 CODECHAL_DECODE_CHK_STATUS_BREAK(DecodeGetHybridStatus(
902 m_decodeStatusBuf.m_decodeStatus, index, CODECHAL_STATUS_QUERY_START_FLAG));
903 }
904
905 auto tempFrameNum = m_debugInterface->m_bufferDumpFrameNum;
906 auto tempPic = m_debugInterface->m_currPic;
907 auto tempFrameType = m_debugInterface->m_frameType;
908 m_debugInterface->m_bufferDumpFrameNum = m_debugInterface->m_decodeSurfDumpFrameNum;
909 m_debugInterface->m_currPic = decodeStatusReport->m_currDecodedPic;
910 m_debugInterface->m_frameType = decodeStatusReport->m_frameType;
911 bool olpDump = false;
912
913 MOS_SURFACE dstSurface;
914 if ((CodecHal_PictureIsFrame(decodeStatusReport->m_currDecodedPic) ||
915 CodecHal_PictureIsInterlacedFrame(decodeStatusReport->m_currDecodedPic) ||
916 CodecHal_PictureIsField(decodeStatusReport->m_currDecodedPic)) &&
917 (m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeBltOutput) ||
918 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeOutputSurface) ||
919 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrStreamOut)))
920 {
921 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
922 dstSurface.Format = Format_NV12;
923 dstSurface.OsResource = decodeStatusReport->m_currDecodedPicRes;
924 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
925 m_osInterface,
926 &dstSurface));
927
928 m_debugInterface->DumpBltOutput(
929 &dstSurface,
930 CodechalDbgAttr::attrDecodeBltOutput);
931
932 CODECHAL_DECODE_CHK_STATUS_BREAK(m_debugInterface->DumpYUVSurface(
933 &dstSurface,
934 CodechalDbgAttr::attrDecodeOutputSurface,
935 "DstSurf"));
936
937 if (m_streamOutEnabled)
938 {
939 //dump streamout buffer
940 CODECHAL_DECODE_CHK_STATUS_BREAK(m_debugInterface->DumpBuffer(
941 decodeStatusReport->m_streamOutBuf,
942 CodechalDbgAttr::attrStreamOut,
943 "StreamOut",
944 dstSurface.dwWidth));
945 // reset the capture status of the streamout buffer
946 m_streamOutCurrStatusIdx[decodeStatusReport->m_streamoutIdx] = CODECHAL_DECODE_STATUS_NUM;
947 }
948
949 olpDump = true;
950 }
951
952 MOS_USER_FEATURE_VALUE_DATA userFeatureData;
953 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
954 MOS_UserFeature_ReadValue_ID(
955 nullptr,
956 __MEDIA_USER_FEATURE_VALUE_DECOMPRESS_DECODE_OUTPUT_ID,
957 &userFeatureData);
958 if (userFeatureData.u32Data)
959 {
960 CODECHAL_DECODE_VERBOSEMESSAGE("force ve decompress decode output");
961 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
962 dstSurface.Format = Format_NV12;
963 dstSurface.OsResource = decodeStatusReport->m_currDecodedPicRes;
964 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
965 m_osInterface,
966 &dstSurface));
967 MOS_LOCK_PARAMS lockFlags {};
968 lockFlags.ReadOnly = 1;
969 lockFlags.TiledAsTiled = 1;
970 lockFlags.NoDecompress = 0;
971 m_osInterface->pfnLockResource(m_osInterface, &dstSurface.OsResource, &lockFlags);
972 m_osInterface->pfnUnlockResource(m_osInterface, &dstSurface.OsResource);
973 }
974
975 if (m_standard == CODECHAL_VC1 &&
976 decodeStatusReport->m_olpNeeded &&
977 olpDump &&
978 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeOutputSurface))
979 {
980 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
981 dstSurface.Format = Format_NV12;
982 dstSurface.OsResource = decodeStatusReport->m_deblockedPicResOlp;
983
984 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
985 m_osInterface,
986 &dstSurface));
987
988 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
989 &dstSurface,
990 CodechalDbgAttr::attrDecodeOutputSurface,
991 "OLP_DstSurf"));
992 }
993
994 if ((m_standard == CODECHAL_HEVC || m_standard == CODECHAL_VP9) &&
995 (decodeStatusReport->m_currSfcOutputPicRes != nullptr) &&
996 m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrSfcOutputSurface))
997 {
998 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
999 dstSurface.Format = Format_NV12;
1000 dstSurface.OsResource = *decodeStatusReport->m_currSfcOutputPicRes;
1001
1002 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
1003 m_osInterface,
1004 &dstSurface));
1005
1006 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpYUVSurface(
1007 &dstSurface,
1008 CodechalDbgAttr::attrSfcOutputSurface,
1009 "SfcDstSurf"));
1010 }
1011
1012 MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData));
1013 MOS_UserFeature_ReadValue_ID(
1014 nullptr,
1015 __MEDIA_USER_FEATURE_VALUE_DECOMPRESS_DECODE_SFC_OUTPUT_ID,
1016 &userFeatureData);
1017 if (userFeatureData.u32Data)
1018 {
1019 CODECHAL_DECODE_VERBOSEMESSAGE("force ve decompress sfc output");
1020 MOS_ZeroMemory(&dstSurface, sizeof(dstSurface));
1021 dstSurface.Format = Format_NV12;
1022 dstSurface.OsResource = *decodeStatusReport->m_currSfcOutputPicRes;
1023 CODECHAL_DECODE_CHK_STATUS_BREAK(CodecHalGetResourceInfo(
1024 m_osInterface,
1025 &dstSurface));
1026
1027 MOS_LOCK_PARAMS lockFlags {};
1028 lockFlags.ReadOnly = 1;
1029 lockFlags.TiledAsTiled = 1;
1030 lockFlags.NoDecompress = 0;
1031 m_osInterface->pfnLockResource(m_osInterface, &dstSurface.OsResource, &lockFlags);
1032 m_osInterface->pfnUnlockResource(m_osInterface, &dstSurface.OsResource);
1033
1034 }
1035
1036 if (CodecHal_PictureIsFrame(decodeStatusReport->m_currDecodedPic) ||
1037 CodecHal_PictureIsInterlacedFrame(decodeStatusReport->m_currDecodedPic) ||
1038 CodecHal_PictureIsField(decodeStatusReport->m_currDecodedPic))
1039 {
1040 CODECHAL_DECODE_CHK_STATUS_BREAK(m_debugInterface->DeleteCfgLinkNode(m_debugInterface->m_decodeSurfDumpFrameNum));
1041 m_debugInterface->m_decodeSurfDumpFrameNum = tempSurfNum;
1042 }
1043 m_debugInterface->m_bufferDumpFrameNum = tempFrameNum;
1044 m_debugInterface->m_currPic = tempPic;
1045 m_debugInterface->m_frameType = tempFrameType;
1046
1047 if (m_decodeStatusBuf.m_decodeStatus[index].m_hwStoredData == CODECHAL_STATUS_QUERY_END_FLAG)
1048 {
1049 // report the CS Engine ID to user feature
1050 for (auto j = 0; j < CODECHAL_CS_INSTANCE_ID_MAX; j++)
1051 {
1052 CODECHAL_CS_ENGINE_ID csEngineIdValue;
1053 csEngineIdValue.value = m_decodeStatusBuf.m_decodeStatus[index].m_mmioCsEngineIdReg[j];
1054
1055 //validate the user feature value
1056 if (csEngineIdValue.value)
1057 {
1058 CODECHAL_DECODE_ASSERT(csEngineIdValue.fields.ClassId == CODECHAL_CLASS_ID_VIDEO_ENGINE);
1059 CODECHAL_DECODE_ASSERT(csEngineIdValue.fields.InstanceId < CODECHAL_CS_INSTANCE_ID_MAX);
1060 CODECHAL_UPDATE_USED_VDBOX_ID_USER_FEATURE(csEngineIdValue.fields.InstanceId);
1061 }
1062 }
1063 preIndex = index + 1;
1064 }
1065 }
1066
1067 m_debugInterface->m_preIndex = preIndex;
1068 )
1069
1070 if (m_consecutiveMbErrorConcealmentInUse &&
1071 m_incompletePicture)
1072 {
1073 CODECHAL_DECODE_VERBOSEMESSAGE("Processing incomplete frame MBs");
1074
1075 if (!m_isHybridDecoder)
1076 {
1077 m_osInterface->pfnSetGpuContext(m_osInterface, m_videoContext);
1078 }
1079
1080 m_decodePhantomMbs = true;
1081
1082 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(DecodePrimitiveLevel(),
1083 "Primitive level decoding failed.");
1084 }
1085
1086 m_decodePhantomMbs = false;
1087
1088 return eStatus;
1089 }
1090
Execute(void * params)1091 MOS_STATUS CodechalDecode::Execute(void *params)
1092 {
1093 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1094
1095 PERF_UTILITY_AUTO(__FUNCTION__, PERF_DECODE, PERF_LEVEL_HAL);
1096
1097 CODECHAL_DECODE_FUNCTION_ENTER;
1098
1099 CODECHAL_DECODE_CHK_STATUS_RETURN(Codechal::Execute(params));
1100
1101 CodechalDecodeParams *decodeParams = (CodechalDecodeParams *)params;
1102 m_executeCallIndex = decodeParams->m_executeCallIndex;
1103
1104 // MSDK event handling
1105 Mos_Solo_SetGpuAppTaskEvent(m_osInterface, decodeParams->m_gpuAppTaskEvent);
1106
1107 #if (_DEBUG || _RELEASE_INTERNAL)
1108
1109 MOS_TraceEvent(EVENT_CODEC_DECODE, EVENT_TYPE_START, &m_standard, sizeof(uint32_t), &m_frameNum, sizeof(uint32_t));
1110
1111 #endif // _DEBUG || _RELEASE_INTERNAL
1112
1113 CODECHAL_DEBUG_TOOL(
1114 m_debugInterface->m_bufferDumpFrameNum = m_frameNum;)
1115
1116 if (m_cencBuf!= nullptr)
1117 {
1118 CODECHAL_DECODE_CHK_STATUS_RETURN(Mos_Solo_DisableAubcaptureOptimizations(
1119 m_osInterface,
1120 IsFirstExecuteCall()));
1121 }
1122
1123 #ifdef _DECODE_PROCESSING_SUPPORTED
1124 if (decodeParams->m_refFrameCnt != 0)
1125 {
1126 PCODECHAL_DECODE_PROCESSING_PARAMS procParams;
1127 uint32_t allocWidth;
1128 uint32_t allocHeight;
1129 MOS_FORMAT format;
1130 uint8_t frameIdx;
1131
1132 CODECHAL_DECODE_CHK_NULL_RETURN(decodeParams->m_picParams);
1133 CODECHAL_DECODE_CHK_NULL_RETURN(decodeParams->m_procParams);
1134
1135 procParams = (PCODECHAL_DECODE_PROCESSING_PARAMS)decodeParams->m_procParams;
1136 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1137 m_osInterface,
1138 procParams->pOutputSurface));
1139
1140 if (procParams->bIsSourceSurfAllocated)
1141 {
1142 procParams->rcOutputSurfaceRegion.Width = procParams->pOutputSurface->dwWidth;
1143 procParams->rcOutputSurfaceRegion.Height = procParams->pOutputSurface->dwHeight;
1144 frameIdx = 0;
1145
1146 m_refSurfaces = procParams->pInputSurface;
1147 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1148 m_osInterface,
1149 m_refSurfaces));
1150
1151 procParams->rcInputSurfaceRegion.X = 0;
1152 procParams->rcInputSurfaceRegion.Y = 0;
1153 procParams->rcInputSurfaceRegion.Width = m_refSurfaces->dwWidth;
1154 procParams->rcInputSurfaceRegion.Height = m_refSurfaces->dwHeight;
1155 }
1156 else
1157 {
1158 CODECHAL_DECODE_CHK_STATUS_RETURN(CalcDownsamplingParams(
1159 decodeParams->m_picParams, &allocWidth, &allocHeight, &format, &frameIdx));
1160
1161 if (frameIdx >= decodeParams->m_refFrameCnt)
1162 {
1163 CODECHAL_DECODE_ASSERTMESSAGE("Invalid Downsampling Reference Frame Index !");
1164 return MOS_STATUS_INVALID_PARAMETER;
1165 }
1166
1167 if (m_refSurfaces == nullptr)
1168 {
1169 m_refFrmCnt = decodeParams->m_refFrameCnt;
1170 CODECHAL_DECODE_CHK_STATUS_RETURN(AllocateRefSurfaces(allocWidth, allocHeight, format));
1171 }
1172 else
1173 {
1174 PMOS_SURFACE currSurface = &m_refSurfaces[frameIdx];
1175 if (currSurface->dwHeight < allocHeight || currSurface->dwWidth < allocWidth)
1176 {
1177 CODECHAL_DECODE_CHK_STATUS_RETURN(RefSurfacesResize(frameIdx, allocWidth, allocHeight, format));
1178 }
1179 }
1180
1181 procParams->rcInputSurfaceRegion.X = 0;
1182 procParams->rcInputSurfaceRegion.Y = 0;
1183 procParams->rcInputSurfaceRegion.Width = allocWidth;
1184 procParams->rcInputSurfaceRegion.Height = allocHeight;
1185
1186 procParams->pInputSurface = &m_refSurfaces[frameIdx];
1187 }
1188 decodeParams->m_destSurface = &m_refSurfaces[frameIdx];
1189 }
1190 #endif
1191 m_decodeParams = *decodeParams;
1192
1193 CODECHAL_DECODE_CHK_STATUS_RETURN(Mos_Solo_PreProcessDecode(
1194 m_osInterface,
1195 m_decodeParams.m_destSurface));
1196
1197 CODECHAL_DECODE_CHK_STATUS_RETURN(m_cpInterface->UpdateParams(true));
1198
1199 CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHalGetResourceInfo(
1200 m_osInterface,
1201 decodeParams->m_destSurface));
1202
1203 if(!m_isHybridDecoder)
1204 {
1205 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSetGpuContext(
1206 m_osInterface,
1207 m_videoContext));
1208 }
1209 if (!m_incompletePicture)
1210 {
1211 m_osInterface->pfnResetOsStates(m_osInterface);
1212 }
1213
1214 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(SetFrameStates(),
1215 "Decoding initialization failed.");
1216
1217 CODECHAL_DECODE_CHK_STATUS_RETURN(VerifySpaceAvailable());
1218
1219 CODECHAL_DECODE_CHK_STATUS_RETURN(SetDummyReference());
1220
1221 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->SetWatchdogTimerThreshold(m_width, m_height, false));
1222
1223 if ((!m_incompletePicture) && (!m_isHybridDecoder))
1224 {
1225 m_osInterface->pfnIncPerfFrameID(m_osInterface);
1226 m_osInterface->pfnSetPerfTag(
1227 m_osInterface,
1228 (uint16_t)(((m_mode << 4) & 0xF0) | (m_perfType & 0xF)));
1229 m_osInterface->pfnResetPerfBufferID(m_osInterface);
1230 }
1231
1232 CODECHAL_DEBUG_TOOL(
1233
1234 if (decodeParams->m_dataBuffer &&
1235 (m_standard != CODECHAL_JPEG && m_cencBuf == nullptr) &&
1236 !(m_standard == CODECHAL_HEVC && m_isHybridDecoder) &&
1237 !(m_standard == CODECHAL_HEVC && (m_incompletePicture || !IsFirstExecuteCall())))
1238 {
1239 if (m_mode == CODECHAL_DECODE_MODE_MPEG2VLD ||
1240 m_mode == CODECHAL_DECODE_MODE_VC1VLD ||
1241 m_mode == CODECHAL_DECODE_MODE_AVCVLD ||
1242 m_mode == CODECHAL_DECODE_MODE_VP8VLD ||
1243 m_mode == CODECHAL_DECODE_MODE_HEVCVLD ||
1244 m_mode == CODECHAL_DECODE_MODE_VP9VLD)
1245 {
1246 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1247 decodeParams->m_dataBuffer,
1248 CodechalDbgAttr::attrBitstream,
1249 "_DEC",
1250 decodeParams->m_dataSize,
1251 decodeParams->m_dataOffset,
1252 CODECHAL_NUM_MEDIA_STATES
1253 ));
1254 }
1255 else
1256 {
1257 // Dump ResidualDifference
1258 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DumpBuffer(
1259 decodeParams->m_dataBuffer,
1260 CodechalDbgAttr::attrResidualDifference,
1261 "_DEC",
1262 decodeParams->m_dataSize));
1263 }
1264 }
1265 )
1266 #ifdef _DECODE_PROCESSING_SUPPORTED
1267 CODECHAL_DEBUG_TOOL(
1268
1269 if (decodeParams->m_procParams)
1270 {
1271 CODECHAL_DECODE_CHK_STATUS_RETURN(DumpProcessingParams(
1272 (PCODECHAL_DECODE_PROCESSING_PARAMS)decodeParams->m_procParams));
1273 }
1274 )
1275 #endif
1276 for(auto i = 0; i < m_decodePassNum; i++)
1277 {
1278 if (!m_incompletePicture)
1279 {
1280 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(DecodeStateLevel(),
1281 "State level decoding failed.");
1282 }
1283
1284 CODECHAL_DECODE_CHK_STATUS_MESSAGE_RETURN(DecodePrimitiveLevel(),
1285 "Primitive level decoding failed.");
1286 }
1287
1288 if (m_secureDecoder != nullptr)
1289 {
1290 CODECHAL_DECODE_CHK_STATUS_RETURN(m_secureDecoder->UpdateHuCStreamoutBufferIndex());
1291 }
1292
1293 *decodeParams = m_decodeParams;
1294
1295 if (m_decodeHistogram != nullptr)
1296 {
1297 CODECHAL_DECODE_CHK_STATUS_RETURN(m_decodeHistogram->RenderHistogram(this, m_decodeParams.m_destSurface));
1298 }
1299
1300 //#if (_DEBUG || _RELEASE_INTERNAL)
1301 //#ifdef _MD5_DEBUG_SUPPORTED
1302 // if (CodecHal_PictureIsFrame(m_debugInterface->CurrPic) ||
1303 // CodecHal_PictureIsInterlacedFrame(m_debugInterface->CurrPic) ||
1304 // m_debugInterface->bSecondField ||
1305 // m_isHybridDecoder)
1306 // {
1307 // if (m_debugInterface->pMD5Context != nullptr)
1308 // {
1309 // if (m_debugInterface->bMD5DDIThreadExecute)
1310 // {
1311 // //calculate md5 hash for each RT surface
1312 // CODECHAL_DECODE_CHK_STATUS_RETURN(CodecHal_DbgExecuteMD5Hash(
1313 // m_debugInterface,
1314 // &decodeParams->m_destSurface->OsResource,
1315 // nullptr,
1316 // 0,
1317 // 0));
1318 // }
1319 // }
1320 // }
1321 //#endif // _MD5_DEBUG_SUPPORTED
1322 //#endif // _DEBUG || _RELEASE_INTERNAL
1323
1324 CODECHAL_DEBUG_TOOL(
1325 if (CodecHal_PictureIsFrame(m_debugInterface->m_currPic) ||
1326 CodecHal_PictureIsInterlacedFrame(m_debugInterface->m_currPic) ||
1327 m_debugInterface->m_secondField) {
1328 if (!m_statusQueryReportingEnabled)
1329 {
1330 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->DeleteCfgLinkNode(m_debugInterface->m_bufferDumpFrameNum));
1331 }
1332 })
1333
1334 if (CodecHal_PictureIsFrame(m_crrPic) ||
1335 CodecHal_PictureIsInterlacedFrame(m_crrPic) ||
1336 m_secondField)
1337 {
1338 m_frameNum++;
1339 }
1340
1341 CODECHAL_DECODE_CHK_STATUS_RETURN(Mos_Solo_PostProcessDecode(m_osInterface, m_decodeParams.m_destSurface));
1342
1343 #if (_DEBUG || _RELEASE_INTERNAL)
1344
1345 MOS_TraceEvent(EVENT_CODEC_DECODE, EVENT_TYPE_END, &eStatus, sizeof(eStatus), nullptr, 0);
1346
1347 #endif // _DEBUG || _RELEASE_INTERNAL
1348
1349 return eStatus;
1350 }
1351
StartStatusReport(PMOS_COMMAND_BUFFER cmdBuffer)1352 MOS_STATUS CodechalDecode::StartStatusReport(
1353 PMOS_COMMAND_BUFFER cmdBuffer)
1354 {
1355 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1356
1357 CODECHAL_DECODE_FUNCTION_ENTER;
1358
1359 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
1360
1361 uint32_t offset =
1362 (m_decodeStatusBuf.m_currIndex * sizeof(CodechalDecodeStatus)) +
1363 m_decodeStatusBuf.m_storeDataOffset +
1364 sizeof(uint32_t) * 2;
1365
1366 MHW_MI_STORE_DATA_PARAMS params;
1367 params.pOsResource = &m_decodeStatusBuf.m_statusBuffer;
1368 params.dwResourceOffset = offset;
1369 params.dwValue = CODECHAL_STATUS_QUERY_START_FLAG;
1370
1371 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(
1372 cmdBuffer,
1373 ¶ms));
1374
1375 CODECHAL_DECODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectStartCmd((void *)this, m_osInterface, m_miInterface, cmdBuffer));
1376
1377 return eStatus;
1378 }
1379
EndStatusReport(CodechalDecodeStatusReport & decodeStatusReport,PMOS_COMMAND_BUFFER cmdBuffer)1380 MOS_STATUS CodechalDecode::EndStatusReport(
1381 CodechalDecodeStatusReport &decodeStatusReport,
1382 PMOS_COMMAND_BUFFER cmdBuffer)
1383 {
1384 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1385
1386 CODECHAL_DECODE_FUNCTION_ENTER;
1387
1388 CODECHAL_DECODE_CHK_COND_RETURN((m_vdboxIndex > m_mfxInterface->GetMaxVdboxIndex()),
1389 "ERROR - vdbox index exceed the maximum");
1390 auto mmioRegistersMfx = m_hwInterface->SelectVdboxAndGetMmioRegister(m_vdboxIndex, cmdBuffer);
1391 auto mmioRegistersHcp = m_hcpInterface ? m_hcpInterface->GetMmioRegisters(m_vdboxIndex) : nullptr;
1392
1393 uint32_t currIndex = m_decodeStatusBuf.m_currIndex;
1394 //Error Status report
1395 uint32_t errStatusOffset =
1396 currIndex * sizeof(CodechalDecodeStatus) +
1397 m_decodeStatusBuf.m_decErrorStatusOffset +
1398 sizeof(uint32_t) * 2;
1399
1400 MHW_MI_STORE_REGISTER_MEM_PARAMS regParams;
1401 regParams.presStoreBuffer = &m_decodeStatusBuf.m_statusBuffer;
1402 regParams.dwOffset = errStatusOffset;
1403 regParams.dwRegister = (m_standard == CODECHAL_HEVC && mmioRegistersHcp) ?
1404 mmioRegistersHcp->hcpCabacStatusRegOffset : mmioRegistersMfx->mfxErrorFlagsRegOffset;
1405 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
1406 cmdBuffer,
1407 ®Params));
1408
1409 //Frame CRC
1410 if (m_reportFrameCrc)
1411 {
1412 uint32_t frameCrcOffset =
1413 currIndex * sizeof(CodechalDecodeStatus) +
1414 m_decodeStatusBuf.m_decFrameCrcOffset +
1415 sizeof(uint32_t) * 2;
1416
1417 regParams.presStoreBuffer = &m_decodeStatusBuf.m_statusBuffer;
1418 regParams.dwOffset = frameCrcOffset;
1419 if (m_standard == CODECHAL_AVC)
1420 {
1421 regParams.dwRegister = mmioRegistersMfx->mfxFrameCrcRegOffset;
1422 }
1423 else if(m_standard == CODECHAL_HEVC)
1424 {
1425 regParams.dwRegister = m_hcpFrameCrcRegOffset;
1426 }
1427
1428 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
1429 cmdBuffer,
1430 ®Params));
1431 }
1432
1433 //MB Count
1434 uint32_t mbCountOffset =
1435 currIndex * sizeof(CodechalDecodeStatus) +
1436 m_decodeStatusBuf.m_decMBCountOffset +
1437 sizeof(uint32_t) * 2;
1438
1439 regParams.presStoreBuffer = &m_decodeStatusBuf.m_statusBuffer;
1440 regParams.dwOffset = mbCountOffset;
1441 regParams.dwRegister = (m_standard == CODECHAL_HEVC && mmioRegistersHcp) ?
1442 mmioRegistersHcp->hcpDecStatusRegOffset : mmioRegistersMfx->mfxMBCountRegOffset;
1443 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
1444 cmdBuffer,
1445 ®Params));
1446
1447 // First copy all the SW data in to the eStatus buffer
1448 m_decodeStatusBuf.m_decodeStatus[currIndex].m_swStoredData = m_decodeStatusBuf.m_swStoreData;
1449 m_decodeStatusBuf.m_decodeStatus[currIndex].m_decodeStatusReport = decodeStatusReport;
1450
1451 uint32_t storeDataOffset =
1452 currIndex * sizeof(CodechalDecodeStatus) +
1453 m_decodeStatusBuf.m_storeDataOffset +
1454 sizeof(uint32_t) * 2;
1455
1456 MHW_MI_STORE_DATA_PARAMS dataParams;
1457 dataParams.pOsResource = &m_decodeStatusBuf.m_statusBuffer;
1458 dataParams.dwResourceOffset = storeDataOffset;
1459 dataParams.dwValue = CODECHAL_STATUS_QUERY_END_FLAG;
1460
1461 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(
1462 cmdBuffer,
1463 &dataParams));
1464
1465 m_decodeStatusBuf.m_currIndex = (m_decodeStatusBuf.m_currIndex + 1) % CODECHAL_DECODE_STATUS_NUM;
1466
1467 CodechalDecodeStatus *decodeStatus = &m_decodeStatusBuf.m_decodeStatus[m_decodeStatusBuf.m_currIndex];
1468 MOS_ZeroMemory(decodeStatus, sizeof(CodechalDecodeStatus));
1469
1470 CODECHAL_DECODE_CHK_STATUS_RETURN(m_perfProfiler->AddPerfCollectEndCmd((void*)this, m_osInterface, m_miInterface, cmdBuffer));
1471 if (!m_osInterface->bEnableKmdMediaFrameTracking && m_osInterface->bInlineCodecStatusUpdate)
1472 {
1473 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1474 // Send MI_FLUSH with protection bit off, which will FORCE exit protected mode for MFX
1475 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1476 flushDwParams.bVideoPipelineCacheInvalidate = true;
1477 flushDwParams.pOsResource = &m_decodeStatusBuf.m_statusBuffer;
1478 flushDwParams.dwDataDW1 = m_decodeStatusBuf.m_swStoreData;
1479 MHW_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(
1480 cmdBuffer,
1481 &flushDwParams));
1482 }
1483
1484 return eStatus;
1485 }
1486
ResetStatusReport(bool nullHwInUse)1487 MOS_STATUS CodechalDecode::ResetStatusReport(
1488 bool nullHwInUse)
1489 {
1490 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1491
1492 CODECHAL_DECODE_FUNCTION_ENTER;
1493
1494 if (!m_osInterface->bEnableKmdMediaFrameTracking &&
1495 !m_osInterface->bInlineCodecStatusUpdate)
1496 {
1497 MOS_COMMAND_BUFFER cmdBuffer;
1498 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnGetCommandBuffer(
1499 m_osInterface,
1500 &cmdBuffer,
1501 0));
1502
1503 // initialize command buffer attributes
1504 cmdBuffer.Attributes.bTurboMode = m_hwInterface->m_turboMode;
1505
1506 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPrologWithFrameTracking(
1507 &cmdBuffer,
1508 false));
1509
1510 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferEnd(
1511 &cmdBuffer,
1512 nullptr));
1513
1514 m_osInterface->pfnReturnCommandBuffer(m_osInterface, &cmdBuffer, 0);
1515
1516 CODECHAL_DECODE_CHK_STATUS_RETURN(m_osInterface->pfnSubmitCommandBuffer(
1517 m_osInterface,
1518 &cmdBuffer,
1519 nullHwInUse));
1520 }
1521
1522 m_decodeStatusBuf.m_swStoreData++;
1523
1524 return eStatus;
1525 }
1526
GetStatusReport(void * status,uint16_t numStatus)1527 MOS_STATUS CodechalDecode::GetStatusReport(
1528 void *status,
1529 uint16_t numStatus)
1530 {
1531 uint16_t reportsGenerated = 0;
1532 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1533
1534 CODECHAL_DECODE_FUNCTION_ENTER;
1535
1536 CODECHAL_DECODE_CHK_NULL_RETURN(status);
1537 CodechalDecodeStatusReport *codecStatus = (CodechalDecodeStatusReport *)status;
1538
1539 uint32_t numReportsAvailable =
1540 (m_decodeStatusBuf.m_currIndex - m_decodeStatusBuf.m_firstIndex) &
1541 (CODECHAL_DECODE_STATUS_NUM - 1);
1542 uint32_t globalHWStoredData = *(m_decodeStatusBuf.m_data);
1543 uint32_t globalCount = m_decodeStatusBuf.m_swStoreData - globalHWStoredData;
1544
1545 CODECHAL_DECODE_VERBOSEMESSAGE(" numStatus = %d, numReportsAvailable = %d.",
1546 numStatus, numReportsAvailable);
1547 CODECHAL_DECODE_VERBOSEMESSAGE(" HWStoreData = %d, globalCount = %d",
1548 globalHWStoredData, globalCount);
1549
1550 if (numReportsAvailable < numStatus)
1551 {
1552 for (auto i = numReportsAvailable ; i < numStatus && i < CODECHAL_DECODE_STATUS_NUM ; i ++)
1553 {
1554 // These buffers are not yet received by driver. Just don't report anything back.
1555 codecStatus[i].m_codecStatus = CODECHAL_STATUS_UNAVAILABLE;
1556 }
1557
1558 numStatus = (uint16_t)numReportsAvailable;
1559 }
1560
1561 if (numReportsAvailable == 0)
1562 {
1563 CODECHAL_DECODE_ASSERTMESSAGE("No reports available, m_currIndex = %d, m_firstIndex = %d",
1564 m_decodeStatusBuf.m_currIndex,
1565 m_decodeStatusBuf.m_firstIndex);
1566 return eStatus;
1567 }
1568
1569 if (m_videoContextUsesNullHw ||
1570 m_videoContextForWaUsesNullHw ||
1571 m_renderContextUsesNullHw)
1572 {
1573 for (auto j = 0 ; j < numStatus ; j++)
1574 {
1575 uint32_t i = (m_decodeStatusBuf.m_firstIndex + numStatus - j - 1) & (CODECHAL_DECODE_STATUS_NUM - 1);
1576 codecStatus[j] = m_decodeStatusBuf.m_decodeStatus[i].m_decodeStatusReport;
1577 codecStatus[j].m_codecStatus = CODECHAL_STATUS_SUCCESSFUL;
1578 reportsGenerated++;
1579 }
1580
1581 m_decodeStatusBuf.m_firstIndex =
1582 (m_decodeStatusBuf.m_firstIndex + reportsGenerated) % CODECHAL_DECODE_STATUS_NUM;
1583
1584 return eStatus;
1585 }
1586
1587 // Report eStatus in reverse temporal order
1588 for (auto j = 0; j < numStatus; j ++)
1589 {
1590 uint32_t i = (m_decodeStatusBuf.m_firstIndex + numStatus - j - 1) & (CODECHAL_DECODE_STATUS_NUM - 1);
1591 CodechalDecodeStatusReport decodeStatusReport = m_decodeStatusBuf.m_decodeStatus[i].m_decodeStatusReport;
1592 uint32_t localCount = m_decodeStatusBuf.m_decodeStatus[i].m_swStoredData - globalHWStoredData;
1593
1594 if (m_isHybridDecoder)
1595 {
1596 codecStatus[j] = decodeStatusReport;
1597 // Consider the decode finished if the event dosen't present.
1598 CODECHAL_DECODE_CHK_STATUS_RETURN(DecodeGetHybridStatus(
1599 m_decodeStatusBuf.m_decodeStatus, i, CODECHAL_STATUS_QUERY_END_FLAG));
1600
1601 if (m_decodeStatusBuf.m_decodeStatus[i].m_hwStoredData == CODECHAL_STATUS_QUERY_END_FLAG)
1602 {
1603 codecStatus[j].m_codecStatus = CODECHAL_STATUS_SUCCESSFUL;
1604 reportsGenerated ++;
1605 }
1606 else
1607 {
1608 codecStatus[j].m_codecStatus = CODECHAL_STATUS_INCOMPLETE;
1609 }
1610 }
1611 else
1612 {
1613 if (localCount == 0 || localCount > globalCount)
1614 {
1615 codecStatus[j] = decodeStatusReport;
1616
1617 // HW execution of these commands is complete.
1618 if (m_osInterface->pfnIsGPUHung(m_osInterface))
1619 {
1620 codecStatus[j].m_codecStatus = CODECHAL_STATUS_INCOMPLETE;
1621 }
1622 else if (m_decodeStatusBuf.m_decodeStatus[i].m_hwStoredData == CODECHAL_STATUS_QUERY_END_FLAG)
1623 {
1624 // No problem in execution
1625 codecStatus[j].m_codecStatus = CODECHAL_STATUS_SUCCESSFUL;
1626
1627 if (m_standard == CODECHAL_HEVC)
1628 {
1629 if ((m_decodeStatusBuf.m_decodeStatus[i].m_mmioErrorStatusReg &
1630 m_hcpInterface->GetHcpCabacErrorFlagsMask()) != 0)
1631 {
1632 codecStatus[j].m_codecStatus = CODECHAL_STATUS_ERROR;
1633 codecStatus[j].m_numMbsAffected =
1634 (m_decodeStatusBuf.m_decodeStatus[i].m_mmioMBCountReg & 0xFFFC0000) >> 18;
1635 }
1636
1637 if (m_reportFrameCrc)
1638 {
1639 codecStatus[j].m_frameCrc = m_decodeStatusBuf.m_decodeStatus[i].m_mmioFrameCrcReg;
1640 CODECHAL_DECODE_NORMALMESSAGE("HCP CRC:: %d\n", codecStatus[j].m_frameCrc);
1641 }
1642 }
1643 else
1644 {
1645 // Check to see if decoding error occurs
1646 if (m_standard != CODECHAL_JPEG)
1647 {
1648 if ((m_decodeStatusBuf.m_decodeStatus[i].m_mmioErrorStatusReg &
1649 m_mfxInterface->GetMfxErrorFlagsMask()) != 0)
1650 {
1651 codecStatus[j].m_codecStatus = CODECHAL_STATUS_ERROR;
1652 }
1653 //MB Count bit[15:0] is error concealment MB count for none JPEG decoder.
1654 codecStatus[j].m_numMbsAffected =
1655 m_decodeStatusBuf.m_decodeStatus[i].m_mmioMBCountReg & 0xFFFF;
1656 }
1657 if (m_standard == CODECHAL_AVC)
1658 {
1659 codecStatus[j].m_frameCrc = m_decodeStatusBuf.m_decodeStatus[i].m_mmioFrameCrcReg;
1660 }
1661 }
1662 }
1663 else if (m_decodeStatusBuf.m_decodeStatus[i].m_hwStoredData == CODECHAL_STATUS_QUERY_SKIPPED)
1664 {
1665 // In the case of AVC PR3.0 it is possible to drop a batch buffer execution
1666 CODECHAL_DECODE_NORMALMESSAGE("Decode skipped.");
1667 codecStatus[j].m_codecStatus = CODECHAL_STATUS_SUCCESSFUL;
1668 }
1669 else
1670 {
1671 // BB_END data not written. Media reset might have occurred.
1672 CODECHAL_DECODE_NORMALMESSAGE("Media reset may have occured.");
1673 codecStatus[j].m_codecStatus = CODECHAL_STATUS_ERROR;
1674 }
1675
1676 if (m_standard == CODECHAL_HEVC)
1677 {
1678 // Print HuC_Status and HuC_Status2 registers
1679 CODECHAL_DECODE_VERBOSEMESSAGE("Index = %d", i);
1680 CODECHAL_DECODE_VERBOSEMESSAGE("HUC_STATUS register = 0x%x",
1681 m_decodeStatusBuf.m_decodeStatus[i].m_hucErrorStatus >> 32);
1682 CODECHAL_DECODE_VERBOSEMESSAGE("HUC_STATUS2 register = 0x%x",
1683 m_decodeStatusBuf.m_decodeStatus[i].m_hucErrorStatus2 >> 32);
1684 }
1685
1686 CODECHAL_DECODE_VERBOSEMESSAGE("Incrementing reports generated to %d.",
1687 (reportsGenerated + 1));
1688 reportsGenerated ++;
1689 }
1690 else
1691 {
1692 CODECHAL_DECODE_VERBOSEMESSAGE("status buffer %d is INCOMPLETE.", j);
1693 codecStatus[j] = decodeStatusReport;
1694 codecStatus[j].m_codecStatus = CODECHAL_STATUS_INCOMPLETE;
1695 if(m_osInterface->bInlineCodecStatusUpdate)
1696 {
1697 // In Linux/Android, inline decode status reporting is enabled.
1698 // If still received CODECHAL_STATUS_INCOMPLETE,
1699 // it will be treat as GPU Hang. so need generate a report.
1700 reportsGenerated ++;
1701 }
1702 }
1703 }
1704 }
1705
1706 m_decodeStatusBuf.m_firstIndex =
1707 (m_decodeStatusBuf.m_firstIndex + reportsGenerated) % CODECHAL_DECODE_STATUS_NUM;
1708 CODECHAL_DECODE_VERBOSEMESSAGE("m_firstIndex now becomes %d.", m_decodeStatusBuf.m_firstIndex);
1709
1710 return eStatus;
1711 }
1712
SendPrologWithFrameTracking(PMOS_COMMAND_BUFFER cmdBuffer,bool frameTrackingRequested)1713 MOS_STATUS CodechalDecode::SendPrologWithFrameTracking(
1714 PMOS_COMMAND_BUFFER cmdBuffer,
1715 bool frameTrackingRequested)
1716 {
1717 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1718
1719 CODECHAL_DECODE_FUNCTION_ENTER;
1720
1721 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
1722
1723 MOS_GPU_CONTEXT gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface);
1724
1725 // Send Start Marker command
1726 if (m_decodeParams.m_setMarkerEnabled)
1727 {
1728 CODECHAL_DECODE_CHK_STATUS_RETURN(SendMarkerCommand(cmdBuffer, MOS_RCS_ENGINE_USED(gpuContext)));
1729 }
1730
1731 if (frameTrackingRequested)
1732 {
1733 // initialize command buffer attributes
1734 cmdBuffer->Attributes.bTurboMode = m_hwInterface->m_turboMode;
1735 cmdBuffer->Attributes.bMediaPreemptionEnabled = MOS_RCS_ENGINE_USED(gpuContext) ?
1736 m_hwInterface->GetRenderInterface()->IsPreemptionEnabled() : 0;
1737 cmdBuffer->Attributes.bEnableMediaFrameTracking = true;
1738 cmdBuffer->Attributes.resMediaFrameTrackingSurface = m_decodeStatusBuf.m_statusBuffer;
1739 cmdBuffer->Attributes.dwMediaFrameTrackingTag = m_decodeStatusBuf.m_swStoreData;
1740 // Set media frame tracking address offset(the offset from the decoder status buffer page, refer to CodecHalDecode_Initialize)
1741 cmdBuffer->Attributes.dwMediaFrameTrackingAddrOffset = 0;
1742 }
1743
1744 if (m_mmc)
1745 {
1746 CODECHAL_DECODE_CHK_STATUS_RETURN(m_mmc->SendPrologCmd(m_miInterface, cmdBuffer, gpuContext));
1747 }
1748
1749 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
1750 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
1751 genericPrologParams.pOsInterface = m_osInterface;
1752 genericPrologParams.pvMiInterface = m_miInterface;
1753 genericPrologParams.bMmcEnabled = CodecHalMmcState::IsMmcEnabled();
1754
1755 CODECHAL_DECODE_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmd(
1756 cmdBuffer,
1757 &genericPrologParams));
1758
1759 // Send predication command
1760 if (m_decodeParams.m_predicationEnabled)
1761 {
1762 CODECHAL_DECODE_CHK_STATUS_RETURN(SendPredicationCommand(
1763 cmdBuffer));
1764 }
1765
1766 return eStatus;
1767 }
1768
SendPredicationCommand(PMOS_COMMAND_BUFFER cmdBuffer)1769 MOS_STATUS CodechalDecode::SendPredicationCommand(
1770 PMOS_COMMAND_BUFFER cmdBuffer)
1771 {
1772 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1773
1774 CODECHAL_DECODE_FUNCTION_ENTER;
1775
1776 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
1777 CODECHAL_DECODE_CHK_NULL_RETURN(m_miInterface);
1778
1779 MHW_MI_CONDITIONAL_BATCH_BUFFER_END_PARAMS condBBEndParams;
1780 MOS_ZeroMemory(&condBBEndParams, sizeof(condBBEndParams));
1781
1782 // Skip current frame if presPredication is not equal to zero
1783 if (m_decodeParams.m_predicationNotEqualZero)
1784 {
1785 auto mmioRegistersMfx = m_hwInterface->SelectVdboxAndGetMmioRegister(m_vdboxIndex, cmdBuffer);
1786 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1787 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1788 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
1789
1790 // load presPredication to general purpose register0
1791 MHW_MI_STORE_REGISTER_MEM_PARAMS loadRegisterMemParams;
1792 MOS_ZeroMemory(&loadRegisterMemParams, sizeof(loadRegisterMemParams));
1793 loadRegisterMemParams.presStoreBuffer = m_decodeParams.m_presPredication;
1794 loadRegisterMemParams.dwOffset = (uint32_t)m_decodeParams.m_predicationResOffset;
1795 loadRegisterMemParams.dwRegister = mmioRegistersMfx->generalPurposeRegister0LoOffset;
1796 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterMemCmd(
1797 cmdBuffer,
1798 &loadRegisterMemParams));
1799 MHW_MI_LOAD_REGISTER_IMM_PARAMS loadRegisterImmParams;
1800 MOS_ZeroMemory(&loadRegisterImmParams, sizeof(loadRegisterImmParams));
1801 loadRegisterImmParams.dwData = 0;
1802 loadRegisterImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister0HiOffset;
1803 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(
1804 cmdBuffer,
1805 &loadRegisterImmParams));
1806
1807 // load 0 to general purpose register4
1808 MOS_ZeroMemory(&loadRegisterImmParams, sizeof(loadRegisterImmParams));
1809 loadRegisterImmParams.dwData = 0;
1810 loadRegisterImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister4LoOffset;
1811 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(
1812 cmdBuffer,
1813 &loadRegisterImmParams));
1814 MOS_ZeroMemory(&loadRegisterImmParams, sizeof(loadRegisterImmParams));
1815 loadRegisterImmParams.dwData = 0;
1816 loadRegisterImmParams.dwRegister = mmioRegistersMfx->generalPurposeRegister4HiOffset;
1817 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiLoadRegisterImmCmd(
1818 cmdBuffer,
1819 &loadRegisterImmParams));
1820
1821 //perform the add operation
1822 MHW_MI_MATH_PARAMS miMathParams;
1823 MHW_MI_ALU_PARAMS miAluParams[4];
1824 MOS_ZeroMemory(&miMathParams, sizeof(miMathParams));
1825 MOS_ZeroMemory(&miAluParams, sizeof(miAluParams));
1826 // load srcA, reg0
1827 miAluParams[0].AluOpcode = MHW_MI_ALU_LOAD;
1828 miAluParams[0].Operand1 = MHW_MI_ALU_SRCA;
1829 miAluParams[0].Operand2 = MHW_MI_ALU_GPREG0;
1830 // load srcB, reg4
1831 miAluParams[1].AluOpcode = MHW_MI_ALU_LOAD;
1832 miAluParams[1].Operand1 = MHW_MI_ALU_SRCB;
1833 miAluParams[1].Operand2 = MHW_MI_ALU_GPREG4;
1834 // add srcA, srcB
1835 miAluParams[2].AluOpcode = MHW_MI_ALU_ADD;
1836 miAluParams[2].Operand1 = MHW_MI_ALU_SRCB;
1837 miAluParams[2].Operand2 = MHW_MI_ALU_GPREG4;
1838 // store reg0, ZF
1839 miAluParams[3].AluOpcode = MHW_MI_ALU_STORE;
1840 miAluParams[3].Operand1 = MHW_MI_ALU_GPREG0;
1841 miAluParams[3].Operand2 = MHW_MI_ALU_ZF;
1842 miMathParams.pAluPayload = miAluParams;
1843 miMathParams.dwNumAluParams = 4; // four ALU commands needed for this substract opertaion. see following ALU commands.
1844 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiMathCmd(
1845 cmdBuffer,
1846 &miMathParams));
1847
1848 // if zero, the zero flag will be 0xFFFFFFFF, else zero flag will be 0x0.
1849 MHW_MI_STORE_REGISTER_MEM_PARAMS storeRegParams;
1850 MOS_ZeroMemory(&storeRegParams, sizeof(storeRegParams));
1851 storeRegParams.presStoreBuffer = &m_predicationBuffer;
1852 storeRegParams.dwOffset = 0;
1853 storeRegParams.dwRegister = mmioRegistersMfx->generalPurposeRegister0LoOffset;
1854 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreRegisterMemCmd(
1855 cmdBuffer,
1856 &storeRegParams));
1857
1858 condBBEndParams.presSemaphoreBuffer = &m_predicationBuffer;
1859 condBBEndParams.dwOffset = 0;
1860 condBBEndParams.dwValue = 0;
1861 condBBEndParams.bDisableCompareMask = true;
1862 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
1863 cmdBuffer,
1864 &condBBEndParams));
1865
1866 *m_decodeParams.m_tempPredicationBuffer = &m_predicationBuffer;
1867 }
1868 else
1869 {
1870 // Skip current frame if presPredication is equal to zero
1871 condBBEndParams.presSemaphoreBuffer = m_decodeParams.m_presPredication;
1872 condBBEndParams.dwOffset = (uint32_t)m_decodeParams.m_predicationResOffset;
1873 condBBEndParams.bDisableCompareMask = true;
1874 condBBEndParams.dwValue = 0;
1875 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiConditionalBatchBufferEndCmd(
1876 cmdBuffer,
1877 &condBBEndParams));
1878 }
1879
1880 return eStatus;
1881 }
1882
SendMarkerCommand(PMOS_COMMAND_BUFFER cmdBuffer,bool isRender)1883 MOS_STATUS CodechalDecode::SendMarkerCommand(
1884 PMOS_COMMAND_BUFFER cmdBuffer,
1885 bool isRender)
1886 {
1887 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
1888
1889 CODECHAL_DECODE_FUNCTION_ENTER;
1890
1891 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
1892 CODECHAL_DECODE_CHK_NULL_RETURN(m_miInterface);
1893
1894 if (isRender)
1895 {
1896 // Send pipe_control to get the timestamp
1897 MHW_PIPE_CONTROL_PARAMS pipeControlParams;
1898 MOS_ZeroMemory(&pipeControlParams, sizeof(pipeControlParams));
1899 pipeControlParams.presDest = (PMOS_RESOURCE)m_decodeParams.m_presSetMarker;
1900 pipeControlParams.dwResourceOffset = 0;
1901 pipeControlParams.dwPostSyncOp = MHW_FLUSH_WRITE_TIMESTAMP_REG;
1902 pipeControlParams.dwFlushMode = MHW_FLUSH_WRITE_CACHE;
1903
1904 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddPipeControl(cmdBuffer, NULL, &pipeControlParams));
1905 }
1906 else
1907 {
1908 // Send flush_dw to get the timestamp
1909 MHW_MI_FLUSH_DW_PARAMS flushDwParams;
1910 MOS_ZeroMemory(&flushDwParams, sizeof(flushDwParams));
1911 flushDwParams.pOsResource = (PMOS_RESOURCE)m_decodeParams.m_presSetMarker;
1912 flushDwParams.dwResourceOffset = 0;
1913 flushDwParams.postSyncOperation = MHW_FLUSH_WRITE_TIMESTAMP_REG;
1914 flushDwParams.bQWordEnable = 1;
1915
1916 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiFlushDwCmd(cmdBuffer, &flushDwParams));
1917 }
1918
1919 return eStatus;
1920 }
1921
SetCencBatchBuffer(PMOS_COMMAND_BUFFER cmdBuffer)1922 MOS_STATUS CodechalDecode::SetCencBatchBuffer(
1923 PMOS_COMMAND_BUFFER cmdBuffer)
1924 {
1925 CODECHAL_DECODE_CHK_NULL_RETURN(cmdBuffer);
1926
1927 MHW_BATCH_BUFFER batchBuffer;
1928 MOS_ZeroMemory(&batchBuffer, sizeof(MHW_BATCH_BUFFER));
1929 MOS_RESOURCE *resHeap = nullptr;
1930 CODECHAL_DECODE_CHK_NULL_RETURN(resHeap = m_cencBuf->secondLvlBbBlock->GetResource());
1931 batchBuffer.OsResource = *resHeap;
1932 batchBuffer.dwOffset = m_cencBuf->secondLvlBbBlock->GetOffset();
1933 batchBuffer.iSize = m_cencBuf->secondLvlBbBlock->GetSize();
1934 batchBuffer.bSecondLevel = true;
1935 #if (_DEBUG || _RELEASE_INTERNAL)
1936 batchBuffer.iLastCurrent = batchBuffer.iSize;
1937 #endif // (_DEBUG || _RELEASE_INTERNAL)
1938
1939 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiBatchBufferStartCmd(
1940 cmdBuffer,
1941 &batchBuffer));
1942
1943 CODECHAL_DEBUG_TOOL(
1944 CODECHAL_DECODE_CHK_STATUS_RETURN(m_debugInterface->Dump2ndLvlBatch(
1945 &batchBuffer,
1946 CODECHAL_NUM_MEDIA_STATES,
1947 "_2ndLvlBatch"));)
1948
1949 // Update GlobalCmdBufId
1950 MHW_MI_STORE_DATA_PARAMS miStoreDataParams;
1951 MOS_ZeroMemory(&miStoreDataParams, sizeof(miStoreDataParams));
1952 miStoreDataParams.pOsResource = m_cencBuf->resTracker;
1953 miStoreDataParams.dwValue = m_cencBuf->trackerId;
1954 CODECHAL_DECODE_VERBOSEMESSAGE("dwCmdBufId = %d", miStoreDataParams.dwValue);
1955 CODECHAL_DECODE_CHK_STATUS_RETURN(m_miInterface->AddMiStoreDataImmCmd(
1956 cmdBuffer,
1957 &miStoreDataParams));
1958 return MOS_STATUS_SUCCESS;
1959 }
1960
1961 #if USE_CODECHAL_DEBUG_TOOL
1962 #ifdef _DECODE_PROCESSING_SUPPORTED
DumpProcessingParams(PCODECHAL_DECODE_PROCESSING_PARAMS decProcParams)1963 MOS_STATUS CodechalDecode::DumpProcessingParams(PCODECHAL_DECODE_PROCESSING_PARAMS decProcParams)
1964 {
1965 CODECHAL_DEBUG_FUNCTION_ENTER;
1966
1967 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrDecodeProcParams))
1968 {
1969 return MOS_STATUS_SUCCESS;
1970 }
1971
1972 CODECHAL_DEBUG_CHK_NULL(decProcParams);
1973 CODECHAL_DEBUG_CHK_NULL(decProcParams->pInputSurface);
1974 CODECHAL_DEBUG_CHK_NULL(decProcParams->pOutputSurface);
1975
1976 std::ostringstream oss;
1977 oss.setf(std::ios::showbase | std::ios::uppercase);
1978
1979 oss << "Input Surface Resolution: "
1980 << +decProcParams->pInputSurface->dwWidth << " x " << +decProcParams->pInputSurface->dwHeight << std::endl;
1981 oss << "Input Region Resolution: "
1982 << +decProcParams->rcInputSurfaceRegion.Width << " x " << +decProcParams->rcInputSurfaceRegion.Height << std::endl;
1983 oss << "Input Region Offset: ("
1984 << +decProcParams->rcInputSurfaceRegion.X << "," << +decProcParams->rcInputSurfaceRegion.Y << ")" << std::endl;
1985 oss << "Input Surface Format: "
1986 << (decProcParams->pInputSurface->Format == Format_NV12 ? "NV12" : "P010" )<< std::endl;
1987 oss << "Output Surface Resolution: "
1988 << +decProcParams->pOutputSurface->dwWidth << " x " << +decProcParams->pOutputSurface->dwHeight << std::endl;
1989 oss << "Output Region Resolution: "
1990 << +decProcParams->rcOutputSurfaceRegion.Width << " x " << +decProcParams->rcOutputSurfaceRegion.Height << std::endl;
1991 oss << "Output Region Offset: ("
1992 << +decProcParams->rcOutputSurfaceRegion.X << ", " << +decProcParams->rcOutputSurfaceRegion.Y << ")" << std::endl;
1993 oss << "Output Surface Format: "
1994 << (decProcParams->pOutputSurface->Format == Format_NV12 ? "NV12" : "YUY2" )<< std::endl;
1995
1996 const char* filePath = m_debugInterface->CreateFileName(
1997 "_DEC",
1998 CodechalDbgBufferType::bufDecProcParams,
1999 CodechalDbgExtType::txt);
2000
2001 std::ofstream ofs(filePath, std::ios::out);
2002 ofs << oss.str();
2003 ofs.close();
2004
2005 return MOS_STATUS_SUCCESS;
2006 }
2007
2008 #endif
2009 #endif
2010
2011