1 /*
2 * Copyright (c) 2022, 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 codechal_decoder.cpp
24 //! \brief Implements the decode interface for CodecHal.
25 //! \details The decode interface is further sub-divided by standard, this file is for the base interface which is shared by all decode standards.
26 //!
27
28 #include "codechal_debug.h"
29
30 #if USE_CODECHAL_DEBUG_TOOL
31 #include <sstream>
32 #include <fstream>
33 #include "codechal_debug.h"
34 #endif
35
36 #if USE_CODECHAL_DEBUG_TOOL
37 #include "codechal_debug_config_manager.h"
38 #include "codechal_encoder_base.h"
39 #include <iomanip>
40
Initialize(CodechalHwInterface * hwInterface,CODECHAL_FUNCTION codecFunction,MediaCopyWrapper * mediaCopyWrapper)41 MOS_STATUS CodechalDebugInterface::Initialize(
42 CodechalHwInterface *hwInterface,
43 CODECHAL_FUNCTION codecFunction,
44 MediaCopyWrapper *mediaCopyWrapper)
45 {
46 CODECHAL_DEBUG_FUNCTION_ENTER;
47
48 CODECHAL_DEBUG_CHK_NULL(hwInterface);
49 m_hwInterface = hwInterface;
50 m_codecFunction = codecFunction;
51 m_osInterface = m_hwInterface->GetOsInterface();
52 m_cpInterface = m_hwInterface->GetCpInterface();
53 m_miInterface = m_hwInterface->GetMiInterface();
54
55 CODECHAL_DEBUG_CHK_NULL(m_osInterface);
56 m_userSettingPtr = m_osInterface->pfnGetUserSettingInstance(m_osInterface);
57 CODECHAL_DEBUG_CHK_STATUS(InitializeUserSetting());
58
59 //dump loctaion is codechaldump
60 MediaDebugInterface::SetOutputFilePath();
61
62 m_configMgr = MOS_New(CodecDebugConfigMgr, this, m_codecFunction, m_outputFilePath);
63 CODECHAL_DEBUG_CHK_NULL(m_configMgr);
64 CODECHAL_DEBUG_CHK_STATUS(m_configMgr->ParseConfig(m_osInterface->pOsContext));
65
66 MediaDebugInterface::InitDumpLocation();
67
68 if (m_hwInterface->GetPlatform().eProductFamily < IGFX_DG2)
69 {
70 m_dumpYUVSurface = m_dumpYUVSurfaceLegacy;
71 m_dumpBuffer = m_dumpBufferLegacy;
72 }
73
74 #if (_DEBUG || _RELEASE_INTERNAL)
75 {
76 MediaUserSetting::Value outValue;
77 ReadUserSettingForDebug(
78 m_userSettingPtr,
79 outValue,
80 __MEDIA_USER_FEATURE_ENABLE_HW_DEBUG_HOOKS_DEBUG,
81 MediaUserSetting::Group::Device, 0, true);
82 m_enableHwDebugHooks = outValue.Get<bool>();
83 }
84 CheckGoldenReferenceExist();
85 if (m_enableHwDebugHooks && m_goldenReferenceExist)
86 {
87 LoadGoldenReference();
88 }
89
90 {
91 MediaUserSetting::Value outValue;
92 ReadUserSettingForDebug(
93 m_userSettingPtr,
94 outValue,
95 __MEDIA_USER_FEATURE_VALUE_CODECHAL_FRAME_NUMBER_TO_STOP_DEBUG,
96 MediaUserSetting::Group::Device,
97 -1,
98 true);
99 m_stopFrameNumber = outValue.Get<int32_t>();
100 }
101
102 {
103 MediaUserSetting::Value outValue;
104 ReadUserSettingForDebug(
105 m_userSettingPtr,
106 outValue,
107 __MEDIA_USER_FEATURE_VALUE_CODECHAL_ENABLE_SW_CRC_DEBUG,
108 MediaUserSetting::Group::Device,
109 0,
110 true);
111 m_swCRC = outValue.Get<bool>();
112 }
113 #endif
114
115 SetFastDumpConfig(mediaCopyWrapper);
116
117 return MOS_STATUS_SUCCESS;
118 }
119
DetectCorruptionSw(std::vector<MOS_RESOURCE> & vResource,PMOS_RESOURCE frameCntRes,uint8_t * buf,uint32_t & size,uint32_t frameNum)120 MOS_STATUS CodechalDebugInterface::DetectCorruptionSw(std::vector<MOS_RESOURCE> &vResource, PMOS_RESOURCE frameCntRes, uint8_t *buf, uint32_t &size, uint32_t frameNum)
121 {
122 if (m_enableHwDebugHooks &&
123 m_goldenReferenceExist &&
124 m_goldenReferences.size() > 0 &&
125 vResource.size() > 0)
126 {
127 MOS_COMMAND_BUFFER cmdBuffer{};
128 std::vector<uint32_t *> vSemaData;
129 MHW_GENERIC_PROLOG_PARAMS genericPrologParams{};
130 genericPrologParams.pOsInterface = m_osInterface;
131 genericPrologParams.pvMiInterface = m_miInterface;
132
133 CODECHAL_DEBUG_CHK_STATUS(m_osInterface->pfnGetCommandBuffer(m_osInterface, &cmdBuffer, 0));
134 CODECHAL_DEBUG_CHK_STATUS(Mhw_SendGenericPrologCmd(
135 &cmdBuffer,
136 &genericPrologParams));
137 LockSemaResource(vSemaData, vResource);
138 // for CRC mismatch detection
139 for (uint32_t i = 0; i < vResource.size(); i++)
140 {
141 CODECHAL_DEBUG_CHK_STATUS(m_hwInterface->SendHwSemaphoreWaitCmd(
142 &vResource[i],
143 m_goldenReferences[frameNum][i],
144 MHW_MI_SAD_EQUAL_SDD,
145 &cmdBuffer));
146 }
147 StoreNumFrame((MhwMiInterface*)m_miInterface, frameCntRes, frameNum, &cmdBuffer);
148
149 SubmitDummyWorkload(&cmdBuffer, false);
150 //Get Decode output
151 std::vector<uint32_t> data = {CalculateCRC(buf, size)};
152 CODECHAL_DEBUG_CHK_STATUS(FillSemaResource(vSemaData, data));
153 }
154 return MOS_STATUS_SUCCESS;
155 }
156
DetectCorruptionHw(void * hwInterface,PMOS_RESOURCE frameCntRes,uint32_t curIdx,uint32_t frameCrcOffset,std::vector<MOS_RESOURCE> & vStatusBuffer,PMOS_COMMAND_BUFFER pCmdBuffer,uint32_t frameNum)157 MOS_STATUS CodechalDebugInterface::DetectCorruptionHw(void *hwInterface, PMOS_RESOURCE frameCntRes, uint32_t curIdx, uint32_t frameCrcOffset, std::vector<MOS_RESOURCE> &vStatusBuffer, PMOS_COMMAND_BUFFER pCmdBuffer, uint32_t frameNum)
158 {
159 if (m_enableHwDebugHooks &&
160 m_goldenReferenceExist &&
161 m_goldenReferences.size() > 0 &&
162 vStatusBuffer.size() > 0)
163 {
164 for (uint32_t i = 0; i < vStatusBuffer.size(); i++)
165 {
166 MEDIA_DEBUG_CHK_STATUS(((CodechalHwInterface*)hwInterface)->SendHwSemaphoreWaitCmd(
167 &vStatusBuffer[i],
168 m_goldenReferences[curIdx][i],
169 MHW_MI_SAD_EQUAL_SDD,
170 pCmdBuffer,
171 frameCrcOffset));
172 }
173 StoreNumFrame((MhwMiInterface*)m_miInterface, frameCntRes, frameNum, pCmdBuffer);
174 }
175 return MOS_STATUS_SUCCESS;
176 }
177
StoreNumFrame(PMHW_MI_INTERFACE pMiInterface,PMOS_RESOURCE pResource,int32_t frameNum,PMOS_COMMAND_BUFFER pCmdBuffer)178 MOS_STATUS CodechalDebugInterface::StoreNumFrame(PMHW_MI_INTERFACE pMiInterface, PMOS_RESOURCE pResource, int32_t frameNum, PMOS_COMMAND_BUFFER pCmdBuffer)
179 {
180 MHW_MI_STORE_DATA_PARAMS storeDataParams{};
181 storeDataParams.pOsResource = pResource;
182 storeDataParams.dwResourceOffset = 0;
183 storeDataParams.dwValue = frameNum;
184 MEDIA_DEBUG_CHK_STATUS(pMiInterface->AddMiStoreDataImmCmd(pCmdBuffer, &storeDataParams));
185 return MOS_STATUS_SUCCESS;
186 }
187
188 #define FIELD_TO_OFS(field_name) ofs << print_shift << std::setfill(' ') << std::setw(25) << std::left << std::string(#field_name) + ": " << (int64_t)report->field_name << std::endl;
189 #define PTR_TO_OFS(ptr_name) ofs << print_shift << std::setfill(' ') << std::setw(25) << std::left << std::string(#ptr_name) + ": " << report->ptr_name << std::endl;
DumpEncodeStatusReport(const EncodeStatusReport * report)190 MOS_STATUS CodechalDebugInterface::DumpEncodeStatusReport(const EncodeStatusReport *report)
191 {
192 CODECHAL_DEBUG_FUNCTION_ENTER;
193
194 CODECHAL_DEBUG_CHK_NULL(report);
195
196 const char *bufferName = "EncodeStatusReport_Parsed";
197 const char *attrName = MediaDbgAttr::attrStatusReport;
198 if (!m_configMgr->AttrIsEnabled(attrName))
199 {
200 return MOS_STATUS_SUCCESS;
201 }
202
203 const char * filePath = CreateFileName(bufferName, attrName, MediaDbgExtType::txt);
204 std::ofstream ofs(filePath);
205
206 if (ofs.fail())
207 {
208 return MOS_STATUS_UNKNOWN;
209 }
210 std::string print_shift = "";
211 sizeof(report->CodecStatus);
212 FIELD_TO_OFS(CodecStatus);
213 FIELD_TO_OFS(StatusReportNumber);
214 FIELD_TO_OFS(CurrOriginalPic.FrameIdx);
215 FIELD_TO_OFS(CurrOriginalPic.PicFlags);
216 FIELD_TO_OFS(CurrOriginalPic.PicEntry);
217 FIELD_TO_OFS(Func);
218 PTR_TO_OFS( pCurrRefList);
219 ofs << std::endl;
220
221 FIELD_TO_OFS(bSequential);
222 FIELD_TO_OFS(bitstreamSize);
223 FIELD_TO_OFS(QpY);
224 FIELD_TO_OFS(SuggestedQpYDelta);
225 FIELD_TO_OFS(NumberPasses);
226 FIELD_TO_OFS(AverageQp);
227 FIELD_TO_OFS(HWCounterValue.IV);
228 FIELD_TO_OFS(HWCounterValue.Count);
229 PTR_TO_OFS( hwctr);
230 FIELD_TO_OFS(QueryStatusFlags);
231
232 print_shift = " ";
233 FIELD_TO_OFS(PanicMode);
234 FIELD_TO_OFS(SliceSizeOverflow);
235 FIELD_TO_OFS(NumSlicesNonCompliant);
236 FIELD_TO_OFS(LongTermReference);
237 FIELD_TO_OFS(FrameSkipped);
238 FIELD_TO_OFS(SceneChangeDetected);
239 print_shift = "";
240 ofs << std::endl;
241
242 FIELD_TO_OFS(MAD);
243 FIELD_TO_OFS(loopFilterLevel);
244 FIELD_TO_OFS(LongTermIndication);
245 FIELD_TO_OFS(NextFrameWidthMinus1);
246 FIELD_TO_OFS(NextFrameHeightMinus1);
247 FIELD_TO_OFS(NumberSlices);
248
249 FIELD_TO_OFS(PSNRx100[0]);
250 FIELD_TO_OFS(PSNRx100[1]);
251 FIELD_TO_OFS(PSNRx100[2]);
252
253 FIELD_TO_OFS(NumberTilesInFrame);
254 FIELD_TO_OFS(UsedVdBoxNumber);
255 FIELD_TO_OFS(SizeOfSliceSizesBuffer);
256 PTR_TO_OFS( pSliceSizes);
257 FIELD_TO_OFS(SizeOfTileInfoBuffer);
258 PTR_TO_OFS( pHEVCTileinfo);
259 FIELD_TO_OFS(NumTileReported);
260 ofs << std::endl;
261
262 FIELD_TO_OFS(StreamId);
263 PTR_TO_OFS( pLookaheadStatus);
264 ofs.close();
265
266 return MOS_STATUS_SUCCESS;
267 }
268 #undef FIELD_TO_OFS
269 #undef PTR_TO_OFS
270
271 #endif // USE_CODECHAL_DEBUG_TOOL
272
273
274