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