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