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