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