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 encode_jpeg_packet.cpp 24 //! \brief Defines the interface for jpeg encode packet 25 //! 26 27 #include "encode_jpeg_packet.h" 28 #include "codec_def_encode_jpeg.h" 29 #include "mos_solo_generic.h" 30 #include "media_jpeg_feature_defs.h" 31 32 namespace encode { 33 JpegPkt(MediaPipeline * pipeline,MediaTask * task,CodechalHwInterfaceNext * hwInterface)34 JpegPkt::JpegPkt( 35 MediaPipeline *pipeline, 36 MediaTask *task, 37 CodechalHwInterfaceNext *hwInterface) : 38 CmdPacket(task), 39 m_pipeline(dynamic_cast<JpegPipeline *>(pipeline)), 40 m_hwInterface(dynamic_cast<CodechalHwInterfaceNext *>(hwInterface)) 41 { 42 ENCODE_CHK_NULL_NO_STATUS_RETURN(hwInterface); 43 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_pipeline); 44 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hwInterface); 45 46 m_osInterface = hwInterface->GetOsInterface(); 47 m_statusReport = m_pipeline->GetStatusReportInstance(); 48 m_featureManager = m_pipeline->GetFeatureManager(); 49 m_encodecp = m_pipeline->GetEncodeCp(); 50 51 CODECHAL_DEBUG_TOOL( 52 m_debugInterface = m_pipeline->GetDebugInterface(); 53 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_debugInterface);) 54 55 m_mfxItf = std::static_pointer_cast<mhw::vdbox::mfx::Itf>(m_hwInterface->GetMfxInterfaceNext()); 56 m_miItf = std::static_pointer_cast<mhw::mi::Itf>(m_hwInterface->GetMiInterfaceNext()); 57 } 58 Init()59 MOS_STATUS JpegPkt::Init() 60 { 61 ENCODE_FUNC_CALL(); 62 ENCODE_CHK_NULL_RETURN(m_statusReport); 63 64 ENCODE_CHK_STATUS_RETURN(CmdPacket::Init()); 65 66 m_basicFeature = dynamic_cast<JpegBasicFeature *>(m_featureManager->GetFeature(FeatureIDs::basicFeature)); 67 ENCODE_CHK_NULL_RETURN(m_basicFeature); 68 69 m_jpgPkrFeature = dynamic_cast<JpegPackerFeature *>(m_featureManager->GetFeature(JpegFeatureIDs::jpegPackerFeature)); 70 ENCODE_CHK_NULL_RETURN(m_jpgPkrFeature); 71 72 #ifdef _MMC_SUPPORTED 73 m_mmcState = m_pipeline->GetMmcState(); 74 ENCODE_CHK_NULL_RETURN(m_mmcState); 75 m_basicFeature->m_mmcState = m_mmcState; 76 #endif 77 78 ENCODE_CHK_STATUS_RETURN(m_statusReport->RegistObserver(this)); 79 80 m_usePatchList = m_osInterface->bUsesPatchList; 81 82 return MOS_STATUS_SUCCESS; 83 } 84 Prepare()85 MOS_STATUS JpegPkt::Prepare() 86 { 87 ENCODE_FUNC_CALL(); 88 89 JpegPipeline *pipeline = dynamic_cast<JpegPipeline *>(m_pipeline); 90 ENCODE_CHK_NULL_RETURN(pipeline); 91 92 m_jpegPicParams = m_basicFeature->m_jpegPicParams; 93 m_jpegScanParams = m_basicFeature->m_jpegScanParams; 94 m_jpegQuantTables = m_basicFeature->m_jpegQuantTables; 95 m_jpegHuffmanTable = m_basicFeature->m_jpegHuffmanTable; 96 m_applicationData = m_basicFeature->m_applicationData; 97 m_numHuffBuffers = m_basicFeature->m_numHuffBuffers; 98 99 return MOS_STATUS_SUCCESS; 100 } 101 Destroy()102 MOS_STATUS JpegPkt::Destroy() 103 { 104 ENCODE_FUNC_CALL(); 105 ENCODE_CHK_STATUS_RETURN(m_statusReport->UnregistObserver(this)); 106 107 return MOS_STATUS_SUCCESS; 108 } 109 Submit(MOS_COMMAND_BUFFER * commandBuffer,uint8_t packetPhase)110 MOS_STATUS JpegPkt::Submit( 111 MOS_COMMAND_BUFFER* commandBuffer, 112 uint8_t packetPhase) 113 { 114 ENCODE_FUNC_CALL(); 115 116 MOS_COMMAND_BUFFER &cmdBuffer = *commandBuffer; 117 ENCODE_CHK_STATUS_RETURN(Mos_Solo_PreProcessEncode(m_osInterface, &m_basicFeature->m_resBitstreamBuffer, &m_basicFeature->m_reconSurface)); 118 119 // Ensure the input is ready to be read. 120 // Currently, mos RegisterResource has sync limitation for Raw resource. 121 // Temporaly, call Resource Wait to do the sync explicitly. 122 // TODO, Refine it when MOS refactor ready. 123 MOS_SYNC_PARAMS syncParams; 124 syncParams = g_cInitSyncParams; 125 syncParams.GpuContext = m_osInterface->pfnGetGpuContext(m_osInterface); 126 syncParams.presSyncResource = &m_basicFeature->m_rawSurface.OsResource; 127 syncParams.bReadOnly = true; 128 ENCODE_CHK_STATUS_RETURN(m_osInterface->pfnResourceWait(m_osInterface, &syncParams)); 129 m_osInterface->pfnSetResourceSyncTag(m_osInterface, &syncParams); 130 131 ENCODE_CHK_STATUS_RETURN(PatchPictureLevelCommands(packetPhase, cmdBuffer)); 132 ENCODE_CHK_STATUS_RETURN(PatchSliceLevelCommands(cmdBuffer, packetPhase)); 133 134 ENCODE_CHK_STATUS_RETURN(Mos_Solo_PostProcessEncode(m_osInterface, &m_basicFeature->m_resBitstreamBuffer, &m_basicFeature->m_reconSurface)); 135 136 return MOS_STATUS_SUCCESS; 137 } 138 Completed(void * mfxStatus,void * rcsStatus,void * statusReport)139 MOS_STATUS JpegPkt::Completed(void *mfxStatus, void *rcsStatus, void *statusReport) 140 { 141 ENCODE_FUNC_CALL(); 142 143 ENCODE_CHK_NULL_RETURN(mfxStatus); 144 ENCODE_CHK_NULL_RETURN(statusReport); 145 146 EncodeStatusMfx *encodeStatusMfx = (EncodeStatusMfx *)mfxStatus; 147 EncodeStatusReportData *statusReportData = (EncodeStatusReportData *)statusReport; 148 149 if (statusReportData->hwCtr) 150 { 151 m_encodecp->UpdateCpStatusReport(statusReport); 152 } 153 154 statusReportData->codecStatus = CODECHAL_STATUS_SUCCESSFUL; 155 156 CODECHAL_DEBUG_TOOL( 157 ENCODE_CHK_STATUS_RETURN(DumpResources(encodeStatusMfx, statusReportData));); 158 159 return MOS_STATUS_SUCCESS; 160 } 161 CalculateCommandSize(uint32_t & commandBufferSize,uint32_t & requestedPatchListSize)162 MOS_STATUS JpegPkt::CalculateCommandSize( 163 uint32_t &commandBufferSize, 164 uint32_t &requestedPatchListSize) 165 { 166 ENCODE_FUNC_CALL(); 167 168 ENCODE_CHK_STATUS_RETURN(CalculateMfxCommandsSize()); 169 commandBufferSize = CalculateCommandBufferSize(); 170 requestedPatchListSize = CalculatePatchListSize(); 171 return MOS_STATUS_SUCCESS; 172 } 173 CalculateMfxCommandsSize()174 MOS_STATUS JpegPkt::CalculateMfxCommandsSize() 175 { 176 ENCODE_FUNC_CALL(); 177 178 // Picture Level Commands 179 ENCODE_CHK_STATUS_RETURN( 180 GetMfxStateCommandsDataSize( 181 &m_pictureStatesSize, 182 &m_picturePatchListSize)); 183 184 // Slice Level Commands (cannot be placed in 2nd level batch) 185 ENCODE_CHK_STATUS_RETURN( 186 GetMfxPrimitiveCommandsDataSize( 187 &m_sliceStatesSize, 188 &m_slicePatchListSize)); 189 190 return MOS_STATUS_SUCCESS; 191 } 192 GetMfxPrimitiveCommandsDataSize(uint32_t * commandsSize,uint32_t * patchListSize)193 MOS_STATUS JpegPkt::GetMfxPrimitiveCommandsDataSize( 194 uint32_t *commandsSize, 195 uint32_t *patchListSize) 196 { 197 ENCODE_FUNC_CALL() 198 uint32_t cpCmdsize = 0; 199 uint32_t cpPatchListSize = 0; 200 201 if (m_mfxItf) 202 { 203 uint32_t maxSize = 0; 204 205 maxSize = 206 m_mfxItf->MHW_GETSIZE_F(MFX_FQM_STATE)() * 3 + 207 m_mfxItf->MHW_GETSIZE_F(MFC_JPEG_HUFF_TABLE_STATE)() * 2 + 208 m_mfxItf->MHW_GETSIZE_F(MFC_JPEG_SCAN_OBJECT)() + 209 m_mfxItf->MHW_GETSIZE_F(MFX_PAK_INSERT_OBJECT)() * 10; 210 211 *commandsSize = maxSize; 212 *patchListSize = 0; 213 214 m_hwInterface->GetCpInterface()->GetCpSliceLevelCmdSize(cpCmdsize, cpPatchListSize); 215 } 216 217 *commandsSize += cpCmdsize; 218 *patchListSize += cpPatchListSize; 219 220 return MOS_STATUS_SUCCESS; 221 } 222 GetMfxStateCommandsDataSize(uint32_t * commandsSize,uint32_t * patchListSize)223 MOS_STATUS JpegPkt::GetMfxStateCommandsDataSize( 224 uint32_t *commandsSize, 225 uint32_t *patchListSize) 226 { 227 ENCODE_FUNC_CALL() 228 ENCODE_CHK_NULL_RETURN(commandsSize); 229 ENCODE_CHK_NULL_RETURN(patchListSize); 230 231 uint32_t cpCmdsize = 0; 232 uint32_t cpPatchListSize = 0; 233 234 if (m_mfxItf && m_miItf) 235 { 236 uint32_t maxSize = 237 m_miItf->MHW_GETSIZE_F(MI_FLUSH_DW)() + 238 m_mfxItf->MHW_GETSIZE_F(MFX_PIPE_MODE_SELECT)() + 239 m_mfxItf->MHW_GETSIZE_F(MFX_SURFACE_STATE)() + 240 m_mfxItf->MHW_GETSIZE_F(MFX_PIPE_BUF_ADDR_STATE)() + 241 m_mfxItf->MHW_GETSIZE_F(MFX_IND_OBJ_BASE_ADDR_STATE)() + 242 2 * m_miItf->MHW_GETSIZE_F(MI_STORE_DATA_IMM)() + 243 2 * m_miItf->MHW_GETSIZE_F(MI_STORE_REGISTER_MEM)() + 244 8 * m_miItf->MHW_GETSIZE_F(MI_LOAD_REGISTER_REG)(); 245 246 uint32_t patchListMaxSize = 247 PATCH_LIST_COMMAND(mhw::vdbox::huc::Itf::MI_FLUSH_DW_CMD) + 248 PATCH_LIST_COMMAND(mhw::vdbox::mfx::Itf::MFX_PIPE_MODE_SELECT_CMD) + 249 PATCH_LIST_COMMAND(mhw::vdbox::mfx::Itf::MFX_SURFACE_STATE_CMD) + 250 PATCH_LIST_COMMAND(mhw::vdbox::mfx::Itf::MFX_PIPE_BUF_ADDR_STATE_CMD) + 251 PATCH_LIST_COMMAND(mhw::vdbox::mfx::Itf::MFX_IND_OBJ_BASE_ADDR_STATE_CMD) + 252 (2 * PATCH_LIST_COMMAND(mhw::vdbox::huc::Itf::MI_STORE_DATA_IMM_CMD)) + 253 (2 * PATCH_LIST_COMMAND(mhw::vdbox::huc::Itf::MI_STORE_REGISTER_MEM_CMD)); 254 255 *commandsSize = maxSize; 256 *patchListSize = patchListMaxSize; 257 258 m_hwInterface->GetCpInterface()->GetCpStateLevelCmdSize(cpCmdsize, cpPatchListSize); 259 } 260 261 *commandsSize += cpCmdsize; 262 *patchListSize += cpPatchListSize; 263 264 return MOS_STATUS_SUCCESS; 265 } 266 SelectVdboxAndGetMmioRegister(MHW_VDBOX_NODE_IND index,PMOS_COMMAND_BUFFER pCmdBuffer)267 MmioRegistersMfx *JpegPkt::SelectVdboxAndGetMmioRegister( 268 MHW_VDBOX_NODE_IND index, 269 PMOS_COMMAND_BUFFER pCmdBuffer) 270 { 271 if (m_hwInterface->m_getVdboxNodeByUMD) 272 { 273 pCmdBuffer->iVdboxNodeIndex = m_osInterface->pfnGetVdboxNodeId(m_osInterface, pCmdBuffer); 274 switch (pCmdBuffer->iVdboxNodeIndex) 275 { 276 case MOS_VDBOX_NODE_1: 277 index = MHW_VDBOX_NODE_1; 278 break; 279 case MOS_VDBOX_NODE_2: 280 index = MHW_VDBOX_NODE_2; 281 break; 282 case MOS_VDBOX_NODE_INVALID: 283 // That's a legal case meaning that we were not assigned with per-bb index because 284 // balancing algorithm can't work (forcedly diabled or miss kernel support). 285 // If that's the case we just proceed with the further static context assignment. 286 break; 287 default: 288 // That's the case when MHW and MOS enumerations mismatch. We again proceed with the 289 // best effort (static context assignment, but provide debug note). 290 MHW_ASSERTMESSAGE("MOS and MHW VDBOX enumerations mismatch! Adjust HW description!"); 291 break; 292 } 293 } 294 295 auto vdencItf = m_hwInterface->GetVdencInterfaceNext(); 296 if (vdencItf) 297 { 298 return vdencItf->GetMmioRegisters(index); 299 } 300 else 301 { 302 MHW_ASSERTMESSAGE("Get vdenc interface failed!"); 303 return nullptr; 304 } 305 } 306 SetPerfTag(uint16_t type,uint16_t mode,uint16_t picCodingType)307 void JpegPkt::SetPerfTag(uint16_t type, uint16_t mode, uint16_t picCodingType) 308 { 309 ENCODE_FUNC_CALL(); 310 311 PerfTagSetting perfTag; 312 perfTag.Value = 0; 313 perfTag.Mode = mode & CODECHAL_ENCODE_MODE_BIT_MASK; 314 perfTag.CallType = type; 315 perfTag.PictureCodingType = picCodingType > 3 ? 0 : picCodingType; 316 m_osInterface->pfnSetPerfTag(m_osInterface, perfTag.Value); 317 m_osInterface->pfnIncPerfBufferID(m_osInterface); 318 } 319 AddPictureMfxCommands(MOS_COMMAND_BUFFER & cmdBuffer)320 MOS_STATUS JpegPkt::AddPictureMfxCommands( 321 MOS_COMMAND_BUFFER & cmdBuffer) 322 { 323 ENCODE_FUNC_CALL(); 324 325 SETPAR_AND_ADDCMD(MFX_WAIT, m_miItf, &cmdBuffer); 326 SETPAR_AND_ADDCMD(MFX_PIPE_MODE_SELECT, m_mfxItf, &cmdBuffer); 327 SETPAR_AND_ADDCMD(MFX_WAIT, m_miItf, &cmdBuffer); 328 329 SETPAR_AND_ADDCMD(MFX_SURFACE_STATE, m_mfxItf, &cmdBuffer); 330 SETPAR_AND_ADDCMD(MFX_PIPE_BUF_ADDR_STATE, m_mfxItf, &cmdBuffer); 331 SETPAR_AND_ADDCMD(MFX_IND_OBJ_BASE_ADDR_STATE, m_mfxItf, &cmdBuffer); 332 SETPAR_AND_ADDCMD(MFX_JPEG_PIC_STATE, m_mfxItf, &cmdBuffer); 333 334 return MOS_STATUS_SUCCESS; 335 } 336 SendPrologCmds(MOS_COMMAND_BUFFER & cmdBuffer)337 MOS_STATUS JpegPkt::SendPrologCmds(MOS_COMMAND_BUFFER &cmdBuffer) 338 { 339 ENCODE_FUNC_CALL(); 340 MOS_GPU_CONTEXT gpuContext = m_osInterface->pfnGetGpuContext(m_osInterface); 341 342 // initialize command buffer attributes 343 cmdBuffer.Attributes.bTurboMode = m_hwInterface->m_turboMode; 344 cmdBuffer.Attributes.bMediaPreemptionEnabled = 0; 345 cmdBuffer.Attributes.dwNumRequestedEUSlices = m_hwInterface->m_numRequestedEuSlices; 346 cmdBuffer.Attributes.dwNumRequestedSubSlices = m_hwInterface->m_numRequestedSubSlices; 347 cmdBuffer.Attributes.dwNumRequestedEUs = m_hwInterface->m_numRequestedEus; 348 cmdBuffer.Attributes.bValidPowerGatingRequest = true; 349 350 #ifdef _MMC_SUPPORTED 351 ENCODE_CHK_NULL_RETURN(m_mmcState); 352 ENCODE_CHK_STATUS_RETURN(m_mmcState->SendPrologCmd(&cmdBuffer, false)); 353 #endif 354 355 MHW_GENERIC_PROLOG_PARAMS genericPrologParams; 356 MOS_ZeroMemory(&genericPrologParams, sizeof(genericPrologParams)); 357 genericPrologParams.pOsInterface = m_osInterface; 358 genericPrologParams.pvMiInterface = nullptr; 359 genericPrologParams.bMmcEnabled = m_mmcState ? m_mmcState->IsMmcEnabled() : false; 360 ENCODE_CHK_STATUS_RETURN(Mhw_SendGenericPrologCmdNext(&cmdBuffer, &genericPrologParams, m_miItf)); 361 362 return MOS_STATUS_SUCCESS; 363 } 364 StartStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)365 MOS_STATUS JpegPkt::StartStatusReport( 366 uint32_t srType, 367 MOS_COMMAND_BUFFER *cmdBuffer) 368 { 369 ENCODE_FUNC_CALL(); 370 ENCODE_CHK_NULL_RETURN(cmdBuffer); 371 372 ENCODE_CHK_STATUS_RETURN(MediaPacket::StartStatusReportNext(srType, cmdBuffer)); 373 m_encodecp->StartCpStatusReport(cmdBuffer); 374 375 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance(); 376 ENCODE_CHK_NULL_RETURN(perfProfiler); 377 ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectStartCmd( 378 (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer)); 379 380 return MOS_STATUS_SUCCESS; 381 } 382 ReadMfcStatus(MOS_COMMAND_BUFFER & cmdBuffer)383 MOS_STATUS JpegPkt::ReadMfcStatus(MOS_COMMAND_BUFFER &cmdBuffer) 384 { 385 ENCODE_FUNC_CALL(); 386 387 ENCODE_CHK_NULL_RETURN(m_hwInterface); 388 389 MOS_RESOURCE *osResource = nullptr; 390 uint32_t offset = 0; 391 392 EncodeStatusReadParams params; 393 MOS_ZeroMemory(¶ms, sizeof(params)); 394 395 ENCODE_CHK_STATUS_RETURN(m_statusReport->GetAddress(encode::statusReportMfxBitstreamByteCountPerFrame, osResource, offset)); 396 params.resBitstreamByteCountPerFrame = osResource; 397 params.bitstreamByteCountPerFrameOffset = offset; 398 399 ENCODE_CHK_STATUS_RETURN(m_statusReport->GetAddress(encode::statusReportMfxBitstreamSyntaxElementOnlyBitCount, osResource, offset)); 400 params.resBitstreamSyntaxElementOnlyBitCount = osResource; 401 params.bitstreamSyntaxElementOnlyBitCountOffset = offset; 402 403 ENCODE_CHK_STATUS_RETURN(m_statusReport->GetAddress(encode::statusReportQPStatusCount, osResource, offset)); 404 params.resQpStatusCount = osResource; 405 params.qpStatusCountOffset = offset; 406 407 ENCODE_CHK_STATUS_RETURN(m_statusReport->GetAddress(encode::statusReportImageStatusMask, osResource, offset)); 408 params.resImageStatusMask = osResource; 409 params.imageStatusMaskOffset = offset; 410 411 ENCODE_CHK_STATUS_RETURN(m_statusReport->GetAddress(encode::statusReportImageStatusCtrl, osResource, offset)); 412 params.resImageStatusCtrl = osResource; 413 params.imageStatusCtrlOffset = offset; 414 415 ENCODE_CHK_STATUS_RETURN(m_statusReport->GetAddress(encode::statusReportNumSlices, osResource, offset)); 416 params.resNumSlices = osResource; 417 params.numSlicesOffset = offset; 418 419 ENCODE_CHK_COND_RETURN((m_vdboxIndex > m_mfxItf->GetMaxVdboxIndex()), "ERROR - vdbox index exceeds the maximum"); 420 421 SETPAR_AND_ADDCMD(MI_FLUSH_DW, m_miItf, &cmdBuffer); 422 423 MmioRegistersMfx *mmioRegisters = SelectVdboxAndGetMmioRegister(m_vdboxIndex, &cmdBuffer); 424 CODEC_HW_CHK_NULL_RETURN(mmioRegisters); 425 m_pResource = params.resBitstreamByteCountPerFrame; 426 m_dwOffset = params.bitstreamByteCountPerFrameOffset; 427 m_dwValue = mmioRegisters->mfcBitstreamBytecountFrameRegOffset; 428 SETPAR_AND_ADDCMD(MI_STORE_REGISTER_MEM, m_miItf, &cmdBuffer); 429 430 m_pResource = params.resBitstreamSyntaxElementOnlyBitCount; 431 m_dwOffset = params.bitstreamSyntaxElementOnlyBitCountOffset; 432 m_dwValue = mmioRegisters->mfcBitstreamSeBitcountFrameRegOffset; 433 SETPAR_AND_ADDCMD(MI_STORE_REGISTER_MEM, m_miItf, &cmdBuffer); 434 435 m_pResource = params.resQpStatusCount; 436 m_dwOffset = params.qpStatusCountOffset; 437 m_dwValue = mmioRegisters->mfcQPStatusCountOffset; 438 SETPAR_AND_ADDCMD(MI_STORE_REGISTER_MEM, m_miItf, &cmdBuffer); 439 440 ENCODE_CHK_STATUS_RETURN(ReadImageStatus(params, &cmdBuffer)) 441 return MOS_STATUS_SUCCESS; 442 } 443 ReadImageStatus(const EncodeStatusReadParams & params,PMOS_COMMAND_BUFFER cmdBuffer)444 MOS_STATUS JpegPkt::ReadImageStatus( 445 const EncodeStatusReadParams ¶ms, 446 PMOS_COMMAND_BUFFER cmdBuffer) 447 { 448 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 449 450 CODEC_HW_FUNCTION_ENTER; 451 452 CODEC_HW_CHK_NULL_RETURN(cmdBuffer); 453 454 CODEC_HW_CHK_COND_RETURN((m_vdboxIndex > m_mfxItf->GetMaxVdboxIndex()), "ERROR - vdbox index exceeds the maximum"); 455 456 MmioRegistersMfx *mmioRegisters = SelectVdboxAndGetMmioRegister(m_vdboxIndex, cmdBuffer); 457 CODEC_HW_CHK_NULL_RETURN(mmioRegisters); 458 m_pResource = params.resImageStatusMask; 459 m_dwOffset = params.imageStatusMaskOffset; 460 m_dwValue = mmioRegisters->mfcImageStatusMaskRegOffset; 461 SETPAR_AND_ADDCMD(MI_STORE_REGISTER_MEM, m_miItf, cmdBuffer); 462 463 m_pResource = params.resImageStatusCtrl; 464 m_dwOffset = params.imageStatusCtrlOffset; 465 m_dwValue = mmioRegisters->mfcImageStatusCtrlRegOffset; 466 SETPAR_AND_ADDCMD(MI_STORE_REGISTER_MEM, m_miItf, cmdBuffer); 467 468 SETPAR_AND_ADDCMD(MI_FLUSH_DW, m_miItf, cmdBuffer); 469 470 return eStatus; 471 } 472 EndStatusReport(uint32_t srType,MOS_COMMAND_BUFFER * cmdBuffer)473 MOS_STATUS JpegPkt::EndStatusReport( 474 uint32_t srType, 475 MOS_COMMAND_BUFFER *cmdBuffer) 476 { 477 ENCODE_FUNC_CALL(); 478 ENCODE_CHK_NULL_RETURN(cmdBuffer); 479 480 ENCODE_CHK_STATUS_RETURN(MediaPacket::EndStatusReportNext(srType, cmdBuffer)); 481 482 MediaPerfProfiler *perfProfiler = MediaPerfProfiler::Instance(); 483 ENCODE_CHK_NULL_RETURN(perfProfiler); 484 ENCODE_CHK_STATUS_RETURN(perfProfiler->AddPerfCollectEndCmd( 485 (void *)m_pipeline, m_osInterface, m_miItf, cmdBuffer)); 486 487 return MOS_STATUS_SUCCESS; 488 } 489 PatchPictureLevelCommands(const uint8_t & packetPhase,MOS_COMMAND_BUFFER & cmdBuffer)490 MOS_STATUS JpegPkt::PatchPictureLevelCommands(const uint8_t &packetPhase, MOS_COMMAND_BUFFER &cmdBuffer) 491 { 492 ENCODE_FUNC_CALL(); 493 494 ENCODE_CHK_STATUS_RETURN(m_miItf->SetWatchdogTimerThreshold(m_basicFeature->m_frameWidth, m_basicFeature->m_frameHeight, true)); 495 496 SetPerfTag(CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE, (uint16_t)m_basicFeature->m_mode, m_basicFeature->m_pictureCodingType); 497 498 SETPAR_AND_ADDCMD(MI_FORCE_WAKEUP, m_miItf, &cmdBuffer); 499 500 // Send command buffer header at the beginning (OS dependent) 501 ENCODE_CHK_STATUS_RETURN(SendPrologCmds(cmdBuffer)); 502 503 if (m_pipeline->IsFirstPipe()) 504 { 505 ENCODE_CHK_STATUS_RETURN(StartStatusReport(statusReportMfx, &cmdBuffer)); 506 } 507 508 ENCODE_CHK_STATUS_RETURN(AddPictureMfxCommands(cmdBuffer)); 509 510 return MOS_STATUS_SUCCESS; 511 } 512 PatchSliceLevelCommands(MOS_COMMAND_BUFFER & cmdBuffer,uint8_t packetPhase)513 MOS_STATUS JpegPkt::PatchSliceLevelCommands(MOS_COMMAND_BUFFER &cmdBuffer, uint8_t packetPhase) 514 { 515 ENCODE_FUNC_CALL(); 516 517 if (m_basicFeature->m_numSlices != 1) 518 { 519 ENCODE_ASSERTMESSAGE("JPEG encode only one scan is supported."); 520 } 521 522 static_assert(JPEG_MAX_NUM_QUANT_TABLE_INDEX <= JPEG_MAX_NUM_OF_QUANTMATRIX, 523 "access to CodecJpegQuantMatrix is controlled by numQuantTables"); 524 525 for (uint32_t scanCount = 0; scanCount < m_basicFeature->m_numSlices; scanCount++) 526 { 527 m_numQuantTables = JPEG_MAX_NUM_QUANT_TABLE_INDEX; 528 ENCODE_CHK_STATUS_RETURN(InitMissedQuantTables()); 529 530 ENCODE_CHK_STATUS_RETURN(InitQuantMatrix()); 531 532 ENCODE_CHK_STATUS_RETURN(AddAllCmds_MFX_FQM_STATE(&cmdBuffer)); 533 534 ENCODE_CHK_STATUS_RETURN(InitHuffTable()); 535 536 ENCODE_CHK_STATUS_RETURN(AddAllCmds_MFC_JPEG_HUFF_TABLE_STATE(&cmdBuffer)); 537 538 SETPAR_AND_ADDCMD(MFC_JPEG_SCAN_OBJECT, m_mfxItf, &cmdBuffer); 539 540 ENCODE_CHK_STATUS_RETURN(AddAllCmds_MFX_PAK_INSERT_OBJECT(&cmdBuffer)); 541 } 542 543 ENCODE_CHK_STATUS_RETURN(ReadMfcStatus(cmdBuffer)); 544 545 if (m_pipeline->IsFirstPipe()) 546 { 547 ENCODE_CHK_STATUS_RETURN(EndStatusReport(statusReportMfx, &cmdBuffer)); 548 } 549 550 if (!m_pipeline->IsSingleTaskPhaseSupported() || m_pipeline->IsLastPass()) 551 { 552 ENCODE_CHK_STATUS_RETURN(UpdateStatusReportNext(statusReportGlobalCount, &cmdBuffer)); 553 } 554 555 ENCODE_CHK_STATUS_RETURN(m_miItf->AddMiBatchBufferEnd(&cmdBuffer, nullptr)); 556 557 std::string pakPassName = "PAK_PASS" + std::to_string(static_cast<uint32_t>(m_pipeline->GetCurrentPass())); 558 CODECHAL_DEBUG_TOOL( 559 CodechalDebugInterface *debugInterface = m_pipeline->GetDebugInterface(); 560 ENCODE_CHK_NULL_RETURN(debugInterface); 561 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpCmdBuffer( 562 &cmdBuffer, 563 CODECHAL_NUM_MEDIA_STATES, 564 pakPassName.data())); 565 ) 566 567 return MOS_STATUS_SUCCESS; 568 } 569 InitMissedQuantTables()570 MOS_STATUS JpegPkt::InitMissedQuantTables() 571 { 572 ENCODE_FUNC_CALL(); 573 574 MOS_SURFACE *surface = m_basicFeature->m_rawSurfaceToPak; 575 bool useSingleDefaultQuantTable = (m_basicFeature->m_jpegQuantMatrixSent == false && 576 ((surface->Format == Format_A8R8G8B8) || 577 (surface->Format == Format_X8R8G8B8) || 578 (surface->Format == Format_A8B8G8R8) || 579 (surface->Format == Format_X8B8G8R8))); 580 581 // For monochrome inputs there will be only 1 quantization table and huffman table sent 582 if (m_jpegPicParams->m_inputSurfaceFormat == codechalJpegY8) 583 { 584 m_numQuantTables = 1; 585 m_numHuffBuffers = 2; //for Y8 only 2 huff tables 586 } 587 // If there is only 1 quantization table copy over the table to 2nd and 3rd table in JPEG state (used for frame header) 588 // OR For RGB input surfaces, if the app does not send quantization tables, then use luma quant table for all 3 components 589 else if (m_jpegPicParams->m_numQuantTable == 1 || useSingleDefaultQuantTable) 590 { 591 for (auto i = 1; i < JPEG_MAX_NUM_QUANT_TABLE_INDEX; i++) 592 { 593 m_jpegQuantTables->m_quantTable[i].m_precision = m_jpegQuantTables->m_quantTable[0].m_precision; 594 m_jpegQuantTables->m_quantTable[i].m_tableID = m_jpegQuantTables->m_quantTable[0].m_tableID; 595 596 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy( 597 &m_jpegQuantTables->m_quantTable[i].m_qm[0], 598 JPEG_NUM_QUANTMATRIX * sizeof(uint16_t), 599 &m_jpegQuantTables->m_quantTable[0].m_qm[0], 600 JPEG_NUM_QUANTMATRIX * sizeof(uint16_t))); 601 } 602 } 603 // If there are 2 quantization tables copy over the second table to 3rd table in JPEG state since U and V share the same table (used for frame header) 604 else if (m_jpegPicParams->m_numQuantTable == 2) 605 { 606 m_jpegQuantTables->m_quantTable[2].m_precision = m_jpegQuantTables->m_quantTable[1].m_precision; 607 m_jpegQuantTables->m_quantTable[2].m_tableID = m_jpegQuantTables->m_quantTable[1].m_tableID; 608 609 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy( 610 &m_jpegQuantTables->m_quantTable[2].m_qm[0], 611 JPEG_NUM_QUANTMATRIX * sizeof(uint16_t), 612 &m_jpegQuantTables->m_quantTable[1].m_qm[0], 613 JPEG_NUM_QUANTMATRIX * sizeof(uint16_t))); 614 } 615 // else 3 quantization tables are sent by the application for non monochrome input formats. In that case, do nothing. 616 617 return MOS_STATUS_SUCCESS; 618 } 619 InitQuantMatrix()620 MOS_STATUS JpegPkt::InitQuantMatrix() 621 { 622 ENCODE_FUNC_CALL(); 623 624 m_jpegQuantMatrix = {}; 625 626 for (uint8_t i = 0; i < m_numQuantTables; i++) 627 { 628 for (auto j = 0; j < JPEG_NUM_QUANTMATRIX; j++) 629 { 630 uint32_t k = jpeg_qm_scan_8x8[j]; 631 632 // copy over Quant matrix in raster order from zig zag 633 m_jpegQuantMatrix.m_quantMatrix[i][k] = (uint8_t)m_jpegQuantTables->m_quantTable[i].m_qm[j]; 634 } 635 } 636 637 return MOS_STATUS_SUCCESS; 638 } 639 InitHuffTable()640 MOS_STATUS JpegPkt::InitHuffTable() 641 { 642 ENCODE_FUNC_CALL(); 643 644 for (uint32_t i = 0; i < m_numHuffBuffers; i++) 645 { 646 EncodeJpegHuffTable huffmanTable; // intermediate table for each AC/DC component which will be copied to m_huffTableParams 647 MOS_ZeroMemory(&huffmanTable, sizeof(huffmanTable)); 648 649 ENCODE_CHK_STATUS_RETURN(ConvertHuffDataToTable(m_jpegHuffmanTable->m_huffmanData[i], &huffmanTable)); 650 651 m_huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].HuffTableID = m_jpegHuffmanTable->m_huffmanData[i].m_tableID; 652 653 if (m_jpegHuffmanTable->m_huffmanData[i].m_tableClass == 0) // DC table 654 { 655 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy( 656 m_huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].pDCCodeValues, 657 JPEG_NUM_HUFF_TABLE_DC_HUFFVAL * sizeof(uint16_t), 658 &huffmanTable.m_huffCode, 659 JPEG_NUM_HUFF_TABLE_DC_HUFFVAL * sizeof(uint16_t))); 660 661 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(m_huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].pDCCodeLength, 662 JPEG_NUM_HUFF_TABLE_DC_HUFFVAL * sizeof(uint8_t), 663 &huffmanTable.m_huffSize, 664 JPEG_NUM_HUFF_TABLE_DC_HUFFVAL * sizeof(uint8_t))); 665 } 666 else // AC Table 667 { 668 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(m_huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].pACCodeValues, 669 JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint16_t), 670 &huffmanTable.m_huffCode, 671 JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint16_t))); 672 673 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(m_huffTableParams[m_jpegHuffmanTable->m_huffmanData[i].m_tableID].pACCodeLength, 674 JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint8_t), 675 &huffmanTable.m_huffSize, 676 JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint8_t))); 677 } 678 } 679 680 // Send 2 huffman table commands - 1 for Luma and one for chroma for non-monchrome input formats 681 // If only one table is sent by the app (2 buffers), send the same table for Luma and chroma 682 m_repeatHuffTable = false; 683 if ((m_numHuffBuffers / 2 < JPEG_MAX_NUM_HUFF_TABLE_INDEX) && (m_jpegPicParams->m_inputSurfaceFormat != codechalJpegY8)) 684 { 685 m_repeatHuffTable = true; 686 687 // Copy over huffman data to the other two data buffers for JPEG picture header 688 for (uint32_t i = 0; i < m_numHuffBuffers; i++) 689 { 690 if ((i + 2) >= JPEG_NUM_ENCODE_HUFF_BUFF) 691 { 692 return MOS_STATUS_INVALID_PARAMETER; 693 } 694 m_jpegHuffmanTable->m_huffmanData[i + 2].m_tableClass = m_jpegHuffmanTable->m_huffmanData[i].m_tableClass; 695 m_jpegHuffmanTable->m_huffmanData[i + 2].m_tableID = m_jpegHuffmanTable->m_huffmanData[i].m_tableID; 696 697 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(&m_jpegHuffmanTable->m_huffmanData[i + 2].m_bits[0], 698 sizeof(uint8_t) * JPEG_NUM_HUFF_TABLE_AC_BITS, 699 &m_jpegHuffmanTable->m_huffmanData[i].m_bits[0], 700 sizeof(uint8_t) * JPEG_NUM_HUFF_TABLE_AC_BITS)); 701 702 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(&m_jpegHuffmanTable->m_huffmanData[i + 2].m_huffVal[0], 703 sizeof(uint8_t) * JPEG_NUM_HUFF_TABLE_AC_HUFFVAL, 704 &m_jpegHuffmanTable->m_huffmanData[i].m_huffVal[0], 705 sizeof(uint8_t) * JPEG_NUM_HUFF_TABLE_AC_HUFFVAL)); 706 } 707 } 708 709 return MOS_STATUS_SUCCESS; 710 } 711 AddSOI(PMOS_COMMAND_BUFFER cmdBuffer) const712 MOS_STATUS JpegPkt::AddSOI(PMOS_COMMAND_BUFFER cmdBuffer) const 713 { 714 ENCODE_FUNC_CALL(); 715 ENCODE_CHK_NULL_RETURN(cmdBuffer); 716 717 BSBuffer bsBuffer = {}; 718 ENCODE_CHK_STATUS_RETURN(m_jpgPkrFeature->PackSOI(&bsBuffer)); 719 720 uint32_t byteSize = (bsBuffer.BufferSize + 7) >> 3; 721 uint32_t dataBitsInLastDw = bsBuffer.BufferSize % 32; 722 if (dataBitsInLastDw == 0) 723 { 724 dataBitsInLastDw = 32; 725 } 726 727 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFX_PAK_INSERT_OBJECT)(); 728 params = {}; 729 params.dwPadding = ((byteSize + 3) >> 2); 730 params.bitstreamstartresetResetbitstreamstartingpos = 1; 731 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 732 733 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 734 735 // Add actual data 736 uint8_t* data = (uint8_t*)(bsBuffer.pBase); 737 MOS_STATUS eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 738 739 MOS_SafeFreeMemory(bsBuffer.pBase); 740 741 return eStatus; 742 } 743 AddApplicationData(PMOS_COMMAND_BUFFER cmdBuffer) const744 MOS_STATUS JpegPkt::AddApplicationData(PMOS_COMMAND_BUFFER cmdBuffer) const 745 { 746 ENCODE_FUNC_CALL(); 747 ENCODE_CHK_NULL_RETURN(cmdBuffer); 748 749 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 750 751 BSBuffer bsBuffer = {}; 752 uint32_t appDataChunkSize = m_basicFeature->m_appDataSize; 753 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFX_PAK_INSERT_OBJECT)(); 754 755 // We can write a maximum of 1020 words per command, so if the size of the app data is 756 // more than 1020 we need to send multiple commands for writing out app data 757 uint32_t numAppDataCmdsNeeded = 1; 758 uint32_t appDataCmdSizeResidue = 0; 759 if (m_basicFeature->m_appDataSize > 1020) 760 { 761 numAppDataCmdsNeeded = m_basicFeature->m_appDataSize / 1020; 762 appDataCmdSizeResidue = m_basicFeature->m_appDataSize % 1020; 763 764 appDataChunkSize = 1020; 765 } 766 767 uint8_t *appDataChunk = (uint8_t *)MOS_AllocAndZeroMemory(appDataChunkSize); 768 ENCODE_CHK_NULL_RETURN(appDataChunk) 769 770 for (uint32_t i = 0; i < numAppDataCmdsNeeded; i++) 771 { 772 uint8_t *copyAddress = (uint8_t *)(m_applicationData) + (i * appDataChunkSize); 773 774 MOS_SecureMemcpy(appDataChunk, appDataChunkSize, copyAddress, appDataChunkSize); 775 eStatus = m_jpgPkrFeature->PackApplicationData(&bsBuffer, appDataChunk, appDataChunkSize); 776 if (eStatus != MOS_STATUS_SUCCESS) 777 { 778 MOS_SafeFreeMemory(appDataChunk); 779 ENCODE_CHK_STATUS_RETURN(eStatus); 780 } 781 782 uint32_t byteSize = (bsBuffer.BufferSize + 7) >> 3; 783 uint32_t dataBitsInLastDw = bsBuffer.BufferSize % 32; 784 if (dataBitsInLastDw == 0) 785 { 786 dataBitsInLastDw = 32; 787 } 788 789 params = {}; 790 params.dwPadding = ((byteSize + 3) >> 2); 791 params.bitstreamstartresetResetbitstreamstartingpos = 1; 792 //if full header is included in application data, it will be the last header to insert and last chunk of it should be marked with EndOfSlice 793 if ((appDataCmdSizeResidue == 0) && m_basicFeature->m_fullHeaderInAppData && (i == numAppDataCmdsNeeded - 1)) 794 { 795 params.endofsliceflagLastdstdatainsertcommandflag = true; 796 params.lastheaderflagLastsrcheaderdatainsertcommandflag = true; 797 } 798 else 799 { 800 params.endofsliceflagLastdstdatainsertcommandflag = false; 801 params.lastheaderflagLastsrcheaderdatainsertcommandflag = false; 802 } 803 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 804 805 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 806 807 // Add actual data 808 uint8_t* data = (uint8_t*)(bsBuffer.pBase); 809 eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 810 if (eStatus != MOS_STATUS_SUCCESS) 811 { 812 MOS_SafeFreeMemory(appDataChunk); 813 ENCODE_CHK_STATUS_RETURN(eStatus); 814 } 815 } 816 817 if (appDataCmdSizeResidue != 0) 818 { 819 uint8_t *lastAddress = (uint8_t *)(m_applicationData) + (numAppDataCmdsNeeded * appDataChunkSize); 820 appDataChunkSize = appDataCmdSizeResidue; 821 822 MOS_SecureMemcpy(appDataChunk, appDataChunkSize, lastAddress, appDataChunkSize); 823 824 eStatus = m_jpgPkrFeature->PackApplicationData(&bsBuffer, appDataChunk, appDataChunkSize); 825 if (eStatus != MOS_STATUS_SUCCESS) 826 { 827 MOS_SafeFreeMemory(appDataChunk); 828 ENCODE_CHK_STATUS_RETURN(eStatus); 829 } 830 831 uint32_t byteSize = (bsBuffer.BufferSize + 7) >> 3; 832 uint32_t dataBitsInLastDw = bsBuffer.BufferSize % 32; 833 if (dataBitsInLastDw == 0) 834 { 835 dataBitsInLastDw = 32; 836 } 837 838 params = {}; 839 params.dwPadding = ((byteSize + 3) >> 2); 840 params.bitstreamstartresetResetbitstreamstartingpos = 1; 841 //if full header is included in application data, it will be the last insert headers 842 if (m_basicFeature->m_fullHeaderInAppData) 843 { 844 params.endofsliceflagLastdstdatainsertcommandflag = true; 845 params.lastheaderflagLastsrcheaderdatainsertcommandflag = true; 846 } 847 else 848 { 849 params.endofsliceflagLastdstdatainsertcommandflag = false; 850 params.lastheaderflagLastsrcheaderdatainsertcommandflag = false; 851 } 852 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 853 854 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 855 856 // Add actual data 857 uint8_t* data = (uint8_t*)(bsBuffer.pBase); 858 eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 859 if (eStatus != MOS_STATUS_SUCCESS) 860 { 861 MOS_SafeFreeMemory(appDataChunk); 862 ENCODE_CHK_STATUS_RETURN(eStatus); 863 } 864 } 865 866 MOS_FreeMemory(appDataChunk); 867 868 return eStatus; 869 } 870 AddQuantTable(PMOS_COMMAND_BUFFER cmdBuffer,bool useSingleDefaultQuantTable) const871 MOS_STATUS JpegPkt::AddQuantTable(PMOS_COMMAND_BUFFER cmdBuffer, bool useSingleDefaultQuantTable) const 872 { 873 ENCODE_FUNC_CALL(); 874 ENCODE_CHK_NULL_RETURN(cmdBuffer); 875 876 // Add Quant Table for Y 877 BSBuffer bsBuffer = {}; 878 ENCODE_CHK_STATUS_RETURN(m_jpgPkrFeature->PackQuantTable(&bsBuffer, jpegComponentY)); 879 880 uint32_t byteSize = (bsBuffer.BufferSize + 7) >> 3; 881 uint32_t dataBitsInLastDw = bsBuffer.BufferSize % 32; 882 if (dataBitsInLastDw == 0) 883 { 884 dataBitsInLastDw = 32; 885 } 886 887 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFX_PAK_INSERT_OBJECT)(); 888 params = {}; 889 params.dwPadding = ((byteSize + 3) >> 2); 890 params.bitstreamstartresetResetbitstreamstartingpos = 1; 891 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 892 893 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 894 895 // Add actual data 896 uint8_t* data = (uint8_t*)(bsBuffer.pBase); 897 MOS_STATUS eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 898 899 MOS_SafeFreeMemory(bsBuffer.pBase); 900 901 ENCODE_CHK_STATUS_RETURN(eStatus); 902 903 if (!useSingleDefaultQuantTable) 904 { 905 // Since there is no U and V in monochrome format, donot add Quantization table header for U and V components 906 if (m_jpegPicParams->m_inputSurfaceFormat != codechalJpegY8) 907 { 908 // Add quant table for U 909 ENCODE_CHK_STATUS_RETURN(m_jpgPkrFeature->PackQuantTable(&bsBuffer, jpegComponentU)); 910 911 byteSize = (bsBuffer.BufferSize + 7) >> 3; 912 dataBitsInLastDw = bsBuffer.BufferSize % 32; 913 if (dataBitsInLastDw == 0) 914 { 915 dataBitsInLastDw = 32; 916 } 917 918 params = {}; 919 params.dwPadding = ((byteSize + 3) >> 2); 920 params.bitstreamstartresetResetbitstreamstartingpos = 1; 921 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 922 923 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 924 925 // Add actual data 926 data = (uint8_t*)(bsBuffer.pBase); 927 eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 928 929 MOS_SafeFreeMemory(bsBuffer.pBase); 930 931 ENCODE_CHK_STATUS_RETURN(eStatus); 932 933 // Add quant table for V 934 ENCODE_CHK_STATUS_RETURN(m_jpgPkrFeature->PackQuantTable(&bsBuffer, jpegComponentV)); 935 936 byteSize = (bsBuffer.BufferSize + 7) >> 3; 937 dataBitsInLastDw = bsBuffer.BufferSize % 32; 938 if (dataBitsInLastDw == 0) 939 { 940 dataBitsInLastDw = 32; 941 } 942 943 params = {}; 944 params.dwPadding = ((byteSize + 3) >> 2); 945 params.bitstreamstartresetResetbitstreamstartingpos = 1; 946 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 947 948 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 949 950 // Add actual data 951 data = (uint8_t*)(bsBuffer.pBase); 952 eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 953 954 MOS_SafeFreeMemory(bsBuffer.pBase); 955 956 ENCODE_CHK_STATUS_RETURN(eStatus); 957 } 958 } 959 960 return eStatus; 961 } 962 AddFrameHeader(PMOS_COMMAND_BUFFER cmdBuffer,bool useSingleDefaultQuantTable) const963 MOS_STATUS JpegPkt::AddFrameHeader(PMOS_COMMAND_BUFFER cmdBuffer, bool useSingleDefaultQuantTable) const 964 { 965 ENCODE_FUNC_CALL(); 966 ENCODE_CHK_NULL_RETURN(cmdBuffer); 967 968 BSBuffer bsBuffer = {}; 969 ENCODE_CHK_STATUS_RETURN(m_jpgPkrFeature->PackFrameHeader(&bsBuffer, useSingleDefaultQuantTable)); 970 971 uint32_t byteSize = (bsBuffer.BufferSize + 7) >> 3; 972 uint32_t dataBitsInLastDw = bsBuffer.BufferSize % 32; 973 if (dataBitsInLastDw == 0) 974 { 975 dataBitsInLastDw = 32; 976 } 977 978 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFX_PAK_INSERT_OBJECT)(); 979 params = {}; 980 params.dwPadding = ((byteSize + 3) >> 2); 981 params.bitstreamstartresetResetbitstreamstartingpos = 1; 982 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 983 984 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 985 986 // Add actual data 987 uint8_t* data = (uint8_t*)(bsBuffer.pBase); 988 MOS_STATUS eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 989 990 MOS_SafeFreeMemory(bsBuffer.pBase); 991 992 return eStatus; 993 } 994 AddHuffmanTable(PMOS_COMMAND_BUFFER cmdBuffer,uint32_t tblInd) const995 MOS_STATUS JpegPkt::AddHuffmanTable(PMOS_COMMAND_BUFFER cmdBuffer, uint32_t tblInd) const 996 { 997 ENCODE_FUNC_CALL(); 998 ENCODE_CHK_NULL_RETURN(cmdBuffer); 999 1000 BSBuffer bsBuffer = {}; 1001 ENCODE_CHK_STATUS_RETURN(m_jpgPkrFeature->PackHuffmanTable(&bsBuffer, tblInd)); 1002 1003 uint32_t byteSize = (bsBuffer.BufferSize + 7) >> 3; 1004 uint32_t dataBitsInLastDw = bsBuffer.BufferSize % 32; 1005 if (dataBitsInLastDw == 0) 1006 { 1007 dataBitsInLastDw = 32; 1008 } 1009 1010 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFX_PAK_INSERT_OBJECT)(); 1011 params = {}; 1012 params.dwPadding = ((byteSize + 3) >> 2); 1013 params.bitstreamstartresetResetbitstreamstartingpos = 1; 1014 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 1015 1016 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 1017 1018 // Add actual data 1019 uint8_t* data = (uint8_t*)(bsBuffer.pBase); 1020 MOS_STATUS eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 1021 1022 MOS_SafeFreeMemory(bsBuffer.pBase); 1023 1024 return eStatus; 1025 } 1026 AddRestartInterval(PMOS_COMMAND_BUFFER cmdBuffer) const1027 MOS_STATUS JpegPkt::AddRestartInterval(PMOS_COMMAND_BUFFER cmdBuffer) const 1028 { 1029 ENCODE_FUNC_CALL(); 1030 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1031 1032 BSBuffer bsBuffer = {}; 1033 ENCODE_CHK_STATUS_RETURN(m_jpgPkrFeature->PackRestartInterval(&bsBuffer)); 1034 1035 uint32_t byteSize = (bsBuffer.BufferSize + 7) >> 3; 1036 uint32_t dataBitsInLastDw = bsBuffer.BufferSize % 32; 1037 if (dataBitsInLastDw == 0) 1038 { 1039 dataBitsInLastDw = 32; 1040 } 1041 1042 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFX_PAK_INSERT_OBJECT)(); 1043 params = {}; 1044 params.dwPadding = ((byteSize + 3) >> 2); 1045 params.bitstreamstartresetResetbitstreamstartingpos = 1; 1046 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 1047 1048 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 1049 1050 // Add actual data 1051 uint8_t* data = (uint8_t*)(bsBuffer.pBase); 1052 MOS_STATUS eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 1053 1054 MOS_SafeFreeMemory(bsBuffer.pBase); 1055 1056 return eStatus; 1057 } 1058 AddScanHeader(PMOS_COMMAND_BUFFER cmdBuffer) const1059 MOS_STATUS JpegPkt::AddScanHeader(PMOS_COMMAND_BUFFER cmdBuffer) const 1060 { 1061 ENCODE_FUNC_CALL(); 1062 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1063 1064 BSBuffer bsBuffer = {}; 1065 ENCODE_CHK_STATUS_RETURN(m_jpgPkrFeature->PackScanHeader(&bsBuffer)); 1066 1067 uint32_t byteSize = (bsBuffer.BufferSize + 7) >> 3; 1068 uint32_t dataBitsInLastDw = bsBuffer.BufferSize % 32; 1069 if (dataBitsInLastDw == 0) 1070 { 1071 dataBitsInLastDw = 32; 1072 } 1073 1074 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFX_PAK_INSERT_OBJECT)(); 1075 params = {}; 1076 params.dwPadding = ((byteSize + 3) >> 2); 1077 params.bitstreamstartresetResetbitstreamstartingpos = 1; 1078 params.endofsliceflagLastdstdatainsertcommandflag = true; 1079 params.lastheaderflagLastsrcheaderdatainsertcommandflag = true; 1080 params.databitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 1081 1082 m_mfxItf->MHW_ADDCMD_F(MFX_PAK_INSERT_OBJECT)(cmdBuffer); 1083 1084 // Add actual data 1085 uint8_t* data = (uint8_t*)(bsBuffer.pBase); 1086 MOS_STATUS eStatus = Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, nullptr, data, byteSize); 1087 1088 MOS_SafeFreeMemory(bsBuffer.pBase); 1089 1090 return eStatus; 1091 } 1092 1093 // Implemented based on table K.5 in JPEG spec MapHuffValIndex(uint8_t huffValIndex)1094 uint8_t JpegPkt::MapHuffValIndex(uint8_t huffValIndex) 1095 { 1096 ENCODE_FUNC_CALL(); 1097 1098 uint8_t mappedIndex = 0; 1099 1100 if (huffValIndex < 0xF0) 1101 { 1102 mappedIndex = (((huffValIndex >> 4) & 0x0F) * 0xA) + (huffValIndex & 0x0F); 1103 } 1104 else 1105 { 1106 mappedIndex = (((huffValIndex >> 4) & 0x0F) * 0xA) + (huffValIndex & 0x0F) + 1; 1107 } 1108 1109 return mappedIndex; 1110 } 1111 1112 // Implemented based on Flowchart in figure C.1 in JPEG spec GenerateSizeTable(uint8_t bits[],uint8_t huffSize[],uint8_t & lastK)1113 MOS_STATUS JpegPkt::GenerateSizeTable( 1114 uint8_t bits[], 1115 uint8_t huffSize[], 1116 uint8_t &lastK) 1117 { 1118 ENCODE_FUNC_CALL(); 1119 1120 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1121 1122 uint8_t i = 1, j = 1; 1123 uint8_t k = 0; 1124 while (i <= 16) 1125 { 1126 while (j <= (int8_t)bits[i - 1]) // bits index is from 0 to 15 1127 { 1128 huffSize[k] = i; 1129 k = k + 1; 1130 j = j + 1; 1131 } 1132 1133 i++; 1134 j = 1; 1135 } 1136 1137 huffSize[k] = 0; 1138 lastK = k; 1139 1140 return eStatus; 1141 } 1142 1143 // Implemented based on Flowchart in figure C.2 in JPEG spec GenerateCodeTable(uint8_t huffSize[],uint16_t huffCode[])1144 MOS_STATUS JpegPkt::GenerateCodeTable( 1145 uint8_t huffSize[], 1146 uint16_t huffCode[]) 1147 { 1148 ENCODE_FUNC_CALL(); 1149 1150 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1151 1152 uint8_t k = 0; 1153 uint8_t si = huffSize[0]; 1154 uint16_t code = 0; 1155 while (huffSize[k] != 0) 1156 { 1157 while (huffSize[k] == si) 1158 { 1159 if (code == 0xFFFF) 1160 { 1161 // Invalid code generated - replace with all zeroes 1162 code = 0x0000; 1163 } 1164 1165 huffCode[k] = code; 1166 code = code + 1; 1167 k = k + 1; 1168 } 1169 1170 code <<= 1; 1171 si = si + 1; 1172 } 1173 1174 return eStatus; 1175 } 1176 1177 // Implemented based on Flowchart in figure C.3 in JPEG spec OrderCodes(uint8_t huffVal[],uint8_t huffSize[],uint16_t huffCode[],uint8_t lastK)1178 MOS_STATUS JpegPkt::OrderCodes( 1179 uint8_t huffVal[], 1180 uint8_t huffSize[], 1181 uint16_t huffCode[], 1182 uint8_t lastK) 1183 { 1184 ENCODE_FUNC_CALL(); 1185 1186 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1187 1188 uint16_t eHuffCo[JPEG_NUM_HUFF_TABLE_AC_HUFFVAL]; 1189 uint8_t eHuffSi[JPEG_NUM_HUFF_TABLE_AC_HUFFVAL]; 1190 MOS_ZeroMemory(&eHuffCo[0], JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint16_t)); 1191 MOS_ZeroMemory(&eHuffSi[0], JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint8_t)); 1192 1193 uint8_t k = 0; 1194 do 1195 { 1196 uint8_t i = MapHuffValIndex((uint8_t)huffVal[k]); 1197 if (i >= JPEG_NUM_HUFF_TABLE_AC_HUFFVAL) 1198 { 1199 ENCODE_ASSERT(false); 1200 return MOS_STATUS_UNKNOWN; 1201 } 1202 eHuffCo[i] = huffCode[k]; 1203 eHuffSi[i] = huffSize[k]; 1204 k++; 1205 } while (k < lastK); 1206 1207 // copy over the first 162 values of reordered arrays to Huffman Code and size arrays 1208 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(&huffCode[0], JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint16_t), &eHuffCo[0], JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint16_t))); 1209 ENCODE_CHK_STATUS_RETURN(MOS_SecureMemcpy(&huffSize[0], JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint8_t), &eHuffSi[0], JPEG_NUM_HUFF_TABLE_AC_HUFFVAL * sizeof(uint8_t))); 1210 1211 return eStatus; 1212 } 1213 ConvertHuffDataToTable(CodecEncodeJpegHuffData huffmanData,EncodeJpegHuffTable * huffmanTable)1214 MOS_STATUS JpegPkt::ConvertHuffDataToTable( 1215 CodecEncodeJpegHuffData huffmanData, 1216 EncodeJpegHuffTable * huffmanTable) 1217 { 1218 ENCODE_FUNC_CALL(); 1219 1220 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1221 1222 huffmanTable->m_tableClass = huffmanData.m_tableClass; 1223 huffmanTable->m_tableID = huffmanData.m_tableID; 1224 1225 uint8_t lastK = 0; 1226 1227 // Step 1 : Generate size table 1228 ENCODE_CHK_STATUS_RETURN(GenerateSizeTable(huffmanData.m_bits, huffmanTable->m_huffSize, lastK)); 1229 1230 // Step2: Generate code table 1231 ENCODE_CHK_STATUS_RETURN(GenerateCodeTable(huffmanTable->m_huffSize, huffmanTable->m_huffCode)); 1232 1233 // Step 3: Order codes 1234 ENCODE_CHK_STATUS_RETURN(OrderCodes(huffmanData.m_huffVal, huffmanTable->m_huffSize, huffmanTable->m_huffCode, lastK)); 1235 1236 return eStatus; 1237 } 1238 CalculateCommandBufferSize()1239 uint32_t JpegPkt::CalculateCommandBufferSize() 1240 { 1241 ENCODE_FUNC_CALL(); 1242 uint32_t commandBufferSize = 1243 m_pictureStatesSize + 1244 (m_sliceStatesSize * m_basicFeature->m_numSlices); 1245 1246 // For JPEG encoder, add the size of PAK_INSERT_OBJ commands which is also part of command buffer 1247 if (m_basicFeature->m_standard == CODECHAL_JPEG) 1248 { 1249 // Add PAK_INSERT_OBJ for app data 1250 // PAK_INSERT_OBJ contains 2 DWORDS + bytes of payload data 1251 // There is a max of 1024 payload bytes of app data per PAK_INSERT_OBJ command, so adding 2 DWORDS for each of them 1252 // Total payload data is the same size as app data 1253 commandBufferSize += (m_basicFeature->m_appDataSize + (2 * sizeof(uint32_t) * (m_basicFeature->m_appDataSize / 1020 + 1))); //to be consistent with how we split app data into chunks. 1254 1255 // Add number of bytes of data added through PAK_INSERT_OBJ command 1256 commandBufferSize += (2 + // SOI = 2 bytes 1257 // Frame header - add sizes of each component of CodechalEncodeJpegFrameHeader 1258 (2 * sizeof(uint8_t)) + (4 * sizeof(uint16_t)) + 3 * sizeof(uint8_t)* jpegNumComponent + 1259 // AC and DC Huffman tables - 2 Huffman tables for each component, and 3 components 1260 (2 * 3 * sizeof(EncodeJpegHuffmanHeader)) + 1261 // Quant tables - 1 for Quant table of each component, so 3 quant tables per frame 1262 (3 * sizeof(EncodeJpegQuantHeader)) + 1263 // Restart interval - 1 per frame 1264 sizeof(EncodeJpegRestartHeader) + 1265 // Scan header - 1 per frame 1266 sizeof(EncodeJpegScanHeader)); 1267 } 1268 1269 if (m_pipeline->IsSingleTaskPhaseSupported()) 1270 { 1271 commandBufferSize *= (m_pipeline->GetPassNum() + 1); 1272 } 1273 1274 // 4K align since allocation is in chunks of 4K bytes. 1275 commandBufferSize = MOS_ALIGN_CEIL(commandBufferSize, 0x1000); 1276 1277 return commandBufferSize; 1278 } 1279 CalculatePatchListSize()1280 uint32_t JpegPkt::CalculatePatchListSize() 1281 { 1282 ENCODE_FUNC_CALL(); 1283 uint32_t requestedPatchListSize = 0; 1284 if (m_usePatchList) 1285 { 1286 requestedPatchListSize = 1287 m_picturePatchListSize + 1288 (m_slicePatchListSize * m_basicFeature->m_numSlices); 1289 1290 if (m_pipeline->IsSingleTaskPhaseSupported()) 1291 { 1292 requestedPatchListSize *= m_pipeline->GetPassNum(); 1293 } 1294 } 1295 return requestedPatchListSize; 1296 } 1297 AddAllCmds_MFX_FQM_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const1298 MOS_STATUS JpegPkt::AddAllCmds_MFX_FQM_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const 1299 { 1300 ENCODE_FUNC_CALL(); 1301 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1302 1303 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFX_FQM_STATE)(); 1304 1305 for (uint8_t i = 0; i < m_numQuantTables; i++) 1306 { 1307 params = {}; 1308 params.qmType = i; 1309 1310 auto j = 0; 1311 // Copy over 32 uint32_t worth of values - Each uint32_t will contain 2 16 bit quantizer values 1312 // where for the DWordx Bits [15: 0] = 1/QM[0][x] Bits[32:16] = 1/QM[1][x] 1313 for (auto k = 0; k < 8; k++) 1314 { 1315 for (auto l = k; l < 64; l += 16) 1316 { 1317 params.quantizermatrix[j] = ((GetReciprocalScalingValue(m_jpegQuantMatrix.m_quantMatrix[i][l + 8]) << 16) | 1318 GetReciprocalScalingValue(m_jpegQuantMatrix.m_quantMatrix[i][l])); 1319 j++; 1320 } 1321 } 1322 1323 m_mfxItf->MHW_ADDCMD_F(MFX_FQM_STATE)(cmdBuffer); 1324 } 1325 1326 return MOS_STATUS_SUCCESS; 1327 } 1328 AddAllCmds_MFC_JPEG_HUFF_TABLE_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const1329 MOS_STATUS JpegPkt::AddAllCmds_MFC_JPEG_HUFF_TABLE_STATE(PMOS_COMMAND_BUFFER cmdBuffer) const 1330 { 1331 ENCODE_FUNC_CALL(); 1332 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1333 1334 auto ¶ms = m_mfxItf->MHW_GETPAR_F(MFC_JPEG_HUFF_TABLE_STATE)(); 1335 1336 // the number of huffman commands is half of the huffman buffers sent by the app, since AC and DC buffers are combined into one command 1337 for (uint32_t i = 0; i < m_numHuffBuffers / 2; i++) 1338 { 1339 params = {}; 1340 params.huffTableId = (uint8_t)m_huffTableParams[i].HuffTableID; 1341 1342 // cmd DWORDS 2:13 for DC Table 1343 // Format- 3Bytes: Byte0 for Code length, Byte1 and Byte2 for Code word, and Byte3 for dummy 1344 for (auto j = 0; j < JPEG_NUM_HUFF_TABLE_DC_HUFFVAL; j++) 1345 { 1346 params.dcTable[j] = 0; 1347 params.dcTable[j] = (m_huffTableParams[i].pDCCodeLength[j] & 0xFF) | 1348 ((m_huffTableParams[i].pDCCodeValues[j] & 0xFFFF) << 8); 1349 } 1350 1351 // cmd DWORDS 14:175 for AC table 1352 // Format- 3Bytes: Byte0 for Code length, Byte1 and Byte2 for Code word, and Byte3 for dummy 1353 for (auto j = 0; j < JPEG_NUM_HUFF_TABLE_AC_HUFFVAL; j++) 1354 { 1355 params.acTable[j] = 0; 1356 params.acTable[j] = (m_huffTableParams[i].pACCodeLength[j] & 0xFF) | 1357 ((m_huffTableParams[i].pACCodeValues[j] & 0xFFFF) << 8); 1358 } 1359 1360 if (m_repeatHuffTable) 1361 { 1362 m_mfxItf->MHW_ADDCMD_F(MFC_JPEG_HUFF_TABLE_STATE)(cmdBuffer); 1363 } 1364 m_mfxItf->MHW_ADDCMD_F(MFC_JPEG_HUFF_TABLE_STATE)(cmdBuffer); 1365 } 1366 1367 return MOS_STATUS_SUCCESS; 1368 } 1369 AddAllCmds_MFX_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const1370 MOS_STATUS JpegPkt::AddAllCmds_MFX_PAK_INSERT_OBJECT(PMOS_COMMAND_BUFFER cmdBuffer) const 1371 { 1372 ENCODE_FUNC_CALL(); 1373 ENCODE_CHK_NULL_RETURN(cmdBuffer); 1374 1375 MOS_SURFACE *surface = m_basicFeature->m_rawSurfaceToPak; 1376 bool useSingleDefaultQuantTable = (m_basicFeature->m_jpegQuantMatrixSent == false && 1377 ((surface->Format == Format_A8R8G8B8) || 1378 (surface->Format == Format_X8R8G8B8) || 1379 (surface->Format == Format_A8B8G8R8) || 1380 (surface->Format == Format_X8B8G8R8))); 1381 1382 if (!m_basicFeature->m_fullHeaderInAppData) 1383 { 1384 // Add SOI (0xFFD8) (only if it was sent by the application) 1385 ENCODE_CHK_STATUS_RETURN(AddSOI(cmdBuffer)); 1386 } 1387 // Add Application data if it was sent by application 1388 if (m_applicationData != nullptr) 1389 { 1390 ENCODE_CHK_STATUS_RETURN(AddApplicationData(cmdBuffer)); 1391 } 1392 if (!m_basicFeature->m_fullHeaderInAppData) 1393 { 1394 ENCODE_CHK_STATUS_RETURN(AddQuantTable(cmdBuffer, useSingleDefaultQuantTable)); 1395 1396 ENCODE_CHK_STATUS_RETURN(AddFrameHeader(cmdBuffer, useSingleDefaultQuantTable)); 1397 1398 // Add Huffman Table for Y - DC table, Y- AC table, U/V - DC table, U/V - AC table 1399 for (uint32_t i = 0; i < m_numHuffBuffers; i++) 1400 { 1401 ENCODE_CHK_STATUS_RETURN(AddHuffmanTable(cmdBuffer, i)); 1402 } 1403 1404 // Restart Interval - Add only if the restart interval is not zero 1405 if (m_jpegScanParams->m_restartInterval != 0) 1406 { 1407 ENCODE_CHK_STATUS_RETURN(AddRestartInterval(cmdBuffer)); 1408 } 1409 1410 ENCODE_CHK_STATUS_RETURN(AddScanHeader(cmdBuffer)); 1411 } 1412 1413 return MOS_STATUS_SUCCESS; 1414 } 1415 MHW_SETPAR_DECL_SRC(MI_STORE_REGISTER_MEM,JpegPkt)1416 MHW_SETPAR_DECL_SRC(MI_STORE_REGISTER_MEM, JpegPkt) 1417 { 1418 params.presStoreBuffer = m_pResource; 1419 params.dwOffset = m_dwOffset; 1420 params.dwRegister = m_dwValue; 1421 1422 return MOS_STATUS_SUCCESS; 1423 } 1424 1425 #if USE_CODECHAL_DEBUG_TOOL DumpResources(EncodeStatusMfx * encodeStatusMfx,EncodeStatusReportData * statusReportData)1426 MOS_STATUS JpegPkt::DumpResources( 1427 EncodeStatusMfx * encodeStatusMfx, 1428 EncodeStatusReportData *statusReportData) 1429 { 1430 ENCODE_FUNC_CALL(); 1431 1432 ENCODE_CHK_NULL_RETURN(encodeStatusMfx); 1433 ENCODE_CHK_NULL_RETURN(statusReportData); 1434 ENCODE_CHK_NULL_RETURN(m_pipeline); 1435 ENCODE_CHK_NULL_RETURN(m_statusReport); 1436 ENCODE_CHK_NULL_RETURN(m_basicFeature); 1437 ENCODE_CHK_NULL_RETURN(m_basicFeature->m_trackedBuf); 1438 1439 if (m_jpegPicParams) 1440 { 1441 ENCODE_CHK_STATUS_RETURN(DumpPicParams( 1442 m_jpegPicParams)); 1443 } 1444 1445 if (m_jpegScanParams) 1446 { 1447 ENCODE_CHK_STATUS_RETURN(DumpScanParams( 1448 m_jpegScanParams)); 1449 } 1450 1451 if (m_jpegHuffmanTable) 1452 { 1453 ENCODE_CHK_STATUS_RETURN(DumpHuffmanTable( 1454 m_jpegHuffmanTable)); 1455 } 1456 1457 if (m_jpegQuantTables) 1458 { 1459 ENCODE_CHK_STATUS_RETURN(DumpQuantTables( 1460 m_jpegQuantTables)); 1461 } 1462 1463 CodechalDebugInterface *debugInterface = m_pipeline->GetStatusReportDebugInterface(); 1464 ENCODE_CHK_NULL_RETURN(debugInterface); 1465 1466 CODEC_REF_LIST currRefList = *((CODEC_REF_LIST *)statusReportData->currRefList); 1467 currRefList.RefPic = statusReportData->currOriginalPic; 1468 1469 debugInterface->m_currPic = statusReportData->currOriginalPic; 1470 debugInterface->m_bufferDumpFrameNum = m_statusReport->GetReportedCount() + 1; // ToDo: for debug purpose 1471 debugInterface->m_frameType = encodeStatusMfx->pictureCodingType; 1472 1473 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpBuffer( 1474 &currRefList.resBitstreamBuffer, 1475 CodechalDbgAttr::attrBitstream, 1476 "_PAK", 1477 statusReportData->bitstreamSize, 1478 0, 1479 CODECHAL_NUM_MEDIA_STATES)); 1480 1481 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpData( 1482 statusReportData, 1483 sizeof(EncodeStatusReportData), 1484 CodechalDbgAttr::attrStatusReport, 1485 "EncodeStatusReport_Buffer")); 1486 1487 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpYUVSurface( 1488 &currRefList.sRefRawBuffer, 1489 CodechalDbgAttr::attrEncodeRawInputSurface, 1490 "SrcSurf")) 1491 1492 ENCODE_CHK_STATUS_RETURN(debugInterface->DumpEncodeStatusReport( 1493 statusReportData)); 1494 1495 return MOS_STATUS_SUCCESS; 1496 } 1497 DumpHuffmanTable(CodecEncodeJpegHuffmanDataArray * huffmanTable)1498 MOS_STATUS JpegPkt::DumpHuffmanTable( 1499 CodecEncodeJpegHuffmanDataArray *huffmanTable) 1500 { 1501 ENCODE_FUNC_CALL(); 1502 1503 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrHuffmanTbl)) 1504 { 1505 return MOS_STATUS_SUCCESS; 1506 } 1507 1508 ENCODE_CHK_NULL_RETURN(huffmanTable); 1509 1510 std::ostringstream oss; 1511 oss.setf(std::ios::showbase | std::ios::uppercase); 1512 1513 //Dump HuffTable[JPEG_MAX_NUM_HUFF_TABLE_INDEX] 1514 for (uint32_t i = 0; i < JPEG_NUM_ENCODE_HUFF_BUFF; ++i) 1515 { 1516 // Dump Table Class 1517 oss << "TableClass: " << +huffmanTable->m_huffmanData[i].m_tableClass << std::endl; 1518 // Dump Table ID 1519 oss << "TableID: " << +huffmanTable->m_huffmanData[i].m_tableID << std::endl; 1520 //Dump ucBits[JPEG_NUM_HUFF_TABLE_AC_BITS] 1521 oss << "HuffTable[" << +i << "].ucBits[0-" << (JPEG_NUM_HUFF_TABLE_AC_BITS - 1) << "]: " << std::endl; 1522 1523 for (uint32_t j = 0; j < JPEG_NUM_HUFF_TABLE_AC_BITS; ++j) 1524 { 1525 oss << +huffmanTable->m_huffmanData[i].m_bits[j]; 1526 if (j % 6 == 5 || j == JPEG_NUM_HUFF_TABLE_AC_BITS - 1) 1527 { 1528 oss << std::endl; 1529 } 1530 } 1531 1532 //Dump ucHuffVal[JPEG_NUM_HUFF_TABLE_AC_HUFFVAL] 1533 oss << "HuffTable[" << +i << "].ucHuffVal[0-" << (JPEG_NUM_HUFF_TABLE_AC_HUFFVAL - 1) << "]: " << std::endl; 1534 1535 for (uint32_t j = 0; j < JPEG_NUM_HUFF_TABLE_AC_HUFFVAL; ++j) 1536 { 1537 oss << +huffmanTable->m_huffmanData[i].m_huffVal[j]; 1538 if (j % 6 == 5 || j == JPEG_NUM_HUFF_TABLE_AC_HUFFVAL - 1) 1539 { 1540 oss << std::endl; 1541 } 1542 } 1543 } 1544 1545 const char *fileName = m_debugInterface->CreateFileName( 1546 "_ENC", 1547 CodechalDbgBufferType::bufHuffmanTbl, 1548 CodechalDbgExtType::txt); 1549 1550 std::ofstream ofs(fileName, std::ios::out); 1551 ofs << oss.str(); 1552 ofs.close(); 1553 return MOS_STATUS_SUCCESS; 1554 } 1555 DumpPicParams(CodecEncodeJpegPictureParams * picParams)1556 MOS_STATUS JpegPkt::DumpPicParams( 1557 CodecEncodeJpegPictureParams *picParams) 1558 { 1559 ENCODE_FUNC_CALL(); 1560 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrPicParams)) 1561 { 1562 return MOS_STATUS_SUCCESS; 1563 } 1564 1565 ENCODE_CHK_NULL_RETURN(picParams); 1566 1567 std::ostringstream oss; 1568 oss.setf(std::ios::showbase | std::ios::uppercase); 1569 1570 oss << "Profile: " << +picParams->m_profile << std::endl; 1571 oss << "Progressive: " << +picParams->m_progressive << std::endl; 1572 oss << "Huffman: " << +picParams->m_huffman << std::endl; 1573 oss << "Interleaved: " << +picParams->m_interleaved << std::endl; 1574 oss << "Differential: " << +picParams->m_differential << std::endl; 1575 oss << "PicWidth: " << +picParams->m_picWidth << std::endl; 1576 oss << "PicHeight: " << +picParams->m_picHeight << std::endl; 1577 oss << "InputSurfaceFormat: " << +picParams->m_inputSurfaceFormat << std::endl; 1578 oss << "SampleBitDepth: " << +picParams->m_sampleBitDepth << std::endl; 1579 oss << "uiNumComponent: " << +picParams->m_numComponent << std::endl; 1580 1581 //Dump componentIdentifier[jpegNumComponent] 1582 for (uint32_t i = 0; i < jpegNumComponent; ++i) 1583 { 1584 oss << "ComponentIdentifier[" << +i << "]: " << +picParams->m_componentID[i] << std::endl; 1585 } 1586 1587 //Dump quantTableSelector[jpegNumComponent] 1588 for (uint32_t i = 0; i < jpegNumComponent; ++i) 1589 { 1590 oss << "QuantTableSelector[" << +i << "]: " << +picParams->m_quantTableSelector[i] << std::endl; 1591 } 1592 oss << "Quality: " << +picParams->m_quality << std::endl; 1593 oss << "NumScan: " << +picParams->m_numScan << std::endl; 1594 oss << "NumQuantTable: " << +picParams->m_numQuantTable << std::endl; 1595 oss << "NumCodingTable: " << +picParams->m_numCodingTable << std::endl; 1596 oss << "StatusReportFeedbackNumber: " << +picParams->m_statusReportFeedbackNumber << std::endl; 1597 1598 const char *fileName = m_debugInterface->CreateFileName( 1599 "_ENC", 1600 CodechalDbgBufferType::bufPicParams, 1601 CodechalDbgExtType::txt); 1602 1603 std::ofstream ofs(fileName, std::ios::out); 1604 ofs << oss.str(); 1605 ofs.close(); 1606 return MOS_STATUS_SUCCESS; 1607 } 1608 DumpScanParams(CodecEncodeJpegScanHeader * scanParams)1609 MOS_STATUS JpegPkt::DumpScanParams( 1610 CodecEncodeJpegScanHeader *scanParams) 1611 { 1612 ENCODE_FUNC_CALL(); 1613 1614 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrScanParams)) 1615 { 1616 return MOS_STATUS_SUCCESS; 1617 } 1618 1619 ENCODE_CHK_NULL_RETURN(scanParams); 1620 1621 std::ostringstream oss; 1622 oss.setf(std::ios::showbase | std::ios::uppercase); 1623 1624 oss << "RestartInterval: " << +scanParams->m_restartInterval << std::endl; 1625 oss << "NumComponents: " << +scanParams->m_numComponent << std::endl; 1626 1627 //Dump ComponentSelector[jpegNumComponent] 1628 for (uint32_t i = 0; i < jpegNumComponent; ++i) 1629 { 1630 oss << "ComponentSelector[" << +i << "]: " << +scanParams->m_componentSelector[i] << std::endl; 1631 } 1632 1633 //Dump DcHuffTblSelector[jpegNumComponent] 1634 for (uint32_t i = 0; i < jpegNumComponent; ++i) 1635 { 1636 oss << "DcHuffTblSelector[" << +i << "]: " << +scanParams->m_dcCodingTblSelector[i] << std::endl; 1637 } 1638 1639 //Dump AcHuffTblSelector[jpegNumComponent] 1640 for (uint32_t i = 0; i < jpegNumComponent; ++i) 1641 { 1642 oss << "AcHuffTblSelector[" << +i << "]: " << +scanParams->m_acCodingTblSelector[i] << std::endl; 1643 } 1644 1645 const char *fileName = m_debugInterface->CreateFileName( 1646 "_ENC", 1647 CodechalDbgBufferType::bufScanParams, 1648 CodechalDbgExtType::txt); 1649 1650 std::ofstream ofs(fileName, std::ios::out); 1651 ofs << oss.str(); 1652 ofs.close(); 1653 1654 return MOS_STATUS_SUCCESS; 1655 } 1656 DumpQuantTables(CodecEncodeJpegQuantTable * quantTable)1657 MOS_STATUS JpegPkt::DumpQuantTables( 1658 CodecEncodeJpegQuantTable *quantTable) 1659 { 1660 ENCODE_FUNC_CALL(); 1661 1662 if (!m_debugInterface->DumpIsEnabled(CodechalDbgAttr::attrIqParams)) 1663 { 1664 return MOS_STATUS_SUCCESS; 1665 } 1666 1667 ENCODE_CHK_NULL_RETURN(quantTable); 1668 1669 std::ostringstream oss; 1670 oss.setf(std::ios::showbase | std::ios::uppercase); 1671 1672 //Dump quantTable[JPEG_MAX_NUM_QUANT_TABLE_INDEX] 1673 for (uint32_t i = 0; i < JPEG_MAX_NUM_QUANT_TABLE_INDEX; ++i) 1674 { 1675 // Dump Table ID 1676 oss << "TableID: " << +quantTable->m_quantTable[i].m_tableID << std::endl; 1677 // Dump Precision 1678 oss << "TableID: " << +quantTable->m_quantTable[i].m_precision << std::endl; 1679 //Dump usQm[JPEG_NUM_QUANTMATRIX]; 1680 oss << "quantTable[" << +i << "].usQm[0-" << (JPEG_NUM_QUANTMATRIX - 1) << "]: " << std::endl; 1681 1682 for (uint32_t j = 0; j < JPEG_NUM_QUANTMATRIX; ++j) 1683 { 1684 oss << +quantTable->m_quantTable[i].m_qm[j]; 1685 if (j % 6 == 5 || j == JPEG_NUM_QUANTMATRIX - 1) 1686 { 1687 oss << std::endl; 1688 } 1689 } 1690 } 1691 const char *fileName = m_debugInterface->CreateFileName( 1692 "_ENC", 1693 CodechalDbgBufferType::bufIqParams, 1694 CodechalDbgExtType::txt); 1695 1696 std::ofstream ofs(fileName, std::ios::out); 1697 ofs << oss.str(); 1698 ofs.close(); 1699 1700 return MOS_STATUS_SUCCESS; 1701 } 1702 #endif 1703 1704 } 1705