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