1 /* 2 * Copyright (c) 2019-2024, 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_status_report.cpp 24 //! \brief Defines the common interface for decode status reporter 25 //! \details 26 //! 27 #include "decode_status_report.h" 28 #include "decode_allocator.h" 29 #include "mos_utilities.h" 30 31 namespace decode { 32 DecodeStatusReport(DecodeAllocator * allocator,bool enableRcs,PMOS_INTERFACE osInterface)33 DecodeStatusReport::DecodeStatusReport( 34 DecodeAllocator* allocator, bool enableRcs, PMOS_INTERFACE osInterface): 35 m_enableRcs(enableRcs), 36 m_allocator(allocator), 37 m_osInterface(osInterface) 38 { 39 m_sizeOfReport = sizeof(DecodeStatusReportData); 40 } 41 ~DecodeStatusReport()42 DecodeStatusReport::~DecodeStatusReport() 43 { 44 Destroy(); 45 } 46 Create()47 MOS_STATUS DecodeStatusReport::Create() 48 { 49 DECODE_FUNC_CALL(); 50 51 SetSizeForStatusBuf(); 52 // Allocate status buffer which includes decode status and completed count 53 uint32_t bufferSize = m_statusBufSizeMfx * m_statusNum + m_completedCountSize; 54 m_statusBufMfx = m_allocator->AllocateBuffer( 55 bufferSize, "StatusQueryBufferMfx", resourceInternalWrite, lockableSystemMem, true, 0, true); 56 DECODE_CHK_NULL(m_statusBufMfx); 57 m_completedCountBuf = &(m_statusBufMfx->OsResource); 58 59 DECODE_CHK_STATUS(m_allocator->SkipResourceSync(m_statusBufMfx)); 60 uint8_t *data = (uint8_t *)m_allocator->LockResourceForRead(m_statusBufMfx); 61 DECODE_CHK_NULL(data); 62 63 // Decode status located at the beginging of the status buffer, following with complete count 64 m_dataStatusMfx = data; 65 m_completedCount = (uint32_t *)(data + m_statusBufSizeMfx * m_statusNum); 66 67 if (m_enableRcs) 68 { 69 m_statusBufRcs = m_allocator->AllocateBuffer( 70 m_statusBufSizeRcs * m_statusNum, "StatusQueryBufferRcs", resourceInternalWrite, lockableSystemMem, true, 0, true); 71 72 DECODE_CHK_STATUS(m_allocator->SkipResourceSync(m_statusBufRcs)); 73 m_dataStatusRcs = (uint8_t *)m_allocator->LockResourceForRead(m_statusBufRcs); 74 DECODE_CHK_NULL(m_dataStatusRcs); 75 } 76 77 m_submittedCount = 0; 78 m_reportedCount = 0; 79 80 m_statusBufAddr = MOS_NewArray(StatusBufAddr, statusReportMaxNum); 81 DECODE_CHK_NULL(m_statusBufAddr); 82 83 m_statusBufAddr[statusReportGlobalCount].osResource = m_completedCountBuf; 84 m_statusBufAddr[statusReportGlobalCount].offset = m_statusBufSizeMfx * m_statusNum; 85 m_statusBufAddr[statusReportGlobalCount].bufSize = sizeof(uint32_t) * 2; 86 87 for (int i = statusReportMfx; i < statusReportMaxNum; i++) 88 { 89 m_statusBufAddr[i].osResource = &m_statusBufMfx->OsResource; 90 m_statusBufAddr[i].bufSize = m_statusBufSizeMfx; 91 } 92 93 m_statusBufAddr[statusReportRcs].osResource = &m_statusBufRcs->OsResource; 94 m_statusBufAddr[statusReportRcs].bufSize = m_statusBufSizeRcs; 95 96 SetOffsetsForStatusBuf(); 97 98 return MOS_STATUS_SUCCESS; 99 } 100 Init(void * inputPar)101 MOS_STATUS DecodeStatusReport::Init(void *inputPar) 102 { 103 DECODE_FUNC_CALL(); 104 105 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 106 107 DecodeStatusParameters* inputParameters = (DecodeStatusParameters*)inputPar; 108 uint32_t submitIndex = CounterToIndex(m_submittedCount); 109 110 if (inputParameters) 111 { 112 m_statusReportData[submitIndex].codecStatus = CODECHAL_STATUS_UNAVAILABLE; 113 m_statusReportData[submitIndex].statusReportNumber = inputParameters->statusReportFeedbackNumber; 114 m_statusReportData[submitIndex].currDecodedPic = inputParameters->currOriginalPic; 115 m_statusReportData[submitIndex].currDecodedPicRes = inputParameters->currDecodedPicRes; 116 #if (_DEBUG || _RELEASE_INTERNAL) 117 m_statusReportData[submitIndex].currSfcOutputSurface = inputParameters->sfcOutputSurface; 118 m_statusReportData[submitIndex].currHistogramOutBuf = inputParameters->histogramOutputBuf; 119 m_statusReportData[submitIndex].frameType = inputParameters->pictureCodingType; 120 m_statusReportData[submitIndex].secondField = inputParameters->isSecondField; 121 m_statusReportData[submitIndex].currFgOutputPicRes = inputParameters->fgOutputPicRes; 122 m_statusReportData[submitIndex].streamSize = inputParameters->streamSize; 123 124 if (inputParameters->streamOutBufRes != nullptr) 125 { 126 m_statusReportData[submitIndex].streamOutBufRes = *(inputParameters->streamOutBufRes); 127 } 128 else 129 { 130 m_statusReportData[submitIndex].streamOutBufRes = {0}; 131 } 132 133 if (inputParameters->streamInBufRes != nullptr) 134 { 135 m_statusReportData[submitIndex].streamInBufRes = *(inputParameters->streamInBufRes); 136 } 137 else 138 { 139 m_statusReportData[submitIndex].streamInBufRes = {0}; 140 } 141 #endif 142 } 143 144 DecodeStatusMfx* decodeStatusMfx = (DecodeStatusMfx*)(m_dataStatusMfx + submitIndex * m_statusBufSizeMfx); 145 decodeStatusMfx->status = querySkipped; 146 147 if (m_enableRcs) 148 { 149 DecodeStatusRcs *decodeStatusRcs = (DecodeStatusRcs *)(m_dataStatusRcs + submitIndex * m_statusBufSizeRcs); 150 decodeStatusRcs->status = querySkipped; 151 } 152 153 return eStatus; 154 } 155 Reset()156 MOS_STATUS DecodeStatusReport::Reset() 157 { 158 DECODE_FUNC_CALL(); 159 160 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 161 162 m_submittedCount++; 163 uint32_t submitIndex = CounterToIndex(m_submittedCount); 164 165 DecodeStatusMfx* decodeStatusMfx = (DecodeStatusMfx*)(m_dataStatusMfx + submitIndex * m_statusBufSizeMfx); 166 MOS_ZeroMemory((uint8_t*)decodeStatusMfx, m_statusBufSizeMfx); 167 168 if (m_enableRcs) 169 { 170 DecodeStatusRcs *decodeStatusRcs = (DecodeStatusRcs *)(m_dataStatusRcs + submitIndex * m_statusBufSizeRcs); 171 MOS_ZeroMemory((uint8_t *)decodeStatusRcs, m_statusBufSizeRcs); 172 } 173 174 return eStatus; 175 } 176 ParseStatus(void * report,uint32_t index)177 MOS_STATUS DecodeStatusReport::ParseStatus(void* report, uint32_t index) 178 { 179 DECODE_FUNC_CALL(); 180 181 DecodeStatusMfx* decodeStatusMfx = nullptr; 182 DecodeStatusRcs* decodeStatusRcs = nullptr; 183 184 DecodeStatusReportData* statusReportData = &m_statusReportData[index]; 185 186 decodeStatusMfx = (DecodeStatusMfx*)(m_dataStatusMfx + index * m_statusBufSizeMfx); 187 bool mfxCompleted = (decodeStatusMfx->status == queryEnd) || (decodeStatusMfx->status == querySkipped); 188 189 bool rcsCompleted = false; 190 if (m_enableRcs) 191 { 192 decodeStatusRcs = (DecodeStatusRcs *)(m_dataStatusRcs + index * m_statusBufSizeRcs); 193 rcsCompleted = (decodeStatusRcs->status == queryEnd) || (decodeStatusRcs->status == querySkipped); 194 } 195 else 196 { 197 rcsCompleted = true; 198 } 199 200 UpdateCodecStatus(statusReportData, decodeStatusMfx, mfxCompleted && rcsCompleted); 201 202 // The frame is completed, notify the observers 203 if (statusReportData->codecStatus == CODECHAL_STATUS_SUCCESSFUL) 204 { 205 NotifyObservers(decodeStatusMfx, decodeStatusRcs, statusReportData); 206 } 207 208 *((DecodeStatusReportData*)report) = *statusReportData; 209 210 return MOS_STATUS_SUCCESS; 211 } 212 SetStatus(void * report,uint32_t index,bool outOfRange)213 MOS_STATUS DecodeStatusReport::SetStatus(void *report, uint32_t index, bool outOfRange) 214 { 215 DECODE_FUNC_CALL(); 216 217 DecodeStatusReportData* statusReportData = &m_statusReportData[index]; 218 219 statusReportData->codecStatus = outOfRange ? CODECHAL_STATUS_UNAVAILABLE : CODECHAL_STATUS_INCOMPLETE; 220 221 *((DecodeStatusReportData*)report) = *statusReportData; 222 223 return MOS_STATUS_SUCCESS; 224 } 225 SetSizeForStatusBuf()226 void DecodeStatusReport::SetSizeForStatusBuf() 227 { 228 m_statusBufSizeMfx = MOS_ALIGN_CEIL(sizeof(DecodeStatusMfx), sizeof(uint64_t)); 229 m_statusBufSizeRcs = MOS_ALIGN_CEIL(sizeof(DecodeStatusRcs), sizeof(uint64_t)); 230 } 231 SetOffsetsForStatusBuf()232 void DecodeStatusReport::SetOffsetsForStatusBuf() 233 { 234 const uint32_t mfxStatusOffset = 0; 235 m_statusBufAddr[statusReportMfx].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, status); 236 m_statusBufAddr[DecErrorStatusOffset].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioErrorStatusReg); 237 m_statusBufAddr[DecMBCountOffset].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioMBCountReg); 238 m_statusBufAddr[DecFrameCrcOffset].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioFrameCrcReg); 239 m_statusBufAddr[CsEngineIdOffset_0].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioCsEngineIdReg[0]); 240 m_statusBufAddr[CsEngineIdOffset_1].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioCsEngineIdReg[1]); 241 m_statusBufAddr[CsEngineIdOffset_2].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioCsEngineIdReg[2]); 242 m_statusBufAddr[CsEngineIdOffset_3].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioCsEngineIdReg[3]); 243 m_statusBufAddr[CsEngineIdOffset_4].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioCsEngineIdReg[4]); 244 m_statusBufAddr[CsEngineIdOffset_5].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioCsEngineIdReg[5]); 245 m_statusBufAddr[CsEngineIdOffset_6].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioCsEngineIdReg[6]); 246 m_statusBufAddr[CsEngineIdOffset_7].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_mmioCsEngineIdReg[7]); 247 m_statusBufAddr[HucErrorStatus2Mask].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_hucErrorStatus2); 248 m_statusBufAddr[HucErrorStatus2Reg].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_hucErrorStatus2) + sizeof(uint32_t); 249 m_statusBufAddr[HucErrorStatusMask].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_hucErrorStatus); 250 m_statusBufAddr[HucErrorStatusReg].offset = mfxStatusOffset + CODECHAL_OFFSETOF(DecodeStatusMfx, m_hucErrorStatus) + sizeof(uint32_t); 251 252 const uint32_t rcsStatusOffset = 0; 253 m_statusBufAddr[statusReportRcs].offset = rcsStatusOffset + CODECHAL_OFFSETOF(DecodeStatusRcs, status); 254 } 255 UpdateCodecStatus(DecodeStatusReportData * statusReportData,DecodeStatusMfx * decodeStatus,bool completed)256 MOS_STATUS DecodeStatusReport::UpdateCodecStatus( 257 DecodeStatusReportData* statusReportData, 258 DecodeStatusMfx* decodeStatus, 259 bool completed) 260 { 261 DECODE_CHK_NULL(statusReportData); 262 DECODE_CHK_NULL(decodeStatus); 263 264 if(m_osInterface != nullptr && m_osInterface->pfnIsGPUHung(m_osInterface)) 265 { 266 statusReportData->codecStatus = CODECHAL_STATUS_INCOMPLETE; 267 DECODE_ASSERTMESSAGE("Gpu hang may have occured."); 268 } 269 else if (!completed) 270 { 271 statusReportData->codecStatus = CODECHAL_STATUS_RESET; 272 DECODE_ASSERTMESSAGE("Media reset may have occured."); 273 } 274 else 275 { 276 statusReportData->codecStatus = CODECHAL_STATUS_SUCCESSFUL; 277 } 278 279 return MOS_STATUS_SUCCESS; 280 } 281 GetMfxStatus(uint32_t counter)282 const DecodeStatusMfx& DecodeStatusReport::GetMfxStatus(uint32_t counter) 283 { 284 uint32_t index = CounterToIndex(counter); 285 DecodeStatusMfx* decodeStatusMfx = (DecodeStatusMfx*)(m_dataStatusMfx + index * m_statusBufSizeMfx); 286 return *decodeStatusMfx; 287 } 288 GetReportData(uint32_t counter)289 const DecodeStatusReportData& DecodeStatusReport::GetReportData(uint32_t counter) 290 { 291 uint32_t index = CounterToIndex(counter); 292 return m_statusReportData[index]; 293 } 294 Destroy()295 MOS_STATUS DecodeStatusReport::Destroy() 296 { 297 DECODE_FUNC_CALL(); 298 299 if (m_allocator != nullptr && m_statusBufMfx != nullptr) 300 { 301 m_allocator->UnLock(m_statusBufMfx); 302 m_allocator->Destroy(m_statusBufMfx); 303 m_statusBufMfx = nullptr; 304 m_completedCountBuf = nullptr; 305 } 306 307 if (m_allocator != nullptr && m_statusBufRcs != nullptr) 308 { 309 m_allocator->UnLock(m_statusBufRcs); 310 m_allocator->Destroy(m_statusBufRcs); 311 m_statusBufRcs = nullptr; 312 } 313 314 if (m_statusBufAddr != nullptr) 315 { 316 MOS_DeleteArray(m_statusBufAddr); 317 m_statusBufAddr = nullptr; 318 } 319 320 return MOS_STATUS_SUCCESS; 321 } 322 } 323