1 /* 2 * Copyright (c) 2017, Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 */ 22 //! 23 //! \file codechal_encode_tracked_buffer.h 24 //! 25 //! \brief Encoder needs to track and store certain surface/resource/buffers, to be used as reference for future frames 26 //! Given the refFrame list of current frame, a slot is dynamically allocated to index/track these resources 27 //! Whenever a RefFrame is no longer used, its corresponding slot will be re-used to minimize memory allocation 28 //! "Tracked buffer" so far includes MbCode/MvData/MvTemporal buffer, and Csc/Ds/DsRecon surface 29 //! 30 31 #ifndef __CODECHAL_ENCODE_TRACKED_BUFFER_H__ 32 #define __CODECHAL_ENCODE_TRACKED_BUFFER_H__ 33 34 #include "codechal.h" 35 #include "codechal_encode_allocator.h" 36 #include "codec_def_common_encode.h" 37 38 //! 39 //! Tracked buffer 40 //! 41 class CodechalEncodeTrackedBuffer 42 { 43 public: 44 //! 45 //! \brief Get the buffer index allocated for current frame 46 //! 47 //! \return the buffer index allocated for current frame 48 //! GetCurrIndex()49 inline uint8_t GetCurrIndex() 50 { 51 return m_trackedBufCurrIdx; 52 } 53 54 //! 55 //! \brief Get the buffer index allocated for MbCode 56 //! 57 //! \return the buffer index allocated for MbCode 58 //! GetCurrIndexMbCode()59 inline uint8_t GetCurrIndexMbCode() 60 { 61 return m_mbCodeCurrIdx; 62 } 63 64 //! 65 //! \brief Get the current MbCode buffer 66 //! 67 //! \return the current MbCode buffer 68 //! GetCurrMbCodeBuffer()69 inline MOS_RESOURCE* GetCurrMbCodeBuffer() 70 { 71 return m_trackedBufCurrMbCode; 72 } 73 74 //! 75 //! \brief Get the current MvData buffer 76 //! 77 //! \return the current MvData buffer 78 //! GetCurrMvDataBuffer()79 inline MOS_RESOURCE* GetCurrMvDataBuffer() 80 { 81 return m_trackedBufCurrMvData; 82 } 83 84 //! 85 //! \brief Get the current MV temporal buffer 86 //! 87 //! \return the current MV temporal buffer 88 //! GetMvTemporalBuffer(uint8_t bufIndex)89 MOS_RESOURCE* GetMvTemporalBuffer(uint8_t bufIndex) 90 { 91 if (bufIndex == CODEC_CURR_TRACKED_BUFFER) 92 { 93 return m_trackedBufCurrMvTemporal; 94 } 95 else 96 { 97 return (MOS_RESOURCE*)m_allocator->GetResource(m_standard, mvTemporalBuffer, bufIndex); 98 } 99 } 100 101 //! 102 //! \brief Get the current CSC surface 103 //! 104 //! \return the current CSC surface 105 //! GetCscSurface(uint8_t bufIndex)106 MOS_SURFACE* GetCscSurface(uint8_t bufIndex) 107 { 108 if (bufIndex == CODEC_CURR_TRACKED_BUFFER) 109 { 110 return m_trackedBufCurrCsc; 111 } 112 else 113 { 114 return (MOS_SURFACE*)m_allocator->GetResource(m_standard, cscSurface, bufIndex); 115 } 116 } 117 118 //! 119 //! \brief Get the current 4x downscaled surface 120 //! 121 //! \return the current 4x downscaled surface 122 //! Get4xDsSurface(uint8_t bufIndex)123 MOS_SURFACE* Get4xDsSurface(uint8_t bufIndex) 124 { 125 if (bufIndex == CODEC_CURR_TRACKED_BUFFER) 126 { 127 return m_trackedBufCurrDs4x; 128 } 129 else 130 { 131 return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds4xSurface, bufIndex); 132 } 133 } 134 135 //! 136 //! \brief Get the current 2x downscaled surface 137 //! 138 //! \return the current 2x downscaled surface 139 //! Get2xDsSurface(uint8_t bufIndex)140 MOS_SURFACE* Get2xDsSurface(uint8_t bufIndex) 141 { 142 if (bufIndex == CODEC_CURR_TRACKED_BUFFER) 143 { 144 return m_trackedBufCurrDs2x; 145 } 146 else 147 { 148 return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds2xSurface, bufIndex); 149 } 150 } 151 152 //! 153 //! \brief Get the current 16x downscaled surface 154 //! 155 //! \return the current 16x downscaled surface 156 //! Get16xDsSurface(uint8_t bufIndex)157 MOS_SURFACE* Get16xDsSurface(uint8_t bufIndex) 158 { 159 if (bufIndex == CODEC_CURR_TRACKED_BUFFER) 160 { 161 return m_trackedBufCurrDs16x; 162 } 163 else 164 { 165 return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds16xSurface, bufIndex); 166 } 167 } 168 169 //! 170 //! \brief Get the current 32x downscaled surface 171 //! 172 //! \return the current 32x downscaled surface 173 //! Get32xDsSurface(uint8_t bufIndex)174 MOS_SURFACE* Get32xDsSurface(uint8_t bufIndex) 175 { 176 if (bufIndex == CODEC_CURR_TRACKED_BUFFER) 177 { 178 return m_trackedBufCurrDs32x; 179 } 180 else 181 { 182 return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds32xSurface, bufIndex); 183 } 184 } 185 186 //! 187 //! \brief Get the current 4x DsRecon surface 188 //! 189 //! \return the current 4x DsRecon buffer 190 //! Get4xDsReconSurface(uint8_t bufIndex)191 inline MOS_SURFACE* Get4xDsReconSurface(uint8_t bufIndex) 192 { 193 if (bufIndex == CODEC_CURR_TRACKED_BUFFER) 194 { 195 return m_trackedBufCurr4xDsRecon; 196 } 197 else 198 { 199 return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds4xRecon, bufIndex); 200 } 201 } 202 203 //! 204 //! \brief Get the current 8x DsRecon surface 205 //! 206 //! \return the current 8x DsRecon buffer 207 //! Get8xDsReconSurface(uint8_t bufIndex)208 inline MOS_SURFACE* Get8xDsReconSurface(uint8_t bufIndex) 209 { 210 if (bufIndex == CODEC_CURR_TRACKED_BUFFER) 211 { 212 return m_trackedBufCurr8xDsRecon; 213 } 214 else 215 { 216 return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds8xRecon, bufIndex); 217 } 218 } 219 220 //! 221 //! \brief Get the wait flag for tracked buffer 222 //! GetWait()223 inline bool GetWait() 224 { 225 return m_waitTrackedBuffer; 226 } 227 228 //! 229 //! \brief Get the wait flag for CSC surface 230 //! GetWaitCsc()231 inline bool GetWaitCsc() 232 { 233 return m_waitCscSurface; 234 } 235 236 //! 237 //! \brief Get the allocation flag 238 //! IsMbCodeAllocationNeeded()239 inline bool IsMbCodeAllocationNeeded() 240 { 241 return m_allocateMbCode; 242 } 243 244 //! 245 //! \brief Set allocation flag 246 //! SetAllocationFlag(bool flag)247 inline void SetAllocationFlag(bool flag) 248 { 249 m_allocateMbCode = flag; 250 } 251 252 //! 253 //! \brief Allocate resource for current frame 254 //! 255 //! \return MOS_STATUS 256 //! MOS_STATUS_SUCCESS if success, else fail reason 257 //! 258 MOS_STATUS AllocateForCurrFrame(); 259 260 //! 261 //! \brief Resize the Tracked Buffer upon resolution change 262 //! 263 //! \return void 264 //! 265 void Resize(); 266 267 //! 268 //! \brief Release the existing CSC surfaces upon resolution change 269 //! 270 //! \return void 271 //! 272 void ResizeCsc(); 273 274 //! 275 //! \brief Allocate for Preenc, so far only set the buffer index for DS surface 276 //! \param [in] bufIndex 277 //! buffer index for DS surface 278 //! 279 //! \return void 280 //! 281 void AllocateForCurrFramePreenc(uint8_t bufIndex); 282 283 //! 284 //! \brief Reset used for current frame flag 285 //! 286 void ResetUsedForCurrFrame(); 287 288 //! 289 //! \brief Encoder pre enc look up buffer index 290 //! \param [in] frameIdx 291 //! frame Index 292 //! \param [in] inCache 293 //! Indicate if it's in cache 294 //! \return uint8_t 295 //! emptyEntry 296 //! 297 uint8_t PreencLookUpBufIndex( 298 uint8_t frameIdx, 299 bool *inCache); 300 301 //! 302 //! \brief Allocate Mb Code Resources 303 //! 304 //! \param [in] bufIndex 305 //! buffer index used 306 //! 307 //! \return MOS_STATUS 308 //! MOS_STATUS_SUCCESS if success, else fail reason 309 //! 310 MOS_STATUS AllocateMbCodeResources(uint8_t bufIndex); 311 312 //! 313 //! \brief Allocate Mv Data Resources 314 //! 315 //! \param [in] bufIndex 316 //! buffer index used 317 //! 318 //! \return MOS_STATUS 319 //! MOS_STATUS_SUCCESS if success, else fail reason 320 //! 321 MOS_STATUS AllocateMvDataResources(uint8_t bufIndex); 322 323 //! 324 //! \brief Allocate CSC surface or pick an existing one from the pool 325 //! 326 //! \return MOS_STATUS 327 //! MOS_STATUS_SUCCESS if success, else fail reason 328 //! 329 MOS_STATUS AllocateSurfaceCsc(); 330 331 //! 332 //! \brief Allocate Copy surface or pick an existing one from the pool 333 //! 334 //! \return MOS_STATUS 335 //! MOS_STATUS_SUCCESS if success, else fail reason 336 //! 337 MOS_STATUS AllocateSurfaceCopy(MOS_FORMAT, uint32_t); 338 339 MOS_STATUS ResizeSurfaceDS(); 340 341 MOS_STATUS ResizeDsReconSurfacesVdenc(); 342 343 //! 344 //! \brief Allocate DS surface or pick an existing one from the pool 345 //! 346 //! \return MOS_STATUS 347 //! MOS_STATUS_SUCCESS if success, else fail reason 348 //! 349 MOS_STATUS AllocateSurfaceDS(); 350 351 //! 352 //! \brief Allocate 2xDS surface or pick an existing one from the pool 353 //! 354 //! \return MOS_STATUS 355 //! MOS_STATUS_SUCCESS if success, else fail reason 356 //! 357 MOS_STATUS AllocateSurface2xDS(); 358 359 //! 360 //! \brief Allocate Mv temporal buffer 361 //! 362 //! \param [in] bufIndex 363 //! buffer index used 364 //! 365 //! \return MOS_STATUS 366 //! MOS_STATUS_SUCCESS if success, else fail reason 367 //! 368 virtual MOS_STATUS AllocateMvTemporalBuffer(uint8_t bufIndex); 369 370 //! 371 //! \brief Constructor 372 //! 373 CodechalEncodeTrackedBuffer(CodechalEncoderState* encoder); 374 375 virtual ~CodechalEncodeTrackedBuffer(); 376 377 protected: 378 //! 379 //! \brief Get slot for current frame 380 //! 381 //! \param [in] refList 382 //! Reference frame list 383 //! \param [in] numRefFrame 384 //! Number of reference frame 385 //! \param [in] usedAsRef 386 //! Current frame is used as reference or not 387 //! 388 //! \return uint8_t 389 //! Index found 390 //! 391 uint8_t LookUpBufIndex( 392 PCODEC_PICTURE refList, 393 uint8_t numRefFrame, 394 bool usedAsRef); 395 396 //! 397 //! \brief Get slot for current frame's CSC surface 398 //! 399 //! \return uint8_t 400 //! Index found 401 //! 402 uint8_t LookUpBufIndexCsc(); 403 404 //! 405 //! \brief Release MbCode buffer 406 //! 407 //! \param [in] bufIndex 408 //! buffer index to be released 409 //! 410 //! \return void 411 //! 412 void ReleaseMbCode(uint8_t bufIndex); 413 414 //! 415 //! \brief Release MvData buffer 416 //! 417 //! \param [in] bufIndex 418 //! buffer index to be released 419 //! 420 //! \return void 421 //! 422 void ReleaseMvData(uint8_t bufIndex); 423 424 //! 425 //! \brief Release CSC surface 426 //! 427 //! \return MOS_STATUS 428 //! MOS_STATUS_SUCCESS if success, else fail reason 429 //! 430 void ReleaseSurfaceCsc(uint8_t index); 431 432 //! 433 //! \brief Release DS surface 434 //! 435 //! \param [in] index 436 //! buffer index to be released 437 //! 438 //! \return void 439 //! 440 void ReleaseSurfaceDS(uint8_t index); 441 442 //! 443 //! \brief Release DsRecon buffer 444 //! 445 //! \param [in] bufIndex 446 //! buffer index to be released 447 //! 448 //! \return void 449 //! 450 void ReleaseDsRecon(uint8_t bufIndex); 451 452 //! 453 //! \brief Defer-deallocate buffer used before resolution reset 454 //! 455 virtual void DeferredDeallocateOnResChange(); 456 457 CodechalEncoderState* m_encoder = nullptr; //!< Pointer to ENCODER base class 458 CodechalEncodeAllocator* m_allocator = nullptr; //!< Pointer to resource allocator 459 460 MOS_RESOURCE* m_trackedBufCurrMbCode = nullptr; //!< Pointer to current MbCode buffer 461 MOS_RESOURCE* m_trackedBufCurrMvData = nullptr; //!< Pointer to current MvData buffer 462 MOS_RESOURCE* m_trackedBufCurrMvTemporal = nullptr; //!< Pointer to current MV temporal buffer 463 MOS_SURFACE* m_trackedBufCurrCsc = nullptr; //!< Pointer to current CSC surface 464 MOS_SURFACE* m_trackedBufCurrDs4x = nullptr; //!< Pointer to current 4x downscaled surface 465 MOS_SURFACE* m_trackedBufCurrDs2x = nullptr; //!< Pointer to current 2x downscaled surface 466 MOS_SURFACE* m_trackedBufCurrDs16x = nullptr; //!< Pointer to current 16x downscaled surface 467 MOS_SURFACE* m_trackedBufCurrDs32x = nullptr; //!< Pointer to current 32x downscaled surface 468 MOS_SURFACE* m_trackedBufCurr4xDsRecon = nullptr; //!< Pointer to current 4x DsRecon buffer 469 MOS_SURFACE* m_trackedBufCurr8xDsRecon = nullptr; //!< Pointer to current 8x DsRecon buffer 470 471 uint32_t m_standard; //!< The encode state's standard 472 uint8_t m_trackedBufCurrIdx = 0; //!< current tracked buffer index 473 uint8_t m_mbCodeCurrIdx = 0; //!< current MbCode buffer index 474 bool m_allocateMbCode = false; //!< need to allocate MbCode buffer for current frame 475 bool m_mbCodeIsTracked = true; //!< tracked buffer algorithm used to manage MbCode buffer 476 477 private: 478 CodechalEncodeTrackedBuffer(const CodechalEncodeTrackedBuffer&) = delete; 479 CodechalEncodeTrackedBuffer& operator=(const CodechalEncodeTrackedBuffer&) = delete; 480 LookUpBufIndexMbCode()481 virtual void LookUpBufIndexMbCode() 482 { 483 m_mbCodeCurrIdx = m_trackedBufCurrIdx; 484 } 485 486 //! 487 //! \brief Allocate Ds Recon Surfaces Vdenc 488 //! 489 //! \param [in] bufIndex 490 //! buffer index used 491 //! 492 //! \return MOS_STATUS 493 //! MOS_STATUS_SUCCESS if success, else fail reason 494 //! 495 MOS_STATUS AllocateDsReconSurfacesVdenc(); 496 497 MOS_INTERFACE* m_osInterface = nullptr; //!< OS interface 498 499 uint8_t m_trackedBufNonRefIdx = 0; //!< current tracked buffer index when frame won't be used as ref 500 uint8_t m_trackedBufCountNonRef = 0; //!< counting number of tracked buffer when ring buffer is used 501 uint8_t m_trackedBufCountResize = 0; //!< 3 buffers to be delay-destructed during res change 502 uint8_t m_trackedBufPenuIdx = 0; //!< 2nd-to-last tracked buffer index 503 uint8_t m_trackedBufAnteIdx = 0; //!< 3rd-to-last tracked buffer index 504 bool m_waitTrackedBuffer = false; //!< wait to re-use tracked buffer 505 506 uint8_t m_cscBufNonRefIdx = 0; //!< current CSC buffer index when ring buffer is used 507 uint8_t m_cscBufCountNonRef = 0; //!< counting number of CSC surface when ring buffer is used 508 uint8_t m_cscBufCurrIdx = 0; //!< curr copy buffer index 509 uint8_t m_cscBufPenuIdx = 0; //!< 2nd-to-last CSC buffer index 510 uint8_t m_cscBufAnteIdx = 0; //!< 3rd-to-last CSC buffer index 511 bool m_waitCscSurface = false; //!< wait to re-use CSC surface 512 513 struct tracker 514 { 515 uint8_t ucSurfIndex7bits; //!< 0xFF means the entry can be re-used 516 bool bUsedforCurFrame; //!< Used for FEI Preenc to mark whether this enty can be reused in multi-call case 517 }; 518 tracker m_tracker[CODEC_NUM_TRACKED_BUFFERS]; 519 }; 520 521 #endif // __CODECHAL_ENCODE_TRACKED_BUFFER_H__