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