blob: 42664654ad5194a9df28977befed01d72b6d9368 [file] [log] [blame]
/*
* Copyright (c) 2017, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file codechal_encode_tracked_buffer.h
//!
//! \brief Encoder needs to track and store certain surface/resource/buffers, to be used as reference for future frames
//! Given the refFrame list of current frame, a slot is dynamically allocated to index/track these resources
//! Whenever a RefFrame is no longer used, its corresponding slot will be re-used to minimize memory allocation
//! "Tracked buffer" so far includes MbCode/MvData/MvTemporal buffer, and Csc/Ds/DsRecon surface
//!
#ifndef __CODECHAL_ENCODE_TRACKED_BUFFER_H__
#define __CODECHAL_ENCODE_TRACKED_BUFFER_H__
#include "codechal.h"
#include "codechal_encode_allocator.h"
#include "codec_def_common_encode.h"
//!
//! Tracked buffer
//!
class CodechalEncodeTrackedBuffer
{
public:
//!
//! \brief Get the buffer index allocated for current frame
//!
//! \return the buffer index allocated for current frame
//!
inline uint8_t GetCurrIndex()
{
return m_trackedBufCurrIdx;
}
//!
//! \brief Get the buffer index allocated for MbCode
//!
//! \return the buffer index allocated for MbCode
//!
inline uint8_t GetCurrIndexMbCode()
{
return m_mbCodeCurrIdx;
}
//!
//! \brief Get the current MbCode buffer
//!
//! \return the current MbCode buffer
//!
inline MOS_RESOURCE* GetCurrMbCodeBuffer()
{
return m_trackedBufCurrMbCode;
}
//!
//! \brief Get the current MvData buffer
//!
//! \return the current MvData buffer
//!
inline MOS_RESOURCE* GetCurrMvDataBuffer()
{
return m_trackedBufCurrMvData;
}
//!
//! \brief Get the current MV temporal buffer
//!
//! \return the current MV temporal buffer
//!
MOS_RESOURCE* GetMvTemporalBuffer(uint8_t bufIndex)
{
if (bufIndex == CODEC_CURR_TRACKED_BUFFER)
{
return m_trackedBufCurrMvTemporal;
}
else
{
return (MOS_RESOURCE*)m_allocator->GetResource(m_standard, mvTemporalBuffer, bufIndex);
}
}
//!
//! \brief Get the current CSC surface
//!
//! \return the current CSC surface
//!
MOS_SURFACE* GetCscSurface(uint8_t bufIndex)
{
if (bufIndex == CODEC_CURR_TRACKED_BUFFER)
{
return m_trackedBufCurrCsc;
}
else
{
return (MOS_SURFACE*)m_allocator->GetResource(m_standard, cscSurface, bufIndex);
}
}
//!
//! \brief Get the current 4x downscaled surface
//!
//! \return the current 4x downscaled surface
//!
MOS_SURFACE* Get4xDsSurface(uint8_t bufIndex)
{
if (bufIndex == CODEC_CURR_TRACKED_BUFFER)
{
return m_trackedBufCurrDs4x;
}
else
{
return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds4xSurface, bufIndex);
}
}
//!
//! \brief Get the current 2x downscaled surface
//!
//! \return the current 2x downscaled surface
//!
MOS_SURFACE* Get2xDsSurface(uint8_t bufIndex)
{
if (bufIndex == CODEC_CURR_TRACKED_BUFFER)
{
return m_trackedBufCurrDs2x;
}
else
{
return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds2xSurface, bufIndex);
}
}
//!
//! \brief Get the current 16x downscaled surface
//!
//! \return the current 16x downscaled surface
//!
MOS_SURFACE* Get16xDsSurface(uint8_t bufIndex)
{
if (bufIndex == CODEC_CURR_TRACKED_BUFFER)
{
return m_trackedBufCurrDs16x;
}
else
{
return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds16xSurface, bufIndex);
}
}
//!
//! \brief Get the current 32x downscaled surface
//!
//! \return the current 32x downscaled surface
//!
MOS_SURFACE* Get32xDsSurface(uint8_t bufIndex)
{
if (bufIndex == CODEC_CURR_TRACKED_BUFFER)
{
return m_trackedBufCurrDs32x;
}
else
{
return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds32xSurface, bufIndex);
}
}
//!
//! \brief Get the current 4x DsRecon surface
//!
//! \return the current 4x DsRecon buffer
//!
inline MOS_SURFACE* Get4xDsReconSurface(uint8_t bufIndex)
{
if (bufIndex == CODEC_CURR_TRACKED_BUFFER)
{
return m_trackedBufCurr4xDsRecon;
}
else
{
return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds4xRecon, bufIndex);
}
}
//!
//! \brief Get the current 8x DsRecon surface
//!
//! \return the current 8x DsRecon buffer
//!
inline MOS_SURFACE* Get8xDsReconSurface(uint8_t bufIndex)
{
if (bufIndex == CODEC_CURR_TRACKED_BUFFER)
{
return m_trackedBufCurr8xDsRecon;
}
else
{
return (MOS_SURFACE*)m_allocator->GetResource(m_standard, ds8xRecon, bufIndex);
}
}
//!
//! \brief Get the wait flag for tracked buffer
//!
inline bool GetWait()
{
return m_waitTrackedBuffer;
}
//!
//! \brief Get the wait flag for CSC surface
//!
inline bool GetWaitCsc()
{
return m_waitCscSurface;
}
//!
//! \brief Get the allocation flag
//!
inline bool IsMbCodeAllocationNeeded()
{
return m_allocateMbCode;
}
//!
//! \brief Set allocation flag
//!
inline void SetAllocationFlag(bool flag)
{
m_allocateMbCode = flag;
}
//!
//! \brief Allocate resource for current frame
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateForCurrFrame();
//!
//! \brief Resize the Tracked Buffer upon resolution change
//!
//! \return void
//!
void Resize();
//!
//! \brief Release the existing CSC surfaces upon resolution change
//!
//! \return void
//!
void ResizeCsc();
//!
//! \brief Allocate for Preenc, so far only set the buffer index for DS surface
//! \param [in] bufIndex
//! buffer index for DS surface
//!
//! \return void
//!
void AllocateForCurrFramePreenc(uint8_t bufIndex);
//!
//! \brief Reset used for current frame flag
//!
void ResetUsedForCurrFrame();
//!
//! \brief Encoder pre enc look up buffer index
//! \param [in] frameIdx
//! frame Index
//! \param [in] inCache
//! Indicate if it's in cache
//! \return uint8_t
//! emptyEntry
//!
uint8_t PreencLookUpBufIndex(
uint8_t frameIdx,
bool *inCache);
//!
//! \brief Allocate Mb Code Resources
//!
//! \param [in] bufIndex
//! buffer index used
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateMbCodeResources(uint8_t bufIndex);
//!
//! \brief Allocate Mv Data Resources
//!
//! \param [in] bufIndex
//! buffer index used
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateMvDataResources(uint8_t bufIndex);
//!
//! \brief Allocate CSC surface or pick an existing one from the pool
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateSurfaceCsc();
MOS_STATUS ResizeSurfaceDS();
MOS_STATUS ResizeDsReconSurfacesVdenc();
//!
//! \brief Allocate DS surface or pick an existing one from the pool
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateSurfaceDS();
//!
//! \brief Allocate 2xDS surface or pick an existing one from the pool
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateSurface2xDS();
//!
//! \brief Allocate Mv temporal buffer
//!
//! \param [in] bufIndex
//! buffer index used
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
virtual MOS_STATUS AllocateMvTemporalBuffer(uint8_t bufIndex);
//!
//! \brief Constructor
//!
CodechalEncodeTrackedBuffer(CodechalEncoderState* encoder);
virtual ~CodechalEncodeTrackedBuffer();
protected:
//!
//! \brief Get slot for current frame
//!
//! \param [in] refList
//! Reference frame list
//! \param [in] numRefFrame
//! Number of reference frame
//! \param [in] usedAsRef
//! Current frame is used as reference or not
//!
//! \return uint8_t
//! Index found
//!
uint8_t LookUpBufIndex(
PCODEC_PICTURE refList,
uint8_t numRefFrame,
bool usedAsRef);
//!
//! \brief Get slot for current frame's CSC surface
//!
//! \return uint8_t
//! Index found
//!
uint8_t LookUpBufIndexCsc();
//!
//! \brief Release MbCode buffer
//!
//! \param [in] bufIndex
//! buffer index to be released
//!
//! \return void
//!
void ReleaseMbCode(uint8_t bufIndex);
//!
//! \brief Release MvData buffer
//!
//! \param [in] bufIndex
//! buffer index to be released
//!
//! \return void
//!
void ReleaseMvData(uint8_t bufIndex);
//!
//! \brief Release CSC surface
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
void ReleaseSurfaceCsc(uint8_t index);
//!
//! \brief Release DS surface
//!
//! \param [in] index
//! buffer index to be released
//!
//! \return void
//!
void ReleaseSurfaceDS(uint8_t index);
//!
//! \brief Release DsRecon buffer
//!
//! \param [in] bufIndex
//! buffer index to be released
//!
//! \return void
//!
void ReleaseDsRecon(uint8_t bufIndex);
//!
//! \brief Defer-deallocate buffer used before resolution reset
//!
virtual void DeferredDeallocateOnResChange();
CodechalEncoderState* m_encoder = nullptr; //!< Pointer to ENCODER base class
CodechalEncodeAllocator* m_allocator = nullptr; //!< Pointer to resource allocator
MOS_RESOURCE* m_trackedBufCurrMbCode = nullptr; //!< Pointer to current MbCode buffer
MOS_RESOURCE* m_trackedBufCurrMvData = nullptr; //!< Pointer to current MvData buffer
MOS_RESOURCE* m_trackedBufCurrMvTemporal = nullptr; //!< Pointer to current MV temporal buffer
MOS_SURFACE* m_trackedBufCurrCsc = nullptr; //!< Pointer to current CSC surface
MOS_SURFACE* m_trackedBufCurrDs4x = nullptr; //!< Pointer to current 4x downscaled surface
MOS_SURFACE* m_trackedBufCurrDs2x = nullptr; //!< Pointer to current 2x downscaled surface
MOS_SURFACE* m_trackedBufCurrDs16x = nullptr; //!< Pointer to current 16x downscaled surface
MOS_SURFACE* m_trackedBufCurrDs32x = nullptr; //!< Pointer to current 32x downscaled surface
MOS_SURFACE* m_trackedBufCurr4xDsRecon = nullptr; //!< Pointer to current 4x DsRecon buffer
MOS_SURFACE* m_trackedBufCurr8xDsRecon = nullptr; //!< Pointer to current 8x DsRecon buffer
uint32_t m_standard; //!< The encode state's standard
uint8_t m_trackedBufCurrIdx = 0; //!< current tracked buffer index
uint8_t m_mbCodeCurrIdx = 0; //!< current MbCode buffer index
bool m_allocateMbCode = false; //!< need to allocate MbCode buffer for current frame
bool m_mbCodeIsTracked = true; //!< tracked buffer algorithm used to manage MbCode buffer
private:
CodechalEncodeTrackedBuffer(const CodechalEncodeTrackedBuffer&) = delete;
CodechalEncodeTrackedBuffer& operator=(const CodechalEncodeTrackedBuffer&) = delete;
virtual void LookUpBufIndexMbCode()
{
m_mbCodeCurrIdx = m_trackedBufCurrIdx;
}
//!
//! \brief Allocate Ds Recon Surfaces Vdenc
//!
//! \param [in] bufIndex
//! buffer index used
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateDsReconSurfacesVdenc();
MOS_INTERFACE* m_osInterface = nullptr; //!< OS interface
uint8_t m_trackedBufNonRefIdx = 0; //!< current tracked buffer index when frame won't be used as ref
uint8_t m_trackedBufCountNonRef = 0; //!< counting number of tracked buffer when ring buffer is used
uint8_t m_trackedBufCountResize = 0; //!< 3 buffers to be delay-destructed during res change
uint8_t m_trackedBufPenuIdx = 0; //!< 2nd-to-last tracked buffer index
uint8_t m_trackedBufAnteIdx = 0; //!< 3rd-to-last tracked buffer index
bool m_waitTrackedBuffer = false; //!< wait to re-use tracked buffer
uint8_t m_cscBufNonRefIdx = 0; //!< current CSC buffer index when ring buffer is used
uint8_t m_cscBufCountNonRef = 0; //!< counting number of CSC surface when ring buffer is used
uint8_t m_cscBufCurrIdx = 0; //!< curr copy buffer index
uint8_t m_cscBufPenuIdx = 0; //!< 2nd-to-last CSC buffer index
uint8_t m_cscBufAnteIdx = 0; //!< 3rd-to-last CSC buffer index
bool m_waitCscSurface = false; //!< wait to re-use CSC surface
struct tracker
{
uint8_t ucSurfIndex7bits; //!< 0xFF means the entry can be re-used
bool bUsedforCurFrame; //!< Used for FEI Preenc to mark whether this enty can be reused in multi-call case
};
tracker m_tracker[CODEC_NUM_TRACKED_BUFFERS];
};
#endif // __CODECHAL_ENCODE_TRACKED_BUFFER_H__