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_vp8_packet.cpp
24 //! \brief Defines the interface for vp8 decode packet
25 //!
26 #include "decode_vp8_packet.h"
27 #include "decode_status_report_defs.h"
28 #include "decode_predication_packet.h"
29 #include "decode_marker_packet.h"
30
31 namespace decode
32 {
Vp8DecodePkt(MediaPipeline * pipeline,MediaTask * task,CodechalHwInterfaceNext * hwInterface)33 Vp8DecodePkt::Vp8DecodePkt(MediaPipeline *pipeline, MediaTask *task, CodechalHwInterfaceNext *hwInterface)
34 : CmdPacket(task)
35 {
36 if (pipeline != nullptr)
37 {
38 m_statusReport = pipeline->GetStatusReportInstance();
39 m_featureManager = pipeline->GetFeatureManager();
40 m_vp8Pipeline = dynamic_cast<Vp8Pipeline *>(pipeline);
41 }
42 if (hwInterface != nullptr)
43 {
44 m_hwInterface = hwInterface;
45 m_miItf = std::static_pointer_cast<mhw::mi::Itf>(hwInterface->GetMiInterfaceNext());
46 m_osInterface = hwInterface->GetOsInterface();
47 }
48 }
49
Init()50 MOS_STATUS Vp8DecodePkt::Init()
51 {
52 DECODE_FUNC_CALL();
53 DECODE_CHK_NULL(m_statusReport);
54 DECODE_CHK_NULL(m_featureManager);
55 DECODE_CHK_NULL(m_vp8Pipeline);
56 DECODE_CHK_NULL(m_osInterface);
57 DECODE_CHK_NULL(m_miItf);
58
59 DECODE_CHK_STATUS(CmdPacket::Init());
60
61 DecodeSubPacket *subPacket = m_vp8Pipeline->GetSubPacket(DecodePacketId(m_vp8Pipeline, vp8PictureSubPacketId));
62 m_picturePkt = dynamic_cast<Vp8DecodePicPkt *>(subPacket);
63 DECODE_CHK_NULL(m_picturePkt);
64
65 subPacket = m_vp8Pipeline->GetSubPacket(DecodePacketId(m_vp8Pipeline, vp8SliceSubPacketId));
66 m_slicePkt = dynamic_cast<Vp8DecodeSlcPkt *>(subPacket);
67 DECODE_CHK_NULL(m_slicePkt);
68
69 m_vp8BasicFeature = dynamic_cast<Vp8BasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
70 DECODE_CHK_NULL(m_vp8BasicFeature);
71
72 m_allocator = m_vp8Pipeline->GetDecodeAllocator();
73 DECODE_CHK_NULL(m_allocator);
74
75 DECODE_CHK_STATUS(m_statusReport->RegistObserver(this));
76
77 return MOS_STATUS_SUCCESS;
78 }
79
Prepare()80 MOS_STATUS Vp8DecodePkt::Prepare()
81 {
82 DECODE_FUNC_CALL();
83
84 DECODE_CHK_NULL(m_vp8BasicFeature);
85 DECODE_CHK_NULL(m_vp8BasicFeature->m_vp8PicParams);
86 m_vp8PicParams = m_vp8BasicFeature->m_vp8PicParams;
87
88 return MOS_STATUS_SUCCESS;
89 }
90
Destroy()91 MOS_STATUS Vp8DecodePkt::Destroy()
92 {
93 m_statusReport->UnregistObserver(this);
94 return MOS_STATUS_SUCCESS;
95 }
96
SetPerfTag(CODECHAL_MODE mode,uint16_t picCodingType)97 void Vp8DecodePkt::SetPerfTag(CODECHAL_MODE mode, uint16_t picCodingType)
98 {
99 DECODE_FUNC_CALL();
100
101 uint16_t perfTag = ((mode << 4) & 0xF0) | (picCodingType & 0xF);
102 m_osInterface->pfnIncPerfFrameID(m_osInterface);
103 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag);
104 m_osInterface->pfnResetPerfBufferID(m_osInterface);
105 }
106
IsPrologRequired()107 bool Vp8DecodePkt::IsPrologRequired()
108 {
109 return true;
110 }
111
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)112 MOS_STATUS Vp8DecodePkt::AddForceWakeup(MOS_COMMAND_BUFFER &cmdBuffer)
113 {
114 DECODE_FUNC_CALL();
115
116 auto &par = m_miItf->GETPAR_MI_FORCE_WAKEUP();
117 MOS_ZeroMemory(&par, sizeof(par));
118 par.bMFXPowerWellControl = true;
119 par.bMFXPowerWellControlMask = true;
120 par.bHEVCPowerWellControl = false;
121 par.bHEVCPowerWellControlMask = true;
122
123 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FORCE_WAKEUP(&cmdBuffer));
124 return MOS_STATUS_SUCCESS;
125 }
126
SendPrologWithFrameTracking(MOS_COMMAND_BUFFER & cmdBuffer,bool frameTrackingRequested)127 MOS_STATUS Vp8DecodePkt::SendPrologWithFrameTracking(MOS_COMMAND_BUFFER &cmdBuffer, bool frameTrackingRequested)
128 {
129 DecodeSubPacket *subPacket = m_vp8Pipeline->GetSubPacket(DecodePacketId(m_vp8Pipeline, markerSubPacketId));
130 DecodeMarkerPkt *makerPacket = dynamic_cast<DecodeMarkerPkt *>(subPacket);
131 DECODE_CHK_NULL(makerPacket);
132 DECODE_CHK_STATUS(makerPacket->Execute(cmdBuffer));
133
134 #ifdef _MMC_SUPPORTED
135 m_mmcState = m_vp8Pipeline->GetMmcState();
136 bool isMmcEnabled = (m_mmcState != nullptr && m_mmcState->IsMmcEnabled());
137 if (isMmcEnabled)
138 {
139 DECODE_CHK_STATUS(m_mmcState->SendPrologCmd(&cmdBuffer, false));
140 }
141 #endif
142
143 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
144 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
145 genericPrologParams.pOsInterface = m_osInterface;
146 genericPrologParams.pvMiInterface = nullptr;
147 #ifdef _MMC_SUPPORTED
148 genericPrologParams.bMmcEnabled = isMmcEnabled;
149 #endif
150
151 DECODE_CHK_STATUS(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
152
153 subPacket = m_vp8Pipeline->GetSubPacket(DecodePacketId(m_vp8Pipeline, predicationSubPacketId));
154 DecodePredicationPkt *predicationPacket = dynamic_cast<DecodePredicationPkt *>(subPacket);
155 DECODE_CHK_NULL(predicationPacket);
156 DECODE_CHK_STATUS(predicationPacket->Execute(cmdBuffer));
157
158 return MOS_STATUS_SUCCESS;
159 }
160
MiFlush(MOS_COMMAND_BUFFER & cmdBuffer)161 MOS_STATUS Vp8DecodePkt::MiFlush(MOS_COMMAND_BUFFER &cmdBuffer)
162 {
163 DECODE_FUNC_CALL();
164
165 auto &par = m_miItf->GETPAR_MI_FLUSH_DW();
166 MOS_ZeroMemory(&par, sizeof(par));
167 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
168
169 return MOS_STATUS_SUCCESS;
170 }
171
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)172 MOS_STATUS Vp8DecodePkt::Completed(void *mfxStatus, void *rcsStatus, void *statusReport)
173 {
174 DECODE_FUNC_CALL();
175
176 DECODE_CHK_NULL(mfxStatus);
177 DECODE_CHK_NULL(statusReport);
178
179 DecodeStatusMfx * decodeStatusMfx = (DecodeStatusMfx *)mfxStatus;
180 DecodeStatusReportData *statusReportData = (DecodeStatusReportData *)statusReport;
181
182 auto hcpInterface = m_hwInterface->GetHcpInterfaceNext();
183 if (hcpInterface != nullptr)
184 {
185 if ((decodeStatusMfx->m_mmioErrorStatusReg & hcpInterface->GetHcpCabacErrorFlagsMask()) != 0)
186 {
187 statusReportData->codecStatus = CODECHAL_STATUS_ERROR;
188 statusReportData->numMbsAffected = (decodeStatusMfx->m_mmioMBCountReg & 0xFFFC0000) >> 18;
189 }
190
191 statusReportData->frameCrc = decodeStatusMfx->m_mmioFrameCrcReg;
192 }
193
194 DECODE_VERBOSEMESSAGE("Index = %d", statusReportData->currDecodedPic.FrameIdx);
195 DECODE_VERBOSEMESSAGE("FrameCrc = 0x%x", statusReportData->frameCrc);
196
197 return MOS_STATUS_SUCCESS;
198 }
199
ReadMfxStatus(MediaStatusReport * statusReport,MOS_COMMAND_BUFFER & cmdBuffer)200 MOS_STATUS Vp8DecodePkt::ReadMfxStatus(MediaStatusReport* statusReport, MOS_COMMAND_BUFFER& cmdBuffer)
201 {
202 DECODE_FUNC_CALL();
203
204 DECODE_CHK_NULL(statusReport);
205
206 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
207 MOS_RESOURCE* osResource = nullptr;
208 uint32_t offset = 0;
209
210 auto &par = m_miItf->GETPAR_MI_STORE_REGISTER_MEM();
211 MOS_ZeroMemory(&par, sizeof(par));
212
213 DECODE_CHK_NULL(m_hwInterface->GetVdencInterfaceNext());
214 auto mmioRegisters = m_hwInterface->GetVdencInterfaceNext()->GetMmioRegisters(MHW_VDBOX_NODE_1);
215
216 DECODE_CHK_STATUS(statusReport->GetAddress(decode::DecodeStatusReportType::DecErrorStatusOffset, osResource, offset));
217
218 par.presStoreBuffer = osResource;
219 par.dwOffset = offset;
220 par.dwRegister = mmioRegisters->mfxErrorFlagsRegOffset;
221 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
222
223
224 DECODE_CHK_STATUS(statusReport->GetAddress(decode::DecodeStatusReportType::DecMBCountOffset, osResource, offset));
225
226 par.presStoreBuffer = osResource;
227 par.dwOffset = offset;
228 par.dwRegister = mmioRegisters->mfxMBCountRegOffset;
229 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
230
231 return MOS_STATUS_SUCCESS;
232 }
233
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)234 MOS_STATUS Vp8DecodePkt::StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer)
235 {
236 DECODE_FUNC_CALL();
237 DECODE_CHK_NULL(cmdBuffer);
238 DECODE_CHK_STATUS(MediaPacket::StartStatusReportNext(srType, cmdBuffer));
239
240 SetPerfTag(CODECHAL_DECODE_MODE_VP8VLD, m_vp8BasicFeature->m_pictureCodingType);
241 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
242 DECODE_CHK_NULL(perfProfiler);
243 DECODE_CHK_STATUS(perfProfiler->AddPerfCollectStartCmd(
244 (void *)m_vp8Pipeline, m_osInterface, m_miItf, cmdBuffer));
245
246 return MOS_STATUS_SUCCESS;
247 }
248
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)249 MOS_STATUS Vp8DecodePkt::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER *cmdBuffer)
250 {
251 DECODE_FUNC_CALL();
252 DECODE_CHK_NULL(cmdBuffer);
253 DECODE_CHK_STATUS(ReadMfxStatus(m_statusReport, *cmdBuffer));
254 DECODE_CHK_STATUS(MediaPacket::EndStatusReportNext(srType, cmdBuffer));
255
256 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
257 DECODE_CHK_NULL(perfProfiler);
258 DECODE_CHK_STATUS(perfProfiler->AddPerfCollectEndCmd(
259 (void *)m_vp8Pipeline, m_osInterface, m_miItf, cmdBuffer));
260
261 // Add Mi flush here to ensure end status tag flushed to memory earlier than completed count
262 DECODE_CHK_STATUS(MiFlush(*cmdBuffer));
263
264 return MOS_STATUS_SUCCESS;
265 }
266
267 } // namespace decode