1 /* 2 * Copyright (c) 2019-2020, Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 //! 23 //! \file encode_hevc_tile.cpp 24 //! \brief Defines the common interface for hevc tile 25 //! 26 27 #include "encode_hevc_tile.h" 28 #include "encode_hevc_basic_feature.h" 29 #include "codec_def_common.h" 30 #include "encode_hevc_vdenc_feature_manager.h" 31 #include "encode_pipeline.h" 32 33 namespace encode 34 { HevcEncodeTile(MediaFeatureManager * featureManager,EncodeAllocator * allocator,CodechalHwInterfaceNext * hwInterface,void * constSettings)35 HevcEncodeTile::HevcEncodeTile( 36 MediaFeatureManager *featureManager, 37 EncodeAllocator *allocator, 38 CodechalHwInterfaceNext *hwInterface, 39 void *constSettings) : 40 EncodeTile(featureManager, allocator, hwInterface, constSettings) 41 { 42 ENCODE_CHK_NULL_NO_STATUS_RETURN(hwInterface); 43 m_mosCtx = hwInterface->GetOsInterface()->pOsContext; 44 45 auto encFeatureManager = dynamic_cast<EncodeHevcVdencFeatureManager *>(featureManager); 46 ENCODE_CHK_NULL_NO_STATUS_RETURN(encFeatureManager); 47 48 m_basicFeature = dynamic_cast<EncodeBasicFeature *>(encFeatureManager->GetFeature(FeatureIDs::basicFeature)); 49 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_basicFeature); 50 51 m_hcpItf = std::static_pointer_cast<mhw::vdbox::hcp::Itf>(hwInterface->GetHcpInterfaceNext()); 52 ENCODE_CHK_NULL_NO_STATUS_RETURN(m_hcpItf); 53 } 54 Init(void * settings)55 MOS_STATUS HevcEncodeTile::Init(void* settings) 56 { 57 ENCODE_FUNC_CALL(); 58 ENCODE_CHK_NULL_RETURN(settings); 59 60 ENCODE_CHK_STATUS_RETURN(EncodeTile::Init(settings)); 61 62 #if (_DEBUG || _RELEASE_INTERNAL) 63 // Tile Replay Enable should be passed from DDI, will change later when DDI is ready 64 MediaUserSetting::Value outValue; 65 ReadUserSetting( 66 m_userSettingPtr, 67 outValue, 68 "HEVC VDEnc TileReplay Enable", 69 MediaUserSetting::Group::Sequence); 70 m_enableTileReplay = outValue.Get<bool>(); 71 #else 72 m_enableTileReplay = false; 73 #endif 74 75 return MOS_STATUS_SUCCESS; 76 } 77 Update(void * params)78 MOS_STATUS HevcEncodeTile::Update(void *params) 79 { 80 ENCODE_FUNC_CALL(); 81 ENCODE_CHK_NULL_RETURN(params); 82 83 EncoderParams* encodeParams = (EncoderParams*)params;; 84 ENCODE_CHK_NULL_RETURN(encodeParams); 85 86 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams = 87 static_cast<PCODEC_HEVC_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams); 88 ENCODE_CHK_NULL_RETURN(hevcPicParams); 89 90 m_enabled = hevcPicParams->tiles_enabled_flag ? true : false; 91 92 93 m_maxTileNumber = CODECHAL_GET_WIDTH_IN_BLOCKS(m_basicFeature->m_frameWidth, CODECHAL_HEVC_MIN_TILE_SIZE) * 94 CODECHAL_GET_HEIGHT_IN_BLOCKS(m_basicFeature->m_frameHeight, CODECHAL_HEVC_MIN_TILE_SIZE); 95 96 ENCODE_CHK_STATUS_RETURN(EncodeTile::Update(params)); 97 98 return MOS_STATUS_SUCCESS; 99 } 100 IsLcuInTile(uint32_t lcuX,uint32_t lcuY,EncodeTileData * currentTile)101 bool HevcEncodeTile::IsLcuInTile( 102 uint32_t lcuX, 103 uint32_t lcuY, 104 EncodeTileData *currentTile) 105 { 106 ENCODE_FUNC_CALL(); 107 108 if (m_basicFeature == nullptr) 109 { 110 ENCODE_ASSERTMESSAGE("Null basic feature, unexpected!"); 111 return false; 112 } 113 auto hevcBasicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 114 if (hevcBasicFeature == nullptr) 115 { 116 ENCODE_ASSERTMESSAGE("Null hevc basic feature, unexpected!"); 117 return false; 118 } 119 auto hevcSeqParams = hevcBasicFeature->m_hevcSeqParams; 120 if (hevcSeqParams == nullptr) 121 { 122 ENCODE_ASSERTMESSAGE("Null seq parameters, unexpected!"); 123 return false; 124 } 125 126 uint32_t shift = hevcSeqParams->log2_max_coding_block_size_minus3 - hevcSeqParams->log2_min_coding_block_size_minus3; 127 uint32_t residual = (1 << shift) - 1; 128 uint32_t tileColumnWidth = (currentTile->tileWidthInMinCbMinus1 + 1 + residual) >> shift; 129 uint32_t tileRowHeight = (currentTile->tileHeightInMinCbMinus1 + 1 + residual) >> shift; 130 131 return (lcuX < currentTile->tileStartXInLCU || 132 lcuY < currentTile->tileStartYInLCU || 133 lcuX >= currentTile->tileStartXInLCU + tileColumnWidth || 134 lcuY >= currentTile->tileStartYInLCU + tileRowHeight); 135 } 136 IsSliceInTile(uint32_t sliceNumber,EncodeTileData * currentTile,bool * sliceInTile,bool * lastSliceInTile)137 MOS_STATUS HevcEncodeTile::IsSliceInTile( 138 uint32_t sliceNumber, 139 EncodeTileData *currentTile, 140 bool * sliceInTile, 141 bool * lastSliceInTile) 142 { 143 ENCODE_FUNC_CALL(); 144 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 145 146 ENCODE_CHK_NULL_RETURN(currentTile); 147 ENCODE_CHK_NULL_RETURN(sliceInTile); 148 ENCODE_CHK_NULL_RETURN(lastSliceInTile); 149 ENCODE_CHK_NULL_RETURN(m_basicFeature); 150 auto tmpHevcBasicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 151 ENCODE_CHK_NULL_RETURN(tmpHevcBasicFeature); 152 153 auto hevcPicParams = tmpHevcBasicFeature->m_hevcPicParams; 154 auto hevcSeqParams = tmpHevcBasicFeature->m_hevcSeqParams; 155 auto hevcSliceParams = tmpHevcBasicFeature->m_hevcSliceParams; 156 ENCODE_CHK_NULL_RETURN(hevcPicParams); 157 ENCODE_CHK_NULL_RETURN(hevcSeqParams); 158 ENCODE_CHK_NULL_RETURN(hevcSliceParams); 159 160 if (!m_enabled) 161 { 162 *lastSliceInTile = *sliceInTile = true; 163 return eStatus; 164 } 165 166 uint32_t shift = hevcSeqParams->log2_max_coding_block_size_minus3 - hevcSeqParams->log2_min_coding_block_size_minus3; 167 uint32_t residual = (1 << shift) - 1; 168 uint32_t frameWidthInLCU = (hevcSeqParams->wFrameWidthInMinCbMinus1 + 1 + residual) >> shift; 169 uint32_t frameHeightInLCU = (hevcSeqParams->wFrameHeightInMinCbMinus1 + 1 + residual) >> shift; 170 171 uint32_t tileColumnWidth = (currentTile->tileWidthInMinCbMinus1 + 1 + residual) >> shift; 172 uint32_t tileRowHeight = (currentTile->tileHeightInMinCbMinus1 + 1 + residual) >> shift; 173 174 const CODEC_HEVC_ENCODE_SLICE_PARAMS *hevcSlcParams = &hevcSliceParams[sliceNumber]; 175 uint32_t sliceStartLCU = hevcSlcParams->slice_segment_address; 176 uint32_t sliceLCUx = sliceStartLCU % frameWidthInLCU; 177 uint32_t sliceLCUy = sliceStartLCU / frameWidthInLCU; 178 179 if (IsLcuInTile(sliceLCUx, sliceLCUy, currentTile)) 180 { 181 // slice start is not in the tile boundary 182 *lastSliceInTile = *sliceInTile = false; 183 return eStatus; 184 } 185 186 sliceLCUx += (hevcSlcParams->NumLCUsInSlice - 1) % tileColumnWidth; 187 sliceLCUy += (hevcSlcParams->NumLCUsInSlice - 1) / tileColumnWidth; 188 189 if (sliceLCUx >= currentTile->tileStartXInLCU + tileColumnWidth) 190 { 191 sliceLCUx -= tileColumnWidth; 192 sliceLCUy++; 193 } 194 195 if (IsLcuInTile(sliceLCUx, sliceLCUy, currentTile)) 196 { 197 // last LCU of the slice is out of the tile boundary 198 *lastSliceInTile = *sliceInTile = false; 199 return eStatus; 200 } 201 202 *sliceInTile = true; 203 204 sliceLCUx++; 205 sliceLCUy++; 206 207 // the end of slice is at the boundary of tile 208 *lastSliceInTile = (sliceLCUx == currentTile->tileStartXInLCU + tileColumnWidth && 209 sliceLCUy == currentTile->tileStartYInLCU + tileRowHeight); 210 211 return eStatus; 212 } 213 SetPipeNumber(uint32_t numPipes)214 MOS_STATUS HevcEncodeTile::SetPipeNumber(uint32_t numPipes) 215 { 216 ENCODE_FUNC_CALL(); 217 218 m_curTileCodingParams.NumberOfActiveBePipes = numPipes; 219 220 return MOS_STATUS_SUCCESS; 221 } 222 SetCurrentTileFromSliceIndex(uint32_t slcCount,EncodePipeline * pipeline)223 MOS_STATUS HevcEncodeTile::SetCurrentTileFromSliceIndex( 224 uint32_t slcCount, 225 EncodePipeline *pipeline) 226 { 227 ENCODE_FUNC_CALL(); 228 229 bool lastSliceInTile = false, sliceInTile = false; 230 231 EncodeTileData curTileData = {}; 232 233 // Find the tileData corresponding to this slice 234 for (uint32_t tileRow = 0; tileRow < m_numTileRows; tileRow++) 235 { 236 for (uint32_t tileCol = 0; tileCol < m_numTileColumns; tileCol++) 237 { 238 ENCODE_CHK_STATUS_RETURN(SetCurrentTile(tileRow, tileCol, pipeline)); 239 ENCODE_CHK_STATUS_RETURN(GetCurrentTile(curTileData)); 240 ENCODE_CHK_STATUS_RETURN(IsSliceInTile(slcCount, &curTileData, &sliceInTile, &lastSliceInTile)); 241 242 if (sliceInTile) 243 { 244 break; 245 } 246 } 247 if (sliceInTile) 248 { 249 break; 250 } 251 } 252 253 return MOS_STATUS_SUCCESS; 254 } 255 CalculateNumLcuByTiles(PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams)256 MOS_STATUS HevcEncodeTile::CalculateNumLcuByTiles(PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams) 257 { 258 ENCODE_FUNC_CALL(); 259 260 ENCODE_CHK_NULL_RETURN(hevcPicParams); 261 262 m_numLcuInPic = 0; 263 for (uint32_t numLcusInTiles = 0, i = 0; i < m_numTileRows; i++) 264 { 265 for (uint32_t j = 0; j < m_numTileColumns; j++) 266 { 267 m_numLcuInPic += hevcPicParams->tile_row_height[i] * hevcPicParams->tile_column_width[j]; 268 } 269 } 270 if (m_numLcuInPic == 0) 271 { 272 ENCODE_ASSERTMESSAGE("LCU num cal by each tile is zero, sth must be wrong!"); 273 return MOS_STATUS_INVALID_PARAMETER; 274 } 275 return MOS_STATUS_SUCCESS; 276 } 277 CalculateTilesBoundary(PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams,uint32_t * rowBd,uint32_t * colBd)278 MOS_STATUS HevcEncodeTile::CalculateTilesBoundary( 279 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams, 280 uint32_t *rowBd, 281 uint32_t *colBd) 282 { 283 ENCODE_FUNC_CALL(); 284 285 ENCODE_CHK_NULL_RETURN(hevcPicParams); 286 ENCODE_CHK_NULL_RETURN(rowBd); 287 ENCODE_CHK_NULL_RETURN(colBd); 288 289 for (uint32_t i = 0; i < m_numTileColumns; i++) 290 { 291 colBd[i + 1] = colBd[i] + hevcPicParams->tile_column_width[i]; 292 } 293 294 for (uint32_t i = 0; i < m_numTileRows; i++) 295 { 296 rowBd[i + 1] = rowBd[i] + hevcPicParams->tile_row_height[i]; 297 } 298 299 return MOS_STATUS_SUCCESS; 300 301 } 302 CalculateTileWidthAndHeight(PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams,PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams,uint32_t rowIndex,uint32_t colIndex,uint32_t * rowBd,uint32_t * colBd)303 MOS_STATUS HevcEncodeTile::CalculateTileWidthAndHeight( 304 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams, 305 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams, 306 uint32_t rowIndex, 307 uint32_t colIndex, 308 uint32_t *rowBd, 309 uint32_t *colBd) 310 { 311 ENCODE_FUNC_CALL(); 312 313 ENCODE_CHK_NULL_RETURN(hevcPicParams); 314 ENCODE_CHK_NULL_RETURN(hevcSeqParams); 315 ENCODE_CHK_NULL_RETURN(rowBd); 316 ENCODE_CHK_NULL_RETURN(colBd); 317 318 uint32_t idx = rowIndex * m_numTileColumns + colIndex; 319 int32_t frameWidthInMinCb = hevcSeqParams->wFrameWidthInMinCbMinus1 + 1; 320 int32_t frameHeightInMinCb = hevcSeqParams->wFrameHeightInMinCbMinus1 + 1; 321 int32_t shift = hevcSeqParams->log2_max_coding_block_size_minus3 - hevcSeqParams->log2_min_coding_block_size_minus3; 322 323 if (colIndex != m_numTileColumns - 1) 324 { 325 m_tileData[idx].tileWidthInMinCbMinus1 = (hevcPicParams->tile_column_width[colIndex] << shift) - 1; 326 m_tileData[idx].isLastTileofRow = false; 327 } 328 else 329 { 330 m_tileData[idx].tileWidthInMinCbMinus1 = (frameWidthInMinCb - (colBd[colIndex] << shift)) - 1; 331 m_tileData[idx].isLastTileofRow = true; 332 } 333 334 if (rowIndex != m_numTileRows - 1) 335 { 336 m_tileData[idx].isLastTileofColumn = false; 337 m_tileData[idx].tileHeightInMinCbMinus1 = (hevcPicParams->tile_row_height[rowIndex] << shift) - 1; 338 } 339 else 340 { 341 m_tileData[idx].tileHeightInMinCbMinus1 = (frameHeightInMinCb - (rowBd[rowIndex] << shift)) - 1; 342 m_tileData[idx].isLastTileofColumn = true; 343 } 344 345 return MOS_STATUS_SUCCESS; 346 } 347 GetTileInfo(uint32_t xPosition,uint32_t yPosition,uint32_t & tileStartLcuX,uint32_t & tileEndLcuX,uint32_t & tileStartLcuY,uint32_t & tileEndLcuY,uint32_t & tileStreaminOffset)348 MOS_STATUS HevcEncodeTile::GetTileInfo( 349 uint32_t xPosition, 350 uint32_t yPosition, 351 uint32_t &tileStartLcuX, 352 uint32_t &tileEndLcuX, 353 uint32_t &tileStartLcuY, 354 uint32_t &tileEndLcuY, 355 uint32_t &tileStreaminOffset) 356 { 357 MOS_STATUS eStatus = MOS_STATUS_INVALID_PARAMETER; 358 359 for (uint32_t i = 0; i < m_numTiles; i++) 360 { 361 tileStartLcuX = m_tileData[i].tileStartXInLCU; 362 tileStartLcuY = m_tileData[i].tileStartYInLCU; 363 tileEndLcuX = m_tileData[i].tileEndXInLCU; 364 tileEndLcuY = m_tileData[i].tileEndYInLCU; 365 366 tileStreaminOffset = m_tileData[i].tileStreaminOffset; 367 368 if ((xPosition >= (tileStartLcuX * 2)) && 369 (yPosition >= (tileStartLcuY * 2)) && 370 (xPosition < (tileEndLcuX * 2)) && 371 (yPosition < (tileEndLcuY * 2))) 372 { 373 eStatus = MOS_STATUS_SUCCESS; 374 break; 375 } 376 } 377 378 return eStatus; 379 } 380 SetTileData(void * params)381 MOS_STATUS HevcEncodeTile::SetTileData(void *params) 382 { 383 ENCODE_FUNC_CALL(); 384 385 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 386 387 if (!m_enabled) 388 { 389 return eStatus; 390 } 391 392 ENCODE_CHK_NULL_RETURN(params); 393 394 EncoderParams* encodeParams = (EncoderParams*)params;; 395 ENCODE_CHK_NULL_RETURN(encodeParams); 396 397 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams = 398 static_cast<PCODEC_HEVC_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams); 399 ENCODE_CHK_NULL_RETURN(hevcPicParams); 400 401 PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams = 402 static_cast<PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS>(encodeParams->pSeqParams); 403 ENCODE_CHK_NULL_RETURN(hevcSeqParams); 404 405 PCODEC_HEVC_ENCODE_SLICE_PARAMS hevcSliceParams = 406 static_cast<PCODEC_HEVC_ENCODE_SLICE_PARAMS>(encodeParams->pSliceParams); 407 ENCODE_CHK_NULL_RETURN(hevcSliceParams); 408 409 m_numTileRows = hevcPicParams->num_tile_rows_minus1 + 1; 410 m_numTileColumns = hevcPicParams->num_tile_columns_minus1 + 1; 411 412 uint32_t colBd[m_maxTileBdNum] = {0}; 413 uint32_t rowBd[m_maxTileBdNum] = {0}; 414 ENCODE_CHK_STATUS_RETURN(CalculateTilesBoundary(hevcPicParams, &rowBd[0], &colBd[0])); 415 416 m_numTiles = m_numTileRows * m_numTileColumns; 417 if (m_numTiles > CODECHAL_GET_WIDTH_IN_BLOCKS(m_basicFeature->m_frameWidth, CODECHAL_HEVC_VDENC_MIN_TILE_WIDTH_SIZE) * 418 CODECHAL_GET_HEIGHT_IN_BLOCKS(m_basicFeature->m_frameHeight, CODECHAL_HEVC_VDENC_MIN_TILE_HEIGHT_SIZE)) 419 { 420 return MOS_STATUS_INVALID_PARAMETER; 421 } 422 423 bool is10Bit = m_basicFeature->m_is10Bit; 424 425 uint32_t const numCuRecordTab[] = {1, 4, 16, 64}; //LCU: 8x8->1, 16x16->4, 32x32->16, 64x64->64 426 uint32_t numCuRecord = numCuRecordTab[MOS_MIN(3, hevcSeqParams->log2_max_coding_block_size_minus3)]; 427 uint32_t maxBytePerLCU = 1 << (hevcSeqParams->log2_max_coding_block_size_minus3 + 3); 428 maxBytePerLCU = maxBytePerLCU * maxBytePerLCU; // number of pixels per LCU 429 maxBytePerLCU = maxBytePerLCU * 3 / (is10Bit ? 1 : 2); //assume 4:2:0 format 430 uint32_t bitstreamByteOffset = 0, saoRowstoreOffset = 0, cuLevelStreamoutOffset = 0, sseRowstoreOffset = 0; 431 int32_t frameWidthInMinCb = hevcSeqParams->wFrameWidthInMinCbMinus1 + 1; 432 int32_t frameHeightInMinCb = hevcSeqParams->wFrameHeightInMinCbMinus1 + 1; 433 int32_t shift = hevcSeqParams->log2_max_coding_block_size_minus3 - hevcSeqParams->log2_min_coding_block_size_minus3; 434 uint32_t ctbSize = 1 << (hevcSeqParams->log2_max_coding_block_size_minus3 + 3); 435 uint32_t streamInWidthinLCU = MOS_ROUNDUP_DIVIDE((frameWidthInMinCb << (hevcSeqParams->log2_min_coding_block_size_minus3 + 3)), ctbSize); 436 uint32_t tileStartLCUAddr = 0; 437 438 ENCODE_CHK_STATUS_RETURN(CalculateNumLcuByTiles(hevcPicParams)); 439 440 uint64_t activeBitstreamSize = (uint64_t)m_basicFeature->m_bitstreamSize; 441 // There would be padding at the end of last tile in CBR, reserve dedicated part in the BS buf 442 if (hevcSeqParams->RateControlMethod == RATECONTROL_CBR) 443 { 444 // Assume max padding num < target frame size derived from target bit rate and frame rate 445 if (hevcSeqParams->FrameRate.Denominator == 0) 446 { 447 return MOS_STATUS_INVALID_PARAMETER; 448 } 449 uint32_t actualFrameRate = hevcSeqParams->FrameRate.Numerator / hevcSeqParams->FrameRate.Denominator; 450 uint64_t reservedPart = (uint64_t)hevcSeqParams->TargetBitRate / 8 / (uint64_t)actualFrameRate * 1024; 451 452 if (reservedPart > activeBitstreamSize) 453 { 454 ENCODE_ASSERTMESSAGE("Frame size cal from target Bit rate is larger than BS buf! Issues in CBR paras!"); 455 return MOS_STATUS_INVALID_PARAMETER; 456 } 457 458 // Capping the reserved part to 1/10 of bs buf size 459 if (reservedPart > activeBitstreamSize / 10) 460 { 461 reservedPart = activeBitstreamSize / 10; 462 } 463 464 activeBitstreamSize -= reservedPart; 465 } 466 467 for (uint32_t numLcusInTiles = 0, i = 0; i < m_numTileRows; i++) 468 { 469 for (uint32_t j = 0; j < m_numTileColumns; j++) 470 { 471 uint32_t idx = i * m_numTileColumns + j; 472 uint32_t numLcuInTile = hevcPicParams->tile_row_height[i] * hevcPicParams->tile_column_width[j]; 473 474 m_tileData[idx].tileStartXInLCU = colBd[j]; 475 m_tileData[idx].tileStartYInLCU = rowBd[i]; 476 477 m_tileData[idx].tileColumnStoreSelect = j % 2; 478 m_tileData[idx].tileRowStoreSelect = i % 2; 479 480 ENCODE_CHK_STATUS_RETURN(CalculateTileWidthAndHeight(hevcPicParams, hevcSeqParams, i, j, &rowBd[0], &colBd[0])); 481 482 m_tileData[idx].numOfTilesInFrame = m_numTiles; 483 m_tileData[idx].numOfTileColumnsInFrame = m_numTileColumns; 484 m_tileData[idx].cuRecordOffset = MOS_ALIGN_CEIL(((numCuRecord * numLcusInTiles) * m_hcpItf->GetEncCuRecordSize()), 485 CODECHAL_CACHELINE_SIZE) / CODECHAL_CACHELINE_SIZE; 486 487 m_tileData[idx].pakTileStatisticsOffset = 9 * idx; 488 m_tileData[idx].tileSizeStreamoutOffset = idx; 489 m_tileData[idx].vp9ProbabilityCounterStreamoutOffset = 0; 490 491 m_tileData[idx].cuLevelStreamoutOffset = cuLevelStreamoutOffset; 492 m_tileData[idx].sseRowstoreOffset = sseRowstoreOffset; 493 m_tileData[idx].bitstreamByteOffset = bitstreamByteOffset; 494 m_tileData[idx].saoRowstoreOffset = saoRowstoreOffset; 495 496 uint32_t tileHeightInLCU = MOS_ROUNDUP_DIVIDE(((m_tileData[idx].tileHeightInMinCbMinus1 + 1) << (hevcSeqParams->log2_min_coding_block_size_minus3 + 3)), ctbSize); 497 uint32_t tileWidthInLCU = MOS_ROUNDUP_DIVIDE(((m_tileData[idx].tileWidthInMinCbMinus1 + 1) << (hevcSeqParams->log2_min_coding_block_size_minus3 + 3)), ctbSize); 498 499 m_tileData[idx].tileEndXInLCU = m_tileData[idx].tileStartXInLCU + tileWidthInLCU; 500 m_tileData[idx].tileEndYInLCU = m_tileData[idx].tileStartYInLCU + tileHeightInLCU; 501 502 //StreamIn data is 4 CLs per LCU 503 m_tileData[idx].tileStreaminOffset = 4 * (m_tileData[idx].tileStartYInLCU * streamInWidthinLCU + m_tileData[idx].tileStartXInLCU * tileHeightInLCU); 504 m_tileData[idx].sliceSizeStreamoutOffset = tileStartLCUAddr; 505 506 tileStartLCUAddr += (tileWidthInLCU * tileHeightInLCU); 507 508 cuLevelStreamoutOffset += (m_tileData[idx].tileWidthInMinCbMinus1 + 1) * (m_tileData[idx].tileHeightInMinCbMinus1 + 1) * 16 / CODECHAL_CACHELINE_SIZE; 509 sseRowstoreOffset += ((hevcPicParams->tile_column_width[j] + 3) * ((HevcBasicFeature*)m_basicFeature)->m_sizeOfSseSrcPixelRowStoreBufferPerLcu) / CODECHAL_CACHELINE_SIZE; 510 saoRowstoreOffset += (MOS_ALIGN_CEIL(hevcPicParams->tile_column_width[j], 4) * CODECHAL_HEVC_SAO_STRMOUT_SIZE_PERLCU) / CODECHAL_CACHELINE_SIZE; 511 512 uint64_t totalSizeTemp = (uint64_t)activeBitstreamSize * (uint64_t)numLcuInTile; 513 uint32_t bitStreamSizePerTile = (uint32_t)(totalSizeTemp / (uint64_t)m_numLcuInPic) + ((totalSizeTemp % (uint64_t)m_numLcuInPic) ? 1 : 0); 514 bitstreamByteOffset += MOS_ALIGN_CEIL(bitStreamSizePerTile, CODECHAL_CACHELINE_SIZE) / CODECHAL_CACHELINE_SIZE; 515 516 numLcusInTiles += numLcuInTile; 517 } 518 519 // same row store buffer for different tile rows. 520 saoRowstoreOffset = 0; 521 sseRowstoreOffset = 0; 522 } 523 524 return eStatus; 525 } 526 AllocateTileStatistics(void * params)527 MOS_STATUS HevcEncodeTile::AllocateTileStatistics(void *params) 528 { 529 ENCODE_FUNC_CALL(); 530 531 MOS_STATUS eStatus = MOS_STATUS_SUCCESS; 532 533 ENCODE_CHK_NULL_RETURN(params); 534 535 if (!m_enabled) 536 { 537 return eStatus; 538 } 539 540 EncoderParams *encodeParams = (EncoderParams *)params; 541 ENCODE_CHK_NULL_RETURN(encodeParams); 542 543 PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams = 544 static_cast<PCODEC_HEVC_ENCODE_PICTURE_PARAMS>(encodeParams->pPicParams); 545 ENCODE_CHK_NULL_RETURN(hevcPicParams); 546 547 auto num_tile_rows = hevcPicParams->num_tile_rows_minus1 + 1; 548 auto num_tile_columns = hevcPicParams->num_tile_columns_minus1 + 1; 549 auto num_tiles = num_tile_rows * num_tile_columns; 550 551 uint32_t maxLcuSize = 64; 552 if (m_numLcuInPic == 0) 553 { 554 ENCODE_ASSERTMESSAGE("LCU num cal by each tile is zero, sth must be wrong!"); 555 return MOS_STATUS_INVALID_PARAMETER; 556 } 557 558 MOS_ZeroMemory(&m_hevcFrameStatsOffset, sizeof(HevcTileStatusInfo)); 559 MOS_ZeroMemory(&m_hevcTileStatsOffset, sizeof(HevcTileStatusInfo)); 560 MOS_ZeroMemory(&m_hevcStatsSize, sizeof(HevcTileStatusInfo)); 561 562 // Set the maximum size based on frame level statistics. 563 m_hevcStatsSize.tileSizeRecord = CODECHAL_CACHELINE_SIZE; 564 m_hevcStatsSize.hevcPakStatistics = EncodeBasicFeature::m_sizeOfHcpPakFrameStats; 565 m_hevcStatsSize.vdencStatistics = CODECHAL_HEVC_VDENC_STATS_SIZE; 566 m_hevcStatsSize.hevcSliceStreamout = CODECHAL_CACHELINE_SIZE; 567 568 // Maintain the offsets to use for patching addresses in to the HuC Pak Integration kernel Aggregated Frame Statistics Output Buffer 569 // Each offset needs to be page aligned as the combined region is fed into different page aligned HuC regions 570 m_hevcFrameStatsOffset.tileSizeRecord = 0; // Tile Size Record is not present in resHuCPakAggregatedFrameStatsBuffer 571 m_hevcFrameStatsOffset.hevcPakStatistics = 0; 572 m_hevcFrameStatsOffset.vdencStatistics = MOS_ALIGN_CEIL(m_hevcFrameStatsOffset.hevcPakStatistics + m_hevcStatsSize.hevcPakStatistics, CODECHAL_PAGE_SIZE); 573 m_hevcFrameStatsOffset.hevcSliceStreamout = MOS_ALIGN_CEIL(m_hevcFrameStatsOffset.vdencStatistics + m_hevcStatsSize.vdencStatistics, CODECHAL_PAGE_SIZE); 574 575 // Frame level statistics 576 m_hwInterface->m_pakIntAggregatedFrameStatsSize = MOS_ALIGN_CEIL(m_hevcFrameStatsOffset.hevcSliceStreamout + (m_hevcStatsSize.hevcSliceStreamout * m_numLcuInPic), CODECHAL_PAGE_SIZE); 577 578 // HEVC Frame Statistics Buffer - Output from HuC PAK Integration kernel 579 if (Mos_ResourceIsNull(&m_resHuCPakAggregatedFrameStatsBuffer)) 580 { 581 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 582 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 583 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 584 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 585 allocParamsForBufferLinear.Format = Format_Buffer; 586 allocParamsForBufferLinear.dwBytes = m_hwInterface->m_pakIntAggregatedFrameStatsSize; 587 allocParamsForBufferLinear.pBufName = "HCP Aggregated Frame Statistics Streamout Buffer"; 588 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_CACHE; 589 auto resource = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 590 ENCODE_CHK_NULL_RETURN(resource); 591 m_resHuCPakAggregatedFrameStatsBuffer = *resource; 592 } 593 594 // Maintain the offsets to use for patching addresses in to the Tile Based Statistics Buffer 595 // Each offset needs to be page aligned as the combined region is fed into different page aligned HuC regions 596 m_hevcTileStatsOffset.tileSizeRecord = 0; // TileRecord is a separated resource 597 m_hevcTileStatsOffset.hevcPakStatistics = 0; // PakStatistics is head of m_resTileBasedStatisticsBuffer; 598 m_hevcTileStatsOffset.vdencStatistics = MOS_ALIGN_CEIL(m_hevcTileStatsOffset.hevcPakStatistics + (m_hevcStatsSize.hevcPakStatistics * num_tiles), CODECHAL_PAGE_SIZE); 599 m_hevcTileStatsOffset.hevcSliceStreamout = MOS_ALIGN_CEIL(m_hevcTileStatsOffset.vdencStatistics + (m_hevcStatsSize.vdencStatistics * num_tiles), CODECHAL_PAGE_SIZE); 600 // Combined statistics size for all tiles 601 m_hwInterface->m_pakIntTileStatsSize = MOS_ALIGN_CEIL(m_hevcTileStatsOffset.hevcSliceStreamout + m_hevcStatsSize.hevcSliceStreamout * m_numLcuInPic, CODECHAL_PAGE_SIZE); 602 603 // Tile size record size for all tiles 604 m_hwInterface->m_tileRecordSize = m_hevcStatsSize.tileSizeRecord * num_tiles; 605 606 MOS_SURFACE surface; 607 MOS_ZeroMemory(&surface, sizeof(surface)); 608 surface.OsResource = m_resTileBasedStatisticsBuffer[m_statisticsBufIndex]; 609 if (!Mos_ResourceIsNull(&surface.OsResource)) 610 { 611 m_allocator->GetSurfaceInfo(&surface); 612 } 613 uint32_t curPakIntTileStatsSize = surface.dwHeight * surface.dwWidth; 614 615 if (Mos_ResourceIsNull(&m_resTileBasedStatisticsBuffer[m_statisticsBufIndex]) || 616 curPakIntTileStatsSize < m_hwInterface->m_pakIntTileStatsSize) 617 { 618 if (!Mos_ResourceIsNull(&m_resTileBasedStatisticsBuffer[m_statisticsBufIndex])) 619 { 620 m_allocator->DestroyResource(&m_resTileBasedStatisticsBuffer[m_statisticsBufIndex]); 621 } 622 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 623 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 624 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 625 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 626 allocParamsForBufferLinear.Format = Format_Buffer; 627 allocParamsForBufferLinear.dwBytes = m_hwInterface->m_pakIntTileStatsSize; 628 allocParamsForBufferLinear.pBufName = "HCP Tile Level Statistics Streamout Buffer"; 629 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE; 630 auto resource = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 631 ENCODE_CHK_NULL_RETURN(resource); 632 m_resTileBasedStatisticsBuffer[m_statisticsBufIndex] = *resource; 633 } 634 635 // Allocate the updated tile size buffer for PAK integration kernel 636 if (Mos_ResourceIsNull(&m_tileRecordBuffer[m_statisticsBufIndex])) 637 { 638 MOS_ALLOC_GFXRES_PARAMS allocParamsForBufferLinear; 639 MOS_ZeroMemory(&allocParamsForBufferLinear, sizeof(MOS_ALLOC_GFXRES_PARAMS)); 640 allocParamsForBufferLinear.Type = MOS_GFXRES_BUFFER; 641 allocParamsForBufferLinear.TileType = MOS_TILE_LINEAR; 642 allocParamsForBufferLinear.Format = Format_Buffer; 643 allocParamsForBufferLinear.dwBytes = CODECHAL_CACHELINE_SIZE * num_tiles; 644 allocParamsForBufferLinear.pBufName = "Tile Record Buffer"; 645 allocParamsForBufferLinear.ResUsageType = MOS_HW_RESOURCE_USAGE_ENCODE_INTERNAL_READ_WRITE_NOCACHE; 646 647 auto resource = m_allocator->AllocateResource(allocParamsForBufferLinear, true); 648 ENCODE_CHK_NULL_RETURN(resource); 649 m_tileRecordBuffer[m_statisticsBufIndex] = *resource; 650 } 651 652 return eStatus; 653 } 654 GetTileStatusInfo(HevcTileStatusInfo & hevcTileStatsOffset,HevcTileStatusInfo & hevcFrameStatsOffset,HevcTileStatusInfo & hevcStatsSize)655 MOS_STATUS HevcEncodeTile::GetTileStatusInfo( 656 HevcTileStatusInfo &hevcTileStatsOffset, 657 HevcTileStatusInfo &hevcFrameStatsOffset, 658 HevcTileStatusInfo &hevcStatsSize) 659 { 660 ENCODE_FUNC_CALL(); 661 if (!m_enabled) 662 { 663 return MOS_STATUS_SUCCESS; 664 } 665 666 hevcTileStatsOffset = m_hevcTileStatsOffset; 667 hevcFrameStatsOffset = m_hevcFrameStatsOffset; 668 hevcStatsSize = m_hevcStatsSize; 669 670 return MOS_STATUS_SUCCESS; 671 } 672 GetTileInfo(HevcTileInfo * hevcTileInfo) const673 MOS_STATUS HevcEncodeTile::GetTileInfo(HevcTileInfo *hevcTileInfo) const 674 { 675 ENCODE_CHK_NULL_RETURN(hevcTileInfo); 676 677 if (m_enabled) 678 { 679 hevcTileInfo->tileId = static_cast<uint16_t>(m_tileIdx); // Tile number in a frame 680 681 const auto currTileData = m_tileData[m_tileIdx]; 682 683 hevcTileInfo->tileColPositionInSb = static_cast<uint16_t>(currTileData.tileStartX); 684 hevcTileInfo->tileRowPositionInSb = static_cast<uint16_t>(currTileData.tileStartY); 685 686 hevcTileInfo->tileWidthInSbMinus1 = currTileData.tileEndX - currTileData.tileStartX - 1; 687 hevcTileInfo->tileHeightInSbMinus1 = currTileData.tileEndY - currTileData.tileStartY - 1; 688 689 hevcTileInfo->tileStartXInLCU = currTileData.tileStartX; 690 hevcTileInfo->tileStartYInLCU = currTileData.tileStartY; 691 hevcTileInfo->tileEndXInLCU = currTileData.tileEndX; 692 hevcTileInfo->tileEndYInLCU = currTileData.tileEndY; 693 hevcTileInfo->tileNum = static_cast<uint16_t>(m_tileIdx); 694 } 695 return MOS_STATUS_SUCCESS; 696 } 697 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT,HevcEncodeTile)698 MHW_SETPAR_DECL_SRC(VDENC_PIPE_MODE_SELECT, HevcEncodeTile) 699 { 700 if (m_enabled) 701 { 702 params.tileBasedReplayMode = m_enableTileReplay; 703 } 704 else 705 { 706 params.tileBasedReplayMode = 0; 707 } 708 return MOS_STATUS_SUCCESS; 709 } 710 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE,HevcEncodeTile)711 MHW_SETPAR_DECL_SRC(VDENC_PIPE_BUF_ADDR_STATE, HevcEncodeTile) 712 { 713 ENCODE_FUNC_CALL(); 714 715 if (!m_enabled) 716 { 717 return MOS_STATUS_SUCCESS; 718 } 719 720 MOS_RESOURCE *tileStatisticsBuffer = const_cast<MOS_RESOURCE *>(& m_resTileBasedStatisticsBuffer[m_statisticsBufIndex]); 721 722 if (!Mos_ResourceIsNull(tileStatisticsBuffer)) 723 { 724 params.streamOutBuffer = tileStatisticsBuffer; 725 params.streamOutOffset = m_hevcTileStatsOffset.vdencStatistics; 726 } 727 728 return MOS_STATUS_SUCCESS; 729 } 730 MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE,HevcEncodeTile)731 MHW_SETPAR_DECL_SRC(VDENC_WALKER_STATE, HevcEncodeTile) 732 { 733 auto hevcBasicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 734 ENCODE_CHK_NULL_RETURN(hevcBasicFeature); 735 auto picParams = hevcBasicFeature->m_hevcPicParams; 736 ENCODE_CHK_NULL_RETURN(picParams); 737 auto seqParams = hevcBasicFeature->m_hevcSeqParams; 738 ENCODE_CHK_NULL_RETURN(seqParams); 739 auto t_sliceParams = hevcBasicFeature->m_hevcSliceParams; 740 ENCODE_CHK_NULL_RETURN(t_sliceParams); 741 CODEC_HEVC_ENCODE_SLICE_PARAMS *sliceParams = (CODEC_HEVC_ENCODE_SLICE_PARAMS *)&t_sliceParams[hevcBasicFeature->m_curNumSlices]; 742 743 uint32_t ctbSize = 1 << (seqParams->log2_max_coding_block_size_minus3 + 3); 744 uint32_t widthInPix = (1 << (seqParams->log2_min_coding_block_size_minus3 + 3)) * (seqParams->wFrameWidthInMinCbMinus1 + 1); 745 uint32_t widthInCtb = (widthInPix / ctbSize) + ((widthInPix % ctbSize) ? 1 : 0); // round up 746 uint32_t heightInPix = (1 << (seqParams->log2_min_coding_block_size_minus3 + 3)) * (seqParams->wFrameHeightInMinCbMinus1 + 1); 747 uint32_t heightInCtb = (heightInPix / ctbSize) + ((heightInPix % ctbSize) ? 1 : 0); // round up 748 uint32_t shift = seqParams->log2_max_coding_block_size_minus3 - seqParams->log2_min_coding_block_size_minus3; 749 750 if (!m_enabled) 751 { 752 params.firstSuperSlice = 0; 753 // No tiling support 754 params.tileSliceStartLcuMbY = sliceParams->slice_segment_address / widthInCtb; 755 params.nextTileSliceStartLcuMbX = (sliceParams->slice_segment_address + sliceParams->NumLCUsInSlice) / heightInCtb; 756 params.nextTileSliceStartLcuMbY = (sliceParams->slice_segment_address + sliceParams->NumLCUsInSlice) / widthInCtb; 757 } 758 else 759 { 760 params.tileSliceStartLcuMbX = (&m_curTileCodingParams)->TileStartLCUX; 761 params.tileSliceStartLcuMbY = (&m_curTileCodingParams)->TileStartLCUY; 762 763 // In HEVC vdnec, always first super slice in each tile 764 params.firstSuperSlice = 1; 765 766 params.nextTileSliceStartLcuMbX = (&m_curTileCodingParams)->TileStartLCUX + ((&m_curTileCodingParams)->TileWidthInMinCbMinus1 >> shift) + 1; 767 params.nextTileSliceStartLcuMbY = (&m_curTileCodingParams)->TileStartLCUY + ((&m_curTileCodingParams)->TileHeightInMinCbMinus1 >> shift) + 1; 768 } 769 770 return MOS_STATUS_SUCCESS; 771 } 772 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT,HevcEncodeTile)773 MHW_SETPAR_DECL_SRC(HCP_PIPE_MODE_SELECT, HevcEncodeTile) 774 { 775 ENCODE_FUNC_CALL(); 776 777 // In single pipe mode, if TileBasedReplayMode is enabled, 778 // the bit stream for each tile will not be continuous 779 if (m_enabled) 780 { 781 params.bTileBasedReplayMode = m_enableTileReplay; 782 } 783 else 784 { 785 params.bTileBasedReplayMode = 0; 786 } 787 788 return MOS_STATUS_SUCCESS; 789 } 790 MHW_SETPAR_DECL_SRC(HCP_TILE_CODING,HevcEncodeTile)791 MHW_SETPAR_DECL_SRC(HCP_TILE_CODING, HevcEncodeTile) 792 { 793 ENCODE_FUNC_CALL(); 794 if (!m_enabled) 795 { 796 return MOS_STATUS_SUCCESS; 797 } 798 799 params.numOfTileColumnsInFrame = m_curTileCodingParams.NumOfTileColumnsInFrame; 800 params.tileRowStoreSelect = m_curTileCodingParams.TileRowStoreSelect; 801 params.tileColumnStoreSelect = m_curTileCodingParams.TileColumnStoreSelect; 802 params.tileStartLCUX = m_curTileCodingParams.TileStartLCUX; 803 params.tileStartLCUY = m_curTileCodingParams.TileStartLCUY; 804 params.isLastTileofColumn = m_curTileCodingParams.IsLastTileofColumn; 805 params.isLastTileofRow = m_curTileCodingParams.IsLastTileofRow; 806 params.tileHeightInMinCbMinus1 = m_curTileCodingParams.TileHeightInMinCbMinus1; 807 params.tileWidthInMinCbMinus1 = m_curTileCodingParams.TileWidthInMinCbMinus1; 808 params.cuRecordOffset = m_curTileCodingParams.CuRecordOffset; 809 params.bitstreamByteOffset = m_curTileCodingParams.BitstreamByteOffset; 810 params.pakTileStatisticsOffset = m_curTileCodingParams.PakTileStatisticsOffset; 811 params.cuLevelStreamoutOffset = m_curTileCodingParams.CuLevelStreamoutOffset; 812 params.sliceSizeStreamoutOffset = m_curTileCodingParams.SliceSizeStreamoutOffset; 813 params.sseRowstoreOffset = m_curTileCodingParams.SseRowstoreOffset; 814 params.saoRowstoreOffset = m_curTileCodingParams.SaoRowstoreOffset; 815 params.tileSizeStreamoutOffset = m_curTileCodingParams.TileSizeStreamoutOffset; 816 params.vp9ProbabilityCounterStreamoutOffset = 0; 817 params.nonFirstPassTile = m_curTileCodingParams.bTileReplayEnable && (!m_curTileCodingParams.IsFirstPass); 818 params.bitstreamByteOffsetEnable = m_curTileCodingParams.bTileReplayEnable; 819 820 return MOS_STATUS_SUCCESS; 821 } 822 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE,HevcEncodeTile)823 MHW_SETPAR_DECL_SRC(HCP_PIPE_BUF_ADDR_STATE, HevcEncodeTile) 824 { 825 ENCODE_FUNC_CALL(); 826 827 if (m_enabled && m_curTileCodingParams.NumberOfActiveBePipes > 1) 828 { 829 MOS_RESOURCE *tileStatisticsBuffer = const_cast<PMOS_RESOURCE>(&m_resTileBasedStatisticsBuffer[m_statisticsBufIndex]); 830 if (!Mos_ResourceIsNull(tileStatisticsBuffer)) 831 { 832 params.presLcuBaseAddressBuffer = tileStatisticsBuffer; 833 params.dwLcuStreamOutOffset = m_hevcTileStatsOffset.hevcSliceStreamout; 834 params.presFrameStatStreamOutBuffer = tileStatisticsBuffer; 835 params.dwFrameStatStreamOutOffset = m_hevcTileStatsOffset.hevcPakStatistics; 836 } 837 } 838 else 839 { 840 params.presLcuBaseAddressBuffer = m_basicFeature->m_recycleBuf->GetBuffer(LcuBaseAddressBuffer, 0); 841 params.presFrameStatStreamOutBuffer = m_basicFeature->m_recycleBuf->GetBuffer(FrameStatStreamOutBuffer, 0); 842 } 843 844 return MOS_STATUS_SUCCESS; 845 } 846 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE,HevcEncodeTile)847 MHW_SETPAR_DECL_SRC(HCP_SLICE_STATE, HevcEncodeTile) 848 { 849 ENCODE_FUNC_CALL(); 850 851 if (!m_enabled) 852 { 853 return MOS_STATUS_SUCCESS; 854 } 855 856 auto hevcFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 857 ENCODE_CHK_NULL_RETURN(hevcFeature); 858 859 params.lastSliceInTile = hevcFeature->m_lastSliceInTile; 860 params.lastSliceInTileColumn = (hevcFeature->m_lastSliceInTile & m_tileData[m_tileIdx].isLastTileofColumn) ? true : false; 861 862 return MOS_STATUS_SUCCESS; 863 } 864 MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE,HevcEncodeTile)865 MHW_SETPAR_DECL_SRC(HCP_IND_OBJ_BASE_ADDR_STATE, HevcEncodeTile) 866 { 867 ENCODE_FUNC_CALL(); 868 869 if (!m_enabled) 870 { 871 return MOS_STATUS_SUCCESS; 872 } 873 874 MOS_RESOURCE *tileRecordBuffer = const_cast<PMOS_RESOURCE>(&m_tileRecordBuffer[m_statisticsBufIndex]); 875 if (!Mos_ResourceIsNull(tileRecordBuffer)) 876 { 877 params.presPakTileSizeStasBuffer = tileRecordBuffer; 878 params.dwPakTileSizeStasBufferSize = m_hwInterface->m_tileRecordSize; 879 params.dwPakTileSizeRecordOffset = m_hevcTileStatsOffset.tileSizeRecord; 880 } 881 882 return MOS_STATUS_SUCCESS; 883 } 884 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE,HevcEncodeTile)885 MHW_SETPAR_DECL_SRC(VDENC_HEVC_VP9_TILE_SLICE_STATE, HevcEncodeTile) 886 { 887 auto hevcBasicFeature = dynamic_cast<HevcBasicFeature *>(m_basicFeature); 888 ENCODE_CHK_NULL_RETURN(hevcBasicFeature); 889 auto picParams = hevcBasicFeature->m_hevcPicParams; 890 ENCODE_CHK_NULL_RETURN(picParams); 891 auto seqParams = hevcBasicFeature->m_hevcSeqParams; 892 ENCODE_CHK_NULL_RETURN(seqParams); 893 auto sliceParams = hevcBasicFeature->m_hevcSliceParams; 894 ENCODE_CHK_NULL_RETURN(sliceParams); 895 896 uint32_t ctbSize = 1 << (seqParams->log2_max_coding_block_size_minus3 + 3); 897 uint32_t widthInPix = (1 << (seqParams->log2_min_coding_block_size_minus3 + 3)) * (seqParams->wFrameWidthInMinCbMinus1 + 1); 898 uint32_t heightInPix = (1 << (seqParams->log2_min_coding_block_size_minus3 + 3)) * (seqParams->wFrameHeightInMinCbMinus1 + 1); 899 uint32_t minCodingBlkSize = seqParams->log2_min_coding_block_size_minus3 + 3; 900 params.ctbSize = ctbSize; 901 902 if (!m_enabled) 903 { 904 // No tiling support 905 params.tileWidth = widthInPix; 906 params.tileHeight = heightInPix; 907 } 908 else 909 { 910 params.tileStartLCUX = (&m_curTileCodingParams)->TileStartLCUX; 911 params.tileStartLCUY = (&m_curTileCodingParams)->TileStartLCUY; 912 913 params.tileWidth = (((&m_curTileCodingParams)->TileWidthInMinCbMinus1 + 1) << minCodingBlkSize); 914 params.tileHeight = (((&m_curTileCodingParams)->TileHeightInMinCbMinus1 + 1) << minCodingBlkSize); 915 916 // NumParEngine is not used by HW 917 //cmd.DW3.NumParEngine = tileSlcParams->dwNumberOfPipes; 918 919 params.tileId = m_tileIdx; 920 params.tileRowStoreSelect = (&m_curTileCodingParams)->TileRowStoreSelect; 921 params.tileEnable = 1; 922 params.tileStreamInOffset = (&m_curTileCodingParams)->TileStreaminOffset; 923 924 // PAK Object StreamOut Offset Computation 925 uint32_t tileLCUStreamOutByteOffset = 0; 926 if ((&m_curTileCodingParams)->TileStartLCUX != 0 || (&m_curTileCodingParams)->TileStartLCUY != 0) 927 { 928 uint32_t NumOfCUInLCU = (ctbSize >> 3) * (ctbSize >> 3); // Min CU size is 8 929 uint32_t ImgWidthInLCU = (widthInPix + ctbSize - 1) / ctbSize; 930 uint32_t ImgHeightInLCU = (heightInPix + ctbSize - 1) / ctbSize; 931 uint32_t NumLCUsCurLocation = (&m_curTileCodingParams)->TileStartLCUY * ImgWidthInLCU + (&m_curTileCodingParams)->TileStartLCUX * 932 (((((&m_curTileCodingParams)->TileHeightInMinCbMinus1 + 1) << minCodingBlkSize) + ctbSize - 1) / ctbSize); 933 //For PAKObject Surface 934 tileLCUStreamOutByteOffset = 2 * BYTES_PER_DWORD * NumLCUsCurLocation * (NUM_PAK_DWS_PER_LCU + NumOfCUInLCU * NUM_DWS_PER_CU); 935 //Add 1 CL for size info at the beginning of each tile 936 tileLCUStreamOutByteOffset += MHW_CACHELINE_SIZE; 937 //CL alignment at end of every tile 938 tileLCUStreamOutByteOffset = MOS_ROUNDUP_DIVIDE(tileLCUStreamOutByteOffset, MHW_CACHELINE_SIZE); 939 } 940 941 params.tileLCUStreamOutOffset = tileLCUStreamOutByteOffset; 942 params.tileRowstoreOffset = (params.tileStartLCUY == 0) ? (params.tileStartLCUX * params.ctbSize) / 32 : 0; 943 } 944 945 return MOS_STATUS_SUCCESS; 946 } 947 948 } // namespace encode 949