1 /*
2 * Copyright (c) 2019-2022, 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     decode_hevc_picture_packet_xe_m_base.cpp
24 //! \brief    Defines the interface for hevc decode picture packet
25 //!
26 #include "codechal_utilities.h"
27 #include "decode_hevc_picture_packet_xe_m_base.h"
28 #include "decode_hevc_phase_real_tile.h"
29 #include "decode_hevc_phase_front_end.h"
30 #include "decode_hevc_phase_back_end.h"
31 #include "decode_common_feature_defs.h"
32 #include "decode_hevc_mem_compression.h"
33 #include "decode_resource_auto_lock.h"
34 
35 namespace decode
36 {
37 
~HevcDecodePicPktXe_M_Base()38 HevcDecodePicPktXe_M_Base::~HevcDecodePicPktXe_M_Base()
39 {
40     FreeResources();
41 }
42 
FreeResources()43 MOS_STATUS HevcDecodePicPktXe_M_Base::FreeResources()
44 {
45     DECODE_FUNC_CALL();
46 
47     if (m_allocator != nullptr)
48     {
49         m_allocator->Destroy(m_resMfdDeblockingFilterRowStoreScratchBuffer);
50         m_allocator->Destroy(m_resMfdDeblockingFilterRowStoreScratchBuffer);
51         m_allocator->Destroy(m_resDeblockingFilterTileRowStoreScratchBuffer);
52         m_allocator->Destroy(m_resDeblockingFilterColumnRowStoreScratchBuffer);
53         m_allocator->Destroy(m_resMetadataLineBuffer);
54         m_allocator->Destroy(m_resMetadataTileLineBuffer);
55         m_allocator->Destroy(m_resMetadataTileColumnBuffer);
56         m_allocator->Destroy(m_resSaoLineBuffer);
57         m_allocator->Destroy(m_resSaoTileLineBuffer);
58         m_allocator->Destroy(m_resSaoTileColumnBuffer);
59         m_allocator->Destroy(m_resSliceStateStreamOutBuffer);
60         m_allocator->Destroy(m_resMvUpRightColStoreBuffer);
61         m_allocator->Destroy(m_resIntraPredUpRightColStoreBuffer);
62         m_allocator->Destroy(m_resIntraPredLeftReconColStoreBuffer);
63         m_allocator->Destroy(m_resCABACSyntaxStreamOutBuffer);
64         m_allocator->Destroy(m_resCABACStreamOutSizeBuffer);
65     }
66 
67     return MOS_STATUS_SUCCESS;
68 }
69 
Init()70 MOS_STATUS HevcDecodePicPktXe_M_Base::Init()
71 {
72     DECODE_FUNC_CALL();
73     DECODE_CHK_NULL(m_featureManager);
74     DECODE_CHK_NULL(m_hwInterface);
75     DECODE_CHK_NULL(m_osInterface);
76     DECODE_CHK_NULL(m_miInterface);
77     DECODE_CHK_NULL(m_hevcPipeline);
78     DECODE_CHK_NULL(m_hcpInterface);
79 
80     m_hevcBasicFeature = dynamic_cast<HevcBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
81     DECODE_CHK_NULL(m_hevcBasicFeature);
82 
83 #ifdef _DECODE_PROCESSING_SUPPORTED
84     m_downSamplingFeature = dynamic_cast<DecodeDownSamplingFeature*>(m_featureManager->GetFeature(DecodeFeatureIDs::decodeDownSampling));
85     DecodeSubPacket* subPacket = m_hevcPipeline->GetSubPacket(DecodePacketId(m_hevcPipeline, downSamplingSubPacketId));
86     m_downSamplingPkt = dynamic_cast<DecodeDownSamplingPkt *>(subPacket);
87 #endif
88 
89     m_allocator = m_pipeline ->GetDecodeAllocator();
90     DECODE_CHK_NULL(m_allocator);
91 
92     DECODE_CHK_STATUS(AllocateFixedResources());
93 
94     return MOS_STATUS_SUCCESS;
95 }
96 
Prepare()97 MOS_STATUS HevcDecodePicPktXe_M_Base::Prepare()
98 {
99     DECODE_FUNC_CALL();
100 
101     m_hevcPicParams      = m_hevcBasicFeature->m_hevcPicParams;
102     m_hevcIqMatrixParams = m_hevcBasicFeature->m_hevcIqMatrixParams;
103     m_hevcRextPicParams  = m_hevcBasicFeature->m_hevcRextPicParams;
104     m_hevcSccPicParams   = m_hevcBasicFeature->m_hevcSccPicParams;
105 
106 #ifdef _MMC_SUPPORTED
107     m_mmcState = m_hevcPipeline->GetMmcState();
108     DECODE_CHK_NULL(m_mmcState);
109 #endif
110 
111     DECODE_CHK_STATUS(SetRowstoreCachingOffsets());
112 
113     DECODE_CHK_STATUS(AllocateVariableResources());
114 
115     return MOS_STATUS_SUCCESS;
116 }
117 
SetPhase(DecodePhase * phase)118 MOS_STATUS HevcDecodePicPktXe_M_Base::SetPhase(DecodePhase *phase)
119 {
120     DECODE_FUNC_CALL();
121     m_phase = phase;
122     return MOS_STATUS_SUCCESS;
123 }
124 
ReportCabacStreamOutSize(MOS_COMMAND_BUFFER & cmdBuffer)125 MOS_STATUS HevcDecodePicPktXe_M_Base::ReportCabacStreamOutSize(MOS_COMMAND_BUFFER &cmdBuffer)
126 {
127     DECODE_FUNC_CALL();
128     DECODE_CHK_NULL(m_resCABACStreamOutSizeBuffer);
129 
130     auto mmioRegistersHcp = m_hwInterface->GetHcpInterface()->GetMmioRegisters(MHW_VDBOX_NODE_1);
131 
132     MHW_MI_STORE_REGISTER_MEM_PARAMS params;
133     MOS_ZeroMemory(&params, sizeof(MHW_MI_STORE_REGISTER_MEM_PARAMS));
134     params.presStoreBuffer = &m_resCABACStreamOutSizeBuffer->OsResource;
135     params.dwOffset        = 0;
136     params.dwRegister      = mmioRegistersHcp->hcpDebugFEStreamOutSizeRegOffset;
137 
138     DECODE_CHK_STATUS(m_miInterface->AddMiStoreRegisterMemCmd(
139         &cmdBuffer,
140         &params));
141 
142     return MOS_STATUS_SUCCESS;
143 }
144 
IsRealTilePhase()145 bool HevcDecodePicPktXe_M_Base::IsRealTilePhase()
146 {
147     if (m_phase == nullptr)
148     {
149         return false;
150     }
151     HevcPhaseRealTile *realtilePhase = dynamic_cast<HevcPhaseRealTile *>(m_phase);
152     return (realtilePhase != nullptr);
153 }
154 
IsFrontEndPhase()155 bool HevcDecodePicPktXe_M_Base::IsFrontEndPhase()
156 {
157     if (m_phase == nullptr)
158     {
159         return false;
160     }
161     HevcPhaseFrontEnd *frontEndPhase = dynamic_cast<HevcPhaseFrontEnd *>(m_phase);
162     return (frontEndPhase != nullptr);
163 }
164 
IsBackEndPhase()165 bool HevcDecodePicPktXe_M_Base::IsBackEndPhase()
166 {
167     if (m_phase == nullptr)
168     {
169         return false;
170     }
171     HevcPhaseBackEnd *backEndPhase = dynamic_cast<HevcPhaseBackEnd *>(m_phase);
172     return (backEndPhase != nullptr);
173 }
174 
SetRowstoreCachingOffsets()175 MOS_STATUS HevcDecodePicPktXe_M_Base::SetRowstoreCachingOffsets()
176 {
177     if (m_hcpInterface->IsRowStoreCachingSupported())
178     {
179         MHW_VDBOX_ROWSTORE_PARAMS rowstoreParams;
180         rowstoreParams.Mode             = CODECHAL_DECODE_MODE_HEVCVLD;
181         rowstoreParams.dwPicWidth       = m_hevcBasicFeature->m_width;
182         rowstoreParams.bMbaff           = false;
183         rowstoreParams.ucBitDepthMinus8 = (uint8_t)MOS_MAX(m_hevcPicParams->bit_depth_luma_minus8,
184                                                            m_hevcPicParams->bit_depth_chroma_minus8);
185         rowstoreParams.ucChromaFormat   = m_hevcPicParams->chroma_format_idc;
186         rowstoreParams.ucLCUSize        = (uint8_t)m_hevcBasicFeature->m_ctbSize;
187         DECODE_CHK_STATUS(m_hwInterface->SetRowstoreCachingOffsets(&rowstoreParams));
188     }
189 
190     return MOS_STATUS_SUCCESS;
191 }
192 
AllocateFixedResources()193 MOS_STATUS HevcDecodePicPktXe_M_Base::AllocateFixedResources()
194 {
195     DECODE_FUNC_CALL();
196 
197     if (m_resSliceStateStreamOutBuffer == nullptr)
198     {
199         uint32_t sizeOfBuffer = CODECHAL_HEVC_MAX_NUM_SLICES_LVL_6 * sliceStateCachelinesPerSlice * CODECHAL_CACHELINE_SIZE;
200         m_resSliceStateStreamOutBuffer = m_allocator->AllocateBuffer(
201             sizeOfBuffer,
202             "SliceStateStreamOut",
203             resourceInternalReadWriteCache,
204             notLockableVideoMem);
205         DECODE_CHK_NULL(m_resSliceStateStreamOutBuffer);
206     }
207 
208     if (m_resCABACStreamOutSizeBuffer == nullptr)
209     {
210         m_resCABACStreamOutSizeBuffer = m_allocator->AllocateBuffer(
211             sizeof(uint64_t),
212             "CABACStreamOutSizeBuffer",
213             resourceInternalReadWriteCache,
214             notLockableVideoMem);
215         DECODE_CHK_NULL(m_resCABACStreamOutSizeBuffer);
216     }
217 
218     return MOS_STATUS_SUCCESS;
219 }
220 
AllocateVariableResources()221 MOS_STATUS HevcDecodePicPktXe_M_Base::AllocateVariableResources()
222 {
223     DECODE_FUNC_CALL();
224 
225     MHW_VDBOX_HCP_BUFFER_SIZE_PARAMS hcpBufSizeParam;
226     MOS_ZeroMemory(&hcpBufSizeParam, sizeof(hcpBufSizeParam));
227     hcpBufSizeParam.ucMaxBitDepth  = m_hevcBasicFeature->m_bitDepth;
228     hcpBufSizeParam.ucChromaFormat = m_hevcBasicFeature->m_chromaFormat;
229     hcpBufSizeParam.dwCtbLog2SizeY = m_hevcPicParams->log2_diff_max_min_luma_coding_block_size +
230                                      m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3;
231     hcpBufSizeParam.dwPicWidth     = m_hevcBasicFeature->m_width;
232     hcpBufSizeParam.dwPicHeight    = m_hevcBasicFeature->m_height;
233     hcpBufSizeParam.dwMaxFrameSize = m_hevcBasicFeature->m_dataSize;
234 
235     auto AllocateBuffer = [&] (PMOS_BUFFER &buffer, MHW_VDBOX_HCP_INTERNAL_BUFFER_TYPE bufferType, const char *bufferName)
236     {
237         DECODE_CHK_STATUS(m_hcpInterface->GetHevcBufferSize(bufferType, &hcpBufSizeParam));
238         if (buffer == nullptr)
239         {
240             buffer = m_allocator->AllocateBuffer(
241                 hcpBufSizeParam.dwBufferSize, bufferName, resourceInternalReadWriteCache, notLockableVideoMem);
242             DECODE_CHK_NULL(buffer);
243         }
244         else
245         {
246             DECODE_CHK_STATUS(m_allocator->Resize(
247                 buffer, hcpBufSizeParam.dwBufferSize, notLockableVideoMem));
248         }
249         return MOS_STATUS_SUCCESS;
250     };
251 
252     if (!m_hcpInterface->IsHevcDfRowstoreCacheEnabled())
253     {
254         // Deblocking Filter Row Store Scratch buffer
255         DECODE_CHK_STATUS(AllocateBuffer(
256             m_resMfdDeblockingFilterRowStoreScratchBuffer,
257             MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_LINE,
258             "DeblockingScratchBuffer"));
259     }
260 
261     // Deblocking Filter Tile Row Store Scratch data surface
262     DECODE_CHK_STATUS(AllocateBuffer(
263         m_resDeblockingFilterTileRowStoreScratchBuffer,
264         MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_LINE,
265         "DeblockingTileScratchBuffer"));
266 
267     // Deblocking Filter Column Row Store Scratch data surface
268     DECODE_CHK_STATUS(AllocateBuffer(
269         m_resDeblockingFilterColumnRowStoreScratchBuffer,
270         MHW_VDBOX_HCP_INTERNAL_BUFFER_DBLK_TILE_COL,
271         "DeblockingColumnScratchBuffer"));
272 
273     if (!m_hcpInterface->IsHevcDatRowstoreCacheEnabled())
274     {
275         // Metadata Line buffer
276         DECODE_CHK_STATUS(AllocateBuffer(
277             m_resMetadataLineBuffer,
278             MHW_VDBOX_HCP_INTERNAL_BUFFER_META_LINE,
279             "MetadataLineBuffer"));
280     }
281 
282     // Metadata Tile Line buffer
283     DECODE_CHK_STATUS(AllocateBuffer(
284         m_resMetadataTileLineBuffer,
285         MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_LINE,
286         "MetadataTileLineBuffer"));
287 
288     // Metadata Tile Column buffer
289     DECODE_CHK_STATUS(AllocateBuffer(
290         m_resMetadataTileColumnBuffer,
291         MHW_VDBOX_HCP_INTERNAL_BUFFER_META_TILE_COL,
292         "MetadataTileColumnBuffer"));
293 
294     if (!m_hcpInterface->IsHevcSaoRowstoreCacheEnabled())
295     {
296         // SAO Line buffer
297         DECODE_CHK_STATUS(AllocateBuffer(
298             m_resSaoLineBuffer,
299             MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_LINE,
300             "SaoLineBuffer"));
301     }
302 
303     // SAO Tile Line buffer
304     DECODE_CHK_STATUS(AllocateBuffer(
305         m_resSaoTileLineBuffer,
306         MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_LINE,
307         "SaoTileLineBuffer"));
308 
309     // SAO Tile Column buffer
310     DECODE_CHK_STATUS(AllocateBuffer(
311         m_resSaoTileColumnBuffer,
312         MHW_VDBOX_HCP_INTERNAL_BUFFER_SAO_TILE_COL,
313         "SaoTileColumnBuffer"));
314 
315     // MV up right column store buffer
316     DECODE_CHK_STATUS(AllocateBuffer(
317         m_resMvUpRightColStoreBuffer,
318         MHW_VDBOX_HCP_INTERNAL_BUFFER_MV_UP_RT_COL,
319         "MVUpperRightColumnStore"));
320 
321     // Intra prediction up right column store buffer
322     DECODE_CHK_STATUS(AllocateBuffer(
323         m_resIntraPredUpRightColStoreBuffer,
324         MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_UP_RIGHT_COL,
325         "MVUpperRightColumnStore"));
326 
327     // Intra prediction left recon column store buffer
328     DECODE_CHK_STATUS(AllocateBuffer(
329         m_resIntraPredLeftReconColStoreBuffer,
330         MHW_VDBOX_HCP_INTERNAL_BUFFER_INTRA_PRED_LFT_RECON_COL,
331         "IntraPredLeftReconColumnStore"));
332 
333     // Cabac stream out buffer
334     DECODE_CHK_STATUS(AllocateBuffer(
335         m_resCABACSyntaxStreamOutBuffer,
336         MHW_VDBOX_HCP_INTERNAL_BUFFER_CABAC_STREAMOUT,
337         "CABACStreamOutBuffer"));
338 
339     return MOS_STATUS_SUCCESS;
340 }
341 
SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS & pipeModeSelectParams)342 void HevcDecodePicPktXe_M_Base::SetHcpPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS& pipeModeSelectParams)
343 {
344     DECODE_FUNC_CALL();
345 
346     pipeModeSelectParams.Mode = m_hevcBasicFeature->m_mode;
347     pipeModeSelectParams.bStreamOutEnabled = false;
348     pipeModeSelectParams.bShortFormatInUse = m_hevcPipeline->IsShortFormat();
349 }
350 
SetHcpDstSurfaceParams(MHW_VDBOX_SURFACE_PARAMS & dstSurfaceParams)351 MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpDstSurfaceParams(MHW_VDBOX_SURFACE_PARAMS& dstSurfaceParams)
352 {
353     DECODE_FUNC_CALL();
354 
355     dstSurfaceParams.Mode                       = CODECHAL_DECODE_MODE_HEVCVLD;
356     dstSurfaceParams.psSurface                  = &m_hevcBasicFeature->m_destSurface;
357     dstSurfaceParams.ucSurfaceStateId           = CODECHAL_HCP_DECODED_SURFACE_ID;
358     dstSurfaceParams.ChromaType                 = m_hevcPicParams->chroma_format_idc;
359     dstSurfaceParams.ucBitDepthLumaMinus8       = m_hevcPicParams->bit_depth_luma_minus8;
360     dstSurfaceParams.ucBitDepthChromaMinus8     = m_hevcPicParams->bit_depth_chroma_minus8;
361     dstSurfaceParams.dwUVPlaneAlignment         = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
362 
363 #ifdef _MMC_SUPPORTED
364     DECODE_CHK_STATUS(m_mmcState->SetSurfaceMmcState(dstSurfaceParams.psSurface));
365     DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(dstSurfaceParams.psSurface, &dstSurfaceParams.mmcState));
366     DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcFormat(dstSurfaceParams.psSurface, &dstSurfaceParams.dwCompressionFormat));
367 #endif
368 
369     return MOS_STATUS_SUCCESS;
370 }
371 
SetHcpRefSurfaceParams(const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams,MHW_VDBOX_SURFACE_PARAMS & refSurfaceParams)372 MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpRefSurfaceParams(
373     const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams, MHW_VDBOX_SURFACE_PARAMS& refSurfaceParams)
374 {
375     DECODE_FUNC_CALL();
376 
377     refSurfaceParams.Mode                       = CODECHAL_DECODE_MODE_HEVCVLD;
378     refSurfaceParams.psSurface                  = &m_hevcBasicFeature->m_destSurface; // For HEVC decode, reference should be same format as dest surface
379     refSurfaceParams.ucSurfaceStateId           = CODECHAL_HCP_REF_SURFACE_ID;
380     refSurfaceParams.ChromaType                 = m_hevcPicParams->chroma_format_idc;
381     refSurfaceParams.ucBitDepthLumaMinus8       = m_hevcPicParams->bit_depth_luma_minus8;
382     refSurfaceParams.ucBitDepthChromaMinus8     = m_hevcPicParams->bit_depth_chroma_minus8;
383     refSurfaceParams.dwUVPlaneAlignment         = 1 << (m_hevcPicParams->log2_min_luma_coding_block_size_minus3 + 3);
384 
385 #ifdef _MMC_SUPPORTED
386     HevcDecodeMemComp *hevcDecodeMemComp = dynamic_cast<HevcDecodeMemComp *>(m_mmcState);
387     DECODE_CHK_NULL(hevcDecodeMemComp);
388     // Set refSurfaceParams mmcState as MOS_MEMCOMP_MC to satisfy MmcEnable in AddHcpSurfaceCmd
389     // The actual mmcstate is recorded by refSurfaceParams.mmcSkipMask
390     if (m_mmcState->IsMmcEnabled())
391     {
392         refSurfaceParams.mmcState = MOS_MEMCOMP_MC;
393         DECODE_CHK_STATUS(hevcDecodeMemComp->SetRefSurfaceMask(*m_hevcBasicFeature, pipeBufAddrParams.presReferences, refSurfaceParams.mmcSkipMask));
394         DECODE_CHK_STATUS(hevcDecodeMemComp->SetRefSurfaceCompressionFormat(*m_hevcBasicFeature, pipeBufAddrParams.presReferences, refSurfaceParams.dwCompressionFormat));
395     }
396     else
397     {
398         refSurfaceParams.mmcState            = MOS_MEMCOMP_DISABLED;
399         refSurfaceParams.dwCompressionFormat = 0;
400     }
401 #endif
402 
403     return MOS_STATUS_SUCCESS;
404 }
405 
AddHcpSurfaces(MOS_COMMAND_BUFFER & cmdBuffer,const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)406 MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpSurfaces(MOS_COMMAND_BUFFER &cmdBuffer, const MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams)
407 {
408     DECODE_FUNC_CALL();
409 
410     MHW_VDBOX_SURFACE_PARAMS dstSurfaceParams;
411     MOS_ZeroMemory(&dstSurfaceParams, sizeof(dstSurfaceParams));
412     DECODE_CHK_STATUS(SetHcpDstSurfaceParams(dstSurfaceParams));
413     DECODE_CHK_STATUS(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &dstSurfaceParams));
414 
415     MHW_VDBOX_SURFACE_PARAMS refSurfaceParams;
416     MOS_ZeroMemory(&refSurfaceParams, sizeof(refSurfaceParams));
417     SetHcpRefSurfaceParams(pipeBufAddrParams, refSurfaceParams);
418     DECODE_CHK_STATUS(m_hcpInterface->AddHcpSurfaceCmd(&cmdBuffer, &refSurfaceParams));
419 
420     return MOS_STATUS_SUCCESS;
421 }
422 
FixHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)423 MOS_STATUS HevcDecodePicPktXe_M_Base::FixHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
424 {
425     if (m_hevcBasicFeature->m_refFrames.m_curIsIntra)
426     {
427         PMOS_RESOURCE dummyRef = &(m_hevcBasicFeature->m_dummyReference.OsResource);
428         if (m_hevcBasicFeature->m_useDummyReference &&
429             !m_allocator->ResourceIsNull(dummyRef))
430         {
431             // set all ref pic addresses to valid addresses for error concealment purpose
432             for (uint32_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
433             {
434                 if (pipeBufAddrParams.presReferences[i] == nullptr)
435                 {
436                     pipeBufAddrParams.presReferences[i] = dummyRef;
437                     m_hevcBasicFeature->m_dummyReferenceSlot[i] = true;
438                 }
439             }
440         }
441     }
442     else
443     {
444         PMOS_RESOURCE validRef = m_hevcBasicFeature->m_refFrames.GetValidReference();
445         for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
446         {
447             // error concealment for the unset reference addresses and unset mv buffers
448             if (pipeBufAddrParams.presReferences[i] == nullptr)
449             {
450                 pipeBufAddrParams.presReferences[i] = validRef;
451             }
452         }
453 
454         PMOS_BUFFER validMvBuf = m_hevcBasicFeature->m_mvBuffers.GetValidBufferForReference(
455                                     m_hevcBasicFeature->m_refFrameIndexList);
456         for (uint32_t i = 0; i < CODEC_NUM_HEVC_MV_BUFFERS; i++)
457         {
458             if (pipeBufAddrParams.presColMvTempBuffer[i] == nullptr)
459             {
460                 pipeBufAddrParams.presColMvTempBuffer[i] = &validMvBuf->OsResource;
461             }
462         }
463     }
464 
465     return MOS_STATUS_SUCCESS;
466 }
467 
SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)468 MOS_STATUS HevcDecodePicPktXe_M_Base::SetHcpPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
469 {
470     DECODE_FUNC_CALL();
471 
472     pipeBufAddrParams.Mode                  = m_hevcBasicFeature->m_mode;
473 
474     PMOS_SURFACE destSurface                = &(m_hevcBasicFeature->m_destSurface);
475     pipeBufAddrParams.psPreDeblockSurface   = destSurface;
476 
477 #ifdef _MMC_SUPPORTED
478     DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(destSurface, &pipeBufAddrParams.PreDeblockSurfMmcState));
479 #endif
480 
481     pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer =
482         &(m_resMfdDeblockingFilterRowStoreScratchBuffer->OsResource);
483     pipeBufAddrParams.presDeblockingFilterTileRowStoreScratchBuffer =
484         &(m_resDeblockingFilterTileRowStoreScratchBuffer->OsResource);
485     pipeBufAddrParams.presDeblockingFilterColumnRowStoreScratchBuffer =
486         &(m_resDeblockingFilterColumnRowStoreScratchBuffer->OsResource);
487 
488     pipeBufAddrParams.presMetadataLineBuffer       = &(m_resMetadataLineBuffer->OsResource);
489     pipeBufAddrParams.presMetadataTileLineBuffer   = &(m_resMetadataTileLineBuffer->OsResource);
490     pipeBufAddrParams.presMetadataTileColumnBuffer = &(m_resMetadataTileColumnBuffer->OsResource);
491     pipeBufAddrParams.presSaoLineBuffer            = &(m_resSaoLineBuffer->OsResource);
492     pipeBufAddrParams.presSaoTileLineBuffer        = &(m_resSaoTileLineBuffer->OsResource);
493     pipeBufAddrParams.presSaoTileColumnBuffer      = &(m_resSaoTileColumnBuffer->OsResource);
494 
495     auto mvBuffers = &(m_hevcBasicFeature->m_mvBuffers);
496     PMOS_BUFFER curMvBuffer = mvBuffers->GetCurBuffer();
497     DECODE_CHK_NULL(curMvBuffer);
498     pipeBufAddrParams.presCurMvTempBuffer = &(curMvBuffer->OsResource);
499 
500     HevcReferenceFrames &refFrames = m_hevcBasicFeature->m_refFrames;
501     const std::vector<uint8_t> & activeRefList = refFrames.GetActiveReferenceList(*m_hevcPicParams);
502     if (!refFrames.m_curIsIntra)
503     {
504         DECODE_ASSERT(activeRefList.size() <= 8);
505         for (uint8_t i = 0; i < activeRefList.size(); i++)
506         {
507             uint8_t frameIdx = activeRefList[i];
508             if (frameIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_HEVC)
509             {
510                 continue;
511             }
512 
513             pipeBufAddrParams.presReferences[i] = refFrames.GetReferenceByFrameIndex(frameIdx);
514             if (pipeBufAddrParams.presReferences[i] == nullptr)
515             {
516                 PCODEC_REF_LIST curFrameInRefList = refFrames.m_refList[m_hevcPicParams->CurrPic.FrameIdx];
517                 DECODE_CHK_NULL(curFrameInRefList);
518                 MOS_ZeroMemory(&curFrameInRefList->resRefPic, sizeof(MOS_RESOURCE));
519                 DECODE_ASSERTMESSAGE("Reference frame for current Frame is not exist, current frame will be skipped. Thus, clear current frame resource in reference list.");
520                 return MOS_STATUS_INVALID_PARAMETER;
521             }
522 
523             PMOS_BUFFER mvBuf = mvBuffers->GetBufferByFrameIndex(frameIdx);
524             pipeBufAddrParams.presColMvTempBuffer[i] = mvBuf ? (&mvBuf->OsResource) : nullptr;
525 
526             // Return error if reference surface's pitch * height is less than dest surface.
527             MOS_SURFACE refSurface;
528             refSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
529             DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&refSurface));
530             DECODE_CHK_COND((refSurface.dwPitch * refSurface.dwHeight) < (destSurface->dwPitch * destSurface->dwHeight),
531                             "Reference surface's pitch * height is less than Dest surface.");
532         }
533     }
534 
535     DECODE_CHK_STATUS(FixHcpPipeBufAddrParams(pipeBufAddrParams));
536 
537     if (m_hevcBasicFeature->m_isSCCIBCMode)
538     {
539         uint8_t IBCRefIdx = refFrames.m_IBCRefIdx;
540         DECODE_CHK_COND(activeRefList.size() <= IBCRefIdx, "Invalid IBC reference index.");
541 
542         uint8_t refIdxMask = 0;
543         for (uint8_t i = 0; i < CODECHAL_MAX_CUR_NUM_REF_FRAME_HEVC; i++)
544         {
545             uint8_t IBCFrameIdx = activeRefList[IBCRefIdx];
546             if (pipeBufAddrParams.presReferences[i] == refFrames.GetReferenceByFrameIndex(IBCFrameIdx))
547             {
548                 refIdxMask |= (1 << i);
549             }
550         }
551         pipeBufAddrParams.IBCRefIdxMask = refIdxMask;
552     }
553 
554     CODECHAL_DEBUG_TOOL(DECODE_CHK_STATUS(DumpResources(pipeBufAddrParams, activeRefList.size(), curMvBuffer->size)));
555 
556     return MOS_STATUS_SUCCESS;
557 }
558 
SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS & indObjBaseAddrParams)559 void HevcDecodePicPktXe_M_Base::SetHcpIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS& indObjBaseAddrParams)
560 {
561     DECODE_FUNC_CALL();
562 
563     indObjBaseAddrParams.Mode            = m_hevcBasicFeature->m_mode;
564     indObjBaseAddrParams.dwDataSize      = m_hevcBasicFeature->m_dataSize;
565     indObjBaseAddrParams.dwDataOffset    = m_hevcBasicFeature->m_dataOffset;
566     indObjBaseAddrParams.presDataBuffer  = &(m_hevcBasicFeature->m_resDataBuffer.OsResource);
567 }
568 
AddHcpIndObjBaseAddrCmd(MOS_COMMAND_BUFFER & cmdBuffer)569 MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpIndObjBaseAddrCmd(MOS_COMMAND_BUFFER  &cmdBuffer)
570 {
571     DECODE_FUNC_CALL();
572 
573     MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
574     MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
575     SetHcpIndObjBaseAddrParams(indObjBaseAddrParams);
576 
577     DECODE_CHK_STATUS(m_hcpInterface->AddHcpIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
578     return MOS_STATUS_SUCCESS;
579 }
580 
SetHcpQmStateParams(MHW_VDBOX_QM_PARAMS & qmParams)581 void HevcDecodePicPktXe_M_Base::SetHcpQmStateParams(MHW_VDBOX_QM_PARAMS& qmParams)
582 {
583     DECODE_FUNC_CALL();
584 
585     qmParams.Standard = CODECHAL_HEVC;
586     qmParams.pHevcIqMatrix = (PMHW_VDBOX_HEVC_QM_PARAMS)m_hevcIqMatrixParams;
587 }
588 
AddHcpQmStateCmd(MOS_COMMAND_BUFFER & cmdBuffer)589 MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpQmStateCmd(MOS_COMMAND_BUFFER  &cmdBuffer)
590 {
591     DECODE_FUNC_CALL();
592 
593     MHW_VDBOX_QM_PARAMS qmParams;
594     MOS_ZeroMemory(&qmParams, sizeof(qmParams));
595     SetHcpQmStateParams(qmParams);
596 
597     DECODE_CHK_STATUS(m_hcpInterface->AddHcpQmStateCmd(&cmdBuffer, &qmParams));
598     return MOS_STATUS_SUCCESS;
599 }
600 
SetHcpPicStateParams(MHW_VDBOX_HEVC_PIC_STATE & picStateParams)601 void HevcDecodePicPktXe_M_Base::SetHcpPicStateParams(MHW_VDBOX_HEVC_PIC_STATE& picStateParams)
602 {
603     DECODE_FUNC_CALL();
604     picStateParams.pHevcPicParams = m_hevcPicParams;
605 }
606 
SetHcpTileStateParams(MHW_VDBOX_HEVC_TILE_STATE & tileStateParams)607 void HevcDecodePicPktXe_M_Base::SetHcpTileStateParams(MHW_VDBOX_HEVC_TILE_STATE& tileStateParams)
608 {
609     DECODE_FUNC_CALL();
610     tileStateParams.pHevcPicParams = m_hevcPicParams;
611     tileStateParams.pTileColWidth  = (uint16_t *)m_hevcBasicFeature->m_tileCoding.GetTileColWidth();
612     tileStateParams.pTileRowHeight = (uint16_t *)m_hevcBasicFeature->m_tileCoding.GetTileRowHeight();
613 }
614 
AddHcpTileStateCmd(MOS_COMMAND_BUFFER & cmdBuffer)615 MOS_STATUS HevcDecodePicPktXe_M_Base::AddHcpTileStateCmd(MOS_COMMAND_BUFFER  &cmdBuffer)
616 {
617     DECODE_FUNC_CALL();
618 
619     MHW_VDBOX_HEVC_TILE_STATE tileStateParams;
620     MOS_ZeroMemory(&tileStateParams, sizeof(tileStateParams));
621     SetHcpTileStateParams(tileStateParams);
622 
623     DECODE_CHK_STATUS(m_hcpInterface->AddHcpTileStateCmd(&cmdBuffer, &tileStateParams));
624     return MOS_STATUS_SUCCESS;
625 }
626 
627 #if USE_CODECHAL_DEBUG_TOOL
DumpResources(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams,uint8_t activeRefListSize,uint32_t mvBufferSize)628 MOS_STATUS HevcDecodePicPktXe_M_Base::DumpResources(
629     MHW_VDBOX_PIPE_BUF_ADDR_PARAMS &pipeBufAddrParams,
630     uint8_t activeRefListSize,
631     uint32_t mvBufferSize)
632 {
633     DECODE_FUNC_CALL();
634 
635     CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
636     DECODE_CHK_NULL(debugInterface);
637 
638     for (uint32_t i = 0; i < activeRefListSize; i++)
639     {
640         if (pipeBufAddrParams.presReferences[i] != nullptr)
641         {
642             MOS_SURFACE refSurface;
643             MOS_ZeroMemory(&refSurface, sizeof(MOS_SURFACE));
644             refSurface.OsResource = *(pipeBufAddrParams.presReferences[i]);
645             DECODE_CHK_STATUS(CodecHalGetResourceInfo(m_osInterface, &refSurface));
646 
647             std::string refSurfDumpName = "RefSurf[" + std::to_string(i) + "]";
648             DECODE_CHK_STATUS(debugInterface->DumpYUVSurface(
649                 &refSurface,
650                 CodechalDbgAttr::attrDecodeReferenceSurfaces,
651                 refSurfDumpName.c_str()));
652         }
653 
654         if (pipeBufAddrParams.presColMvTempBuffer[i] != nullptr)
655         {
656             std::string mvBufDumpName = "_DEC_" + std::to_string(i);
657             DECODE_CHK_STATUS(debugInterface->DumpBuffer(
658                 pipeBufAddrParams.presColMvTempBuffer[i],
659                 CodechalDbgAttr::attrMvData,
660                 mvBufDumpName.c_str(),
661                 mvBufferSize));
662         }
663     }
664 
665     return MOS_STATUS_SUCCESS;
666 }
667 #endif
668 
669 }
670