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         CodecDecodeMpeg2MbParams* 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         mpeg2MbState.dwITCoffDataAddrOffset = mb->m_mbDataLoc << 2;  // byte offset
85 
86         // only for MB in PB picture.
87         if (mpeg2MbState.wPicCodingType != I_TYPE)
88         {
89             bool intraMB = mpeg2MbState.pMBParams->MBType.m_intraMb ? true : false;
90 
91             MOS_ZeroMemory(mpeg2MbState.sPackedMVs0, sizeof(mpeg2MbState.sPackedMVs0));
92             MOS_ZeroMemory(mpeg2MbState.sPackedMVs1, sizeof(mpeg2MbState.sPackedMVs1));
93             if ((!intraMB) && (mpeg2MbState.pMBParams->MBType.m_value &
94                 (CODEC_MPEG2_MB_MOTION_BACKWARD | CODEC_MPEG2_MB_MOTION_FORWARD)))
95             {
96                 PackMotionVectors(m_mpeg2PicParams->m_currPic.PicFlags, &mpeg2MbState);
97             }
98         }
99 
100         return MOS_STATUS_SUCCESS;
101     }
102 
PackMotionVectors(CODEC_PICTURE_FLAG pic_flag,PMHW_VDBOX_MPEG2_MB_STATE mpeg2MbState)103     void Mpeg2DecodeMbPktXe_M_Base::PackMotionVectors(CODEC_PICTURE_FLAG pic_flag, PMHW_VDBOX_MPEG2_MB_STATE mpeg2MbState)
104     {
105         CodecDecodeMpeg2MbParams* mbParams = mpeg2MbState->pMBParams;
106 
107         uint16_t motionType = mbParams->MBType.m_motionType;
108         uint16_t intelMotionType = Mpeg2ImtNone;
109 
110         // convert to Intel Motion Type
111         if (pic_flag == PICTURE_FRAME)
112         {
113             switch (motionType)
114             {
115             case CodechalDecodeMcFrame:
116                 intelMotionType = Mpeg2ImtFrameFrame;
117                 break;
118             case CodechalDecodeMcField:
119                 intelMotionType = Mpeg2ImtFrameFiled;
120                 break;
121             case CodechalDecodeMcDmv:
122                 intelMotionType = Mpeg2ImtFrameDualPrime;
123                 break;
124             default:
125                 break;
126             }
127         }
128         else // must be field picture
129         {
130             switch (motionType)
131             {
132             case CodechalDecodeMcField:
133                 intelMotionType = Mpeg2ImtFieldField;
134                 break;
135             case CodechalDecodeMcDmv:
136                 intelMotionType = Mpeg2ImtFieldDualPrime;
137                 break;
138             case CodechalDecodeMc16x8:
139                 intelMotionType = Mpeg2Imt16x8;
140                 break;
141             default:
142                 break;
143             }
144         }
145 
146         int16_t* mv = mbParams->m_motionVectors;
147 
148         switch (intelMotionType)
149         {
150         case Mpeg2Imt16x8:
151         case Mpeg2ImtFieldField:
152         case Mpeg2ImtFrameFrame:
153         case Mpeg2ImtFieldDualPrime:
154             mpeg2MbState->sPackedMVs0[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
155             mpeg2MbState->sPackedMVs0[1] = (short)mv[CodechalDecodeRstFirstForwVert];
156             mpeg2MbState->sPackedMVs0[2] = (short)mv[CodechalDecodeRstFirstBackHorz];
157             mpeg2MbState->sPackedMVs0[3] = (short)mv[CodechalDecodeRstFirstBackVert];
158             break;
159 
160         case Mpeg2ImtFrameFiled:
161         case Mpeg2ImtFrameDualPrime:
162             mpeg2MbState->sPackedMVs0[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
163             mpeg2MbState->sPackedMVs0[1] = (short)(mv[CodechalDecodeRstFirstForwVert] >> 1);
164             mpeg2MbState->sPackedMVs0[2] = (short)mv[CodechalDecodeRstFirstBackHorz];
165             mpeg2MbState->sPackedMVs0[3] = (short)(mv[CodechalDecodeRstFirstBackVert] >> 1);
166             break;
167 
168         default:
169             break;
170         }
171 
172         switch (intelMotionType)
173         {
174         case Mpeg2Imt16x8:
175             mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstSecndForwHorz];
176             mpeg2MbState->sPackedMVs1[1] = (short)mv[CodechalDecodeRstSecndForwVert];
177             mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
178             mpeg2MbState->sPackedMVs1[3] = (short)mv[CodechalDecodeRstSecndBackVert];
179             break;
180 
181         case Mpeg2ImtFrameDualPrime:
182             mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstFirstForwHorz];
183             mpeg2MbState->sPackedMVs1[1] = (short)(mv[CodechalDecodeRstFirstForwVert] >> 1);
184             mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
185             mpeg2MbState->sPackedMVs1[3] = (short)(mv[CodechalDecodeRstSecndBackVert] >> 1);
186             break;
187 
188         case Mpeg2ImtFrameFiled:
189             mpeg2MbState->sPackedMVs1[0] = (short)mv[CodechalDecodeRstSecndForwHorz];
190             mpeg2MbState->sPackedMVs1[1] = (short)(mv[CodechalDecodeRstSecndForwVert] >> 1);
191             mpeg2MbState->sPackedMVs1[2] = (short)mv[CodechalDecodeRstSecndBackHorz];
192             mpeg2MbState->sPackedMVs1[3] = (short)(mv[CodechalDecodeRstSecndBackVert] >> 1);
193             break;
194 
195         default:
196             break;
197         }
198     }
199 
AddITObj(MHW_BATCH_BUFFER & batchBuffer,uint32_t mbIdx)200     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::AddITObj(MHW_BATCH_BUFFER& batchBuffer, uint32_t mbIdx)
201     {
202         DECODE_FUNC_CALL();
203 
204         MHW_VDBOX_MPEG2_MB_STATE mpeg2MbState;
205         DECODE_CHK_STATUS(SetMpeg2MbStateParams(mpeg2MbState, mbIdx));
206         DECODE_CHK_STATUS(m_mfxInterface->AddMfdMpeg2ITObject(
207             nullptr,
208             &batchBuffer,
209             &mpeg2MbState));
210 
211         return MOS_STATUS_SUCCESS;
212     }
213 
InsertSkippedMacroblocks(MHW_BATCH_BUFFER & batchBuffer,uint32_t mbIdx,uint16_t nextMBStart,uint16_t skippedMBs)214     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::InsertSkippedMacroblocks(
215         MHW_BATCH_BUFFER& batchBuffer,
216         uint32_t mbIdx,
217         uint16_t nextMBStart,
218         uint16_t skippedMBs)
219     {
220         DECODE_FUNC_CALL();
221 
222         MHW_VDBOX_MPEG2_MB_STATE    mpeg2MbState;
223         MOS_ZeroMemory(&mpeg2MbState, sizeof(mpeg2MbState));
224         mpeg2MbState.wPicWidthInMb = m_mpeg2BasicFeature->m_picWidthInMb;
225         mpeg2MbState.wPicHeightInMb = m_mpeg2BasicFeature->m_picHeightInMb;
226         mpeg2MbState.wPicCodingType = (uint16_t)m_mpeg2PicParams->m_pictureCodingType;
227 
228         // insert skipped Macroblocks with the first available MB params
229         mpeg2MbState.pMBParams = &(m_mpeg2BasicFeature->m_mbRecord[mbIdx].recordMbParam);
230 
231         // save the original MB params, and restore the orignal MB params when function exit.
232         CodechalDecodeRestoreData<CodecDecodeMpeg2MbParams> MBParamsRestore(mpeg2MbState.pMBParams);
233 
234         mpeg2MbState.dwDCTLength = 0;
235         mpeg2MbState.dwITCoffDataAddrOffset = 0;
236         mpeg2MbState.pMBParams->m_codedBlockPattern = 0;
237 
238         MOS_ZeroMemory(mpeg2MbState.sPackedMVs0, sizeof(mpeg2MbState.sPackedMVs0));
239         MOS_ZeroMemory(mpeg2MbState.sPackedMVs1, sizeof(mpeg2MbState.sPackedMVs1));
240 
241         for (uint16_t i = 0; i < skippedMBs; i++)
242         {
243             mpeg2MbState.pMBParams->m_mbAddr = nextMBStart + i;
244             DECODE_CHK_STATUS(m_mfxInterface->AddMfdMpeg2ITObject(
245                 nullptr,
246                 &batchBuffer,
247                 &mpeg2MbState));
248         }
249 
250         return MOS_STATUS_SUCCESS;
251     }
252 
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)253     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::CalculateCommandSize(
254         uint32_t& commandBufferSize, uint32_t& requestedPatchListSize)
255     {
256         DECODE_FUNC_CALL();
257 
258         commandBufferSize = m_mbStatesSize;
259         requestedPatchListSize = m_mbPatchListSize;
260 
261         return MOS_STATUS_SUCCESS;
262     }
263 
CalculateMbStateCommandSize()264     MOS_STATUS Mpeg2DecodeMbPktXe_M_Base::CalculateMbStateCommandSize()
265     {
266         DECODE_FUNC_CALL();
267 
268         // MB Level Commands
269         DECODE_CHK_STATUS(m_hwInterface->GetMfxPrimitiveCommandsDataSize(
270             m_mpeg2BasicFeature->m_mode,
271             &m_mbStatesSize,
272             &m_mbPatchListSize,
273             0));
274 
275         return MOS_STATUS_SUCCESS;
276     }
277 
278 }  // namespace decode
279