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