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_mb_packet_xe_m_base.cpp
24 //! \brief    Defines the interface of mpeg2 decode macroblock packet for Xe_M_Base
25 //!
26 #include "codechal_utilities.h"
27 #include "decode_mpeg2_mb_packet_xe_m_base.h"
28 
29 namespace decode {
30 
Init()31     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::Init()
32     {
33         DECODE_FUNC_CALL();
34 
35         DECODE_CHK_NULL(m_featureManager);
36         DECODE_CHK_NULL(m_hwInterface);
37         DECODE_CHK_NULL(m_osInterface);
38         DECODE_CHK_NULL(m_miInterface);
39         DECODE_CHK_NULL(m_mpeg2Pipeline);
40         DECODE_CHK_NULL(m_mfxInterface);
41 
42         m_mpeg2BasicFeature = dynamic_cast<Mpeg2BasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
43         DECODE_CHK_NULL(m_mpeg2BasicFeature);
44 
45         m_allocator = m_pipeline->GetDecodeAllocator();
46         DECODE_CHK_NULL(m_allocator);
47 
48         DECODE_CHK_STATUS(CalculateMbStateCommandSize());
49 
50         return MOS_STATUS_SUCCESS;
51     }
52 
Prepare()53     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::Prepare()
54     {
55         DECODE_FUNC_CALL();
56 
57         DECODE_CHK_NULL(m_mpeg2BasicFeature->m_mpeg2PicParams);
58         m_mpeg2PicParams = m_mpeg2BasicFeature->m_mpeg2PicParams;
59 
60         return MOS_STATUS_SUCCESS;
61     }
62 
SetMpeg2MbStateParams(MHW_VDBOX_MPEG2_MB_STATE & mpeg2MbState,uint32_t mbIdx)63     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::SetMpeg2MbStateParams(
64         MHW_VDBOX_MPEG2_MB_STATE& mpeg2MbState, uint32_t mbIdx)
65     {
66         DECODE_FUNC_CALL();
67 
68         MOS_ZeroMemory(&mpeg2MbState, sizeof(mpeg2MbState));
69         CodecDecodeMpeg2MbParmas* mb = &m_mpeg2BasicFeature->m_mbRecord[mbIdx].recordMbParam;
70 
71         mpeg2MbState.wPicWidthInMb = m_mpeg2BasicFeature->m_picWidthInMb;
72         mpeg2MbState.wPicHeightInMb = m_mpeg2BasicFeature->m_picHeightInMb;
73         mpeg2MbState.wPicCodingType = (uint16_t)m_mpeg2PicParams->m_pictureCodingType;
74 
75         // common field for MBs in I picture and PB picture .
76         mpeg2MbState.pMBParams = mb;
77         mpeg2MbState.dwDCTLength = 0;
78 
79         for (uint32_t i = 0; i < CODEC_NUM_BLOCK_PER_MB; i++)
80         {
81             mpeg2MbState.dwDCTLength += mb->m_numCoeff[i];
82         }
83 
84         // only for MB in PB picture.
85         if (mpeg2MbState.wPicCodingType != I_TYPE)
86         {
87             bool intraMB = mpeg2MbState.pMBParams->MBType.m_intraMb ? true : false;
88 
89             MOS_ZeroMemory(mpeg2MbState.sPackedMVs0, sizeof(mpeg2MbState.sPackedMVs0));
90             MOS_ZeroMemory(mpeg2MbState.sPackedMVs1, sizeof(mpeg2MbState.sPackedMVs1));
91             if ((!intraMB) && (mpeg2MbState.pMBParams->MBType.m_value &
92                 (CODEC_MPEG2_MB_MOTION_BACKWARD | CODEC_MPEG2_MB_MOTION_FORWARD)))
93             {
94                 PackMotionVectors(m_mpeg2PicParams->m_currPic.PicFlags, &mpeg2MbState);
95             }
96         }
97 
98         return MOS_STATUS_SUCCESS;
99     }
100 
PackMotionVectors(CODEC_PICTURE_FLAG pic_flag,PMHW_VDBOX_MPEG2_MB_STATE mpeg2MbState)101     void Mpeg2DecodeMbPktXe_M_Base::PackMotionVectors(CODEC_PICTURE_FLAG pic_flag, PMHW_VDBOX_MPEG2_MB_STATE mpeg2MbState)
102     {
103         CodecDecodeMpeg2MbParmas* mbParams = mpeg2MbState->pMBParams;
104 
105         uint16_t motionType = mbParams->MBType.m_motionType;
106         uint16_t intelMotionType = Mpeg2ImtNone;
107 
108         // convert to Intel Motion Type
109         if (pic_flag == PICTURE_FRAME)
110         {
111             switch (motionType)
112             {
113             case CodechalDecodeMcFrame:
114                 intelMotionType = Mpeg2ImtFrameFrame;
115                 break;
116             case CodechalDecodeMcField:
117                 intelMotionType = Mpeg2ImtFrameFiled;
118                 break;
119             case CodechalDecodeMcDmv:
120                 intelMotionType = Mpeg2ImtFrameDualPrime;
121                 break;
122             default:
123                 break;
124             }
125         }
126         else // must be field picture
127         {
128             switch (motionType)
129             {
130             case CodechalDecodeMcField:
131                 intelMotionType = Mpeg2ImtFieldField;
132                 break;
133             case CodechalDecodeMcDmv:
134                 intelMotionType = Mpeg2ImtFieldDualPrime;
135                 break;
136             case CodechalDecodeMc16x8:
137                 intelMotionType = Mpeg2Imt16x8;
138                 break;
139             default:
140                 break;
141             }
142         }
143 
144         int16_t* mv = mbParams->m_motionVectors;
145 
146         switch (intelMotionType)
147         {
148         case Mpeg2Imt16x8:
149         case Mpeg2ImtFieldField:
150         case Mpeg2ImtFrameFrame:
151         case Mpeg2ImtFieldDualPrime:
152             mpeg2MbState->sPackedMVs0[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
153             mpeg2MbState->sPackedMVs0[1] = (short)mv[CodechalDecodeRstFirstForwVert];
154             mpeg2MbState->sPackedMVs0[2] = (short)mv[CodechalDecodeRstFirstBackHorz];
155             mpeg2MbState->sPackedMVs0[3] = (short)mv[CodechalDecodeRstFirstBackVert];
156             break;
157 
158         case Mpeg2ImtFrameFiled:
159         case Mpeg2ImtFrameDualPrime:
160             mpeg2MbState->sPackedMVs0[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
161             mpeg2MbState->sPackedMVs0[1] = (short)(mv[CodechalDecodeRstFirstForwVert] >> 1);
162             mpeg2MbState->sPackedMVs0[2] = (short)mv[CodechalDecodeRstFirstBackHorz];
163             mpeg2MbState->sPackedMVs0[3] = (short)(mv[CodechalDecodeRstFirstBackVert] >> 1);
164             break;
165 
166         default:
167             break;
168         }
169 
170         switch (intelMotionType)
171         {
172         case Mpeg2Imt16x8:
173             mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstSecndForwHorz];
174             mpeg2MbState->sPackedMVs1[1] = (short)mv[CodechalDecodeRstSecndForwVert];
175             mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
176             mpeg2MbState->sPackedMVs1[3] = (short)mv[CodechalDecodeRstSecndBackVert];
177             break;
178 
179         case Mpeg2ImtFrameDualPrime:
180             mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
181             mpeg2MbState->sPackedMVs1[1] = (short)(mv[CodechalDecodeRstFirstForwVert] >> 1);
182             mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
183             mpeg2MbState->sPackedMVs1[3] = (short)(mv[CodechalDecodeRstSecndBackVert] >> 1);
184             break;
185 
186         case Mpeg2ImtFrameFiled:
187             mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstSecndForwHorz];
188             mpeg2MbState->sPackedMVs1[1] = (short)(mv[CodechalDecodeRstSecndForwVert] >> 1);
189             mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
190             mpeg2MbState->sPackedMVs1[3] = (short)(mv[CodechalDecodeRstSecndBackVert] >> 1);
191             break;
192 
193         default:
194             break;
195         }
196     }
197 
AddITObj(MHW_BATCH_BUFFER & batchBuffer,uint32_t mbIdx)198     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::AddITObj(MHW_BATCH_BUFFER& batchBuffer, uint32_t mbIdx)
199     {
200         DECODE_FUNC_CALL();
201 
202         MHW_VDBOX_MPEG2_MB_STATE mpeg2MbState;
203         DECODE_CHK_STATUS(SetMpeg2MbStateParams(mpeg2MbState, mbIdx));
204         DECODE_CHK_STATUS(m_mfxInterface->AddMfdMpeg2ITObject(
205             nullptr,
206             &batchBuffer,
207             &mpeg2MbState));
208 
209         return MOS_STATUS_SUCCESS;
210     }
211 
InsertSkippedMacroblocks(MHW_BATCH_BUFFER & batchBuffer,uint32_t mbIdx,uint16_t nextMBStart,uint16_t skippedMBs)212     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::InsertSkippedMacroblocks(
213         MHW_BATCH_BUFFER& batchBuffer,
214         uint32_t mbIdx,
215         uint16_t nextMBStart,
216         uint16_t skippedMBs)
217     {
218         DECODE_FUNC_CALL();
219 
220         MHW_VDBOX_MPEG2_MB_STATE    mpeg2MbState;
221         MOS_ZeroMemory(&mpeg2MbState, sizeof(mpeg2MbState));
222         mpeg2MbState.wPicWidthInMb = m_mpeg2BasicFeature->m_picWidthInMb;
223         mpeg2MbState.wPicHeightInMb = m_mpeg2BasicFeature->m_picHeightInMb;
224         mpeg2MbState.wPicCodingType = (uint16_t)m_mpeg2PicParams->m_pictureCodingType;
225 
226         // insert skipped Macroblocks with the first available MB params
227         mpeg2MbState.pMBParams = &(m_mpeg2BasicFeature->m_mbRecord[mbIdx].recordMbParam);
228 
229         // save the original MB params, and restore the orignal MB params when function exit.
230         CodechalDecodeRestoreData<CodecDecodeMpeg2MbParmas> MBParamsRestore(mpeg2MbState.pMBParams);
231 
232         mpeg2MbState.dwDCTLength = 0;
233         mpeg2MbState.dwITCoffDataAddrOffset = 0;
234         mpeg2MbState.pMBParams->m_codedBlockPattern = 0;
235 
236         MOS_ZeroMemory(mpeg2MbState.sPackedMVs0, sizeof(mpeg2MbState.sPackedMVs0));
237         MOS_ZeroMemory(mpeg2MbState.sPackedMVs1, sizeof(mpeg2MbState.sPackedMVs1));
238 
239         for (uint16_t i = 0; i < skippedMBs; i++)
240         {
241             mpeg2MbState.pMBParams->m_mbAddr = nextMBStart + i;
242             DECODE_CHK_STATUS(m_mfxInterface->AddMfdMpeg2ITObject(
243                 nullptr,
244                 &batchBuffer,
245                 &mpeg2MbState));
246         }
247 
248         return MOS_STATUS_SUCCESS;
249     }
250 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)251     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::CalculateCommandSize(
252         uint32_t& commandBufferSize, uint32_t& requestedPatchListSize)
253     {
254         DECODE_FUNC_CALL();
255 
256         commandBufferSize = m_mbStatesSize;
257         requestedPatchListSize = m_mbPatchListSize;
258 
259         return MOS_STATUS_SUCCESS;
260     }
261 
CalculateMbStateCommandSize()262     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::CalculateMbStateCommandSize()
263     {
264         DECODE_FUNC_CALL();
265 
266         // MB Level Commands
267         DECODE_CHK_STATUS(m_hwInterface->GetMfxPrimitiveCommandsDataSize(
268             m_mpeg2BasicFeature->m_mode,
269             &m_mbStatesSize,
270             &m_mbPatchListSize,
271             0));
272 
273         return MOS_STATUS_SUCCESS;
274     }
275 
276 }  // namespace decode
277