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