1 /* 2 * Copyright (c) 2017-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 mhw_vdbox_mfx_generic.h 24 //! \brief MHW interface for constructing MFX commands for the Vdbox engine 25 //! \details Impelements shared Vdbox MFX command construction functions across all platforms as templates 26 //! 27 28 #ifndef _MHW_VDBOX_MFX_GENERIC_H_ 29 #define _MHW_VDBOX_MFX_GENERIC_H_ 30 31 #include "mhw_vdbox_mfx_interface.h" 32 #include "mhw_cp_interface.h" 33 34 //! MHW Vdbox Mfx generic interface 35 /*! 36 This class defines the shared Mfx command construction functions across all platforms as templates 37 */ 38 template <class TMfxCmds, class TMiCmds> 39 class MhwVdboxMfxInterfaceGeneric : public MhwVdboxMfxInterface 40 { 41 protected: 42 //! 43 //! \brief Constructor 44 //! MhwVdboxMfxInterfaceGeneric(PMOS_INTERFACE osInterface,MhwMiInterface * miInterface,MhwCpInterface * cpInterface,bool decodeInUse)45 MhwVdboxMfxInterfaceGeneric( 46 PMOS_INTERFACE osInterface, 47 MhwMiInterface *miInterface, 48 MhwCpInterface *cpInterface, 49 bool decodeInUse) : 50 MhwVdboxMfxInterface(osInterface, miInterface, cpInterface, decodeInUse) 51 { 52 MHW_FUNCTION_ENTER; 53 } 54 55 //! 56 //! \brief Destructor 57 //! ~MhwVdboxMfxInterfaceGeneric()58 virtual ~MhwVdboxMfxInterfaceGeneric() {} 59 AddMfdAvcPicidCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_PIC_ID_PARAMS params)60 MOS_STATUS AddMfdAvcPicidCmd( 61 PMOS_COMMAND_BUFFER cmdBuffer, 62 PMHW_VDBOX_PIC_ID_PARAMS params) 63 { 64 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 65 66 MHW_FUNCTION_ENTER; 67 68 MHW_MI_CHK_NULL(m_osInterface); 69 MHW_MI_CHK_NULL(cmdBuffer); 70 MHW_MI_CHK_NULL(params); 71 MHW_MI_CHK_NULL(params->pAvcPicIdx); 72 73 typename TMfxCmds::MFD_AVC_PICID_STATE_CMD cmd; 74 75 cmd.DW1.PictureidRemappingDisable = 1; 76 if (params->bPicIdRemappingInUse) 77 { 78 uint32_t j = 0; 79 cmd.DW1.PictureidRemappingDisable = 0; 80 81 for (auto i = 0; i < (CODEC_MAX_NUM_REF_FRAME / 2); i++) 82 { 83 cmd.Pictureidlist1616Bits[i] = avcPicidDefault; 84 85 if (params->pAvcPicIdx[j++].bValid) 86 { 87 cmd.Pictureidlist1616Bits[i] = (cmd.Pictureidlist1616Bits[i] & 0xffff0000) | params->pAvcPicIdx[j - 1].ucPicIdx; 88 } 89 90 if (params->pAvcPicIdx[j++].bValid) 91 { 92 cmd.Pictureidlist1616Bits[i] = (cmd.Pictureidlist1616Bits[i] & 0x0000ffff) | (params->pAvcPicIdx[j - 1].ucPicIdx << 16); 93 } 94 } 95 } 96 else 97 { 98 for (auto i = 0; i < (CODEC_MAX_NUM_REF_FRAME / 2); i++) 99 { 100 cmd.Pictureidlist1616Bits[i] = avcPicidDisabled; 101 } 102 } 103 104 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 105 106 return eStatus; 107 } 108 AddMfxQmCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_QM_PARAMS params)109 MOS_STATUS AddMfxQmCmd( 110 PMOS_COMMAND_BUFFER cmdBuffer, 111 PMHW_VDBOX_QM_PARAMS params) 112 { 113 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 114 115 MHW_FUNCTION_ENTER; 116 117 MHW_MI_CHK_NULL(m_osInterface); 118 MHW_MI_CHK_NULL(cmdBuffer); 119 MHW_MI_CHK_NULL(params); 120 121 typename TMfxCmds::MFX_QM_STATE_CMD cmd; 122 123 uint8_t* qMatrix = (uint8_t*)cmd.ForwardQuantizerMatrix; 124 125 if (params->Standard == CODECHAL_AVC) 126 { 127 MHW_MI_CHK_NULL(params->pAvcIqMatrix); 128 129 for (auto i = 0; i < 16; i++) 130 { 131 cmd.ForwardQuantizerMatrix[i] = 0; 132 } 133 134 cmd.DW1.Obj0.Avc = avcQmIntra4x4; 135 for (auto i = 0; i < 3; i++) 136 { 137 for (auto ii = 0; ii < 16; ii++) 138 { 139 qMatrix[i * 16 + ii] = params->pAvcIqMatrix->List4x4[i][ii]; 140 } 141 } 142 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 143 144 cmd.DW1.Obj0.Avc = avcQmInter4x4; 145 for (auto i = 3; i < 6; i++) 146 { 147 for (auto ii = 0; ii < 16; ii++) 148 { 149 qMatrix[(i - 3) * 16 + ii] = params->pAvcIqMatrix->List4x4[i][ii]; 150 } 151 } 152 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 153 154 cmd.DW1.Obj0.Avc = avcQmIntra8x8; 155 for (auto ii = 0; ii < 64; ii++) 156 { 157 qMatrix[ii] = params->pAvcIqMatrix->List8x8[0][ii]; 158 } 159 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 160 161 cmd.DW1.Obj0.Avc = avcQmInter8x8; 162 for (auto ii = 0; ii < 64; ii++) 163 { 164 qMatrix[ii] = params->pAvcIqMatrix->List8x8[1][ii]; 165 } 166 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 167 } 168 else if (params->Standard == CODECHAL_MPEG2) 169 { 170 MHW_MI_CHK_NULL(params->pMpeg2IqMatrix); 171 172 if (params->Mode == CODECHAL_ENCODE_MODE_MPEG2) 173 { 174 cmd.DW1.Obj0.Avc = mpeg2QmIntra; 175 if (params->pMpeg2IqMatrix->m_loadIntraQuantiserMatrix) 176 { 177 for (auto i = 0; i < 64; i++) 178 { 179 qMatrix[i] = (uint8_t)(params->pMpeg2IqMatrix->m_intraQuantiserMatrix[m_mpeg2QuantMatrixScan[i]]); 180 } 181 } 182 else 183 { 184 for (auto i = 0; i < 64; i++) 185 { 186 qMatrix[i] = (uint8_t)(m_mpeg2DefaultIntraQuantizerMatrix[i]); 187 } 188 } 189 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 190 191 cmd.DW1.Obj0.Avc = mpeg2QmNonIntra; 192 if (params->pMpeg2IqMatrix->m_loadNonIntraQuantiserMatrix) 193 { 194 for (auto i = 0; i < 64; i++) 195 { 196 qMatrix[i] = (uint8_t)(params->pMpeg2IqMatrix->m_nonIntraQuantiserMatrix[m_mpeg2QuantMatrixScan[i]]); 197 } 198 } 199 else 200 { 201 for (auto i = 0; i < 64; i++) 202 { 203 qMatrix[i] = (uint8_t)(m_mpeg2DefaultNonIntraQuantizerMatrix[i]); 204 } 205 } 206 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 207 } 208 else 209 { 210 cmd.DW1.Obj0.Avc = mpeg2QmIntra; 211 if (params->pMpeg2IqMatrix->m_loadIntraQuantiserMatrix) 212 { 213 uint8_t *src = params->pMpeg2IqMatrix->m_intraQuantiserMatrix; 214 for (auto i = 0; i < 64; i++) 215 { 216 qMatrix[i] = (uint8_t)(src[m_mpeg2QuantMatrixScan[i]]); 217 } 218 } 219 else 220 { 221 for (auto i = 0; i < 64; i++) 222 { 223 qMatrix[i] = (uint8_t)(m_mpeg2DefaultIntraQuantizerMatrix[i]); 224 } 225 } 226 227 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 228 229 cmd.DW1.Obj0.Avc = mpeg2QmNonIntra; 230 if (params->pMpeg2IqMatrix->m_loadNonIntraQuantiserMatrix) 231 { 232 uint8_t *src = params->pMpeg2IqMatrix->m_nonIntraQuantiserMatrix; 233 for (auto i = 0; i < 64; i++) 234 { 235 qMatrix[i] = (uint8_t)(src[m_mpeg2QuantMatrixScan[i]]); 236 } 237 } 238 else 239 { 240 for (auto i = 0; i < 64; i++) 241 { 242 qMatrix[i] = (uint8_t)(m_mpeg2DefaultNonIntraQuantizerMatrix[i]); 243 } 244 } 245 246 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 247 } 248 } 249 else if (params->Standard == CODECHAL_JPEG) 250 { 251 MHW_MI_CHK_NULL(params->pJpegQuantMatrix); 252 cmd.DW1.Obj0.Avc = params->pJpegQuantMatrix->m_jpegQMTableType[params->JpegQMTableSelector]; 253 254 if (params->bJpegQMRotation) 255 { 256 for (auto i = 0; i < 8; i++) 257 { 258 for (auto ii = 0; ii < 8; ii++) 259 { 260 qMatrix[i + 8 * ii] = params->pJpegQuantMatrix->m_quantMatrix[params->JpegQMTableSelector][i * 8 + ii]; 261 } 262 } 263 } 264 else 265 { 266 for (auto i = 0; i < 64; i++) 267 { 268 qMatrix[i] = params->pJpegQuantMatrix->m_quantMatrix[params->JpegQMTableSelector][i]; 269 } 270 } 271 272 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 273 } 274 else 275 { 276 eStatus = MOS_STATUS_INVALID_PARAMETER; 277 } 278 279 return eStatus; 280 } 281 AddMfxFqmCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_QM_PARAMS params)282 MOS_STATUS AddMfxFqmCmd( 283 PMOS_COMMAND_BUFFER cmdBuffer, 284 PMHW_VDBOX_QM_PARAMS params) 285 { 286 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 287 288 MHW_FUNCTION_ENTER; 289 290 MHW_MI_CHK_NULL(m_osInterface); 291 MHW_MI_CHK_NULL(cmdBuffer); 292 MHW_MI_CHK_NULL(params); 293 294 typename TMfxCmds::MFX_FQM_STATE_CMD cmd; 295 296 if (params->Standard == CODECHAL_AVC) 297 { 298 MHW_MI_CHK_NULL(params->pAvcIqMatrix); 299 300 PMHW_VDBOX_AVC_QM_PARAMS iqMatrix = params->pAvcIqMatrix; 301 uint16_t *fqMatrix = (uint16_t*)cmd.ForwardQuantizerMatrix; 302 303 for (auto i = 0; i < 32; i++) 304 { 305 cmd.ForwardQuantizerMatrix[i] = 0; 306 } 307 308 cmd.DW1.Obj0.Avc = avcQmIntra4x4; 309 for (auto i = 0; i < 3; i++) 310 { 311 for (auto ii = 0; ii < 16; ii++) 312 { 313 fqMatrix[i * 16 + ii] = 314 GetReciprocalScalingValue(iqMatrix->List4x4[i][m_columnScan4x4[ii]]); 315 } 316 } 317 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 318 319 cmd.DW1.Obj0.Avc = avcQmInter4x4; 320 for (auto i = 0; i < 3; i++) 321 { 322 for (auto ii = 0; ii < 16; ii++) 323 { 324 fqMatrix[i * 16 + ii] = 325 GetReciprocalScalingValue(iqMatrix->List4x4[i + 3][m_columnScan4x4[ii]]); 326 } 327 } 328 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 329 330 cmd.DW1.Obj0.Avc = avcQmIntra8x8; 331 for (auto i = 0; i < 64; i++) 332 { 333 fqMatrix[i] = GetReciprocalScalingValue(iqMatrix->List8x8[0][m_columnScan8x8[i]]); 334 } 335 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 336 337 cmd.DW1.Obj0.Avc = avcQmInter8x8; 338 for (auto i = 0; i < 64; i++) 339 { 340 fqMatrix[i] = GetReciprocalScalingValue(iqMatrix->List8x8[1][m_columnScan8x8[i]]); 341 } 342 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 343 } 344 else if (params->Standard == CODECHAL_MPEG2) 345 { 346 uint16_t *fqMatrix = (uint16_t*)cmd.ForwardQuantizerMatrix; 347 348 cmd.DW1.Obj0.Avc = mpeg2QmIntra; 349 if (params->pMpeg2IqMatrix->m_loadIntraQuantiserMatrix) 350 { 351 for (auto i = 0; i < 64; i++) 352 { 353 fqMatrix[i] = GetReciprocalScalingValue( 354 (uint8_t)(params->pMpeg2IqMatrix->m_intraQuantiserMatrix[m_mpeg2QuantMatrixScan[m_columnScan8x8[i]]])); 355 } 356 } 357 else 358 { 359 for (auto i = 0; i < 64; i++) 360 { 361 fqMatrix[i] = GetReciprocalScalingValue( 362 (uint8_t)m_mpeg2DefaultIntraQuantizerMatrix[m_columnScan8x8[i]]); 363 } 364 } 365 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 366 367 cmd.DW1.Obj0.Avc = mpeg2QmNonIntra; 368 if (params->pMpeg2IqMatrix->m_loadNonIntraQuantiserMatrix) 369 { 370 for (auto i = 0; i < 64; i++) 371 { 372 fqMatrix[i] = GetReciprocalScalingValue( 373 (uint8_t)(params->pMpeg2IqMatrix->m_nonIntraQuantiserMatrix[m_mpeg2QuantMatrixScan[m_columnScan8x8[i]]])); 374 } 375 } 376 else 377 { 378 for (auto i = 0; i < 64; i++) 379 { 380 fqMatrix[i] = GetReciprocalScalingValue( 381 (uint8_t)m_mpeg2DefaultNonIntraQuantizerMatrix[m_columnScan8x8[i]]); 382 } 383 } 384 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 385 } 386 387 return eStatus; 388 } 389 AddMfxAvcRefIdx(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_REF_IDX_PARAMS params)390 MOS_STATUS AddMfxAvcRefIdx( 391 PMOS_COMMAND_BUFFER cmdBuffer, 392 PMHW_BATCH_BUFFER batchBuffer, 393 PMHW_VDBOX_AVC_REF_IDX_PARAMS params) 394 { 395 MHW_FUNCTION_ENTER; 396 397 MHW_MI_CHK_NULL(params); 398 399 if (cmdBuffer == nullptr && batchBuffer == nullptr) 400 { 401 MHW_ASSERTMESSAGE("No valid buffer to add the command to!"); 402 return MOS_STATUS_INVALID_PARAMETER; 403 } 404 405 typename TMfxCmds::MFX_AVC_REF_IDX_STATE_CMD cmd; 406 407 // Need to add an empty MFX_AVC_REF_IDX_STATE_CMD for dummy reference on I-Frame 408 if (!params->bDummyReference) 409 { 410 auto uiList = params->uiList; 411 412 cmd.DW1.RefpiclistSelect = uiList; 413 414 CODEC_REF_LIST **avcRefList = (CODEC_REF_LIST **)params->avcRefList; 415 AvcRefListWrite *cmdAvcRefListWrite = (AvcRefListWrite *)&(cmd.ReferenceListEntry); 416 417 uint8_t picIDOneOnOneMapping = 0; 418 if (params->bVdencInUse && uiList == LIST_1) 419 { 420 picIDOneOnOneMapping += params->uiNumRefForList[LIST_0] << 1; 421 } 422 423 for (uint32_t i = 0; i < params->uiNumRefForList[uiList]; i++) 424 { 425 uint8_t idx = params->RefPicList[uiList][i].FrameIdx; 426 427 if (!params->bIntelEntrypointInUse) 428 { 429 if (idx >= CODEC_MAX_NUM_REF_FRAME) 430 { 431 MHW_ASSERT(false); // Idx must be within 0 to 15 432 idx = 0; 433 } 434 435 idx = params->pAvcPicIdx[idx].ucPicIdx; 436 } 437 438 uint8_t picID = params->bPicIdRemappingInUse ? 439 params->RefPicList[uiList][i].FrameIdx : avcRefList[idx]->ucFrameId; 440 441 // When one on one ref idx mapping is enabled, program picID count from 0, 2 ... 442 if (params->oneOnOneMapping) 443 { 444 picID = picIDOneOnOneMapping; 445 picIDOneOnOneMapping += 2; 446 } 447 cmdAvcRefListWrite->UC[i].frameStoreID = picID; 448 cmdAvcRefListWrite->UC[i].bottomField = 449 CodecHal_PictureIsBottomField(params->RefPicList[uiList][i]); 450 cmdAvcRefListWrite->UC[i].fieldPicFlag = 451 CodecHal_PictureIsField(params->RefPicList[uiList][i]); 452 cmdAvcRefListWrite->UC[i].longTermFlag = 453 CodecHal_PictureIsLongTermRef(avcRefList[idx]->RefPic); 454 cmdAvcRefListWrite->UC[i].nonExisting = 0; 455 } 456 457 for (auto i = params->uiNumRefForList[uiList]; i < 32; i++) 458 { 459 cmdAvcRefListWrite->UC[i].value = 0x80; 460 } 461 } 462 463 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, sizeof(cmd))); 464 465 return MOS_STATUS_SUCCESS; 466 } 467 AddMfxDecodeAvcWeightOffset(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS params)468 MOS_STATUS AddMfxDecodeAvcWeightOffset( 469 PMOS_COMMAND_BUFFER cmdBuffer, 470 PMHW_BATCH_BUFFER batchBuffer, 471 PMHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS params) 472 { 473 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 474 475 MHW_FUNCTION_ENTER; 476 477 MHW_MI_CHK_NULL(params); 478 479 if (cmdBuffer == nullptr && batchBuffer == nullptr) 480 { 481 MHW_ASSERTMESSAGE("No valid buffer to add the command to!"); 482 return MOS_STATUS_INVALID_PARAMETER; 483 } 484 485 typename TMfxCmds::MFX_AVC_WEIGHTOFFSET_STATE_CMD cmd; 486 487 cmd.DW1.WeightAndOffsetSelect = params->uiList; 488 489 //The correct explicit calculation (like in Cantiga) 490 for (auto i = 0; i < CODEC_MAX_NUM_REF_FIELD; i++) 491 { 492 cmd.Weightoffset[3 * i] = params->Weights[params->uiList][i][0][0] & 0xFFFF; // Y weight 493 cmd.Weightoffset[3 * i] |= (params->Weights[params->uiList][i][0][1] & 0xFFFF) << 16; // Y offset 494 cmd.Weightoffset[3 * i + 1] = params->Weights[params->uiList][i][1][0] & 0xFFFF; // Cb weight 495 cmd.Weightoffset[3 * i + 1] |= (params->Weights[params->uiList][i][1][1] & 0xFFFF) << 16; // Cb offset 496 cmd.Weightoffset[3 * i + 2] = params->Weights[params->uiList][i][2][0] & 0xFFFF; // Cr weight 497 cmd.Weightoffset[3 * i + 2] |= (params->Weights[params->uiList][i][2][1] & 0xFFFF) << 16; // Cr offset 498 } 499 500 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, sizeof(cmd))); 501 502 return eStatus; 503 } 504 AddMfxEncodeAvcWeightOffset(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS params)505 MOS_STATUS AddMfxEncodeAvcWeightOffset( 506 PMOS_COMMAND_BUFFER cmdBuffer, 507 PMHW_BATCH_BUFFER batchBuffer, 508 PMHW_VDBOX_AVC_WEIGHTOFFSET_PARAMS params) 509 { 510 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 511 512 MHW_FUNCTION_ENTER; 513 514 MHW_MI_CHK_NULL(params); 515 516 if (cmdBuffer == nullptr && batchBuffer == nullptr) 517 { 518 MHW_ASSERTMESSAGE("No valid buffer to add the command to!"); 519 return MOS_STATUS_INVALID_PARAMETER; 520 } 521 522 typename TMfxCmds::MFX_AVC_WEIGHTOFFSET_STATE_CMD cmd; 523 524 cmd.DW1.WeightAndOffsetSelect = params->uiList; 525 526 for (uint32_t i = 0; i < params->uiNumRefForList; i++) 527 { 528 if (params->uiLumaWeightFlag & (1 << i)) 529 { 530 cmd.Weightoffset[3 * i] = params->Weights[params->uiList][i][0][0] & 0xFFFF; // Y weight 531 cmd.Weightoffset[3 * i] |= (params->Weights[params->uiList][i][0][1] & 0xFFFF) << 16; // Y offset 532 } 533 else 534 { 535 cmd.Weightoffset[3 * i] = 1 << (params->uiLumaLogWeightDenom); // Y weight 536 cmd.Weightoffset[3 * i] = cmd.Weightoffset[3 * i] | (0 << 16); // Y offset 537 } 538 539 if (params->uiChromaWeightFlag & (1 << i)) 540 { 541 cmd.Weightoffset[3 * i + 1] = params->Weights[params->uiList][i][1][0] & 0xFFFF; // Cb weight 542 cmd.Weightoffset[3 * i + 1] |= (params->Weights[params->uiList][i][1][1] & 0xFFFF) << 16; // Cb offset 543 cmd.Weightoffset[3 * i + 2] = params->Weights[params->uiList][i][2][0] & 0xFFFF; // Cr weight 544 cmd.Weightoffset[3 * i + 2] |= (params->Weights[params->uiList][i][2][1] & 0xFFFF) << 16; // Cr offset 545 } 546 else 547 { 548 cmd.Weightoffset[3 * i + 1] = 1 << (params->uiChromaLogWeightDenom); // Cb weight 549 cmd.Weightoffset[3 * i + 1] = cmd.Weightoffset[3 * i + 1] | (0 << 16); // Cb offset 550 cmd.Weightoffset[3 * i + 2] = 1 << (params->uiChromaLogWeightDenom); // Cr weight 551 cmd.Weightoffset[3 * i + 2] = cmd.Weightoffset[3 * i + 2] | (0 << 16); // Cr offset 552 } 553 } 554 555 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, sizeof(cmd))); 556 557 return eStatus; 558 } 559 AddMfxDecodeAvcSlice(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)560 MOS_STATUS AddMfxDecodeAvcSlice( 561 PMOS_COMMAND_BUFFER cmdBuffer, 562 PMHW_BATCH_BUFFER batchBuffer, 563 PMHW_VDBOX_AVC_SLICE_STATE avcSliceState) 564 { 565 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 566 567 MHW_FUNCTION_ENTER; 568 569 MHW_MI_CHK_NULL(avcSliceState); 570 MHW_MI_CHK_NULL(avcSliceState->pAvcPicParams); 571 MHW_MI_CHK_NULL(avcSliceState->pAvcSliceParams); 572 573 if (cmdBuffer == nullptr && batchBuffer == nullptr) 574 { 575 MHW_ASSERTMESSAGE("No valid buffer to add the command to!"); 576 return MOS_STATUS_INVALID_PARAMETER; 577 } 578 579 auto picParams = avcSliceState->pAvcPicParams; 580 uint32_t mbaffMultiplier = 1; 581 if (picParams->seq_fields.mb_adaptive_frame_field_flag && 582 !picParams->pic_fields.field_pic_flag) 583 { 584 mbaffMultiplier++; 585 } 586 587 uint16_t frameFieldHeightInMb = 0; 588 CodecHal_GetFrameFieldHeightInMb( 589 picParams->CurrPic, 590 picParams->pic_height_in_mbs_minus1 + 1, 591 frameFieldHeightInMb); 592 593 auto sliceParams = avcSliceState->pAvcSliceParams; 594 typename TMfxCmds::MFX_AVC_SLICE_STATE_CMD cmd; 595 596 // Set MFX_AVC_SLICE_STATE_CMD 597 cmd.DW1.SliceType = m_AvcBsdSliceType[sliceParams->slice_type]; 598 cmd.DW2.Log2WeightDenomChroma = sliceParams->chroma_log2_weight_denom; 599 cmd.DW2.Log2WeightDenomLuma = sliceParams->luma_log2_weight_denom; 600 cmd.DW3.WeightedPredictionIndicator = 0; 601 cmd.DW3.DisableDeblockingFilterIndicator = avcSliceState->ucDisableDeblockingFilterIdc; 602 cmd.DW3.CabacInitIdc10 = sliceParams->cabac_init_idc; 603 cmd.DW3.SliceQuantizationParameter = 26 + picParams->pic_init_qp_minus26 + sliceParams->slice_qp_delta; 604 cmd.DW3.SliceBetaOffsetDiv2 = avcSliceState->ucSliceBetaOffsetDiv2; 605 cmd.DW3.SliceAlphaC0OffsetDiv2 = avcSliceState->ucSliceAlphaC0OffsetDiv2; 606 607 auto widthInMb = picParams->pic_width_in_mbs_minus1 + 1; 608 cmd.DW4.SliceStartMbNum = sliceParams->first_mb_in_slice * mbaffMultiplier; 609 cmd.DW4.SliceVerticalPosition = (sliceParams->first_mb_in_slice / widthInMb) * mbaffMultiplier; 610 cmd.DW4.SliceHorizontalPosition = sliceParams->first_mb_in_slice % widthInMb; 611 612 if (avcSliceState->bLastSlice) 613 { 614 cmd.DW5.NextSliceVerticalPosition = frameFieldHeightInMb; 615 cmd.DW5.NextSliceHorizontalPosition = 0; 616 } 617 else 618 { 619 cmd.DW5.NextSliceVerticalPosition = (sliceParams->first_mb_in_next_slice / widthInMb) * mbaffMultiplier; 620 cmd.DW5.NextSliceHorizontalPosition = sliceParams->first_mb_in_next_slice % widthInMb; 621 } 622 623 cmd.DW6.IsLastSlice = avcSliceState->bLastSlice; 624 625 cmd.DW9.Roundintra = 5; 626 cmd.DW9.Roundintraenable = 1; 627 cmd.DW9.Roundinter = 2; 628 629 if (IsAvcPSlice(sliceParams->slice_type)) 630 { 631 cmd.DW2.NumberOfReferencePicturesInInterPredictionList0 = sliceParams->num_ref_idx_l0_active_minus1 + 1; 632 cmd.DW3.WeightedPredictionIndicator = picParams->pic_fields.weighted_pred_flag; 633 } 634 else if (IsAvcBSlice(sliceParams->slice_type)) 635 { 636 cmd.DW2.NumberOfReferencePicturesInInterPredictionList1 = sliceParams->num_ref_idx_l1_active_minus1 + 1; 637 cmd.DW2.NumberOfReferencePicturesInInterPredictionList0 = sliceParams->num_ref_idx_l0_active_minus1 + 1; 638 cmd.DW3.WeightedPredictionIndicator = picParams->pic_fields.weighted_bipred_idc; 639 cmd.DW3.DirectPredictionType = sliceParams->direct_spatial_mv_pred_flag; 640 641 // Set MFX_AVC_WEIGHTOFFSET_STATE_CMD_G6 642 if (picParams->pic_fields.weighted_bipred_idc != 1) 643 { 644 // luma/chroma_log2_weight_denoms need to be set to default value in the case of implicit mode 645 cmd.DW2.Log2WeightDenomChroma = m_log2WeightDenomDefault; 646 cmd.DW2.Log2WeightDenomLuma = m_log2WeightDenomDefault; 647 } 648 } 649 650 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, sizeof(cmd))); 651 652 return eStatus; 653 } 654 AddMfxEncodeAvcSlice(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_AVC_SLICE_STATE avcSliceState)655 MOS_STATUS AddMfxEncodeAvcSlice( 656 PMOS_COMMAND_BUFFER cmdBuffer, 657 PMHW_BATCH_BUFFER batchBuffer, 658 PMHW_VDBOX_AVC_SLICE_STATE avcSliceState) 659 { 660 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 661 662 MHW_FUNCTION_ENTER; 663 664 MHW_MI_CHK_NULL(avcSliceState); 665 MHW_MI_CHK_NULL(avcSliceState->pEncodeAvcSeqParams); 666 MHW_MI_CHK_NULL(avcSliceState->pEncodeAvcPicParams); 667 MHW_MI_CHK_NULL(avcSliceState->pEncodeAvcSliceParams); 668 669 if (cmdBuffer == nullptr && batchBuffer == nullptr) 670 { 671 MHW_ASSERTMESSAGE("No valid buffer to add the command to!"); 672 return MOS_STATUS_INVALID_PARAMETER; 673 } 674 675 auto seqParams = avcSliceState->pEncodeAvcSeqParams; 676 auto sliceParams = avcSliceState->pEncodeAvcSliceParams; 677 auto picParams = avcSliceState->pEncodeAvcPicParams; 678 679 uint16_t widthInMb = seqParams->pic_width_in_mbs_minus1 + 1; 680 uint16_t frameFieldHeightInMb = avcSliceState->wFrameFieldHeightInMB; 681 bool mbaffFrameFlag = seqParams->mb_adaptive_frame_field_flag ? true : false; 682 uint32_t startMbNum = sliceParams->first_mb_in_slice * (1 + mbaffFrameFlag); 683 684 typename TMfxCmds::MFX_AVC_SLICE_STATE_CMD cmd; 685 686 //DW1 687 cmd.DW1.SliceType = Slice_Type[sliceParams->slice_type]; 688 //DW2 689 cmd.DW2.Log2WeightDenomLuma = sliceParams->luma_log2_weight_denom; 690 cmd.DW2.Log2WeightDenomChroma = sliceParams->chroma_log2_weight_denom; 691 cmd.DW2.NumberOfReferencePicturesInInterPredictionList0 = 0; 692 cmd.DW2.NumberOfReferencePicturesInInterPredictionList1 = 0; 693 //DW3 694 cmd.DW3.SliceAlphaC0OffsetDiv2 = sliceParams->slice_alpha_c0_offset_div2; 695 cmd.DW3.SliceBetaOffsetDiv2 = sliceParams->slice_beta_offset_div2; 696 cmd.DW3.SliceQuantizationParameter = 26 + picParams->pic_init_qp_minus26 + sliceParams->slice_qp_delta; 697 cmd.DW3.CabacInitIdc10 = sliceParams->cabac_init_idc; 698 cmd.DW3.DisableDeblockingFilterIndicator = sliceParams->disable_deblocking_filter_idc; 699 cmd.DW3.DirectPredictionType = 700 IsAvcBSlice(sliceParams->slice_type) ? sliceParams->direct_spatial_mv_pred_flag : 0; 701 cmd.DW3.WeightedPredictionIndicator = DEFAULT_WEIGHTED_INTER_PRED_MODE; 702 //DW4 703 cmd.DW4.SliceHorizontalPosition = startMbNum % widthInMb; 704 cmd.DW4.SliceVerticalPosition = startMbNum / widthInMb; 705 //DW5 706 cmd.DW5.NextSliceHorizontalPosition = (startMbNum + sliceParams->NumMbsForSlice) % widthInMb; 707 cmd.DW5.NextSliceVerticalPosition = (startMbNum + sliceParams->NumMbsForSlice) / widthInMb; 708 //DW6 709 cmd.DW6.StreamId10 = 0; 710 cmd.DW6.SliceId30 = sliceParams->slice_id; 711 cmd.DW6.Cabaczerowordinsertionenable = 1; 712 cmd.DW6.Emulationbytesliceinsertenable = 1; 713 cmd.DW6.IsLastSlice = 714 (startMbNum + sliceParams->NumMbsForSlice) >= (uint32_t)(widthInMb * frameFieldHeightInMb); 715 // Driver only programs 1st slice state, VDENC will detect the last slice 716 if (avcSliceState->bVdencInUse) 717 { 718 cmd.DW6.TailInsertionPresentInBitstream = avcSliceState->bVdencNoTailInsertion ? 719 0 : (picParams->bLastPicInSeq || picParams->bLastPicInStream); 720 } 721 else 722 { 723 cmd.DW6.TailInsertionPresentInBitstream = (picParams->bLastPicInSeq || picParams->bLastPicInStream) && cmd.DW6.IsLastSlice; 724 } 725 cmd.DW6.SlicedataInsertionPresentInBitstream = 1; 726 cmd.DW6.HeaderInsertionPresentInBitstream = 1; 727 cmd.DW6.MbTypeSkipConversionDisable = 0; 728 cmd.DW6.MbTypeDirectConversionDisable = 0; 729 cmd.DW6.RateControlCounterEnable = (avcSliceState->bBrcEnabled && (!avcSliceState->bFirstPass)); 730 731 if (cmd.DW6.RateControlCounterEnable == true) 732 { 733 // These fields are valid only when RateControlCounterEnable = 1 734 cmd.DW6.RcPanicType = 1; // CBP Panic 735 cmd.DW6.RcPanicEnable = 736 (avcSliceState->bRCPanicEnable && 737 (seqParams->RateControlMethod != RATECONTROL_AVBR) && 738 (seqParams->RateControlMethod != RATECONTROL_IWD_VBR) && 739 (seqParams->RateControlMethod != RATECONTROL_ICQ) && 740 (seqParams->RateControlMethod != RATECONTROL_VCM) && 741 (seqParams->RateControlMethod != RATECONTROL_CQP) && 742 avcSliceState->bLastPass); // Enable only in the last pass 743 cmd.DW6.RcStableTolerance = 0; 744 cmd.DW6.RcTriggleMode = 2; // Loose Rate Control 745 cmd.DW6.Resetratecontrolcounter = !startMbNum; 746 } 747 748 cmd.DW9.Roundinter = 2; 749 750 if (IsAvcPSlice(sliceParams->slice_type)) 751 { 752 cmd.DW2.NumberOfReferencePicturesInInterPredictionList0 = sliceParams->num_ref_idx_l0_active_minus1_from_DDI + 1; 753 cmd.DW3.WeightedPredictionIndicator = picParams->weighted_pred_flag; 754 755 cmd.DW9.Roundinterenable = avcSliceState->bRoundingInterEnable; 756 cmd.DW9.Roundinter = avcSliceState->dwRoundingValue; 757 } 758 else if (IsAvcBSlice(sliceParams->slice_type)) 759 { 760 cmd.DW2.NumberOfReferencePicturesInInterPredictionList1 = sliceParams->num_ref_idx_l1_active_minus1_from_DDI + 1; 761 cmd.DW2.NumberOfReferencePicturesInInterPredictionList0 = sliceParams->num_ref_idx_l0_active_minus1_from_DDI + 1; 762 cmd.DW3.WeightedPredictionIndicator = picParams->weighted_bipred_idc; 763 if (picParams->weighted_bipred_idc == IMPLICIT_WEIGHTED_INTER_PRED_MODE) 764 { 765 if (avcSliceState->bVdencInUse) 766 { 767 cmd.DW2.Log2WeightDenomLuma = 0; 768 cmd.DW2.Log2WeightDenomChroma = 0; 769 } 770 else 771 { 772 // SNB requirement 773 cmd.DW2.Log2WeightDenomLuma = 5; 774 cmd.DW2.Log2WeightDenomChroma = 5; 775 } 776 } 777 778 cmd.DW9.Roundinterenable = avcSliceState->bRoundingInterEnable; 779 cmd.DW9.Roundinter = avcSliceState->dwRoundingValue; 780 } 781 782 cmd.DW9.Roundintra = avcSliceState->dwRoundingIntraValue; 783 cmd.DW9.Roundintraenable = 1; 784 785 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, sizeof(cmd))); 786 787 return eStatus; 788 } 789 AddMfdAvcDpbCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_AVC_DPB_PARAMS params)790 MOS_STATUS AddMfdAvcDpbCmd( 791 PMOS_COMMAND_BUFFER cmdBuffer, 792 PMHW_VDBOX_AVC_DPB_PARAMS params) 793 { 794 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 795 796 MHW_FUNCTION_ENTER; 797 798 MHW_MI_CHK_NULL(m_osInterface); 799 MHW_MI_CHK_NULL(cmdBuffer); 800 MHW_MI_CHK_NULL(params); 801 MHW_MI_CHK_NULL(params->pAvcPicParams); 802 803 auto avcPicParams = params->pAvcPicParams; 804 auto currFrameIdx = avcPicParams->CurrPic.FrameIdx; 805 auto currAvcRefList = params->ppAvcRefList[currFrameIdx]; 806 807 int16_t refFrameOrder[CODEC_MAX_NUM_REF_FRAME] = { 0 }; 808 uint32_t usedForRef = 0; 809 uint16_t nonExistingFrameFlags = 0; 810 uint16_t longTermFrame = 0; 811 812 for (uint8_t i = 0; i < currAvcRefList->ucNumRef; i++) 813 { 814 auto picIdx = currAvcRefList->RefList[i].FrameIdx; 815 auto refAvcRefList = params->ppAvcRefList[picIdx]; 816 bool longTermFrameFlag = (currAvcRefList->RefList[i].PicFlags == PICTURE_LONG_TERM_REFERENCE); 817 818 uint8_t frameID = params->bPicIdRemappingInUse ? i : refAvcRefList->ucFrameId; 819 int16_t frameNum = refAvcRefList->sFrameNumber; 820 821 refFrameOrder[frameID] = frameNum; 822 usedForRef |= (((currAvcRefList->uiUsedForReferenceFlags >> (i * 2)) & 3) << (frameID * 2)); 823 nonExistingFrameFlags |= (((currAvcRefList->usNonExistingFrameFlags >> i) & 1) << frameID); 824 longTermFrame |= (((uint16_t)longTermFrameFlag) << frameID); 825 } 826 827 typename TMfxCmds::MFD_AVC_DPB_STATE_CMD cmd; 828 829 cmd.DW1.NonExistingframeFlag161Bit = nonExistingFrameFlags; 830 cmd.DW1.LongtermframeFlag161Bit = longTermFrame; 831 cmd.DW2.Value = usedForRef; 832 833 for (auto i = 0, j = 0; i < 8; i++, j++) 834 { 835 cmd.Ltstframenumlist1616Bits[i] = (refFrameOrder[j++] & 0xFFFF); //FirstEntry 836 cmd.Ltstframenumlist1616Bits[i] = cmd.Ltstframenumlist1616Bits[i] | ((refFrameOrder[j] & 0xFFFF) << 16); //SecondEntry 837 } 838 839 auto mvcExtPicParams = params->pMvcExtPicParams; 840 if (mvcExtPicParams) 841 { 842 for (auto i = 0, j = 0; i < (CODEC_MAX_NUM_REF_FRAME / 2); i++, j++) 843 { 844 cmd.Viewidlist1616Bits[i] = mvcExtPicParams->ViewIDList[j++]; 845 cmd.Viewidlist1616Bits[i] = cmd.Viewidlist1616Bits[i] | (mvcExtPicParams->ViewIDList[j] << 16); 846 } 847 848 for (auto i = 0, j = 0; i < (CODEC_MAX_NUM_REF_FRAME / 4); i++, j++) 849 { 850 cmd.Vieworderlistl0168Bits[i] = GetViewOrder(params, j++, LIST_0); //FirstEntry 851 cmd.Vieworderlistl0168Bits[i] = cmd.Vieworderlistl0168Bits[i] | (GetViewOrder(params, j++, LIST_0) << 8); //SecondEntry 852 cmd.Vieworderlistl0168Bits[i] = cmd.Vieworderlistl0168Bits[i] | (GetViewOrder(params, j++, LIST_0) << 16); //ThirdEntry 853 cmd.Vieworderlistl0168Bits[i] = cmd.Vieworderlistl0168Bits[i] | (GetViewOrder(params, j, LIST_0) << 24); //FourthEntry 854 } 855 856 for (auto i = 0, j = 0; i < (CODEC_MAX_NUM_REF_FRAME / 4); i++, j++) 857 { 858 cmd.Vieworderlistl1168Bits[i] = GetViewOrder(params, j++, LIST_1); //FirstEntry 859 cmd.Vieworderlistl1168Bits[i] = cmd.Vieworderlistl1168Bits[i] | (GetViewOrder(params, j++, LIST_1) << 8); //SecondEntry 860 cmd.Vieworderlistl1168Bits[i] = cmd.Vieworderlistl1168Bits[i] | (GetViewOrder(params, j++, LIST_1) << 16); //ThirdEntry 861 cmd.Vieworderlistl1168Bits[i] = cmd.Vieworderlistl1168Bits[i] | (GetViewOrder(params, j, LIST_1) << 24); //FourthEntry 862 } 863 } 864 else 865 { 866 for (auto i = 0, j = 0; i < (CODEC_MAX_NUM_REF_FRAME / 2); i++, j++) 867 { 868 cmd.Viewidlist1616Bits[i] = 0; 869 } 870 871 for (auto i = 0, j = 0; i < (CODEC_MAX_NUM_REF_FRAME / 4); i++, j++) 872 { 873 cmd.Vieworderlistl0168Bits[i] = 0; //FirstEntry 874 } 875 876 for (auto i = 0, j = 0; i < (CODEC_MAX_NUM_REF_FRAME / 4); i++, j++) 877 { 878 cmd.Vieworderlistl1168Bits[i] = 0; //FirstEntry 879 } 880 } 881 882 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 883 884 return eStatus; 885 } 886 AddMfxAvcImgBrcBuffer(PMOS_RESOURCE brcImgBuffer,PMHW_VDBOX_AVC_IMG_PARAMS params)887 MOS_STATUS AddMfxAvcImgBrcBuffer( 888 PMOS_RESOURCE brcImgBuffer, 889 PMHW_VDBOX_AVC_IMG_PARAMS params) 890 { 891 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 892 893 MHW_FUNCTION_ENTER; 894 895 MHW_MI_CHK_NULL(brcImgBuffer); 896 MHW_MI_CHK_NULL(params); 897 898 MOS_LOCK_PARAMS lockFlags; 899 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); 900 lockFlags.WriteOnly = 1; 901 uint8_t *data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, brcImgBuffer, &lockFlags); 902 MHW_MI_CHK_NULL(data); 903 904 MOS_COMMAND_BUFFER constructedCmdBuf; 905 constructedCmdBuf.pCmdBase = (uint32_t *)data; 906 constructedCmdBuf.pCmdPtr = (uint32_t *)data; 907 constructedCmdBuf.iOffset = 0; 908 constructedCmdBuf.iRemaining = BRC_IMG_STATE_SIZE_PER_PASS * m_numBrcPakPasses; 909 910 MHW_MI_CHK_STATUS(AddMfxAvcImgCmd(&constructedCmdBuf, nullptr, params)); 911 912 typename TMfxCmds::MFX_AVC_IMG_STATE_CMD cmd = *(typename TMfxCmds::MFX_AVC_IMG_STATE_CMD *)data; 913 914 for (uint32_t i = 0; i < m_numBrcPakPasses; i++) 915 { 916 if (i == 0) 917 { 918 cmd.DW4.Mbstatenabled = 919 cmd.DW5.Nonfirstpassflag = false; 920 } 921 else 922 { 923 cmd.DW4.Mbstatenabled = true; 924 cmd.DW5.IntraIntermbipcmflagForceipcmcontrolmask = true; 925 cmd.DW5.Nonfirstpassflag = true; 926 } 927 928 /* Setting the MbRateCtrlFlag to 0 so that the accumulative delta QP for consecutive passes is applied on top of 929 the macroblock QP values in inline data. This is changed because the streamout QP behavior is causing a mismatch 930 between the HW output and prototype output.*/ 931 cmd.DW5.MbratectrlflagMbLevelRateControlEnablingFlag = false; 932 *(typename TMfxCmds::MFX_AVC_IMG_STATE_CMD *)data = cmd; 933 934 /* add batch buffer end insertion flag */ 935 uint32_t* insertion = (uint32_t*)(data + (TMfxCmds::MFX_AVC_IMG_STATE_CMD::byteSize)); 936 *insertion = 0x05000000; 937 938 data += BRC_IMG_STATE_SIZE_PER_PASS; 939 } 940 941 return eStatus; 942 } 943 AddMfxDecodeMpeg2PicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_MPEG2_PIC_STATE params)944 MOS_STATUS AddMfxDecodeMpeg2PicCmd( 945 PMOS_COMMAND_BUFFER cmdBuffer, 946 PMHW_VDBOX_MPEG2_PIC_STATE params) 947 { 948 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 949 950 MHW_FUNCTION_ENTER; 951 952 MHW_MI_CHK_NULL(m_osInterface); 953 MHW_MI_CHK_NULL(cmdBuffer); 954 MHW_MI_CHK_NULL(params); 955 MHW_MI_CHK_NULL(params->pMpeg2PicParams); 956 957 typename TMfxCmds::MFX_MPEG2_PIC_STATE_CMD cmd; 958 auto picParams = params->pMpeg2PicParams; 959 960 cmd.DW1.ScanOrder = picParams->W0.m_scanOrder; 961 cmd.DW1.IntraVlcFormat = picParams->W0.m_intraVlcFormat; 962 cmd.DW1.QuantizerScaleType = picParams->W0.m_quantizerScaleType; 963 cmd.DW1.ConcealmentMotionVectorFlag = picParams->W0.m_concealmentMVFlag; 964 cmd.DW1.FramePredictionFrameDct = picParams->W0.m_frameDctPrediction; 965 cmd.DW1.TffTopFieldFirst = (CodecHal_PictureIsFrame(picParams->m_currPic)) ? 966 picParams->W0.m_topFieldFirst : picParams->m_topFieldFirst; 967 968 cmd.DW1.PictureStructure = (CodecHal_PictureIsFrame(picParams->m_currPic)) ? 969 mpeg2Vc1Frame : (CodecHal_PictureIsTopField(picParams->m_currPic)) ? 970 mpeg2Vc1TopField : mpeg2Vc1BottomField; 971 cmd.DW1.IntraDcPrecision = picParams->W0.m_intraDCPrecision; 972 cmd.DW1.FCode00 = picParams->W1.m_fcode00; 973 cmd.DW1.FCode01 = picParams->W1.m_fcode01; 974 cmd.DW1.FCode10 = picParams->W1.m_fcode10; 975 cmd.DW1.FCode11 = picParams->W1.m_fcode11; 976 977 cmd.DW2.PictureCodingType = picParams->m_pictureCodingType; 978 979 if (params->Mode == CODECHAL_DECODE_MODE_MPEG2VLD) 980 { 981 cmd.DW2.ISliceConcealmentMode = params->dwMPEG2ISliceConcealmentMode; 982 cmd.DW2.PBSliceConcealmentMode = params->dwMPEG2PBSliceConcealmentMode; 983 cmd.DW2.PBSlicePredictedBidirMotionTypeOverrideBiDirectionMvTypeOverride = params->dwMPEG2PBSlicePredBiDirMVTypeOverride; 984 cmd.DW2.PBSlicePredictedMotionVectorOverrideFinalMvValueOverride = params->dwMPEG2PBSlicePredMVOverride; 985 986 cmd.DW3.SliceConcealmentDisableBit = 1; 987 } 988 989 uint16_t widthInMbs = 990 (picParams->m_horizontalSize + CODECHAL_MACROBLOCK_WIDTH - 1) / 991 CODECHAL_MACROBLOCK_WIDTH; 992 993 uint16_t heightInMbs = 994 (picParams->m_verticalSize + CODECHAL_MACROBLOCK_HEIGHT - 1) / 995 CODECHAL_MACROBLOCK_HEIGHT; 996 997 cmd.DW3.Framewidthinmbsminus170PictureWidthInMacroblocks = widthInMbs - 1; 998 cmd.DW3.Frameheightinmbsminus170PictureHeightInMacroblocks = (CodecHal_PictureIsField(picParams->m_currPic)) ? 999 ((heightInMbs * 2) - 1) : heightInMbs - 1; 1000 1001 if (params->bDeblockingEnabled) 1002 { 1003 cmd.DW3.Reserved120 = 9; 1004 } 1005 1006 cmd.DW4.Roundintradc = 3; 1007 cmd.DW4.Roundinterdc = 1; 1008 cmd.DW4.Roundintraac = 5; 1009 cmd.DW4.Roundinterac = 1; 1010 1011 cmd.DW6.Intrambmaxsize = 0xfff; 1012 cmd.DW6.Intermbmaxsize = 0xfff; 1013 1014 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 1015 1016 return eStatus; 1017 } 1018 AddMfxEncodeMpeg2PicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_MPEG2_PIC_STATE params)1019 MOS_STATUS AddMfxEncodeMpeg2PicCmd( 1020 PMOS_COMMAND_BUFFER cmdBuffer, 1021 PMHW_VDBOX_MPEG2_PIC_STATE params) 1022 { 1023 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1024 1025 MHW_FUNCTION_ENTER; 1026 1027 MHW_MI_CHK_NULL(m_osInterface); 1028 MHW_MI_CHK_NULL(cmdBuffer); 1029 MHW_MI_CHK_NULL(params); 1030 MHW_MI_CHK_NULL(params->pEncodeMpeg2PicParams); 1031 1032 typename TMfxCmds::MFX_MPEG2_PIC_STATE_CMD cmd; 1033 auto picParams = params->pEncodeMpeg2PicParams; 1034 1035 cmd.DW1.ScanOrder = picParams->m_alternateScan; 1036 cmd.DW1.IntraVlcFormat = picParams->m_intraVlcFormat; 1037 cmd.DW1.QuantizerScaleType = picParams->m_qscaleType; 1038 cmd.DW1.ConcealmentMotionVectorFlag = picParams->m_concealmentMotionVectors; 1039 cmd.DW1.FramePredictionFrameDct = picParams->m_framePredFrameDCT; 1040 cmd.DW1.TffTopFieldFirst = !picParams->m_interleavedFieldBFF; 1041 cmd.DW1.PictureStructure = (CodecHal_PictureIsFrame(picParams->m_currOriginalPic)) ? 1042 mpeg2Vc1Frame : (CodecHal_PictureIsTopField(picParams->m_currOriginalPic)) ? 1043 mpeg2Vc1TopField : mpeg2Vc1BottomField; 1044 cmd.DW1.IntraDcPrecision = picParams->m_intraDCprecision; 1045 if (picParams->m_pictureCodingType == I_TYPE) 1046 { 1047 cmd.DW1.FCode00 = 0xf; 1048 cmd.DW1.FCode01 = 0xf; 1049 } 1050 else 1051 { 1052 cmd.DW1.FCode00 = picParams->m_fcode00; 1053 cmd.DW1.FCode01 = picParams->m_fcode01; 1054 } 1055 cmd.DW1.FCode10 = picParams->m_fcode10; 1056 cmd.DW1.FCode11 = picParams->m_fcode11; 1057 1058 cmd.DW2.PictureCodingType = picParams->m_pictureCodingType; 1059 cmd.DW2.LoadslicepointerflagLoadbitstreampointerperslice = 0; // Do not reload bitstream pointer for each slice 1060 1061 cmd.DW3.Framewidthinmbsminus170PictureWidthInMacroblocks = params->wPicWidthInMb - 1; 1062 cmd.DW3.Frameheightinmbsminus170PictureHeightInMacroblocks = params->wPicHeightInMb - 1; 1063 1064 cmd.DW4.Roundintradc = 3; 1065 cmd.DW4.Roundinterdc = 1; 1066 cmd.DW4.Roundintraac = 5; 1067 cmd.DW4.Roundinterac = 1; 1068 cmd.DW4.Mbstatenabled = 0; 1069 1070 cmd.DW5.Mbratecontrolmask = 0; 1071 cmd.DW5.Framesizecontrolmask = 0; // Disable first for PAK pass, used when MacroblockStatEnable is 1 1072 1073 cmd.DW6.Intrambmaxsize = 0xfff; 1074 cmd.DW6.Intermbmaxsize = 0xfff; 1075 1076 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 1077 1078 return eStatus; 1079 } 1080 AddMfdMpeg2BsdObject(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_MPEG2_SLICE_STATE params)1081 MOS_STATUS AddMfdMpeg2BsdObject( 1082 PMOS_COMMAND_BUFFER cmdBuffer, 1083 PMHW_BATCH_BUFFER batchBuffer, 1084 PMHW_VDBOX_MPEG2_SLICE_STATE params) 1085 { 1086 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1087 1088 MHW_FUNCTION_ENTER; 1089 1090 MHW_MI_CHK_NULL(params); 1091 MHW_MI_CHK_NULL(params->pMpeg2SliceParams); 1092 1093 if (cmdBuffer == nullptr && batchBuffer == nullptr) 1094 { 1095 MHW_ASSERTMESSAGE("No valid buffer to add the command to!"); 1096 return MOS_STATUS_INVALID_PARAMETER; 1097 } 1098 1099 typename TMfxCmds::MFD_MPEG2_BSD_OBJECT_CMD cmd; 1100 auto sliceParams = params->pMpeg2SliceParams; 1101 1102 uint32_t endMb = params->dwSliceStartMbOffset + sliceParams->m_numMbsForSlice; 1103 uint32_t slcLocation = (uint32_t)(sliceParams->m_sliceDataOffset + params->dwOffset); 1104 1105 cmd.DW1.IndirectBsdDataLength = params->dwLength; 1106 cmd.DW2.IndirectDataStartAddress = slcLocation; 1107 cmd.DW3.FirstMacroblockBitOffset = (sliceParams->m_macroblockOffset & 0x0007); 1108 1109 cmd.DW3.IsLastMb = cmd.DW3.LastPicSlice = params->bLastSlice; 1110 cmd.DW3.Reserved100 = 1111 ((endMb / params->wPicWidthInMb) != sliceParams->m_sliceVerticalPosition) ? 1 : 0; 1112 1113 cmd.DW3.MacroblockCount = sliceParams->m_numMbsForSlice; 1114 cmd.DW3.SliceHorizontalPosition = sliceParams->m_sliceHorizontalPosition; 1115 cmd.DW3.SliceVerticalPosition = sliceParams->m_sliceVerticalPosition; 1116 cmd.DW4.QuantizerScaleCode = sliceParams->m_quantiserScaleCode; 1117 1118 if (cmd.DW3.IsLastMb) 1119 { 1120 cmd.DW4.NextSliceHorizontalPosition = 0; 1121 cmd.DW4.NextSliceVerticalPosition = params->wPicHeightInMb; 1122 } 1123 else 1124 { 1125 cmd.DW4.NextSliceHorizontalPosition = endMb % params->wPicWidthInMb; 1126 cmd.DW4.NextSliceVerticalPosition = endMb / params->wPicWidthInMb; 1127 } 1128 1129 uint32_t offset = ((sliceParams->m_macroblockOffset & 0x0000fff8) >> 3); // #of bytes of header data in bitstream buffer (before video data) 1130 1131 MHW_CP_SLICE_INFO_PARAMS sliceInfoParam; 1132 sliceInfoParam.presDataBuffer = params->presDataBuffer; 1133 sliceInfoParam.dwDataStartOffset[0] = sliceParams->m_sliceDataOffset + offset; 1134 1135 MHW_MI_CHK_STATUS(m_cpInterface->SetMfxProtectionState( 1136 m_decodeInUse, 1137 cmdBuffer, 1138 batchBuffer, 1139 &sliceInfoParam)); 1140 1141 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, sizeof(cmd))); 1142 1143 return eStatus; 1144 } 1145 1146 //! 1147 //! \struct MFD_MPEG2_IT_OBJECT_CMD 1148 //! \brief MFD MPEG2 it object command 1149 //! 1150 struct MFD_MPEG2_IT_OBJECT_CMD 1151 { 1152 typename TMfxCmds::MFD_IT_OBJECT_CMD m_header; 1153 typename TMfxCmds::MFD_IT_OBJECT_MPEG2_INLINE_DATA_CMD m_inlineData; 1154 }; 1155 AddMfdMpeg2ITObject(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_MPEG2_MB_STATE params)1156 MOS_STATUS AddMfdMpeg2ITObject( 1157 PMOS_COMMAND_BUFFER cmdBuffer, 1158 PMHW_BATCH_BUFFER batchBuffer, 1159 PMHW_VDBOX_MPEG2_MB_STATE params) 1160 { 1161 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1162 1163 MHW_FUNCTION_ENTER; 1164 1165 MHW_MI_CHK_NULL(params); 1166 1167 if (cmdBuffer == nullptr && batchBuffer == nullptr) 1168 { 1169 MHW_ASSERTMESSAGE("No valid buffer to add the command to!"); 1170 return MOS_STATUS_INVALID_PARAMETER; 1171 } 1172 1173 MFD_MPEG2_IT_OBJECT_CMD cmd; 1174 cmd.m_inlineData.DW0.MacroblockIntraType = mpeg2Vc1MacroblockIntra; 1175 1176 typename TMfxCmds::MFD_IT_OBJECT_MPEG2_INLINE_DATA_CMD *inlineDataMpeg2 = &(cmd.m_inlineData); 1177 typename TMfxCmds::MFD_IT_OBJECT_CMD *cmdMfdItObject = &(cmd.m_header); 1178 1179 //------------------------------------ 1180 // Shared indirect data 1181 //------------------------------------ 1182 cmdMfdItObject->DW0.DwordLength += TMfxCmds::MFD_IT_OBJECT_MPEG2_INLINE_DATA_CMD::dwSize; 1183 1184 cmdMfdItObject->DW3.IndirectItCoeffDataLength = (params->dwDCTLength) << 2; 1185 cmdMfdItObject->DW4.IndirectItCoeffDataStartAddressOffset = params->dwITCoffDataAddrOffset; 1186 1187 //------------------------------------ 1188 // Shared inline data 1189 //------------------------------------ 1190 auto mbParams = params->pMBParams; 1191 inlineDataMpeg2->DW0.DctType = mbParams->MBType.m_fieldResidual; 1192 inlineDataMpeg2->DW0.CodedBlockPattern = mbParams->m_codedBlockPattern; 1193 inlineDataMpeg2->DW1.Horzorigin = mbParams->m_mbAddr % params->wPicWidthInMb; 1194 inlineDataMpeg2->DW1.Vertorigin = mbParams->m_mbAddr / params->wPicWidthInMb; 1195 inlineDataMpeg2->DW0.Lastmbinrow = (inlineDataMpeg2->DW1.Horzorigin == (params->wPicWidthInMb - 1)); 1196 1197 if (params->wPicCodingType != I_TYPE) 1198 { 1199 inlineDataMpeg2->DW0.MacroblockIntraType = mbParams->MBType.m_intraMb; 1200 inlineDataMpeg2->DW0.MacroblockMotionForward = mbParams->MBType.m_motionFwd; 1201 inlineDataMpeg2->DW0.MacroblockMotionBackward = mbParams->MBType.m_motionBwd; 1202 inlineDataMpeg2->DW0.MotionType = mbParams->MBType.m_motionType; 1203 inlineDataMpeg2->DW0.MotionVerticalFieldSelect = mbParams->MBType.m_mvertFieldSel; 1204 1205 // Next, copy in the motion vectors 1206 if (mbParams->MBType.m_intraMb == 0) 1207 { 1208 uint32_t *point = (uint32_t*)(params->sPackedMVs0); 1209 inlineDataMpeg2->DW2.Value = *point++; 1210 inlineDataMpeg2->DW3.Value = *point++; 1211 1212 point = (uint32_t*)(params->sPackedMVs1); 1213 inlineDataMpeg2->DW4.Value = *point++; 1214 inlineDataMpeg2->DW5.Value = *point++; 1215 } 1216 } 1217 1218 MHW_MI_CHK_STATUS(Mhw_AddCommandCmdOrBB(m_osInterface, cmdBuffer, batchBuffer, &cmd, sizeof(cmd))); 1219 1220 return eStatus; 1221 } 1222 AddMfcMpeg2SliceGroupCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_MPEG2_SLICE_STATE mpeg2SliceState)1223 MOS_STATUS AddMfcMpeg2SliceGroupCmd( 1224 PMOS_COMMAND_BUFFER cmdBuffer, 1225 PMHW_VDBOX_MPEG2_SLICE_STATE mpeg2SliceState) 1226 { 1227 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1228 1229 MHW_FUNCTION_ENTER; 1230 1231 MHW_MI_CHK_NULL(m_osInterface); 1232 MHW_MI_CHK_NULL(cmdBuffer); 1233 MHW_MI_CHK_NULL(mpeg2SliceState); 1234 MHW_MI_CHK_NULL(mpeg2SliceState->pEncodeMpeg2PicParams); 1235 MHW_MI_CHK_NULL(mpeg2SliceState->pEncodeMpeg2SliceParams); 1236 MHW_MI_CHK_NULL(mpeg2SliceState->pSlcData); 1237 1238 auto sliceParams = mpeg2SliceState->pEncodeMpeg2SliceParams; 1239 auto picParams = mpeg2SliceState->pEncodeMpeg2PicParams; 1240 auto seqParams = mpeg2SliceState->pEncodeMpeg2SeqParams; 1241 auto slcData = mpeg2SliceState->pSlcData; 1242 1243 typename TMfxCmds::MFC_MPEG2_SLICEGROUP_STATE_CMD cmd; 1244 1245 cmd.DW1.Streamid10EncoderOnly = 0; 1246 cmd.DW1.Sliceid30EncoderOnly = 0; 1247 cmd.DW1.Intrasliceflag = 1; 1248 cmd.DW1.Intraslice = sliceParams->m_intraSlice; 1249 cmd.DW1.Firstslicehdrdisabled = 0; 1250 cmd.DW1.TailpresentflagTailInsertionPresentInBitstreamEncoderOnly = 1251 (picParams->m_lastPicInStream && (slcData->SliceGroup & SLICE_GROUP_LAST)); 1252 cmd.DW1.SlicedataPresentflagSlicedataInsertionPresentInBitstreamEncoderOnly = 1; 1253 cmd.DW1.HeaderpresentflagHeaderInsertionPresentInBitstreamEncoderOnly = 1; 1254 cmd.DW1.BitstreamoutputflagCompressedBitstreamOutputDisableFlagEncoderOnly = 0; 1255 cmd.DW1.Islastslicegrp = (slcData->SliceGroup & SLICE_GROUP_LAST) ? 1 : 0; 1256 cmd.DW1.SkipconvdisabledMbTypeSkipConversionDisableEncoderOnly = sliceParams->m_intraSlice; // Disable for I slice 1257 1258 cmd.DW1.MbratectrlflagRatecontrolcounterenableEncoderOnly = (mpeg2SliceState->bBrcEnabled && (!mpeg2SliceState->bFirstPass)); 1259 cmd.DW1.MbratectrlresetResetratecontrolcounterEncoderOnly = 1; 1260 cmd.DW1.RatectrlpanictypeRcPanicTypeEncoderOnly = 1; // CBP type 1261 cmd.DW1.MbratectrlmodeRcTriggleModeEncoderOnly = 2; // Loose Rate Control Mode 1262 cmd.DW1.RatectrlpanicflagRcPanicEnableEncoderOnly = 1263 (mpeg2SliceState->bRCPanicEnable && 1264 (seqParams->m_rateControlMethod != RATECONTROL_AVBR) && 1265 (seqParams->m_rateControlMethod != RATECONTROL_IWD_VBR) && 1266 (seqParams->m_rateControlMethod != RATECONTROL_ICQ) && 1267 (seqParams->m_rateControlMethod != RATECONTROL_VCM) && 1268 (seqParams->m_rateControlMethod != RATECONTROL_CQP) && 1269 mpeg2SliceState->bLastPass); // Enable only in the last pass 1270 1271 cmd.DW2.FirstmbxcntAlsoCurrstarthorzpos = sliceParams->m_firstMbX; 1272 cmd.DW2.FirstmbycntAlsoCurrstartvertpos = sliceParams->m_firstMbY; 1273 cmd.DW2.NextsgmbxcntAlsoNextstarthorzpos = slcData->NextSgMbXCnt; 1274 cmd.DW2.NextsgmbycntAlsoNextstartvertpos = slcData->NextSgMbYCnt; 1275 1276 cmd.DW3.Slicegroupqp = sliceParams->m_quantiserScaleCode; 1277 cmd.DW3.Slicegroupskip = 0; // MBZ for MPEG2 1278 1279 // H/W should use this start addr only for the first slice, since LoadSlicePointerFlag = 0 in PIC_STATE 1280 cmd.DW4.BitstreamoffsetIndirectPakBseDataStartAddressWrite = 0; 1281 1282 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 1283 1284 return eStatus; 1285 } 1286 AddMfcMpeg2PakInsertBrcBuffer(PMOS_RESOURCE brcPicHeaderInputBuffer,PMHW_VDBOX_PAK_INSERT_PARAMS params)1287 MOS_STATUS AddMfcMpeg2PakInsertBrcBuffer( 1288 PMOS_RESOURCE brcPicHeaderInputBuffer, 1289 PMHW_VDBOX_PAK_INSERT_PARAMS params) 1290 { 1291 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1292 1293 MHW_FUNCTION_ENTER; 1294 1295 MHW_MI_CHK_NULL(brcPicHeaderInputBuffer); 1296 MHW_MI_CHK_NULL(params); 1297 MHW_MI_CHK_NULL(params->pBsBuffer); 1298 1299 typename TMfxCmds::MFX_PAK_INSERT_OBJECT_CMD cmd; 1300 1301 uint32_t byteSize = (params->pBsBuffer->BitSize + 7) >> 3; 1302 uint32_t dataBitsInLastDw = params->pBsBuffer->BitSize % 32; 1303 if (dataBitsInLastDw == 0) 1304 { 1305 dataBitsInLastDw = 32; 1306 } 1307 1308 uint32_t dwordsUsed = TMfxCmds::MFX_PAK_INSERT_OBJECT_CMD::dwSize + ((byteSize + 3) >> 2); 1309 cmd.DW0.DwordLength = OP_LENGTH(dwordsUsed); 1310 cmd.DW1.BitstreamstartresetResetbitstreamstartingpos = 0; 1311 cmd.DW1.EndofsliceflagLastdstdatainsertcommandflag = 0; 1312 cmd.DW1.LastheaderflagLastsrcheaderdatainsertcommandflag = 1; 1313 cmd.DW1.EmulationflagEmulationbytebitsinsertenable = 0; 1314 cmd.DW1.SkipemulbytecntSkipEmulationByteCount = 0; 1315 cmd.DW1.DatabitsinlastdwSrcdataendingbitinclusion50 = dataBitsInLastDw; 1316 cmd.DW1.DatabyteoffsetSrcdatastartingbyteoffset10 = 0; 1317 1318 MOS_LOCK_PARAMS lockFlags; 1319 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); 1320 lockFlags.WriteOnly = 1; 1321 uint8_t* data = (uint8_t*)m_osInterface->pfnLockResource( 1322 m_osInterface, 1323 brcPicHeaderInputBuffer, 1324 &lockFlags); 1325 MHW_MI_CHK_NULL(data); 1326 1327 eStatus = MOS_SecureMemcpy(data, TMfxCmds::MFX_PAK_INSERT_OBJECT_CMD::byteSize, &cmd, TMfxCmds::MFX_PAK_INSERT_OBJECT_CMD::byteSize); 1328 if (eStatus != MOS_STATUS_SUCCESS) 1329 { 1330 MHW_ASSERTMESSAGE("Failed to copy memory."); 1331 return eStatus; 1332 } 1333 1334 // Use the exact data byte size to make sure that we don't overrun the bit buffer. 1335 eStatus = MOS_SecureMemcpy(data + TMfxCmds::MFX_PAK_INSERT_OBJECT_CMD::byteSize, byteSize, params->pBsBuffer->pBase, byteSize); 1336 if (eStatus != MOS_STATUS_SUCCESS) 1337 { 1338 MHW_ASSERTMESSAGE("Failed to copy memory."); 1339 return eStatus; 1340 } 1341 1342 // Need to make sure that the batch buffer end command begins on a dword boundary. So use 1343 // a dword aligned data size in the offset calculation instead of the straight byte size. 1344 // Note: The variable dwDwordsUsed already contains the size of the INSERT command. 1345 typename TMiCmds::MI_BATCH_BUFFER_END_CMD cmdMiBatchBufferEnd; 1346 eStatus = MOS_SecureMemcpy(data + sizeof(uint32_t)*dwordsUsed, 1347 sizeof(cmdMiBatchBufferEnd), 1348 &cmdMiBatchBufferEnd, 1349 cmdMiBatchBufferEnd.byteSize); 1350 if (eStatus != MOS_STATUS_SUCCESS) 1351 { 1352 MHW_ASSERTMESSAGE("Failed to copy memory."); 1353 return eStatus; 1354 } 1355 1356 MHW_MI_CHK_STATUS(m_osInterface->pfnUnlockResource(m_osInterface, brcPicHeaderInputBuffer)); 1357 1358 *(params->pdwMpeg2PicHeaderTotalBufferSize) = sizeof(uint32_t)* dwordsUsed + 1359 cmdMiBatchBufferEnd.byteSize; 1360 *(params->pdwMpeg2PicHeaderDataStartOffset) = TMfxCmds::MFX_PAK_INSERT_OBJECT_CMD::byteSize; 1361 1362 return eStatus; 1363 } 1364 AddMfxMpeg2PicBrcBuffer(PMOS_RESOURCE brcImgBuffer,PMHW_VDBOX_MPEG2_PIC_STATE params)1365 MOS_STATUS AddMfxMpeg2PicBrcBuffer( 1366 PMOS_RESOURCE brcImgBuffer, 1367 PMHW_VDBOX_MPEG2_PIC_STATE params) 1368 { 1369 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1370 1371 MHW_FUNCTION_ENTER; 1372 1373 MHW_MI_CHK_NULL(brcImgBuffer); 1374 MHW_MI_CHK_NULL(params); 1375 1376 MOS_LOCK_PARAMS lockFlags; 1377 MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS)); 1378 lockFlags.WriteOnly = 1; 1379 uint8_t *data = (uint8_t*)m_osInterface->pfnLockResource(m_osInterface, brcImgBuffer, &lockFlags); 1380 MHW_MI_CHK_NULL(data); 1381 1382 MOS_COMMAND_BUFFER constructedCmdBuf; 1383 constructedCmdBuf.pCmdBase = (uint32_t *)data; 1384 constructedCmdBuf.pCmdPtr = (uint32_t *)data; 1385 constructedCmdBuf.iOffset = 0; 1386 constructedCmdBuf.iRemaining = BRC_IMG_STATE_SIZE_PER_PASS * m_numBrcPakPasses; 1387 1388 MHW_MI_CHK_STATUS(AddMfxMpeg2PicCmd(&constructedCmdBuf, params)); 1389 1390 typename TMfxCmds::MFX_MPEG2_PIC_STATE_CMD cmd = *(typename TMfxCmds::MFX_MPEG2_PIC_STATE_CMD *)data; 1391 1392 for (uint32_t i = 0; i < m_numBrcPakPasses; i++) 1393 { 1394 cmd.DW5.Framebitratemaxreportmask = 1; 1395 cmd.DW5.Framebitrateminreportmask = 1; 1396 1397 if (i == 0) 1398 { 1399 cmd.DW4.Mbstatenabled = 0; // Disable for first PAK pass 1400 cmd.DW5.Mbratecontrolmask = 0; 1401 cmd.DW5.Framesizecontrolmask = 0; // Disable first for PAK pass 1402 } 1403 else 1404 { 1405 cmd.DW4.Mbstatenabled = 1; // Disable for first PAK pass 1406 cmd.DW5.Mbratecontrolmask = 1; 1407 cmd.DW5.Framesizecontrolmask = 1; 1408 } 1409 1410 cmd.DW8.Value = m_mpeg2SliceDeltaQPMax[i]; 1411 cmd.DW9.Value = m_mpeg2InitSliceDeltaQPMin[i]; 1412 cmd.DW10.Value = m_mpeg2FrameBitrateMinMax[i]; 1413 cmd.DW11.Value = m_mpeg2FrameBitrateMinMaxDelta[i]; 1414 1415 *(typename TMfxCmds::MFX_MPEG2_PIC_STATE_CMD *)data = cmd; 1416 data += BRC_IMG_STATE_SIZE_PER_PASS; 1417 } 1418 1419 return eStatus; 1420 } 1421 AddMfxVc1PredPipeCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VC1_PRED_PIPE_PARAMS params)1422 MOS_STATUS AddMfxVc1PredPipeCmd( 1423 PMOS_COMMAND_BUFFER cmdBuffer, 1424 PMHW_VDBOX_VC1_PRED_PIPE_PARAMS params) 1425 { 1426 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1427 1428 MHW_FUNCTION_ENTER; 1429 1430 MHW_MI_CHK_NULL(m_osInterface); 1431 MHW_MI_CHK_NULL(cmdBuffer); 1432 MHW_MI_CHK_NULL(params); 1433 MHW_MI_CHK_NULL(params->pVc1PicParams); 1434 1435 auto vc1PicParams = params->pVc1PicParams; 1436 auto destParams = params->ppVc1RefList[vc1PicParams->CurrPic.FrameIdx]; 1437 auto fwdRefParams = params->ppVc1RefList[vc1PicParams->ForwardRefIdx]; 1438 auto bwdRefParams = params->ppVc1RefList[vc1PicParams->BackwardRefIdx]; 1439 1440 bool isPPicture = IsVc1PPicture( 1441 vc1PicParams->CurrPic, 1442 vc1PicParams->picture_fields.is_first_field, 1443 vc1PicParams->picture_fields.picture_type); 1444 1445 bool isBPicture = IsVc1BPicture( 1446 vc1PicParams->CurrPic, 1447 vc1PicParams->picture_fields.is_first_field, 1448 vc1PicParams->picture_fields.picture_type); 1449 1450 bool isSecondField = !vc1PicParams->picture_fields.is_first_field; 1451 1452 RefBoundaryReplicationMode refBoundaryReplicationMode; 1453 refBoundaryReplicationMode.BY0.value = 0; 1454 1455 if (isPPicture || isBPicture) 1456 { 1457 if (fwdRefParams->dwRefSurfaceFlags & CODECHAL_VC1_PROGRESSIVE) 1458 { 1459 if (!vc1PicParams->picture_fields.is_first_field) 1460 { 1461 if (vc1PicParams->picture_fields.top_field_first) 1462 { 1463 refBoundaryReplicationMode.BY0.ref0 = vc1InterlacedBoundary; 1464 refBoundaryReplicationMode.BY0.ref2 = vc1ProgressiveBoundary; 1465 } 1466 else 1467 { 1468 refBoundaryReplicationMode.BY0.ref2 = vc1InterlacedBoundary; 1469 refBoundaryReplicationMode.BY0.ref0 = vc1ProgressiveBoundary; 1470 } 1471 } 1472 else 1473 { 1474 refBoundaryReplicationMode.BY0.ref0 = vc1ProgressiveBoundary; 1475 refBoundaryReplicationMode.BY0.ref2 = vc1ProgressiveBoundary; 1476 } 1477 } 1478 else 1479 { 1480 refBoundaryReplicationMode.BY0.ref0 = refBoundaryReplicationMode.BY0.ref2 = vc1InterlacedBoundary; 1481 } 1482 } 1483 if (isBPicture) 1484 { 1485 if (bwdRefParams->dwRefSurfaceFlags & CODECHAL_VC1_PROGRESSIVE) 1486 { 1487 refBoundaryReplicationMode.BY0.ref1 = refBoundaryReplicationMode.BY0.ref3 = vc1ProgressiveBoundary; 1488 } 1489 else 1490 { 1491 refBoundaryReplicationMode.BY0.ref1 = refBoundaryReplicationMode.BY0.ref3 = vc1InterlacedBoundary; 1492 } 1493 } 1494 1495 typename TMfxCmds::MFX_VC1_PRED_PIPE_STATE_CMD cmd; 1496 cmd.DW1.ReferenceFrameBoundaryReplicationMode = refBoundaryReplicationMode.BY0.value; 1497 1498 uint32_t fwdDoubleIcEnable = 0, fwdSingleIcEnable = 0; 1499 uint32_t bwdDoubleIcEnable = 0, bwdSingleIcEnable = 0; 1500 uint8_t icField = 0; 1501 1502 // Interlaced Frame & Frame 1503 if (!CodecHal_PictureIsField(vc1PicParams->CurrPic)) 1504 { 1505 if (isPPicture) 1506 { 1507 if (vc1PicParams->picture_fields.intensity_compensation) 1508 { 1509 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP)) 1510 { 1511 fwdDoubleIcEnable = TOP_FIELD; 1512 cmd.DW3.Lumscale1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1513 cmd.DW3.Lumshift1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1514 // IC values for the bottom out of bound pixels (replicated lines of the last 1515 // line of top field) 1516 cmd.DW3.Lumscale2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1517 cmd.DW3.Lumshift2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1518 1519 MOS_BIT_ON(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP_2); 1520 icField++; 1521 } 1522 else if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP)) 1523 { 1524 fwdDoubleIcEnable = BOTTOM_FIELD; 1525 // IC values for the top out of bound pixels (replicated lines of the first 1526 // line of bottom field) 1527 cmd.DW3.Lumscale1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1528 cmd.DW3.Lumshift1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1529 cmd.DW3.Lumscale2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1530 cmd.DW3.Lumshift2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1531 1532 MOS_BIT_ON(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP_2); 1533 icField++; 1534 } 1535 1536 uint16_t lumaScale = vc1PicParams->luma_scale; 1537 uint16_t lumaShift = vc1PicParams->luma_shift; 1538 1539 MOS_BIT_ON(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_FRAME_COMP); 1540 1541 fwdSingleIcEnable = TOP_FIELD | BOTTOM_FIELD; 1542 cmd.DW2.Lumscale1SingleFwd = lumaScale; 1543 cmd.DW2.Lumshift1SingleFwd = lumaShift; 1544 1545 cmd.DW2.Lumscale2SingleFwd = lumaScale; 1546 cmd.DW2.Lumshift2SingleFwd = lumaShift; 1547 1548 // Set double backward values for top and bottom out of bound pixels 1549 bwdDoubleIcEnable = TOP_FIELD | BOTTOM_FIELD; 1550 cmd.DW5.Lumscale1DoubleBwd = lumaScale; 1551 cmd.DW5.Lumshift1DoubleBwd = lumaShift; 1552 cmd.DW5.Lumscale2DoubleBwd = lumaScale; 1553 cmd.DW5.Lumshift2DoubleBwd = lumaShift; 1554 1555 // Save IC 1556 fwdRefParams->Vc1IcValues[icField].wICCScale1 = 1557 fwdRefParams->Vc1IcValues[icField].wICCScale2 = lumaScale; 1558 fwdRefParams->Vc1IcValues[icField].wICCShiftL1 = 1559 fwdRefParams->Vc1IcValues[icField].wICCShiftL2 = lumaShift; 1560 } 1561 else 1562 { 1563 // special case for interlaced field references when no IC is indicated 1564 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP)) 1565 { 1566 cmd.DW2.Lumscale1SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1567 cmd.DW2.Lumshift1SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1568 1569 fwdSingleIcEnable = TOP_FIELD; 1570 icField++; 1571 } 1572 1573 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP)) 1574 { 1575 cmd.DW2.Lumscale2SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1576 cmd.DW2.Lumshift2SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1577 1578 fwdSingleIcEnable |= BOTTOM_FIELD; 1579 icField++; 1580 } 1581 1582 } 1583 } 1584 else if (isBPicture) 1585 { 1586 // Forward reference IC 1587 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP_2)) 1588 { 1589 fwdDoubleIcEnable = TOP_FIELD; 1590 cmd.DW3.Lumscale1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1591 cmd.DW3.Lumshift1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1592 // IC values for the bottom out of bound pixels (replicated lines of the last 1593 // line of top field) 1594 cmd.DW3.Lumscale2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1595 cmd.DW3.Lumshift2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1596 } 1597 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP_2)) 1598 { 1599 fwdDoubleIcEnable |= BOTTOM_FIELD; 1600 // IC values for the top out of bound pixels (replicated lines of the first 1601 // line of bottom field) 1602 cmd.DW3.Lumscale1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1603 cmd.DW3.Lumshift1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1604 cmd.DW3.Lumscale2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1605 cmd.DW3.Lumshift2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1606 } 1607 if (fwdDoubleIcEnable) 1608 { 1609 icField++; 1610 } 1611 1612 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP)) 1613 { 1614 fwdSingleIcEnable = TOP_FIELD; 1615 cmd.DW2.Lumscale1SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1616 cmd.DW2.Lumshift1SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1617 } 1618 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP)) 1619 { 1620 fwdSingleIcEnable |= BOTTOM_FIELD; 1621 cmd.DW2.Lumscale2SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1622 cmd.DW2.Lumshift2SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1623 } 1624 1625 // If the reference picture is interlaced field, set double backward values for top 1626 // and bottom out of bound pixels 1627 if (fwdSingleIcEnable == (TOP_FIELD | BOTTOM_FIELD)) 1628 { 1629 bwdDoubleIcEnable = TOP_FIELD | BOTTOM_FIELD; 1630 cmd.DW5.Lumscale1DoubleBwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1631 cmd.DW5.Lumshift1DoubleBwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1632 cmd.DW5.Lumscale2DoubleBwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1633 cmd.DW5.Lumshift2DoubleBwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1634 } 1635 1636 // Backward reference IC 1637 icField = 0; 1638 if (MOS_IS_BIT_SET(bwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP)) 1639 { 1640 bwdSingleIcEnable = TOP_FIELD; 1641 cmd.DW4.Lumscale1SingleBwd = bwdRefParams->Vc1IcValues[icField].wICCScale1; 1642 cmd.DW4.Lumshift1SingleBwd = bwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1643 } 1644 else if (MOS_IS_BIT_SET(bwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP)) 1645 { 1646 bwdSingleIcEnable = BOTTOM_FIELD; 1647 cmd.DW4.Lumscale2SingleBwd = bwdRefParams->Vc1IcValues[icField].wICCScale2; 1648 cmd.DW4.Lumshift2SingleBwd = bwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1649 } 1650 } 1651 } 1652 // Interlace field 1653 else 1654 { 1655 if (isPPicture) 1656 { 1657 fwdSingleIcEnable = 1658 vc1PicParams->picture_fields.intensity_compensation ? (TOP_FIELD | BOTTOM_FIELD) : 0; 1659 1660 // Top field IC 1661 uint16_t lumaScale = vc1PicParams->luma_scale >> 8; 1662 uint16_t lumaShift = vc1PicParams->luma_shift >> 8; 1663 1664 if (CodecHal_PictureIsBottomField(vc1PicParams->CurrPic) && isSecondField) 1665 { 1666 fwdRefParams = destParams; 1667 } 1668 1669 if (((lumaScale == 32) && (lumaShift == 0)) || !(fwdSingleIcEnable & TOP_FIELD)) 1670 { 1671 // No IC for top field 1672 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP)) 1673 { 1674 cmd.DW2.Lumscale1SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1675 cmd.DW2.Lumshift1SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1676 fwdSingleIcEnable |= TOP_FIELD; 1677 } 1678 else 1679 { 1680 fwdSingleIcEnable &= BOTTOM_FIELD; 1681 } 1682 } 1683 else 1684 { 1685 // IC for top field is enabled 1686 cmd.DW2.Lumscale1SingleFwd = lumaScale; 1687 cmd.DW2.Lumshift1SingleFwd = lumaShift; 1688 1689 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP)) 1690 { 1691 fwdDoubleIcEnable = TOP_FIELD; 1692 cmd.DW3.Lumscale1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1693 cmd.DW3.Lumshift1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1694 1695 MOS_BIT_ON(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP_2); 1696 icField++; 1697 } 1698 else 1699 { 1700 MOS_BIT_ON(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP); 1701 } 1702 1703 // set double backward values for top out of bound pixels 1704 if (vc1PicParams->picture_fields.intensity_compensation) 1705 { 1706 bwdDoubleIcEnable = TOP_FIELD; 1707 // If the reference picture is not interlaced field and current picture is bottom field 1708 // and second field, double backwards values are identical to the the single forward 1709 // values used by the p interlaced field top field 1710 if (!CodecHal_PictureIsField((params->ppVc1RefList[vc1PicParams->ForwardRefIdx])->RefPic) && 1711 (CodecHal_PictureIsBottomField(vc1PicParams->CurrPic) && isSecondField)) 1712 { 1713 cmd.DW5.Lumscale1DoubleBwd = 1714 (params->ppVc1RefList[vc1PicParams->ForwardRefIdx])->Vc1IcValues[icField].wICCScale1; 1715 cmd.DW5.Lumshift1DoubleBwd = 1716 (params->ppVc1RefList[vc1PicParams->ForwardRefIdx])->Vc1IcValues[icField].wICCShiftL1; 1717 } 1718 else 1719 { 1720 cmd.DW5.Lumscale1DoubleBwd = lumaScale; 1721 cmd.DW5.Lumshift1DoubleBwd = lumaShift; 1722 } 1723 } 1724 1725 // Save IC 1726 fwdRefParams->Vc1IcValues[icField].wICCScale1 = lumaScale; 1727 fwdRefParams->Vc1IcValues[icField].wICCShiftL1 = lumaShift; 1728 } 1729 1730 // Bottom field IC 1731 icField = 0; 1732 lumaScale = vc1PicParams->luma_scale & 0x00ff; 1733 lumaShift = vc1PicParams->luma_shift & 0x00ff; 1734 1735 if (CodecHal_PictureIsTopField(vc1PicParams->CurrPic) && isSecondField) 1736 { 1737 fwdRefParams = destParams; 1738 } 1739 else 1740 { 1741 fwdRefParams = params->ppVc1RefList[vc1PicParams->ForwardRefIdx]; 1742 } 1743 1744 if (((lumaScale == 32) && (lumaShift == 0)) || !(fwdSingleIcEnable & BOTTOM_FIELD)) 1745 { 1746 // No IC for bottom field 1747 1748 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP)) 1749 { 1750 cmd.DW2.Lumscale2SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1751 cmd.DW2.Lumshift2SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1752 fwdSingleIcEnable |= BOTTOM_FIELD; 1753 } 1754 else 1755 { 1756 fwdSingleIcEnable &= TOP_FIELD; 1757 } 1758 } 1759 else 1760 { 1761 // IC is on 1762 cmd.DW2.Lumscale2SingleFwd = lumaScale; 1763 cmd.DW2.Lumshift2SingleFwd = lumaShift; 1764 1765 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP)) 1766 { 1767 fwdDoubleIcEnable |= BOTTOM_FIELD; 1768 cmd.DW3.Lumscale2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1769 cmd.DW3.Lumshift2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1770 1771 MOS_BIT_ON(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP_2); 1772 icField++; 1773 } 1774 else 1775 { 1776 MOS_BIT_ON(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP); 1777 } 1778 1779 // set double backward values for bottom out of bound pixels 1780 if (vc1PicParams->picture_fields.intensity_compensation) 1781 { 1782 bwdDoubleIcEnable |= BOTTOM_FIELD; 1783 // If the reference picture is not interlaced field and current picture is top field and 1784 // second field, double backwards values are identical to the the single forward values 1785 // used by the p interlaced field bottom field 1786 if (!CodecHal_PictureIsField((params->ppVc1RefList[vc1PicParams->ForwardRefIdx])->RefPic) && 1787 (CodecHal_PictureIsTopField(vc1PicParams->CurrPic) && isSecondField)) 1788 { 1789 cmd.DW5.Lumscale2DoubleBwd = 1790 (params->ppVc1RefList[vc1PicParams->ForwardRefIdx])->Vc1IcValues[icField].wICCScale2; 1791 cmd.DW5.Lumshift2DoubleBwd = 1792 (params->ppVc1RefList[vc1PicParams->ForwardRefIdx])->Vc1IcValues[icField].wICCShiftL2; 1793 } 1794 else 1795 { 1796 cmd.DW5.Lumscale2DoubleBwd = lumaScale; 1797 cmd.DW5.Lumshift2DoubleBwd = lumaShift; 1798 } 1799 } 1800 1801 // Save IC 1802 fwdRefParams->Vc1IcValues[icField].wICCScale2 = lumaScale; 1803 fwdRefParams->Vc1IcValues[icField].wICCShiftL2 = lumaShift; 1804 } 1805 } 1806 else if (isBPicture) 1807 { 1808 // Forward reference IC 1809 if (CodecHal_PictureIsTopField(vc1PicParams->CurrPic) || !isSecondField) 1810 { 1811 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP_2)) 1812 { 1813 cmd.DW3.Lumscale1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1814 cmd.DW3.Lumshift1DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1815 fwdDoubleIcEnable = TOP_FIELD; 1816 icField++; 1817 } 1818 1819 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP)) 1820 { 1821 cmd.DW2.Lumscale1SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale1; 1822 cmd.DW2.Lumshift1SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1823 fwdSingleIcEnable = TOP_FIELD; 1824 } 1825 } 1826 1827 if ((vc1PicParams->CurrPic.PicFlags == PICTURE_BOTTOM_FIELD) || !isSecondField) 1828 { 1829 icField = 0; 1830 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP_2)) 1831 { 1832 cmd.DW3.Lumscale2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1833 cmd.DW3.Lumshift2DoubleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1834 fwdDoubleIcEnable |= BOTTOM_FIELD; 1835 icField++; 1836 } 1837 if (MOS_IS_BIT_SET(fwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP)) 1838 { 1839 cmd.DW2.Lumscale2SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCScale2; 1840 cmd.DW2.Lumshift2SingleFwd = fwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1841 fwdSingleIcEnable |= BOTTOM_FIELD; 1842 } 1843 } 1844 1845 // Backward reference IC 1846 icField = 0; 1847 if (MOS_IS_BIT_SET(bwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_TOP_FIELD_COMP)) 1848 { 1849 cmd.DW4.Lumscale1SingleBwd = bwdRefParams->Vc1IcValues[icField].wICCScale1; 1850 cmd.DW4.Lumshift1SingleBwd = bwdRefParams->Vc1IcValues[icField].wICCShiftL1; 1851 bwdSingleIcEnable = TOP_FIELD; 1852 } 1853 1854 if (MOS_IS_BIT_SET(bwdRefParams->dwRefSurfaceFlags, CODECHAL_VC1_BOT_FIELD_COMP)) 1855 { 1856 cmd.DW4.Lumscale2SingleBwd = bwdRefParams->Vc1IcValues[icField].wICCScale2; 1857 cmd.DW4.Lumshift2SingleBwd = bwdRefParams->Vc1IcValues[icField].wICCShiftL2; 1858 bwdSingleIcEnable |= BOTTOM_FIELD; 1859 } 1860 } 1861 } 1862 1863 cmd.DW1.VinIntensitycompDoubleFwden = fwdDoubleIcEnable; 1864 cmd.DW1.VinIntensitycompDoubleBwden = bwdDoubleIcEnable; 1865 cmd.DW1.VinIntensitycompSingleFwden = fwdSingleIcEnable; 1866 cmd.DW1.VinIntensitycompSingleBwden = bwdSingleIcEnable; 1867 1868 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 1869 1870 return eStatus; 1871 } 1872 AddMfxVc1LongPicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VC1_PIC_STATE vc1PicState)1873 MOS_STATUS AddMfxVc1LongPicCmd( 1874 PMOS_COMMAND_BUFFER cmdBuffer, 1875 PMHW_VDBOX_VC1_PIC_STATE vc1PicState) 1876 { 1877 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 1878 1879 MHW_FUNCTION_ENTER; 1880 1881 MHW_MI_CHK_NULL(m_osInterface); 1882 MHW_MI_CHK_NULL(cmdBuffer); 1883 MHW_MI_CHK_NULL(vc1PicState); 1884 MHW_MI_CHK_NULL(vc1PicState->pVc1PicParams); 1885 1886 auto vc1PicParams = vc1PicState->pVc1PicParams; 1887 1888 bool isFramePicture = 1889 ((vc1PicParams->CurrPic.PicFlags == PICTURE_FRAME) | 1890 (vc1PicParams->CurrPic.PicFlags == PICTURE_INTERLACED_FRAME)); 1891 1892 uint16_t widthInMbs = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(vc1PicParams->coded_width); 1893 uint16_t heightInMbs = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(vc1PicParams->coded_height); 1894 1895 uint16_t frameFieldHeightInMb = 0; 1896 CodecHal_GetFrameFieldHeightInMb( 1897 vc1PicParams->CurrPic, 1898 heightInMbs, 1899 frameFieldHeightInMb); 1900 1901 bool isIPicture = IsVc1IPicture( 1902 vc1PicParams->CurrPic, 1903 vc1PicParams->picture_fields.is_first_field, 1904 vc1PicParams->picture_fields.picture_type); 1905 1906 bool isPPicture = IsVc1PPicture( 1907 vc1PicParams->CurrPic, 1908 vc1PicParams->picture_fields.is_first_field, 1909 vc1PicParams->picture_fields.picture_type); 1910 1911 bool isBPicture = IsVc1BPicture( 1912 vc1PicParams->CurrPic, 1913 vc1PicParams->picture_fields.is_first_field, 1914 vc1PicParams->picture_fields.picture_type); 1915 1916 bool isBIPicture = IsVc1BIPicture( 1917 vc1PicParams->CurrPic, 1918 vc1PicParams->picture_fields.is_first_field, 1919 vc1PicParams->picture_fields.picture_type); 1920 1921 auto destParams = vc1PicState->ppVc1RefList[vc1PicParams->CurrPic.FrameIdx]; 1922 auto fwdRefParams = vc1PicState->ppVc1RefList[vc1PicParams->ForwardRefIdx]; 1923 1924 typename TMfxCmds::MFD_VC1_LONG_PIC_STATE_CMD cmd; 1925 1926 cmd.DW1.Picturewidthinmbsminus1PictureWidthMinus1InMacroblocks = widthInMbs - 1; 1927 cmd.DW1.Pictureheightinmbsminus1PictureHeightMinus1InMacroblocks = frameFieldHeightInMb - 1; 1928 1929 cmd.DW2.Vc1Profile = vc1PicParams->sequence_fields.AdvancedProfileFlag; 1930 cmd.DW2.Secondfield = !vc1PicParams->picture_fields.is_first_field; 1931 cmd.DW2.OverlapSmoothingEnableFlag = vc1PicParams->sequence_fields.overlap; 1932 cmd.DW2.LoopfilterEnableFlag = vc1PicParams->entrypoint_fields.loopfilter; 1933 cmd.DW2.InterpolationRounderContro = vc1PicParams->rounding_control; 1934 cmd.DW2.MotionVectorMode = (vc1PicParams->mv_fields.MvMode & 0x9); 1935 1936 // Simple and Main profile dynamic range adjustment 1937 if ((!vc1PicParams->sequence_fields.AdvancedProfileFlag) && isPPicture) 1938 { 1939 if ((destParams->dwRefSurfaceFlags & CODECHAL_WMV9_RANGE_ADJUSTMENT) && 1940 !(fwdRefParams->dwRefSurfaceFlags & CODECHAL_WMV9_RANGE_ADJUSTMENT)) 1941 { 1942 cmd.DW2.RangereductionEnable = 1; 1943 cmd.DW2.Rangereductionscale = 0; 1944 } 1945 else if (!(destParams->dwRefSurfaceFlags & CODECHAL_WMV9_RANGE_ADJUSTMENT) && 1946 (fwdRefParams->dwRefSurfaceFlags & CODECHAL_WMV9_RANGE_ADJUSTMENT)) 1947 { 1948 cmd.DW2.RangereductionEnable = 1; 1949 cmd.DW2.Rangereductionscale = 1; 1950 } 1951 } 1952 1953 cmd.DW3.PquantPictureQuantizationValue = vc1PicParams->pic_quantizer_fields.pic_quantizer_scale; 1954 1955 if (vc1PicState->Mode == CODECHAL_DECODE_MODE_VC1IT) 1956 { 1957 if (isIPicture || isBIPicture) 1958 { 1959 cmd.DW3.PictypePictureType = vc1IFrame; // 0 = I or I/I 1960 } 1961 else if (isPPicture) 1962 { 1963 cmd.DW3.PictypePictureType = isFramePicture ? (uint32_t)vc1PFrame: (uint32_t)vc1PPField; 1964 } 1965 else if (isBPicture) 1966 { 1967 cmd.DW3.PictypePictureType = isFramePicture ? (uint32_t)vc1BFrame: (uint32_t)vc1BBField; 1968 } 1969 1970 if (isFramePicture) 1971 { 1972 cmd.DW3.FcmFrameCodingMode = (vc1PicParams->CurrPic.PicFlags == PICTURE_INTERLACED_FRAME); 1973 } 1974 else 1975 { 1976 cmd.DW3.FcmFrameCodingMode = (vc1PicParams->picture_fields.top_field_first) ? vc1TffFrame : vc1BffFrame; 1977 } 1978 1979 cmd.DW4.FastuvmcflagFastUvMotionCompensationFlag = (vc1PicParams->mv_fields.MvMode & 0x1); 1980 cmd.DW4.Pquantuniform = 1; // uniform 1981 cmd.DW2.Implicitquantizer = 1; // implicit 1982 } 1983 else // CODECHAL_DECODE_MODE_VC1VLD 1984 { 1985 cmd.DW2.Syncmarker = vc1PicParams->sequence_fields.syncmarker; 1986 cmd.DW2.Implicitquantizer = (vc1PicParams->pic_quantizer_fields.quantizer == vc1QuantizerImplicit); 1987 if (isBPicture && 1988 (CodecHal_PictureIsBottomField(vc1PicParams->CurrPic) ? 1989 vc1PicState->bPrevOddAnchorPictureIsP : vc1PicState->bPrevEvenAnchorPictureIsP)) // OR if I not before B in decoding order 1990 { 1991 cmd.DW2.Dmvsurfacevalid = true; 1992 } 1993 1994 if (vc1PicParams->raw_coding.bitplane_present) 1995 { 1996 cmd.DW2.BitplaneBufferPitchMinus1 = (widthInMbs - 1) >> 1; 1997 } 1998 1999 cmd.DW3.Bscalefactor = vc1PicParams->ScaleFactor; 2000 cmd.DW3.AltpquantAlternativePictureQuantizationValue = vc1PicParams->pic_quantizer_fields.alt_pic_quantizer; 2001 cmd.DW3.FcmFrameCodingMode = vc1PicParams->picture_fields.frame_coding_mode; 2002 cmd.DW3.PictypePictureType = vc1PicParams->picture_fields.picture_type; 2003 cmd.DW3.Condover = vc1PicParams->conditional_overlap_flag; 2004 2005 cmd.DW4.Pquantuniform = vc1PicParams->pic_quantizer_fields.pic_quantizer_type; 2006 cmd.DW4.Halfqp = vc1PicParams->pic_quantizer_fields.half_qp; 2007 cmd.DW4.AltpquantconfigAlternativePictureQuantizationConfiguration = vc1PicParams->pic_quantizer_fields.AltPQuantConfig; 2008 cmd.DW4.AltpquantedgemaskAlternativePictureQuantizationEdgeMask = vc1PicParams->pic_quantizer_fields.AltPQuantEdgeMask; 2009 2010 // AltPQuant parameters must be set to 0 for I or BI pictures in simple/main profile 2011 if (!vc1PicParams->sequence_fields.AdvancedProfileFlag && (isIPicture || isBIPicture)) 2012 { 2013 cmd.DW4.AltpquantconfigAlternativePictureQuantizationConfiguration = 0; 2014 cmd.DW4.AltpquantedgemaskAlternativePictureQuantizationEdgeMask = 0; 2015 cmd.DW3.AltpquantAlternativePictureQuantizationValue = 0; 2016 } 2017 2018 cmd.DW4.ExtendedmvrangeExtendedMotionVectorRangeFlag = vc1PicParams->mv_fields.extended_mv_range; 2019 cmd.DW4.ExtendeddmvrangeExtendedDifferentialMotionVectorRangeFlag = vc1PicParams->mv_fields.extended_dmv_range; 2020 cmd.DW4.FwdrefdistReferenceDistance = vc1PicParams->reference_fields.reference_distance; 2021 cmd.DW4.BwdrefdistReferenceDistance = vc1PicParams->reference_fields.BwdReferenceDistance; 2022 2023 if (!isFramePicture && isBPicture) 2024 { 2025 // For B field pictures, NumberOfReferencePictures is always 2 (i.e. set to 1). 2026 cmd.DW4.NumrefNumberOfReferences = 1; 2027 } 2028 else 2029 { 2030 cmd.DW4.NumrefNumberOfReferences = vc1PicParams->reference_fields.num_reference_pictures; 2031 } 2032 2033 if (isPPicture && 2034 CodecHal_PictureIsField(vc1PicParams->CurrPic) && 2035 (cmd.DW4.NumrefNumberOfReferences == 0)) 2036 { 2037 // Derive polarity of the reference field: Top = 0, Bottom = 1 2038 if (vc1PicParams->reference_fields.reference_field_pic_indicator == 0) 2039 { 2040 // Temporally closest reference 2041 if (vc1PicParams->picture_fields.is_first_field) 2042 { 2043 // Reference frame 2044 cmd.DW4.ReffieldpicpolarityReferenceFieldPicturePolarity = vc1PicState->wPrevAnchorPictureTFF; 2045 } 2046 else 2047 { 2048 // Same frame 2049 cmd.DW4.ReffieldpicpolarityReferenceFieldPicturePolarity = !vc1PicParams->picture_fields.top_field_first; 2050 } 2051 } 2052 else 2053 { 2054 // Second most temporally closest reference 2055 if (vc1PicParams->picture_fields.is_first_field) 2056 { 2057 // First field of reference frame 2058 cmd.DW4.ReffieldpicpolarityReferenceFieldPicturePolarity = !vc1PicState->wPrevAnchorPictureTFF; 2059 } 2060 else 2061 { 2062 // Second field of reference frame 2063 cmd.DW4.ReffieldpicpolarityReferenceFieldPicturePolarity = vc1PicState->wPrevAnchorPictureTFF; 2064 } 2065 } 2066 } 2067 2068 cmd.DW4.FastuvmcflagFastUvMotionCompensationFlag = vc1PicParams->fast_uvmc_flag; 2069 cmd.DW4.FourmvswitchFourMotionVectorSwitch = vc1PicParams->mv_fields.four_mv_switch; 2070 cmd.DW4.UnifiedmvmodeUnifiedMotionVectorMode = vc1PicParams->mv_fields.UnifiedMvMode; 2071 2072 // If bitplane is present (BitplanePresentFlag == 1) update the "raw" bitplane 2073 // flags. If bitplane is not present leave all "raw" flags to their initialized 2074 // value which is all bitplanes are present "raw". 2075 cmd.DW5.BitplanepresentflagBitplaneBufferPresentFlag = vc1PicParams->raw_coding.bitplane_present; 2076 2077 cmd.DW5.Fieldtxraw = vc1RawMode; 2078 cmd.DW5.Acpredraw = vc1RawMode; 2079 cmd.DW5.Overflagsraw = vc1RawMode; 2080 cmd.DW5.Directmbraw = vc1RawMode; 2081 cmd.DW5.Skipmbraw = vc1RawMode; 2082 cmd.DW5.Mvtypembraw = vc1RawMode; 2083 cmd.DW5.Forwardmbraw = vc1RawMode; 2084 2085 if (vc1PicParams->raw_coding.bitplane_present) 2086 { 2087 cmd.DW5.Fieldtxraw = vc1PicParams->raw_coding.field_tx; 2088 cmd.DW5.Acpredraw = vc1PicParams->raw_coding.ac_pred; 2089 cmd.DW5.Overflagsraw = vc1PicParams->raw_coding.overflags; 2090 cmd.DW5.Directmbraw = vc1PicParams->raw_coding.direct_mb; 2091 cmd.DW5.Skipmbraw = vc1PicParams->raw_coding.skip_mb; 2092 cmd.DW5.Mvtypembraw = vc1PicParams->raw_coding.mv_type_mb; 2093 cmd.DW5.Forwardmbraw = vc1PicParams->raw_coding.forward_mb; 2094 } 2095 2096 cmd.DW5.CbptabCodedBlockPatternTable = vc1PicParams->cbp_table; 2097 cmd.DW5.TransdctabIntraTransformDcTable = vc1PicParams->transform_fields.intra_transform_dc_table; 2098 cmd.DW5.TransacuvPictureLevelTransformChromaAcCodingSetIndexTransactable = vc1PicParams->transform_fields.transform_ac_codingset_idx1; 2099 cmd.DW5.TransacyPictureLevelTransformLumaAcCodingSetIndexTransactable2 = (isIPicture || isBIPicture) ? 2100 vc1PicParams->transform_fields.transform_ac_codingset_idx2 : cmd.DW5.TransacuvPictureLevelTransformChromaAcCodingSetIndexTransactable; 2101 cmd.DW5.MbmodetabMacroblockModeTable = vc1PicParams->mb_mode_table; 2102 2103 if (vc1PicParams->transform_fields.variable_sized_transform_flag == 0) 2104 { 2105 // H/W decodes TTMB, TTBLK and SUBBLKPAT if the picture level TTMBF flag is not set. 2106 // If the VSTRANSFORM is 0, 8x8 TransformType is used for all the pictures belonging to this Entry-Point. 2107 // Hence H/W overloads the TTMBF = 1 and TTFRM = 8x8 in this case. 2108 cmd.DW5.TranstypembflagMacroblockTransformTypeFlag = 1; 2109 cmd.DW5.TranstypePictureLevelTransformType = 0; 2110 } 2111 else 2112 { 2113 cmd.DW5.TranstypembflagMacroblockTransformTypeFlag = vc1PicParams->transform_fields.mb_level_transform_type_flag; 2114 cmd.DW5.TranstypePictureLevelTransformType = vc1PicParams->transform_fields.frame_level_transform_type; 2115 } 2116 cmd.DW5.Twomvbptab2MvBlockPatternTable = vc1PicParams->mv_fields.two_mv_block_pattern_table; 2117 cmd.DW5.Fourmvbptab4MvBlockPatternTable = vc1PicParams->mv_fields.four_mv_block_pattern_table; 2118 cmd.DW5.MvtabMotionVectorTable = vc1PicParams->mv_fields.mv_table; 2119 } 2120 2121 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 2122 2123 return eStatus; 2124 } 2125 AddMfdVc1ShortPicCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VC1_PIC_STATE vc1PicState)2126 MOS_STATUS AddMfdVc1ShortPicCmd( 2127 PMOS_COMMAND_BUFFER cmdBuffer, 2128 PMHW_VDBOX_VC1_PIC_STATE vc1PicState) 2129 { 2130 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 2131 2132 MHW_FUNCTION_ENTER; 2133 2134 MHW_MI_CHK_NULL(m_osInterface); 2135 MHW_MI_CHK_NULL(cmdBuffer); 2136 MHW_MI_CHK_NULL(vc1PicState); 2137 MHW_MI_CHK_NULL(vc1PicState->pVc1PicParams); 2138 2139 auto vc1PicParams = vc1PicState->pVc1PicParams; 2140 2141 uint16_t widthInMbs = CODECHAL_GET_WIDTH_IN_MACROBLOCKS(vc1PicParams->coded_width); 2142 uint16_t heightInMbs = CODECHAL_GET_HEIGHT_IN_MACROBLOCKS(vc1PicParams->coded_height); 2143 2144 uint16_t frameFieldHeightInMb = 0; 2145 CodecHal_GetFrameFieldHeightInMb( 2146 vc1PicParams->CurrPic, 2147 heightInMbs, 2148 frameFieldHeightInMb); 2149 2150 bool isIPicture = IsVc1IPicture( 2151 vc1PicParams->CurrPic, 2152 vc1PicParams->picture_fields.is_first_field, 2153 vc1PicParams->picture_fields.picture_type); 2154 2155 bool isPPicture = IsVc1PPicture( 2156 vc1PicParams->CurrPic, 2157 vc1PicParams->picture_fields.is_first_field, 2158 vc1PicParams->picture_fields.picture_type); 2159 2160 bool isBPicture = IsVc1BPicture( 2161 vc1PicParams->CurrPic, 2162 vc1PicParams->picture_fields.is_first_field, 2163 vc1PicParams->picture_fields.picture_type); 2164 2165 bool isBIPicture = IsVc1BIPicture( 2166 vc1PicParams->CurrPic, 2167 vc1PicParams->picture_fields.is_first_field, 2168 vc1PicParams->picture_fields.picture_type); 2169 2170 typename TMfxCmds::MFD_VC1_SHORT_PIC_STATE_CMD cmd; 2171 2172 // DW 1 2173 cmd.DW1.PictureWidth = widthInMbs - 1; 2174 cmd.DW1.PictureHeight = frameFieldHeightInMb - 1; 2175 2176 // DW 2 2177 cmd.DW2.PictureStructure = 2178 (CodecHal_PictureIsTopField(vc1PicParams->CurrPic)) ? 2179 mpeg2Vc1TopField : (CodecHal_PictureIsBottomField(vc1PicParams->CurrPic)) ? 2180 mpeg2Vc1BottomField : mpeg2Vc1Frame; 2181 cmd.DW2.Secondfield = !vc1PicParams->picture_fields.is_first_field; 2182 cmd.DW2.IntraPictureFlag = isIPicture || isBIPicture; 2183 cmd.DW2.BackwardPredictionPresentFlag = isBPicture; 2184 2185 cmd.DW2.Vc1Profile = vc1PicParams->sequence_fields.AdvancedProfileFlag; 2186 if (isBPicture && 2187 (CodecHal_PictureIsBottomField(vc1PicParams->CurrPic) ? 2188 vc1PicState->bPrevOddAnchorPictureIsP : vc1PicState->bPrevEvenAnchorPictureIsP)) // OR if I not before B in decoding order 2189 { 2190 cmd.DW2.Dmvsurfacevalid = true; 2191 } 2192 2193 cmd.DW2.MotionVectorMode = vc1PicParams->mv_fields.MvMode & 0x9; 2194 cmd.DW2.InterpolationRounderControl = vc1PicParams->rounding_control; 2195 cmd.DW2.BitplaneBufferPitchMinus1 = (vc1PicParams->coded_width <= 2048) ? 2196 (MHW_VDBOX_VC1_BITPLANE_BUFFER_PITCH_SMALL - 1) : (MHW_VDBOX_VC1_BITPLANE_BUFFER_PITCH_LARGE - 1); 2197 2198 // DW 3 2199 cmd.DW3.VstransformFlag = vc1PicParams->transform_fields.variable_sized_transform_flag; 2200 cmd.DW3.Dquant = vc1PicParams->pic_quantizer_fields.dquant; 2201 cmd.DW3.ExtendedMvPresentFlag = vc1PicParams->mv_fields.extended_mv_flag; 2202 cmd.DW3.FastuvmcflagFastUvMotionCompensationFlag = vc1PicParams->fast_uvmc_flag; 2203 cmd.DW3.LoopfilterEnableFlag = vc1PicParams->entrypoint_fields.loopfilter; 2204 cmd.DW3.RefdistFlag = (vc1PicParams->sequence_fields.AdvancedProfileFlag) ? 2205 vc1PicParams->reference_fields.reference_distance_flag : 1; 2206 cmd.DW3.PanscanPresentFlag = vc1PicParams->entrypoint_fields.panscan_flag; 2207 2208 cmd.DW3.Maxbframes = vc1PicParams->sequence_fields.max_b_frames; 2209 cmd.DW3.RangeredPresentFlagForSimpleMainProfileOnly = vc1PicParams->sequence_fields.rangered; 2210 cmd.DW3.SyncmarkerPresentFlagForSimpleMainProfileOnly = vc1PicParams->sequence_fields.syncmarker; 2211 cmd.DW3.MultiresPresentFlagForSimpleMainProfileOnly = vc1PicParams->sequence_fields.multires; 2212 cmd.DW3.Quantizer = vc1PicParams->pic_quantizer_fields.quantizer; 2213 cmd.DW3.PPicRefDistance = vc1PicParams->reference_fields.reference_distance; 2214 2215 cmd.DW3.ProgressivePicType = (CodecHal_PictureIsFrame(vc1PicParams->CurrPic)) ? 1 : 2; 2216 // Dynamic range adjustment disabled 2217 cmd.DW3.RangeReductionEnable = 0; 2218 cmd.DW3.RangeReductionScale = 1; 2219 if (vc1PicParams->sequence_fields.AdvancedProfileFlag) 2220 { 2221 cmd.DW3.OverlapSmoothingEnableFlag = vc1PicParams->sequence_fields.overlap; 2222 } 2223 else 2224 { 2225 cmd.DW3.OverlapSmoothingEnableFlag = 1; 2226 if (isBPicture || (vc1PicParams->pic_quantizer_fields.pic_quantizer_scale < 9) || !vc1PicParams->sequence_fields.overlap) 2227 { 2228 cmd.DW3.OverlapSmoothingEnableFlag = 0; 2229 } 2230 } 2231 2232 // DW 4 2233 cmd.DW4.ExtendedDmvPresentFlag = vc1PicParams->mv_fields.extended_dmv_flag; 2234 cmd.DW4.Psf = vc1PicParams->sequence_fields.psf; 2235 cmd.DW4.Finterflag = vc1PicParams->sequence_fields.finterpflag; 2236 cmd.DW4.Tfcntrflag = vc1PicParams->sequence_fields.tfcntrflag; 2237 cmd.DW4.Interlace = vc1PicParams->sequence_fields.interlace; 2238 cmd.DW4.Pulldown = vc1PicParams->sequence_fields.pulldown; 2239 cmd.DW4.PostprocFlag = vc1PicParams->post_processing; 2240 if (isPPicture || (isBPicture && vc1PicParams->sequence_fields.interlace)) 2241 { 2242 cmd.DW4._4MvAllowedFlag = vc1PicParams->mv_fields.four_mv_allowed; 2243 } 2244 cmd.DW4.RefpicFlag = vc1PicParams->reference_fields.reference_picture_flag; 2245 if (isBPicture) 2246 { 2247 cmd.DW4.BfractionEnumeration = vc1PicParams->b_picture_fraction; 2248 } 2249 2250 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 2251 2252 return eStatus; 2253 } 2254 AddMfxVc1DirectmodeCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VC1_DIRECTMODE_PARAMS params)2255 MOS_STATUS AddMfxVc1DirectmodeCmd( 2256 PMOS_COMMAND_BUFFER cmdBuffer, 2257 PMHW_VDBOX_VC1_DIRECTMODE_PARAMS params) 2258 { 2259 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 2260 2261 MHW_FUNCTION_ENTER; 2262 2263 MHW_MI_CHK_NULL(m_osInterface); 2264 MHW_MI_CHK_NULL(cmdBuffer); 2265 MHW_MI_CHK_NULL(params); 2266 2267 typename TMfxCmds::MFX_VC1_DIRECTMODE_STATE_CMD cmd; 2268 2269 MHW_RESOURCE_PARAMS resourceParams; 2270 MOS_ZeroMemory(&resourceParams, sizeof(resourceParams)); 2271 resourceParams.dwLsbNum = MHW_VDBOX_MFX_GENERAL_STATE_SHIFT; 2272 resourceParams.HwCommandType = MOS_MFX_VC1_DIRECT_MODE; 2273 2274 cmd.DW3.MemoryObjectControlState = 2275 m_cacheabilitySettings[MOS_CODEC_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC].Value; 2276 2277 resourceParams.presResource = params->presDmvWriteBuffer; 2278 resourceParams.dwOffset = 0; 2279 resourceParams.pdwCmd = &(cmd.DW1.Value); 2280 resourceParams.dwLocationInCmd = 1; 2281 resourceParams.bIsWritable = true; 2282 2283 MHW_MI_CHK_STATUS(AddResourceToCmd( 2284 m_osInterface, 2285 cmdBuffer, 2286 &resourceParams)); 2287 2288 cmd.DW6.MemoryObjectControlState = 2289 m_cacheabilitySettings[MOS_CODEC_RESOURCE_USAGE_DIRECTMV_BUFFER_CODEC].Value; 2290 2291 resourceParams.presResource = params->presDmvReadBuffer; 2292 resourceParams.dwOffset = 0; 2293 resourceParams.pdwCmd = &(cmd.DW4.Value); 2294 resourceParams.dwLocationInCmd = 4; 2295 resourceParams.bIsWritable = false; 2296 2297 MHW_MI_CHK_STATUS(AddResourceToCmd( 2298 m_osInterface, 2299 cmdBuffer, 2300 &resourceParams)); 2301 2302 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 2303 2304 return eStatus; 2305 } 2306 AddMfdVc1BsdObjectCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VC1_SLICE_STATE vc1SliceState)2307 MOS_STATUS AddMfdVc1BsdObjectCmd( 2308 PMOS_COMMAND_BUFFER cmdBuffer, 2309 PMHW_VDBOX_VC1_SLICE_STATE vc1SliceState) 2310 { 2311 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 2312 2313 MHW_FUNCTION_ENTER; 2314 2315 MHW_MI_CHK_NULL(m_osInterface); 2316 MHW_MI_CHK_NULL(cmdBuffer); 2317 MHW_MI_CHK_NULL(vc1SliceState); 2318 MHW_MI_CHK_NULL(vc1SliceState->pSlc); 2319 2320 typename TMfxCmds::MFD_VC1_BSD_OBJECT_CMD cmd; 2321 auto slcParams = vc1SliceState->pSlc; 2322 2323 cmd.DW1.IndirectBsdDataLength = vc1SliceState->dwLength; 2324 2325 cmd.DW2.IndirectDataStartAddress = slcParams->slice_data_offset + vc1SliceState->dwOffset; // byte aligned 2326 2327 cmd.DW3.SliceStartVerticalPosition = slcParams->slice_vertical_position; 2328 cmd.DW3.NextSliceVerticalPosition = vc1SliceState->dwNextVerticalPosition; 2329 2330 cmd.DW4.FirstMbByteOffsetOfSliceDataOrSliceHeader = (slcParams->macroblock_offset >> 3) - vc1SliceState->dwOffset; 2331 cmd.DW4.FirstmbbitoffsetFirstMacroblockBitOffset = slcParams->macroblock_offset & 0x7; // bit offset 2332 2333 MHW_CP_SLICE_INFO_PARAMS sliceInfoParam; 2334 sliceInfoParam.presDataBuffer = vc1SliceState->presDataBuffer; 2335 sliceInfoParam.dwDataStartOffset[0] = cmd.DW2.IndirectDataStartAddress; 2336 2337 MHW_MI_CHK_STATUS(m_cpInterface->SetMfxProtectionState( 2338 m_decodeInUse, 2339 cmdBuffer, 2340 nullptr, 2341 &sliceInfoParam)); 2342 2343 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 2344 2345 return eStatus; 2346 } 2347 2348 //! 2349 //! \struct MFD_VC1_IT_OBJECT_CMD 2350 //! \brief MFD VC1 it object command 2351 //! 2352 struct MFD_VC1_IT_OBJECT_CMD 2353 { 2354 typename TMfxCmds::MFD_IT_OBJECT_CMD m_header; 2355 typename TMfxCmds::MFD_IT_OBJECT_VC1_INLINE_DATA_CMD m_inlineData; 2356 }; 2357 2358 //! 2359 //! \brief Get VC1 intra flag 2360 //! 2361 //! \param [in] mbState 2362 //! Pointer to MHW vdbox VC1 mb state 2363 //! \param [in] mbParams 2364 //! Pointer to codec VC1 mb parameters 2365 //! 2366 //! \return uint8_t 2367 //! VC1 intra flag 2368 //! GetVc1IntraFlag(PMHW_VDBOX_VC1_MB_STATE mbState,PCODEC_VC1_MB_PARAMS mbParams)2369 uint8_t GetVc1IntraFlag(PMHW_VDBOX_VC1_MB_STATE mbState, PCODEC_VC1_MB_PARAMS mbParams) 2370 { 2371 const uint8_t PATTERN_CODE_INTRA_MB = 0xF; 2372 uint8_t intra8x8Flag = 0; 2373 2374 if(mbState == nullptr || mbParams == nullptr) 2375 { 2376 MHW_ASSERTMESSAGE("mbState or mbParams is nullptr!"); 2377 return 0; 2378 } 2379 2380 if (mbParams->mb_type.intra_mb) 2381 { 2382 intra8x8Flag = PATTERN_CODE_INTRA_MB; 2383 } 2384 else if (mbParams->mb_type.motion_4mv && (mbState->PicFlags == PICTURE_FRAME)) 2385 { 2386 intra8x8Flag = mbParams->pattern_code.block_luma_intra; 2387 } 2388 else 2389 { 2390 intra8x8Flag = 0; 2391 } 2392 2393 return intra8x8Flag; 2394 } 2395 2396 #define GET_VC1_BLOCK(mb, i) ((mb >> (3 - i)) & 1) 2397 2398 //! 2399 //! \brief VC1 it object set overlap smoothing filter 2400 //! 2401 //! \param [in] inlineDataVc1 2402 //! MFD it object VC1 inline data command 2403 //! \param [in] mbState 2404 //! Pointer to MHW vdbox VC1 mb state 2405 //! \param [in] mbParams 2406 //! Pointer to codec VC1 mb parameters 2407 //! \param [in] mbHorizOrigin 2408 //! Mb horizontal origin 2409 //! \param [in] mbVertOrigin 2410 //! Mb vertical origin 2411 //! Vc1ItObjectSetOverlapSmoothingFilter(typename TMfxCmds::MFD_IT_OBJECT_VC1_INLINE_DATA_CMD * inlineDataVc1,PMHW_VDBOX_VC1_MB_STATE mbState,PCODEC_VC1_MB_PARAMS mbParams,uint8_t mbHorizOrigin,uint8_t mbVertOrigin)2412 MOS_STATUS Vc1ItObjectSetOverlapSmoothingFilter( 2413 typename TMfxCmds::MFD_IT_OBJECT_VC1_INLINE_DATA_CMD *inlineDataVc1, 2414 PMHW_VDBOX_VC1_MB_STATE mbState, 2415 PCODEC_VC1_MB_PARAMS mbParams, 2416 uint8_t mbHorizOrigin, 2417 uint8_t mbVertOrigin) 2418 { 2419 static const uint8_t chromaIntra[16] = 2420 { 2421 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1 2422 }; 2423 MHW_CHK_NULL_RETURN(inlineDataVc1); 2424 MHW_CHK_NULL_RETURN(mbState); 2425 MHW_CHK_NULL_RETURN(mbParams); 2426 2427 auto vc1PicParams = mbState->pVc1PicParams; 2428 MHW_CHK_NULL_RETURN(vc1PicParams); 2429 2430 //------------------------------------ 2431 // Overlap smoothing enabled for this mb? 2432 //------------------------------------ 2433 uint8_t mbOverlapSmoothing = mbParams->mb_type.h261_loopfilter; 2434 inlineDataVc1->DW0.Overlaptransform = mbOverlapSmoothing; 2435 2436 // Horizontal origin is last mb of the row 2437 inlineDataVc1->DW0.Lastmbinrow = (mbHorizOrigin == (mbState->wPicWidthInMb - 1)); 2438 // Vertical origin is last mb of the column 2439 inlineDataVc1->DW0.LastRowFlag = (mbVertOrigin == (mbState->wPicHeightInMb - 1)); 2440 2441 if (mbOverlapSmoothing) 2442 { 2443 uint8_t intra8x8 = GetVc1IntraFlag(mbState, mbParams); 2444 2445 if ((vc1PicParams->picture_fields.picture_type == vc1BBField) || !intra8x8) 2446 { 2447 // Reset parameters 2448 inlineDataVc1->DW0.Overlaptransform = 0; 2449 inlineDataVc1->DW1.Osedgemaskluma = 0; 2450 inlineDataVc1->DW1.Osedgemaskchroma = 0; 2451 2452 return MOS_STATUS_SUCCESS; 2453 } 2454 2455 //------------------------------------ 2456 // Set edge control bitmasks (luma & chroma) 2457 //------------------------------------ 2458 2459 // Overlap smoothing applied to an edge when 2460 // 1. Edge between two 8x8 luma regions or corresponding 4x4 2461 // chroma regions of the same mb for which the H261loopFilter 2462 // flag is equal to 1 2463 // 2. Edge between 8x8 luma regions or corresponding 4x4 chroma 2464 // regions in different MBs for which both are true: 2465 // a. H261loopFilter flag is equal to 1 in both macroblocks, and 2466 // b. Edge is a vertical edge between horizontally-neighboring macroblocks, 2467 // OR is a horizontal edge between vertically-neighboring macroblocks and 2468 // ReservedBits flag (bit 11) is equal to 0 in the wMBtype element of the 2469 // macroblock control command for the lower macroblock and the picture is not an 2470 // interlaced frame (i.e., a picture with bPicStructure equal to '11' and 2471 // bPicExtrapolation equal to 2). 2472 2473 // Condition 1: Top Y2, Top Y3, Left Y1, Left Y3 2474 uint16_t edgeMaskLuma = 0, edgeMaskChroma = 0; 2475 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 0) & GET_VC1_BLOCK(intra8x8, 2)) << 2; 2476 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 1) & GET_VC1_BLOCK(intra8x8, 3)) << 3; 2477 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 0) & GET_VC1_BLOCK(intra8x8, 1)) << 5; 2478 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 2) & GET_VC1_BLOCK(intra8x8, 3)) << 7; 2479 2480 // Condition 2: 2481 // Top Y0, Top Y1, Top Cb/Cr: horizontal edges 2482 if (mbVertOrigin != 0) 2483 { 2484 // Not the top row, so get upper pMB 2485 auto upperMbParams = mbParams - mbState->wPicWidthInMb; 2486 2487 if (upperMbParams && 2488 upperMbParams->mb_type.h261_loopfilter && 2489 !mbParams->mb_type.reserved && 2490 (mbState->PicFlags != PICTURE_INTERLACED_FRAME)) 2491 { 2492 uint8_t adjIntra8x8 = GetVc1IntraFlag(mbState, upperMbParams); 2493 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 0) & GET_VC1_BLOCK(adjIntra8x8, 2)); 2494 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 1) & GET_VC1_BLOCK(adjIntra8x8, 3)) << 1; 2495 edgeMaskChroma |= (chromaIntra[intra8x8] & chromaIntra[adjIntra8x8]); 2496 } 2497 } 2498 2499 // Left Y0, Left Y2, Left Cb/Cr: vertical edges 2500 if (mbHorizOrigin != 0) 2501 { 2502 // Not the first column, so get left pMB 2503 auto leftMbParams = mbParams - 1; 2504 2505 if (leftMbParams && 2506 leftMbParams->mb_type.h261_loopfilter) 2507 { 2508 uint8_t adjIntra8x8 = GetVc1IntraFlag(mbState, leftMbParams); 2509 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 0) & GET_VC1_BLOCK(adjIntra8x8, 1)) << 4; 2510 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 2) & GET_VC1_BLOCK(adjIntra8x8, 3)) << 6; 2511 edgeMaskChroma |= (chromaIntra[intra8x8] & chromaIntra[adjIntra8x8]) << 1; 2512 } 2513 } 2514 2515 // Right Y1, Right Y3, Right Cb/Cr: vertical edges 2516 if (mbHorizOrigin != (mbState->wPicWidthInMb - 1)) 2517 { 2518 // Not the last column, so get right pMB 2519 auto rightMbParams = mbParams + 1; 2520 2521 if (rightMbParams && 2522 rightMbParams->mb_type.h261_loopfilter) 2523 { 2524 uint8_t adjIntra8x8 = GetVc1IntraFlag(mbState, rightMbParams); 2525 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 1) & GET_VC1_BLOCK(adjIntra8x8, 0)) << 8; 2526 edgeMaskLuma |= (GET_VC1_BLOCK(intra8x8, 3) & GET_VC1_BLOCK(adjIntra8x8, 2)) << 9; 2527 edgeMaskChroma |= (chromaIntra[intra8x8] & chromaIntra[adjIntra8x8]) << 2; 2528 } 2529 } 2530 2531 inlineDataVc1->DW1.Osedgemaskluma = edgeMaskLuma; 2532 inlineDataVc1->DW1.Osedgemaskchroma = edgeMaskChroma; 2533 } 2534 else 2535 { 2536 // Reset parameters 2537 inlineDataVc1->DW1.Osedgemaskluma = 0; 2538 inlineDataVc1->DW1.Osedgemaskchroma = 0; 2539 } 2540 2541 return MOS_STATUS_SUCCESS; 2542 } 2543 AddMfdVc1ItObjectCmd(PMHW_BATCH_BUFFER batchBuffer,PMHW_VDBOX_VC1_MB_STATE mbState)2544 MOS_STATUS AddMfdVc1ItObjectCmd( 2545 PMHW_BATCH_BUFFER batchBuffer, 2546 PMHW_VDBOX_VC1_MB_STATE mbState) 2547 { 2548 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 2549 2550 MHW_FUNCTION_ENTER; 2551 2552 MHW_MI_CHK_NULL(batchBuffer); 2553 MHW_MI_CHK_NULL(mbState); 2554 2555 auto mbParams = mbState->pMb; 2556 auto vc1PicParams = mbState->pVc1PicParams; 2557 2558 MFD_VC1_IT_OBJECT_CMD cmd; 2559 typename TMfxCmds::MFD_IT_OBJECT_CMD *cmdMfdItObject = &cmd.m_header; 2560 typename TMfxCmds::MFD_IT_OBJECT_VC1_INLINE_DATA_CMD *inlineDataVc1 = &cmd.m_inlineData; 2561 2562 inlineDataVc1->DW0.MacroblockIntraType = mpeg2Vc1MacroblockIntra; 2563 2564 cmdMfdItObject->DW0.DwordLength += TMfxCmds::MFD_IT_OBJECT_VC1_INLINE_DATA_CMD::dwSize; 2565 2566 if (mbState->bSkipped) 2567 { 2568 inlineDataVc1->DW0.DctType = mbParams->mb_type.field_residual; 2569 2570 if (vc1PicParams->picture_fields.picture_type != vc1IIField) 2571 { 2572 inlineDataVc1->DW0.MacroblockIntraType = mpeg2Vc1MacroblockNonintra; 2573 inlineDataVc1->DW0.MacroblockMotionForward = mbParams->mb_type.motion_forward; 2574 inlineDataVc1->DW0.MacroblockMotionBackward = mbParams->mb_type.motion_backward; 2575 inlineDataVc1->DW0.MotionType = mbParams->mb_type.motion_type; 2576 inlineDataVc1->DW0.MotionVerticalFieldSelect = (mbParams->mb_type.value & 0xF000) >> 12; 2577 inlineDataVc1->DW1.Horzorigin = mbState->bMbHorizOrigin; 2578 inlineDataVc1->DW1.Vertorigin = mbState->bMbVertOrigin; 2579 inlineDataVc1->DW0.Lastmbinrow = 2580 ((inlineDataVc1->DW1.Horzorigin == (mbState->wPicWidthInMb - 1)) && 2581 ((inlineDataVc1->DW1.Vertorigin == (mbState->wPicHeightInMb - 1)))); 2582 } 2583 2584 MHW_MI_CHK_STATUS(Mhw_AddCommandBB(batchBuffer, &cmd, sizeof(cmd))); 2585 2586 return eStatus; 2587 } 2588 2589 // For VC-1 IT VFE Dword is Reserved : MBZ 2590 cmdMfdItObject->DW3.IndirectItCoeffDataLength = mbState->dwLength; 2591 cmdMfdItObject->DW4.IndirectItCoeffDataStartAddressOffset = mbState->dwOffset; 2592 2593 // VC-1 inline data 2594 inlineDataVc1->DW0.MotionType = mbParams->mb_type.motion_type; 2595 inlineDataVc1->DW0.DctType = mbParams->mb_type.field_residual; 2596 2597 inlineDataVc1->DW1.Horzorigin = mbState->bMbHorizOrigin; 2598 inlineDataVc1->DW1.Vertorigin = mbState->bMbVertOrigin; 2599 2600 inlineDataVc1->DW7.SubblockCodeForY0 = mbParams->num_coef[0]; 2601 inlineDataVc1->DW7.SubblockCodeForY1 = mbParams->num_coef[1]; 2602 inlineDataVc1->DW7.SubblockCodeForY2 = mbParams->num_coef[2]; 2603 inlineDataVc1->DW7.SubblockCodeForY3 = mbParams->num_coef[3]; 2604 inlineDataVc1->DW8.SubblockCodeForCb = mbParams->num_coef[4]; 2605 inlineDataVc1->DW8.SubblockCodeForCr = mbParams->num_coef[5]; 2606 2607 // Subblock coding information not present in bNumCoef for Interlace Frame 2608 // intra MBs, so when all 0 (i.e. subblock partition is 8x8) assume subblock present = 1 2609 if (MEDIA_IS_WA(m_waTable, WaAssumeSubblockPresent)) 2610 { 2611 if ((mbState->PicFlags == PICTURE_INTERLACED_FRAME) && mbParams->mb_type.intra_mb && 2612 (inlineDataVc1->DW7.Value == 0) && (inlineDataVc1->DW8.Value == 0)) 2613 { 2614 inlineDataVc1->DW7.SubblockCodeForY0 |= 4; 2615 inlineDataVc1->DW7.SubblockCodeForY1 |= 4; 2616 inlineDataVc1->DW7.SubblockCodeForY2 |= 4; 2617 inlineDataVc1->DW7.SubblockCodeForY3 |= 4; 2618 inlineDataVc1->DW8.SubblockCodeForCb |= 4; 2619 inlineDataVc1->DW8.SubblockCodeForCr |= 4; 2620 } 2621 } 2622 2623 if (vc1PicParams->picture_fields.picture_type == vc1PFrame || 2624 vc1PicParams->sequence_fields.AdvancedProfileFlag) 2625 { 2626 inlineDataVc1->DW9.IldbControlDataForBlockY0 = mbState->DeblockData[0]; 2627 inlineDataVc1->DW9.IldbControlDataForBlockY1 = mbState->DeblockData[1]; 2628 inlineDataVc1->DW9.IldbControlDataForBlockY2 = mbState->DeblockData[2]; 2629 inlineDataVc1->DW9.IldbControlDataForBlockY3 = mbState->DeblockData[3]; 2630 inlineDataVc1->DW10.IldbControlDataForCbBlock = mbState->DeblockData[4]; 2631 inlineDataVc1->DW10.IldbControlDataForCrBlock = mbState->DeblockData[5]; 2632 } 2633 else if (vc1PicParams->entrypoint_fields.loopfilter) 2634 { 2635 //driver generates the edge control value for I and B frames in VC1 Simple and Main profile 2636 if (mbState->bMbHorizOrigin == 0 && mbState->bMbVertOrigin == 0) 2637 { 2638 inlineDataVc1->DW9.Value = MHW_VDBOX_DECODE_VC1_IT_ILDB_EDGE_CONTROL_LUMA_X0Y0; 2639 inlineDataVc1->DW10.Value = MHW_VDBOX_DECODE_VC1_IT_ILDB_EDGE_CONTROL_CHROMA_X0Y0; 2640 } 2641 else if (mbState->bMbHorizOrigin == 0) 2642 { 2643 inlineDataVc1->DW9.Value = MHW_VDBOX_DECODE_VC1_IT_ILDB_EDGE_CONTROL_LUMA_X0Y1; 2644 inlineDataVc1->DW10.Value = MHW_VDBOX_DECODE_VC1_IT_ILDB_EDGE_CONTROL_CHROMA_X0Y1; 2645 } 2646 else if (mbState->bMbVertOrigin == 0) 2647 { 2648 inlineDataVc1->DW9.Value = MHW_VDBOX_DECODE_VC1_IT_ILDB_EDGE_CONTROL_LUMA_X1Y0; 2649 inlineDataVc1->DW10.Value = MHW_VDBOX_DECODE_VC1_IT_ILDB_EDGE_CONTROL_CHROMA_X1Y0; 2650 } 2651 else 2652 { 2653 inlineDataVc1->DW9.Value = MHW_VDBOX_DECODE_VC1_IT_ILDB_EDGE_CONTROL_LUMA_X1Y1; 2654 inlineDataVc1->DW10.Value = MHW_VDBOX_DECODE_VC1_IT_ILDB_EDGE_CONTROL_CHROMA_X1Y1; 2655 } 2656 } 2657 else 2658 { 2659 inlineDataVc1->DW9.Value = 0; 2660 inlineDataVc1->DW10.Value = 0; 2661 } 2662 2663 if (vc1PicParams->picture_fields.picture_type == vc1IFrame) 2664 { 2665 // Intra MB 2666 inlineDataVc1->DW0.CodedBlockPattern = 63; 2667 2668 MHW_MI_CHK_STATUS(Vc1ItObjectSetOverlapSmoothingFilter( 2669 inlineDataVc1, 2670 mbState, 2671 mbParams, 2672 mbState->bMbHorizOrigin, 2673 mbState->bMbVertOrigin)); 2674 2675 MHW_MI_CHK_STATUS(Mhw_AddCommandBB(batchBuffer, &cmd, sizeof(cmd))); 2676 } 2677 else 2678 { 2679 // Motion vectors 2680 inlineDataVc1->DW0.MotionVerticalFieldSelect = (mbParams->mb_type.value & 0xF000) >> 12; 2681 inlineDataVc1->DW0.Motion4Mv = mbParams->mb_type.motion_4mv; 2682 inlineDataVc1->DW0.MacroblockMotionForward = mbParams->mb_type.motion_forward; 2683 inlineDataVc1->DW0.MacroblockMotionBackward = mbParams->mb_type.motion_backward; 2684 inlineDataVc1->DW0.MacroblockIntraType = mbParams->mb_type.intra_mb; 2685 inlineDataVc1->DW0.CodedBlockPattern = 2686 mbParams->mb_type.intra_mb ? 63 : mbParams->pattern_code.block_coded_pattern; 2687 2688 if (mbParams->mb_type.motion_4mv && (mbState->PicFlags == PICTURE_FRAME)) 2689 { 2690 uint8_t cbp = (uint8_t)mbParams->pattern_code.block_luma_intra; 2691 inlineDataVc1->DW0.CodedBlockPattern |= (cbp << 2); // Update luma residue blocks from intra Flags 2692 inlineDataVc1->DW0.LumaIntra8X8Flag = mbParams->pattern_code.block_luma_intra; 2693 inlineDataVc1->DW0.ChromaIntraFlag = mbParams->pattern_code.block_chroma_intra; 2694 2695 if (!mbParams->mb_type.intra_mb && (cbp == 0xF)) // top 4 bits of wPatternCode all set means intra 2696 { 2697 mbParams->mb_type.intra_mb = 1; 2698 inlineDataVc1->DW0.MacroblockIntraType = 1; 2699 inlineDataVc1->DW0.MotionType = 0; // Intra 2700 inlineDataVc1->DW0.MacroblockMotionForward = 0; 2701 inlineDataVc1->DW0.MacroblockMotionBackward = 0; 2702 } 2703 } 2704 2705 // Next, copy in the motion vectors if not skipped frame 2706 if (!mbParams->mb_type.intra_mb && mbState->dwDataSize) 2707 { 2708 inlineDataVc1->DW2.Value = mbState->PackedLumaMvs[0]; 2709 inlineDataVc1->DW3.Value = mbState->PackedLumaMvs[1]; 2710 inlineDataVc1->DW4.Value = mbState->PackedLumaMvs[2]; 2711 inlineDataVc1->DW5.Value = mbState->PackedLumaMvs[3]; 2712 inlineDataVc1->DW6.Value = 2713 (mbState->PicFlags == PICTURE_INTERLACED_FRAME) ? 0 : mbState->PackedChromaMv; 2714 2715 inlineDataVc1->DW0.MotionVerticalFieldSelect = (mbParams->mb_type.value & 0xF000) >> 12; 2716 inlineDataVc1->DW0.Mvfieldselectchroma = mbState->bFieldPolarity; 2717 inlineDataVc1->DW0.Mvswitch = mbState->bMotionSwitch; 2718 } 2719 2720 if (!mbParams->mb_skips_following) 2721 { 2722 MHW_MI_CHK_STATUS(Vc1ItObjectSetOverlapSmoothingFilter( 2723 inlineDataVc1, 2724 mbState, 2725 mbParams, 2726 mbState->bMbHorizOrigin, 2727 mbState->bMbVertOrigin)); 2728 2729 MHW_MI_CHK_STATUS(Mhw_AddCommandBB(batchBuffer, &cmd, sizeof(cmd))); 2730 } 2731 else 2732 { 2733 // Skipped MB's are inter MB's (no residual data, only MV's) so no overlap smoothing 2734 uint16_t skippedMBs = (uint16_t)mbParams->mb_skips_following + 1; 2735 2736 for (uint16_t num = 0; num < skippedMBs; num++) 2737 { 2738 inlineDataVc1->DW0.CodedBlockPattern = 0; 2739 inlineDataVc1->DW1.Horzorigin = (mbParams->mb_address + num) % mbState->wPicWidthInMb; 2740 inlineDataVc1->DW1.Vertorigin = (mbParams->mb_address + num) / mbState->wPicWidthInMb; 2741 2742 // Reset overlap smoothing params 2743 inlineDataVc1->DW0.Lastmbinrow = (inlineDataVc1->DW1.Horzorigin == (mbState->wPicWidthInMb - 1)); 2744 inlineDataVc1->DW0.LastRowFlag = (inlineDataVc1->DW1.Vertorigin == (mbState->wPicHeightInMb - 1)); 2745 inlineDataVc1->DW1.Osedgemaskluma = 0; 2746 inlineDataVc1->DW1.Osedgemaskchroma = 0; 2747 2748 MHW_MI_CHK_STATUS(Mhw_AddCommandBB(batchBuffer, &cmd, sizeof(cmd))); 2749 } 2750 } 2751 } 2752 2753 return eStatus; 2754 } 2755 AddMfxJpegHuffTableCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_HUFF_TABLE_PARAMS params)2756 MOS_STATUS AddMfxJpegHuffTableCmd( 2757 PMOS_COMMAND_BUFFER cmdBuffer, 2758 PMHW_VDBOX_HUFF_TABLE_PARAMS params) 2759 { 2760 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 2761 2762 MHW_FUNCTION_ENTER; 2763 2764 MHW_MI_CHK_NULL(m_osInterface); 2765 MHW_MI_CHK_NULL(cmdBuffer); 2766 MHW_MI_CHK_NULL(params); 2767 MHW_MI_CHK_NULL(params->pDCBits); 2768 MHW_MI_CHK_NULL(params->pDCValues); 2769 MHW_MI_CHK_NULL(params->pACBits); 2770 MHW_MI_CHK_NULL(params->pACValues); 2771 2772 typename TMfxCmds::MFX_JPEG_HUFF_TABLE_STATE_CMD cmd; 2773 2774 cmd.DW1.Hufftableid1Bit = params->HuffTableID; 2775 2776 MHW_MI_CHK_STATUS(MOS_SecureMemcpy( 2777 cmd.DcBits128BitArray, 2778 sizeof(cmd.DcBits128BitArray), 2779 params->pDCBits, 2780 sizeof(cmd.DcBits128BitArray))); 2781 MHW_MI_CHK_STATUS(MOS_SecureMemcpy( 2782 cmd.DcHuffval128BitArray, 2783 sizeof(cmd.DcHuffval128BitArray), 2784 params->pDCValues, 2785 sizeof(cmd.DcHuffval128BitArray))); 2786 MHW_MI_CHK_STATUS(MOS_SecureMemcpy( 2787 cmd.AcBits168BitArray, 2788 sizeof(cmd.AcBits168BitArray), 2789 params->pACBits, 2790 sizeof(cmd.AcBits168BitArray))); 2791 MHW_MI_CHK_STATUS(MOS_SecureMemcpy( 2792 cmd.AcHuffval1608BitArray, 2793 sizeof(cmd.AcHuffval1608BitArray), 2794 params->pACValues, 2795 sizeof(cmd.AcHuffval1608BitArray))); 2796 2797 MHW_MI_CHK_STATUS(MOS_SecureMemcpy( 2798 &cmd.DW52.Value, 2799 sizeof(uint16_t), 2800 (uint8_t*)params->pACValues + sizeof(cmd.AcHuffval1608BitArray), 2801 sizeof(uint16_t))); 2802 2803 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 2804 2805 return eStatus; 2806 } 2807 AddMfxJpegBsdObjCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_JPEG_BSD_PARAMS params)2808 MOS_STATUS AddMfxJpegBsdObjCmd( 2809 PMOS_COMMAND_BUFFER cmdBuffer, 2810 PMHW_VDBOX_JPEG_BSD_PARAMS params) 2811 { 2812 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 2813 2814 MHW_FUNCTION_ENTER; 2815 2816 MHW_MI_CHK_NULL(m_osInterface); 2817 MHW_MI_CHK_NULL(cmdBuffer); 2818 MHW_MI_CHK_NULL(params); 2819 2820 typename TMfxCmds::MFD_JPEG_BSD_OBJECT_CMD cmd; 2821 2822 cmd.DW1.IndirectDataLength = params->dwIndirectDataLength; 2823 cmd.DW2.IndirectDataStartAddress = params->dwDataStartAddress; 2824 cmd.DW3.ScanVerticalPosition = params->dwScanVerticalPosition; 2825 cmd.DW3.ScanHorizontalPosition = params->dwScanHorizontalPosition; 2826 cmd.DW4.McuCount = params->dwMCUCount; 2827 cmd.DW4.ScanComponents = params->sScanComponent; 2828 cmd.DW4.Interleaved = params->bInterleaved; 2829 cmd.DW5.Restartinterval16Bit = params->dwRestartInterval; 2830 2831 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 2832 2833 return eStatus; 2834 } 2835 AddMfdVp8BsdObjectCmd(PMOS_COMMAND_BUFFER cmdBuffer,PMHW_VDBOX_VP8_BSD_PARAMS params)2836 MOS_STATUS AddMfdVp8BsdObjectCmd( 2837 PMOS_COMMAND_BUFFER cmdBuffer, 2838 PMHW_VDBOX_VP8_BSD_PARAMS params) 2839 { 2840 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 2841 2842 MHW_FUNCTION_ENTER; 2843 2844 MHW_MI_CHK_NULL(m_osInterface); 2845 MHW_MI_CHK_NULL(cmdBuffer); 2846 MHW_MI_CHK_NULL(params); 2847 2848 typename TMfxCmds::MFD_VP8_BSD_OBJECT_CMD cmd; 2849 auto vp8PicParams = params->pVp8PicParams; 2850 2851 uint8_t numPartitions = (1 << vp8PicParams->CodedCoeffTokenPartition); 2852 2853 cmd.DW1.CodedNumOfCoeffTokenPartitions = vp8PicParams->CodedCoeffTokenPartition; 2854 cmd.DW1.Partition0CpbacEntropyRange = vp8PicParams->uiP0EntropyRange; 2855 cmd.DW1.Partition0CpbacEntropyCount = vp8PicParams->ucP0EntropyCount; 2856 cmd.DW2.Partition0CpbacEntropyValue = vp8PicParams->ucP0EntropyValue; 2857 2858 cmd.DW3.IndirectPartition0DataLength = vp8PicParams->uiPartitionSize[0] + 1; 2859 cmd.DW4.IndirectPartition0DataStartOffset = vp8PicParams->uiFirstMbByteOffset; 2860 2861 cmd.DW5.IndirectPartition1DataLength = vp8PicParams->uiPartitionSize[1] + 1; 2862 cmd.DW6.IndirectPartition1DataStartOffset = cmd.DW4.IndirectPartition0DataStartOffset + 2863 vp8PicParams->uiPartitionSize[0] + 2864 (numPartitions - 1) * 3; // Account for P Sizes: 3 bytes per partition 2865 // excluding partition 0 and last partition. 2866 2867 int32_t i = 2; 2868 if (i < ((1 + numPartitions))) 2869 { 2870 cmd.DW7.IndirectPartition2DataLength = vp8PicParams->uiPartitionSize[i] + 1; 2871 cmd.DW8.IndirectPartition2DataStartOffset = cmd.DW6.IndirectPartition1DataStartOffset + vp8PicParams->uiPartitionSize[i - 1]; 2872 } 2873 2874 i = 3; 2875 if (i < ((1 + numPartitions))) 2876 { 2877 cmd.DW9.IndirectPartition3DataLength = vp8PicParams->uiPartitionSize[i] + 1; 2878 cmd.DW10.IndirectPartition3DataStartOffset = cmd.DW8.IndirectPartition2DataStartOffset + vp8PicParams->uiPartitionSize[i - 1]; 2879 } 2880 2881 i = 4; 2882 if (i < ((1 + numPartitions))) 2883 { 2884 cmd.DW11.IndirectPartition4DataLength = vp8PicParams->uiPartitionSize[i] + 1; 2885 cmd.DW12.IndirectPartition4DataStartOffset = cmd.DW10.IndirectPartition3DataStartOffset + vp8PicParams->uiPartitionSize[i - 1]; 2886 } 2887 2888 i = 5; 2889 if (i < ((1 + numPartitions))) 2890 { 2891 cmd.DW13.IndirectPartition5DataLength = vp8PicParams->uiPartitionSize[i] + 1; 2892 cmd.DW14.IndirectPartition5DataStartOffset = cmd.DW12.IndirectPartition4DataStartOffset + vp8PicParams->uiPartitionSize[i - 1]; 2893 } 2894 2895 i = 6; 2896 if (i < ((1 + numPartitions))) 2897 { 2898 cmd.DW15.IndirectPartition6DataLength = vp8PicParams->uiPartitionSize[i] + 1; 2899 cmd.DW16.IndirectPartition6DataStartOffset = cmd.DW14.IndirectPartition5DataStartOffset + vp8PicParams->uiPartitionSize[i - 1]; 2900 } 2901 2902 i = 7; 2903 if (i < ((1 + numPartitions))) 2904 { 2905 cmd.DW17.IndirectPartition7DataLength = vp8PicParams->uiPartitionSize[i] + 1; 2906 cmd.DW18.IndirectPartition7DataStartOffset = cmd.DW16.IndirectPartition6DataStartOffset + vp8PicParams->uiPartitionSize[i - 1]; 2907 } 2908 2909 i = 8; 2910 if (i < ((1 + numPartitions))) 2911 { 2912 cmd.DW19.IndirectPartition8DataLength = vp8PicParams->uiPartitionSize[i] + 1; 2913 cmd.DW20.IndirectPartition8DataStartOffset = cmd.DW18.IndirectPartition7DataStartOffset + vp8PicParams->uiPartitionSize[i - 1]; 2914 } 2915 2916 MHW_MI_CHK_STATUS(m_osInterface->pfnAddCommand(cmdBuffer, &cmd, sizeof(cmd))); 2917 2918 return eStatus; 2919 } 2920 2921 public: GetAvcImgStateSize()2922 inline uint32_t GetAvcImgStateSize() 2923 { 2924 return TMfxCmds::MFX_AVC_IMG_STATE_CMD::byteSize; 2925 } 2926 GetAvcSlcStateSize()2927 inline uint32_t GetAvcSlcStateSize() 2928 { 2929 return TMfxCmds::MFX_AVC_SLICE_STATE_CMD::byteSize; 2930 } 2931 2932 }; 2933 2934 #endif 2935