mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-07 13:38:06 +02:00
mediafoundation: set reasonable number of reference frames if the user didn't set CODECAPI_AVEncVideoMaxNumRefFrame
Reviewed-by: Yubo Xie <yuboxie@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40511>
This commit is contained in:
parent
c97ff97df6
commit
d2ad51fc0a
4 changed files with 30 additions and 19 deletions
|
|
@ -615,7 +615,7 @@ CDX12EncHMFT::GetParameterRange( const GUID *Api, VARIANT *ValueMin, VARIANT *Va
|
|||
ValueMin->ulVal = 1;
|
||||
|
||||
ValueMax->vt = VT_UI4;
|
||||
ValueMax->ulVal = m_uiMaxNumRefFrame;
|
||||
ValueMax->ulVal = GetMaxReferences( m_uiOutputWidth, m_uiOutputHeight );
|
||||
SteppingDelta->vt = VT_UI4;
|
||||
SteppingDelta->ulVal = 1;
|
||||
|
||||
|
|
@ -1572,7 +1572,8 @@ CDX12EncHMFT::SetValue( const GUID *Api, VARIANT *Value )
|
|||
else if( *Api == CODECAPI_AVEncVideoMaxNumRefFrame )
|
||||
{
|
||||
debug_printf( "[dx12 hmft 0x%p] SET CODECAPI_AVEncVideoMaxNumRefFrame - %u\n", this, Value->ulVal );
|
||||
if( Value->vt != VT_UI4 )
|
||||
UINT32 maxReferences = GetMaxReferences( m_uiOutputWidth, m_uiOutputHeight );
|
||||
if( Value->vt != VT_UI4 || Value->ulVal > maxReferences )
|
||||
{
|
||||
CHECKHR_GOTO( E_INVALIDARG, done );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1143,8 +1143,12 @@ GetMaxDPBSize( int width, int height, eAVEncH264VLevel level_idc )
|
|||
UINT32
|
||||
CDX12EncHMFT::GetMaxReferences( unsigned int width, unsigned int height )
|
||||
{
|
||||
int maxDPBSize = GetMaxDPBSize( width, height, m_uiLevel );
|
||||
UINT32 uiMaxReferences = std::min( (int) m_EncoderCapabilities.m_uiMaxHWSupportedDPBCapacity, maxDPBSize );
|
||||
UINT32 uiMaxReferences = m_EncoderCapabilities.m_uiMaxHWSupportedDPBCapacity;
|
||||
if( width != 0 && height != 0 )
|
||||
{
|
||||
int maxDPBSize = GetMaxDPBSize( width, height, m_uiLevel );
|
||||
uiMaxReferences = std::min( (int) m_EncoderCapabilities.m_uiMaxHWSupportedDPBCapacity, maxDPBSize );
|
||||
}
|
||||
return uiMaxReferences;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -980,9 +980,13 @@ GetMaxDPBSize( int width, int height, eAVEncH265VLevel level_idc, int minCBSizeY
|
|||
UINT32
|
||||
CDX12EncHMFT::GetMaxReferences( unsigned int width, unsigned int height )
|
||||
{
|
||||
const int minCbSizeY = 1 << ( m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_coding_block_size_minus3 + 3 );
|
||||
int maxDPBSize = GetMaxDPBSize( width, height, m_uiLevel, minCbSizeY );
|
||||
UINT32 uiMaxReferences = std::min( (int) m_EncoderCapabilities.m_uiMaxHWSupportedDPBCapacity, maxDPBSize );
|
||||
UINT32 uiMaxReferences = m_EncoderCapabilities.m_uiMaxHWSupportedDPBCapacity;
|
||||
if( width != 0 && height != 0 )
|
||||
{
|
||||
const int minCbSizeY = 1 << ( m_EncoderCapabilities.m_HWSupportH265BlockSizes.bits.log2_min_luma_coding_block_size_minus3 + 3 );
|
||||
int maxDPBSize = GetMaxDPBSize( width, height, m_uiLevel, minCbSizeY );
|
||||
uiMaxReferences = std::min( (int) m_EncoderCapabilities.m_uiMaxHWSupportedDPBCapacity, maxDPBSize );
|
||||
}
|
||||
return uiMaxReferences;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -888,23 +888,25 @@ CDX12EncHMFT::InitializeEncoder( pipe_video_profile videoProfile, UINT32 Width,
|
|||
CHECKHR_GOTO( MF_E_OUT_OF_RANGE, done );
|
||||
}
|
||||
|
||||
// Please note in scenarios (e.g LTR or SVC) the backend may need to keep track of more references
|
||||
// than the m_uiMaxNumRefFrame, since the references may be more in the past (up to 16, 8 frames max before
|
||||
// depending on the codec)
|
||||
// TODO: If we know at this point that we're not using LTR nor SVC we can set max_references to
|
||||
// m_uiMaxNumRefFrame and use less ram, but not sure how would this work with codecapi reconfigurations/dynamic
|
||||
// LTR/SVC requests
|
||||
|
||||
// max_references is the number of previous submitted frame recon pics the frontend reference
|
||||
// pic trackers will keep track of and can be indexed by current frame submissions by from the L0/L1 reference lists
|
||||
|
||||
UINT32 uiMaxNumRefFrame = GetMaxReferences( Width, Height );
|
||||
// if user sets m_uiMaxNumRefFrame, use that to limit
|
||||
if( m_bMaxNumRefFrameSet )
|
||||
// if user didn't set max reference, try to set a reasonable amount
|
||||
if( !m_bMaxNumRefFrameSet )
|
||||
{
|
||||
uiMaxNumRefFrame = std::min( uiMaxNumRefFrame, m_uiMaxNumRefFrame );
|
||||
UINT32 uiMaxNumRefFrame = GetMaxReferences( Width, Height );
|
||||
UINT32 uiEstimatedRefFrame = 1 /*current frame*/ + 1 /* slack */ + m_uiMaxLongTermReferences;
|
||||
if( m_uiLayerCount > 1 )
|
||||
{
|
||||
uiEstimatedRefFrame += ( m_uiLayerCount - 1 );
|
||||
}
|
||||
if( uiEstimatedRefFrame > uiMaxNumRefFrame )
|
||||
{
|
||||
CHECKHR_GOTO( E_INVALIDARG, done );
|
||||
}
|
||||
MFE_INFO( "[dx12 hmft 0x%p] HMFT adjusted max_references from %u to %u", this, uiMaxNumRefFrame, uiEstimatedRefFrame );
|
||||
m_uiMaxNumRefFrame = uiEstimatedRefFrame; // update CodecAPI value.
|
||||
}
|
||||
m_uiMaxNumRefFrame = uiMaxNumRefFrame; // update CodecAPI value.
|
||||
|
||||
encoderSettings.profile = videoProfile;
|
||||
encoderSettings.level = m_uiLevel;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue