1 /*
2 * Copyright (c) 2021, 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_mpeg2_picture_packet_xe_m_base.cpp
24 //! \brief    Defines the interface of mpeg2 decode picture packet for Xe_M_Base
25 //!
26 
27 #include "codechal_utilities.h"
28 #include "decode_mpeg2_picture_packet_xe_m_base.h"
29 #include "codechal_debug.h"
30 #include "decode_common_feature_defs.h"
31 
32 namespace decode {
33 
~Mpeg2DecodePicPktXe_M_Base()34     Mpeg2DecodePicPktXe_M_Base::~Mpeg2DecodePicPktXe_M_Base()
35     {
36         FreeResources();
37     }
38 
FreeResources()39     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::FreeResources()
40     {
41         DECODE_FUNC_CALL();
42 
43         if (m_allocator != nullptr)
44         {
45             m_allocator->Destroy(m_resMfdDeblockingFilterRowStoreScratchBuffer);
46             m_allocator->Destroy(m_resBsdMpcRowStoreScratchBuffer);
47         }
48 
49         return MOS_STATUS_SUCCESS;
50     }
51 
Init()52     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::Init()
53     {
54         DECODE_FUNC_CALL();
55 
56         DECODE_CHK_NULL(m_featureManager);
57         DECODE_CHK_NULL(m_hwInterface);
58         DECODE_CHK_NULL(m_osInterface);
59         DECODE_CHK_NULL(m_miInterface);
60         DECODE_CHK_NULL(m_mpeg2Pipeline);
61         DECODE_CHK_NULL(m_mfxInterface);
62 
63         m_mpeg2BasicFeature = dynamic_cast<Mpeg2BasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
64         DECODE_CHK_NULL(m_mpeg2BasicFeature);
65 
66         m_allocator = m_pipeline->GetDecodeAllocator();
67         DECODE_CHK_NULL(m_allocator);
68 
69         DECODE_CHK_STATUS(AllocateFixedResources());
70 
71         return MOS_STATUS_SUCCESS;
72     }
73 
Prepare()74     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::Prepare()
75     {
76         DECODE_FUNC_CALL();
77 
78         m_mpeg2PicParams = m_mpeg2BasicFeature->m_mpeg2PicParams;
79         DECODE_CHK_NULL(m_mpeg2PicParams);
80 
81 #ifdef _MMC_SUPPORTED
82         m_mmcState = m_mpeg2Pipeline->GetMmcState();
83         DECODE_CHK_NULL(m_mmcState);
84 #endif
85 
86         return MOS_STATUS_SUCCESS;
87     }
88 
AllocateFixedResources()89     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::AllocateFixedResources()
90     {
91         DECODE_FUNC_CALL();
92 
93         uint16_t picWidthInMb = m_mpeg2BasicFeature->m_picWidthInMb;
94         uint16_t picHeightInMb = m_mpeg2BasicFeature->m_picHeightInMb;
95 
96         // Deblocking Filter Row Store Scratch buffer
97         // (Num MacroBlock Width) * (Num Cachlines) * (Cachline size)
98         m_resMfdDeblockingFilterRowStoreScratchBuffer = m_allocator->AllocateBuffer(
99             picWidthInMb * 7 * CODECHAL_CACHELINE_SIZE,
100             "DeblockingFilterScratch",
101             resourceInternalReadWriteCache,
102             notLockableVideoMem);
103 
104         // MPR Row Store Scratch buffer
105         // (FrameWidth in MB) * (CacheLine size per MB) * 2
106         m_resBsdMpcRowStoreScratchBuffer = m_allocator->AllocateBuffer(
107             ((uint32_t)(picWidthInMb * CODECHAL_CACHELINE_SIZE)) * 2,
108             "MprScratchBuffer",
109             resourceInternalReadWriteCache,
110             notLockableVideoMem);
111 
112         return MOS_STATUS_SUCCESS;
113     }
114 
SetMfxPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS_G12 & pipeModeSelectParams)115     void Mpeg2DecodePicPktXe_M_Base::SetMfxPipeModeSelectParams(MHW_VDBOX_PIPE_MODE_SELECT_PARAMS_G12& pipeModeSelectParams)
116     {
117         DECODE_FUNC_CALL();
118 
119         pipeModeSelectParams.Mode = m_mpeg2BasicFeature->m_mode;
120         pipeModeSelectParams.bStreamOutEnabled = m_mpeg2BasicFeature->m_streamOutEnabled;
121         pipeModeSelectParams.bPostDeblockOutEnable = m_mpeg2BasicFeature->m_deblockingEnabled;
122         pipeModeSelectParams.bPreDeblockOutEnable = !m_mpeg2BasicFeature->m_deblockingEnabled;
123     }
124 
SetMfxSurfaceParams(MHW_VDBOX_SURFACE_PARAMS & dstSurfaceParams)125     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::SetMfxSurfaceParams(MHW_VDBOX_SURFACE_PARAMS& dstSurfaceParams)
126     {
127         DECODE_FUNC_CALL();
128 
129         MOS_ZeroMemory(&dstSurfaceParams, sizeof(dstSurfaceParams));
130         dstSurfaceParams.Mode = m_mpeg2BasicFeature->m_mode;
131         dstSurfaceParams.psSurface = &m_mpeg2BasicFeature->m_destSurface;
132 
133 #ifdef _MMC_SUPPORTED
134         DECODE_CHK_STATUS(m_mmcState->SetSurfaceMmcState(&(m_mpeg2BasicFeature->m_destSurface)));
135         DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(dstSurfaceParams.psSurface, &dstSurfaceParams.mmcState));
136         DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcFormat(dstSurfaceParams.psSurface, &dstSurfaceParams.dwCompressionFormat));
137 #endif
138 
139         return MOS_STATUS_SUCCESS;
140     }
141 
AddMfxSurfacesCmd(MOS_COMMAND_BUFFER & cmdBuffer)142     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::AddMfxSurfacesCmd(MOS_COMMAND_BUFFER& cmdBuffer)
143     {
144         DECODE_FUNC_CALL();
145 
146         MHW_VDBOX_SURFACE_PARAMS dstSurfaceParams;
147         DECODE_CHK_STATUS(SetMfxSurfaceParams(dstSurfaceParams));
148         DECODE_CHK_STATUS(m_mfxInterface->AddMfxSurfaceCmd(&cmdBuffer, &dstSurfaceParams));
149 
150         return MOS_STATUS_SUCCESS;
151     }
152 
SetMfxPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)153     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::SetMfxPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
154     {
155         DECODE_FUNC_CALL();
156 
157         pipeBufAddrParams.Mode = m_mpeg2BasicFeature->m_mode;
158 
159         if (m_mpeg2BasicFeature->m_deblockingEnabled)
160         {
161             pipeBufAddrParams.psPostDeblockSurface = &(m_mpeg2BasicFeature->m_destSurface);
162         }
163         else
164         {
165             pipeBufAddrParams.psPreDeblockSurface = &(m_mpeg2BasicFeature->m_destSurface);
166         }
167         pipeBufAddrParams.presMfdDeblockingFilterRowStoreScratchBuffer = &m_resMfdDeblockingFilterRowStoreScratchBuffer->OsResource;
168 
169         if (m_mpeg2BasicFeature->m_streamOutEnabled)
170         {
171             pipeBufAddrParams.presStreamOutBuffer = m_mpeg2BasicFeature->m_streamOutBuffer;
172         }
173 
174         Mpeg2ReferenceFrames& refFrames = m_mpeg2BasicFeature->m_refFrames;
175 
176         // when there is not a forward or backward reference,
177         // the index is set to the destination frame index
178         pipeBufAddrParams.presReferences[CodechalDecodeFwdRefTop] =
179             pipeBufAddrParams.presReferences[CodechalDecodeFwdRefBottom] =
180             pipeBufAddrParams.presReferences[CodechalDecodeBwdRefTop] =
181             pipeBufAddrParams.presReferences[CodechalDecodeBwdRefBottom] =
182             &m_mpeg2BasicFeature->m_destSurface.OsResource;
183 
184         if (m_mpeg2BasicFeature->m_fwdRefIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
185         {
186             pipeBufAddrParams.presReferences[CodechalDecodeFwdRefTop] =
187                 pipeBufAddrParams.presReferences[CodechalDecodeFwdRefBottom] =
188                 &refFrames.m_refList[m_mpeg2BasicFeature->m_fwdRefIdx]->resRefPic;
189         }
190         if (m_mpeg2BasicFeature->m_bwdRefIdx < CODECHAL_NUM_UNCOMPRESSED_SURFACE_MPEG2)
191         {
192             pipeBufAddrParams.presReferences[CodechalDecodeBwdRefTop] =
193                 pipeBufAddrParams.presReferences[CodechalDecodeBwdRefBottom] =
194                 &refFrames.m_refList[m_mpeg2BasicFeature->m_bwdRefIdx]->resRefPic;
195         }
196 
197         // special case for second fields
198         if (m_mpeg2PicParams->m_secondField && m_mpeg2PicParams->m_pictureCodingType == P_TYPE)
199         {
200             if (m_mpeg2PicParams->m_topFieldFirst)
201             {
202                 pipeBufAddrParams.presReferences[CodechalDecodeFwdRefTop] =
203                     &m_mpeg2BasicFeature->m_destSurface.OsResource;
204             }
205             else
206             {
207                 pipeBufAddrParams.presReferences[CodechalDecodeFwdRefBottom] =
208                     &m_mpeg2BasicFeature->m_destSurface.OsResource;
209             }
210         }
211 
212 #ifdef _MMC_SUPPORTED
213         DECODE_CHK_STATUS(m_mmcState->GetSurfaceMmcState(pipeBufAddrParams.psPreDeblockSurface, &pipeBufAddrParams.PreDeblockSurfMmcState));
214         if (m_mmcState->IsMmcEnabled())
215         {
216             pipeBufAddrParams.bMmcEnabled = true;
217         }
218 #endif
219 
220         DECODE_CHK_STATUS(FixMfxPipeBufAddrParams(pipeBufAddrParams));
221 
222         CODECHAL_DEBUG_TOOL(DumpResources(pipeBufAddrParams));
223 
224         return MOS_STATUS_SUCCESS;
225     }
226 
FixMfxPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)227     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::FixMfxPipeBufAddrParams(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
228     {
229         DECODE_FUNC_CALL();
230 
231         PMOS_RESOURCE dummyRef = &(m_mpeg2BasicFeature->m_dummyReference.OsResource);
232 
233         // set all ref pic addresses to valid addresses for error concealment purpose
234         for (uint32_t i = 0; i < CODEC_MAX_NUM_REF_FRAME_NON_AVC; i++)
235         {
236             if (m_mpeg2BasicFeature->m_useDummyReference && !m_allocator->ResourceIsNull(dummyRef) &&
237                 pipeBufAddrParams.presReferences[i] == nullptr)
238             {
239                 pipeBufAddrParams.presReferences[i] = dummyRef;
240             }
241         }
242 
243         return MOS_STATUS_SUCCESS;
244     }
245 
SetMfxIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS & indObjBaseAddrParams)246     void Mpeg2DecodePicPktXe_M_Base::SetMfxIndObjBaseAddrParams(MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS& indObjBaseAddrParams)
247     {
248         DECODE_FUNC_CALL();
249 
250         MOS_ZeroMemory(&indObjBaseAddrParams, sizeof(indObjBaseAddrParams));
251         indObjBaseAddrParams.Mode = m_mpeg2BasicFeature->m_mode;;
252         indObjBaseAddrParams.dwDataSize = m_mpeg2BasicFeature->m_copiedDataBufferInUse ?
253             m_mpeg2BasicFeature->m_copiedDataBufferSize :
254             m_mpeg2BasicFeature->m_dataSize;
255         indObjBaseAddrParams.presDataBuffer = m_mpeg2BasicFeature->m_copiedDataBufferInUse ?
256             &(m_mpeg2BasicFeature->m_copiedDataBuf->OsResource) :
257             &(m_mpeg2BasicFeature->m_resDataBuffer.OsResource);
258     }
259 
AddMfxIndObjBaseAddrCmd(MOS_COMMAND_BUFFER & cmdBuffer)260     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::AddMfxIndObjBaseAddrCmd(MOS_COMMAND_BUFFER& cmdBuffer)
261     {
262         DECODE_FUNC_CALL();
263 
264         MHW_VDBOX_IND_OBJ_BASE_ADDR_PARAMS indObjBaseAddrParams;
265         SetMfxIndObjBaseAddrParams(indObjBaseAddrParams);
266         DECODE_CHK_STATUS(m_mfxInterface->AddMfxIndObjBaseAddrCmd(&cmdBuffer, &indObjBaseAddrParams));
267 
268         return MOS_STATUS_SUCCESS;
269     }
270 
SetMfxBspBufBaseAddrParams(MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS & bspBufBaseAddrParams)271     void Mpeg2DecodePicPktXe_M_Base::SetMfxBspBufBaseAddrParams(MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS& bspBufBaseAddrParams)
272     {
273         DECODE_FUNC_CALL();
274 
275         MOS_ZeroMemory(&bspBufBaseAddrParams, sizeof(bspBufBaseAddrParams));
276         bspBufBaseAddrParams.presBsdMpcRowStoreScratchBuffer = &m_resBsdMpcRowStoreScratchBuffer->OsResource;
277     }
278 
AddMfxBspBufBaseAddrCmd(MOS_COMMAND_BUFFER & cmdBuffer)279     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::AddMfxBspBufBaseAddrCmd(MOS_COMMAND_BUFFER& cmdBuffer)
280     {
281         DECODE_FUNC_CALL();
282 
283         MHW_VDBOX_BSP_BUF_BASE_ADDR_PARAMS BspBufBaseAddrParams;
284         SetMfxBspBufBaseAddrParams(BspBufBaseAddrParams);
285         DECODE_CHK_STATUS(m_mfxInterface->AddMfxBspBufBaseAddrCmd(&cmdBuffer, &BspBufBaseAddrParams));
286 
287         return MOS_STATUS_SUCCESS;
288     }
289 
SetMfxMpeg2PicStateParams(MHW_VDBOX_MPEG2_PIC_STATE & mpeg2PicState)290     void Mpeg2DecodePicPktXe_M_Base::SetMfxMpeg2PicStateParams(MHW_VDBOX_MPEG2_PIC_STATE& mpeg2PicState)
291     {
292         DECODE_FUNC_CALL();
293 
294         MOS_ZeroMemory(&mpeg2PicState, sizeof(mpeg2PicState));
295         mpeg2PicState.Mode = m_mpeg2BasicFeature->m_mode;
296         mpeg2PicState.pMpeg2PicParams = m_mpeg2PicParams;
297         mpeg2PicState.bDeblockingEnabled = m_mpeg2BasicFeature->m_deblockingEnabled;
298         mpeg2PicState.dwMPEG2ISliceConcealmentMode = m_mpeg2BasicFeature->m_mpeg2ISliceConcealmentMode;
299         mpeg2PicState.dwMPEG2PBSliceConcealmentMode = m_mpeg2BasicFeature->m_mpeg2PbSliceConcealmentMode;
300         mpeg2PicState.dwMPEG2PBSlicePredBiDirMVTypeOverride = m_mpeg2BasicFeature->m_mpeg2PbSlicePredBiDirMvTypeOverride;
301         mpeg2PicState.dwMPEG2PBSlicePredMVOverride = m_mpeg2BasicFeature->m_mpeg2PbSlicePredMvOverride;
302     }
303 
AddMfxMpeg2PicCmd(MOS_COMMAND_BUFFER & cmdBuffer)304     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::AddMfxMpeg2PicCmd(MOS_COMMAND_BUFFER& cmdBuffer)
305     {
306         DECODE_FUNC_CALL();
307 
308         MHW_VDBOX_MPEG2_PIC_STATE mpeg2PicState;
309         SetMfxMpeg2PicStateParams(mpeg2PicState);
310         DECODE_CHK_STATUS(m_mfxInterface->AddMfxMpeg2PicCmd(&cmdBuffer, &mpeg2PicState));
311 
312         return MOS_STATUS_SUCCESS;
313     }
314 
SetMfxQmParams(MHW_VDBOX_QM_PARAMS & qmParams)315     void Mpeg2DecodePicPktXe_M_Base::SetMfxQmParams(MHW_VDBOX_QM_PARAMS& qmParams)
316     {
317         DECODE_FUNC_CALL();
318 
319         MOS_ZeroMemory(&qmParams, sizeof(qmParams));
320         qmParams.Standard = CODECHAL_MPEG2;
321         qmParams.pMpeg2IqMatrix = m_mpeg2BasicFeature->m_mpeg2IqMatrixBuffer;
322     }
323 
AddMfxQmCmd(MOS_COMMAND_BUFFER & cmdBuffer)324     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::AddMfxQmCmd(MOS_COMMAND_BUFFER& cmdBuffer)
325     {
326         DECODE_FUNC_CALL();
327 
328         MHW_VDBOX_QM_PARAMS qmParams;
329         SetMfxQmParams(qmParams);
330         DECODE_CHK_STATUS(m_mfxInterface->AddMfxQmCmd(&cmdBuffer, &qmParams));
331 
332         return MOS_STATUS_SUCCESS;
333     }
334 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)335     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::CalculateCommandSize(uint32_t& commandBufferSize, uint32_t& requestedPatchListSize)
336     {
337         DECODE_FUNC_CALL();
338 
339         commandBufferSize = m_pictureStatesSize;
340         requestedPatchListSize = m_picturePatchListSize;
341 
342         return MOS_STATUS_SUCCESS;
343     }
344 
345 #if USE_CODECHAL_DEBUG_TOOL
DumpResources(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS & pipeBufAddrParams)346     MOS_STATUS Mpeg2DecodePicPktXe_M_Base::DumpResources(MHW_VDBOX_PIPE_BUF_ADDR_PARAMS& pipeBufAddrParams)
347     {
348         DECODE_FUNC_CALL();
349 
350         CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface();
351         DECODE_CHK_NULL(debugInterface);
352 
353         if (m_mpeg2PicParams->m_pictureCodingType != I_TYPE)
354         {
355             for (uint16_t n = 0; n <= CodechalDecodeBwdRefBottom; n++)
356             {
357                 if (pipeBufAddrParams.presReferences[n])
358                 {
359                     MOS_SURFACE refSurface;
360                     MOS_ZeroMemory(&refSurface, sizeof(MOS_SURFACE));
361                     refSurface.OsResource = *(pipeBufAddrParams.presReferences[n]);
362                     DECODE_CHK_STATUS(m_allocator->GetSurfaceInfo(&refSurface));
363 
364                     debugInterface->m_refIndex = n;
365                     std::string refSurfName    = "RefSurf[" + std::to_string(static_cast<uint32_t>(debugInterface->m_refIndex)) + "]";
366                     DECODE_CHK_STATUS(debugInterface->DumpYUVSurface(
367                         &refSurface,
368                         CodechalDbgAttr::attrDecodeReferenceSurfaces,
369                         refSurfName.c_str()));
370                 }
371             }
372         }
373 
374         return MOS_STATUS_SUCCESS;
375     }
376 #endif
377 }  // namespace decode
378