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_jpeg_packet.cpp
24 //! \brief Defines the interface for jpeg decode packet.
25 //!
26
27 #include "decode_jpeg_packet.h"
28 #include "decode_utils.h"
29 #include "decode_marker_packet.h"
30 #include "decode_status_report_defs.h"
31 #include "decode_predication_packet.h"
32 #include "codechal_debug.h"
33
34 namespace decode {
35
Init()36 MOS_STATUS JpegDecodePkt::Init()
37 {
38 DECODE_FUNC_CALL();
39 DECODE_CHK_NULL(m_miItf);
40 DECODE_CHK_NULL(m_statusReport);
41 DECODE_CHK_NULL(m_featureManager);
42 DECODE_CHK_NULL(m_jpegPipeline);
43 DECODE_CHK_NULL(m_osInterface);
44
45 DECODE_CHK_STATUS(CmdPacket::Init());
46
47 m_jpegBasicFeature = dynamic_cast<JpegBasicFeature*>(m_featureManager->GetFeature(FeatureIDs::basicFeature));
48 DECODE_CHK_NULL(m_jpegBasicFeature);
49
50 m_allocator = m_jpegPipeline->GetDecodeAllocator();
51 DECODE_CHK_NULL(m_allocator);
52
53 DECODE_CHK_STATUS(m_statusReport->RegistObserver(this));
54
55 DecodeSubPacket* subPacket = m_jpegPipeline->GetSubPacket(DecodePacketId(m_jpegPipeline, jpegPictureSubPacketId));
56 m_picturePkt = dynamic_cast<JpegDecodePicPkt*>(subPacket);
57 DECODE_CHK_NULL(m_picturePkt);
58 DECODE_CHK_STATUS(m_picturePkt->CalculateCommandSize(m_pictureStatesSize, m_picturePatchListSize));
59
60 return MOS_STATUS_SUCCESS;
61 }
62
Prepare()63 MOS_STATUS JpegDecodePkt::Prepare()
64 {
65 DECODE_FUNC_CALL();
66
67 DECODE_CHK_NULL(m_jpegBasicFeature->m_jpegPicParams);
68 m_jpegPicParams = m_jpegBasicFeature->m_jpegPicParams;
69
70 return MOS_STATUS_SUCCESS;
71 }
72
Destroy()73 MOS_STATUS JpegDecodePkt::Destroy()
74 {
75 m_statusReport->UnregistObserver(this);
76
77 return MOS_STATUS_SUCCESS;
78 }
79
SetPerfTag(CODECHAL_MODE mode,uint16_t picCodingType)80 void JpegDecodePkt::SetPerfTag(CODECHAL_MODE mode, uint16_t picCodingType)
81 {
82 DECODE_FUNC_CALL();
83
84 uint16_t perfTag = ((mode << 4) & 0xF0) | (picCodingType & 0xF);
85 m_osInterface->pfnIncPerfFrameID(m_osInterface);
86 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag);
87 m_osInterface->pfnResetPerfBufferID(m_osInterface);
88 }
89
IsPrologRequired()90 bool JpegDecodePkt::IsPrologRequired()
91 {
92 return true;
93 }
94
AddForceWakeup(MOS_COMMAND_BUFFER & cmdBuffer)95 MOS_STATUS JpegDecodePkt::AddForceWakeup(MOS_COMMAND_BUFFER& cmdBuffer)
96 {
97 DECODE_FUNC_CALL();
98
99 auto &par = m_miItf->GETPAR_MI_FORCE_WAKEUP();
100 par = {};
101 par.bMFXPowerWellControl = true;
102 par.bMFXPowerWellControlMask = true;
103 par.bHEVCPowerWellControl = false;
104 par.bHEVCPowerWellControlMask = true;
105
106 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FORCE_WAKEUP(&cmdBuffer));
107
108 return MOS_STATUS_SUCCESS;
109 }
110
SendPrologWithFrameTracking(MOS_COMMAND_BUFFER & cmdBuffer,bool frameTrackingRequested)111 MOS_STATUS JpegDecodePkt::SendPrologWithFrameTracking(MOS_COMMAND_BUFFER& cmdBuffer, bool frameTrackingRequested)
112 {
113 DECODE_FUNC_CALL();
114
115 DecodeSubPacket* subPacket = m_jpegPipeline->GetSubPacket(DecodePacketId(m_jpegPipeline, markerSubPacketId));
116 DecodeMarkerPkt *makerPacket = dynamic_cast<DecodeMarkerPkt*>(subPacket);
117 DECODE_CHK_NULL(makerPacket);
118 DECODE_CHK_STATUS(makerPacket->Execute(cmdBuffer));
119
120 #ifdef _MMC_SUPPORTED
121 m_mmcState = m_jpegPipeline->GetMmcState();
122 bool isMmcEnabled = (m_mmcState != nullptr && m_mmcState->IsMmcEnabled());
123 if (isMmcEnabled)
124 {
125 DECODE_CHK_STATUS(m_mmcState->SendPrologCmd(&cmdBuffer, false));
126 }
127 #endif
128
129 MHW_GENERIC_PROLOG_PARAMS genericPrologParams;
130 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams));
131 genericPrologParams.pOsInterface = m_osInterface;
132 genericPrologParams.pvMiInterface = nullptr;
133
134 #ifdef _MMC_SUPPORTED
135 genericPrologParams.bMmcEnabled = isMmcEnabled;
136 #endif
137
138 DECODE_CHK_STATUS(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf));
139
140 subPacket = m_jpegPipeline->GetSubPacket(DecodePacketId(m_jpegPipeline, predicationSubPacketId));
141 DecodePredicationPkt *predicationPacket = dynamic_cast<DecodePredicationPkt*>(subPacket);
142 DECODE_CHK_NULL(predicationPacket);
143 DECODE_CHK_STATUS(predicationPacket->Execute(cmdBuffer));
144
145 return MOS_STATUS_SUCCESS;
146 }
147
MiFlush(MOS_COMMAND_BUFFER & cmdBuffer)148 MOS_STATUS JpegDecodePkt::MiFlush(MOS_COMMAND_BUFFER & cmdBuffer)
149 {
150 DECODE_FUNC_CALL();
151
152 auto &par = m_miItf->GETPAR_MI_FLUSH_DW();
153 par = {};
154 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_FLUSH_DW(&cmdBuffer));
155
156 return MOS_STATUS_SUCCESS;
157 }
158
Completed(void * mfxStatus,void * rcsStatus,void * statusReport)159 MOS_STATUS JpegDecodePkt::Completed(void *mfxStatus, void *rcsStatus, void *statusReport)
160 {
161 DECODE_FUNC_CALL();
162
163 DecodeStatusMfx *decodeStatusMfx = (DecodeStatusMfx *)mfxStatus;
164 DecodeStatusReportData *statusReportData = (DecodeStatusReportData *)statusReport;
165 auto mfxItf = std::static_pointer_cast<mhw::vdbox::mfx::Itf>(m_hwInterface->GetMfxInterfaceNext());
166
167 if (mfxItf && decodeStatusMfx && statusReportData)
168 {
169 if ((decodeStatusMfx->m_mmioErrorStatusReg & mfxItf->GetMfxErrorFlagsMask()) != 0)
170 {
171 statusReportData->codecStatus = CODECHAL_STATUS_ERROR;
172 statusReportData->numMbsAffected = decodeStatusMfx->m_mmioMBCountReg & 0xFFFF;
173 }
174 DECODE_VERBOSEMESSAGE("Current Frame Index = %d", statusReportData->currDecodedPic.FrameIdx);
175 }
176
177 return MOS_STATUS_SUCCESS;
178 }
179
CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)180 MOS_STATUS JpegDecodePkt::CalculateCommandSize(uint32_t &commandBufferSize, uint32_t &requestedPatchListSize)
181 {
182 commandBufferSize = CalculateCommandBufferSize();
183 requestedPatchListSize = CalculatePatchListSize();
184
185 return MOS_STATUS_SUCCESS;
186 }
187
CalculateCommandBufferSize()188 uint32_t JpegDecodePkt::CalculateCommandBufferSize()
189 {
190 // slice/macroblock level commands are put into 2nd level BB.
191 return (m_pictureStatesSize + COMMAND_BUFFER_RESERVED_SPACE);
192 }
193
CalculatePatchListSize()194 uint32_t JpegDecodePkt::CalculatePatchListSize()
195 {
196 if (!m_osInterface->bUsesPatchList)
197 {
198 return 0;
199 }
200
201 return m_picturePatchListSize;
202 }
203
ReadMfxStatus(MediaStatusReport * statusReport,MOS_COMMAND_BUFFER & cmdBuffer)204 MOS_STATUS JpegDecodePkt::ReadMfxStatus(MediaStatusReport* statusReport, MOS_COMMAND_BUFFER& cmdBuffer)
205 {
206 DECODE_FUNC_CALL();
207
208 DECODE_CHK_NULL(statusReport);
209
210 MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
211 MOS_RESOURCE* osResource = nullptr;
212 uint32_t offset = 0;
213
214 auto &par = m_miItf->GETPAR_MI_STORE_REGISTER_MEM();
215 par = {};
216
217 DECODE_CHK_NULL(m_hwInterface->GetVdencInterfaceNext());
218 auto mmioRegisters = m_hwInterface->GetVdencInterfaceNext()->GetMmioRegisters(MHW_VDBOX_NODE_1);
219
220 DECODE_CHK_STATUS(statusReport->GetAddress(decode::DecodeStatusReportType::DecErrorStatusOffset, osResource, offset));
221 par.presStoreBuffer = osResource;
222 par.dwOffset = offset;
223 par.dwRegister = mmioRegisters->mfxErrorFlagsRegOffset;
224
225 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
226
227 DECODE_CHK_STATUS(statusReport->GetAddress(decode::DecodeStatusReportType::DecMBCountOffset, osResource, offset));
228 par.presStoreBuffer = osResource;
229 par.dwOffset = offset;
230 par.dwRegister = mmioRegisters->mfxMBCountRegOffset;
231
232 DECODE_CHK_STATUS(m_miItf->ADDCMD_MI_STORE_REGISTER_MEM(&cmdBuffer));
233
234 return MOS_STATUS_SUCCESS;
235 }
236
StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)237 MOS_STATUS JpegDecodePkt::StartStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
238 {
239 DECODE_FUNC_CALL();
240
241 DECODE_CHK_STATUS(MediaPacket::StartStatusReportNext(srType, cmdBuffer));
242
243 // no frame type for Jpeg decode, use I as default value here
244 SetPerfTag(CODECHAL_DECODE_MODE_JPEG, I_TYPE);
245
246 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
247 DECODE_CHK_NULL(perfProfiler);
248 DECODE_CHK_STATUS(perfProfiler->AddPerfCollectStartCmd(
249 (void*)m_jpegPipeline, m_osInterface, m_miItf, cmdBuffer));
250
251 return MOS_STATUS_SUCCESS;
252 }
253
EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)254 MOS_STATUS JpegDecodePkt::EndStatusReport(uint32_t srType, MOS_COMMAND_BUFFER* cmdBuffer)
255 {
256 DECODE_FUNC_CALL();
257
258 DECODE_CHK_NULL(cmdBuffer);
259 DECODE_CHK_STATUS(ReadMfxStatus(m_statusReport, *cmdBuffer));
260 DECODE_CHK_STATUS(MediaPacket::EndStatusReportNext(srType, cmdBuffer));
261
262 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance();
263 DECODE_CHK_NULL(perfProfiler);
264 DECODE_CHK_STATUS(perfProfiler->AddPerfCollectEndCmd(
265 (void*)m_jpegPipeline, m_osInterface, m_miItf, cmdBuffer));
266
267 DECODE_CHK_STATUS(MiFlush(*cmdBuffer));
268
269 return MOS_STATUS_SUCCESS;
270 }
271
272 }
273