1 /* 2 * Copyright (c) 2020, 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_avc_slice_packet_m12.cpp 24 //! \brief Defines the interface for avc decode slice packet for GEN12 25 //! 26 #include "codechal_utilities.h" 27 #include "decode_avc_slice_packet_m12.h" 28 #include "mhw_vdbox_mfx_g12_X.h" 29 30 namespace decode 31 { 32 ~AvcDecodeSlcPktM12()33 AvcDecodeSlcPktM12::~AvcDecodeSlcPktM12() 34 { 35 } 36 Prepare()37 MOS_STATUS AvcDecodeSlcPktM12::Prepare() 38 { 39 DECODE_CHK_STATUS(AvcDecodeSlcPktXe_M_Base::Prepare()); 40 //update frame by frame for first valid slice 41 m_firstValidSlice = true; 42 return MOS_STATUS_SUCCESS; 43 } 44 Execute(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)45 MOS_STATUS AvcDecodeSlcPktM12::Execute(MOS_COMMAND_BUFFER& cmdBuffer, uint32_t slcIdx) 46 { 47 //AVC Slice Level Commands 48 if (m_avcPipeline->IsShortFormat()) 49 { 50 DECODE_CHK_STATUS(AddMfxSliceState(cmdBuffer, slcIdx)); 51 } 52 else 53 { 54 PCODEC_AVC_SLICE_PARAMS slc = m_avcSliceParams + slcIdx; 55 56 // Add phantom slice command if necessary 57 if (m_firstValidSlice && slc->first_mb_in_slice) 58 { 59 // ensure that slc->first_mb_in_next_slice is always non-zero for this phantom slice 60 uint16_t nextStartMbNum = slc->first_mb_in_next_slice; 61 uint16_t startMbNum = slc->first_mb_in_slice; 62 slc->first_mb_in_slice = 0; 63 slc->first_mb_in_next_slice = startMbNum; 64 65 DECODE_CHK_STATUS(AddPhantomSliceCmd(cmdBuffer, slcIdx)); 66 67 slc->first_mb_in_slice = startMbNum; 68 slc->first_mb_in_next_slice = nextStartMbNum; 69 m_firstValidSlice = false; 70 } 71 else 72 { 73 m_firstValidSlice = false; 74 } 75 76 if (!m_mfxInterface->IsAvcISlice(slc->slice_type)) 77 { 78 DECODE_CHK_STATUS(AddMfxAvcRefIdx(cmdBuffer, slcIdx)); 79 DECODE_CHK_STATUS(AddMfxAvcWeightOffset(cmdBuffer, slcIdx)); 80 } 81 else if (m_avcBasicFeature->m_useDummyReference && !m_osInterface->bSimIsActive) 82 { 83 // set dummy reference for I Frame 84 MHW_VDBOX_AVC_REF_IDX_PARAMS refIdxParams; 85 MOS_ZeroMemory(&refIdxParams, sizeof(MHW_VDBOX_AVC_REF_IDX_PARAMS)); 86 refIdxParams.bDummyReference = true; 87 DECODE_CHK_STATUS(m_mfxInterface->AddMfxAvcRefIdx(&cmdBuffer, nullptr, &refIdxParams)); 88 } 89 90 DECODE_CHK_STATUS(AddMfxAvcSlice(cmdBuffer, slcIdx)); 91 } 92 DECODE_CHK_STATUS(AddBsdObj(cmdBuffer, slcIdx)); 93 94 return MOS_STATUS_SUCCESS; 95 } 96 AddPhantomSliceCmd(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)97 MOS_STATUS AvcDecodeSlcPktM12::AddPhantomSliceCmd( 98 MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx) 99 { 100 DECODE_FUNC_CALL(); 101 102 MHW_VDBOX_AVC_SLICE_STATE avcSliceState; 103 PCODEC_AVC_SLICE_PARAMS slc = m_avcSliceParams + slcIdx; 104 105 if (!m_mfxInterface->IsAvcISlice(slc->slice_type)) 106 { 107 DECODE_CHK_STATUS(AddMfxAvcRefIdx(cmdBuffer, slcIdx)); 108 DECODE_CHK_STATUS(AddMfxAvcWeightOffset(cmdBuffer, slcIdx)); 109 } 110 111 DECODE_CHK_STATUS(SetAvcPhantomSliceParams(avcSliceState, slcIdx)); 112 //both slice state and bsd obj are needed for phantom slice decoding 113 DECODE_CHK_STATUS(m_mfxInterface->AddMfxAvcSlice(&cmdBuffer, nullptr, &avcSliceState)); 114 DECODE_CHK_STATUS(m_mfxInterface->AddMfdAvcBsdObjectCmd(&cmdBuffer, &avcSliceState)); 115 116 return MOS_STATUS_SUCCESS; 117 } 118 AddMfxSliceState(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)119 MOS_STATUS AvcDecodeSlcPktM12::AddMfxSliceState( 120 MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx) 121 { 122 DECODE_FUNC_CALL(); 123 124 MHW_VDBOX_AVC_SLICE_STATE avcSliceState; 125 126 DECODE_CHK_STATUS(SetAvcSliceStateParams(avcSliceState, slcIdx)); 127 if (!avcSliceState.bLastSlice) 128 { 129 DECODE_CHK_STATUS(m_mfxInterface->AddMfdAvcSliceAddrCmd(&cmdBuffer, &avcSliceState)); 130 } 131 132 return MOS_STATUS_SUCCESS; 133 } 134 AddMfxAvcRefIdx(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)135 MOS_STATUS AvcDecodeSlcPktM12::AddMfxAvcRefIdx( 136 MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx) 137 { 138 DECODE_FUNC_CALL(); 139 140 MHW_VDBOX_AVC_REF_IDX_PARAMS refIdxParams; 141 PCODEC_AVC_SLICE_PARAMS slc = m_avcSliceParams + slcIdx; 142 143 SetSliceRefIdxParams(refIdxParams, slcIdx); 144 DECODE_CHK_STATUS(m_mfxInterface->AddMfxAvcRefIdx(&cmdBuffer, nullptr, &refIdxParams)); 145 if (m_mfxInterface->IsAvcBSlice(slc->slice_type)) 146 { 147 refIdxParams.uiList = LIST_1; 148 refIdxParams.uiNumRefForList[LIST_1] = slc->num_ref_idx_l1_active_minus1 + 1; 149 DECODE_CHK_STATUS(m_mfxInterface->AddMfxAvcRefIdx(&cmdBuffer, nullptr, &refIdxParams)); 150 } 151 152 return MOS_STATUS_SUCCESS; 153 } 154 AddMfxAvcWeightOffset(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)155 MOS_STATUS AvcDecodeSlcPktM12::AddMfxAvcWeightOffset( 156 MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx) 157 { 158 DECODE_FUNC_CALL(); 159 160 MHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS weightOffsetParams; 161 PCODEC_AVC_SLICE_PARAMS slc = m_avcSliceParams + slcIdx; 162 163 if (m_mfxInterface->IsAvcPSlice(slc->slice_type) && 164 m_avcPicParams->pic_fields.weighted_pred_flag == 1) 165 { 166 SetSliceWeightOffsetParams(weightOffsetParams, slcIdx); 167 DECODE_CHK_STATUS(m_mfxInterface->AddMfxAvcWeightOffset(&cmdBuffer, nullptr, &weightOffsetParams)); 168 } 169 170 if (m_mfxInterface->IsAvcBSlice(slc->slice_type) && 171 m_avcPicParams->pic_fields.weighted_bipred_idc == 1) 172 { 173 SetSliceWeightOffsetParams(weightOffsetParams, slcIdx); 174 DECODE_CHK_STATUS(m_mfxInterface->AddMfxAvcWeightOffset(&cmdBuffer, nullptr, &weightOffsetParams)); 175 weightOffsetParams.uiList = 1; 176 DECODE_CHK_STATUS(m_mfxInterface->AddMfxAvcWeightOffset(&cmdBuffer, nullptr, &weightOffsetParams)); 177 } 178 179 return MOS_STATUS_SUCCESS; 180 } 181 AddMfxAvcSlice(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)182 MOS_STATUS AvcDecodeSlcPktM12::AddMfxAvcSlice( 183 MOS_COMMAND_BUFFER &cmdBuffer, uint32_t slcIdx) 184 { 185 DECODE_FUNC_CALL(); 186 187 MHW_VDBOX_AVC_SLICE_STATE avcSliceState; 188 DECODE_CHK_STATUS(SetAvcSliceStateParams(avcSliceState, slcIdx)); 189 DECODE_CHK_STATUS(m_mfxInterface->AddMfxAvcSlice(&cmdBuffer, nullptr, &avcSliceState)); 190 191 return MOS_STATUS_SUCCESS; 192 } 193 AddBsdObj(MOS_COMMAND_BUFFER & cmdBuffer,uint32_t slcIdx)194 MOS_STATUS AvcDecodeSlcPktM12::AddBsdObj( 195 MOS_COMMAND_BUFFER &cmdBuffer, 196 uint32_t slcIdx) 197 { 198 DECODE_FUNC_CALL(); 199 200 MHW_VDBOX_AVC_SLICE_STATE avcSliceState; 201 DECODE_CHK_STATUS(SetAvcSliceStateParams(avcSliceState, slcIdx)); 202 DECODE_CHK_STATUS(m_mfxInterface->AddMfdAvcBsdObjectCmd(&cmdBuffer, &avcSliceState)); 203 204 return MOS_STATUS_SUCCESS; 205 } 206 } 207