From 0af342ce36f4ca3aa8c85a2d4221a00a84328b6f Mon Sep 17 00:00:00 2001 From: Wenfeng Gao Date: Fri, 13 Jun 2025 15:34:56 -0700 Subject: [PATCH] mediafoundation: Modify the newly added CODECAPI behavior CODECAPI_AVEncVideoOutputQPMapBlockSize, CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize. IsSupported() returns S_OK only when the HW encoder supports this API. GetValue() returns the supported block size for CODECAPI_AVEncVideoOutputQPMapBlockSize and CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize. SetValue() returns E_INVALIDARG if the set value does not match the supported value. User can call GetValue() to get the supported block size before calling SetValue() to avoid the failure. Reviewed-by: Pohsiang (John) Hsu Part-of: --- .../frontends/mediafoundation/codecapi.cpp | 87 +++++++++++++++++-- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/src/gallium/frontends/mediafoundation/codecapi.cpp b/src/gallium/frontends/mediafoundation/codecapi.cpp index 2c4346fb841..88e46ba172b 100644 --- a/src/gallium/frontends/mediafoundation/codecapi.cpp +++ b/src/gallium/frontends/mediafoundation/codecapi.cpp @@ -312,9 +312,7 @@ CDX12EncHMFT::IsSupported( const GUID *Api ) *Api == CODECAPI_AVEncVideoMaxNumRefFrame || *Api == CODECAPI_AVEncVideoMeanAbsoluteDifference || *Api == CODECAPI_AVEncVideoMaxQP || *Api == CODECAPI_AVEncVideoGradualIntraRefresh || *Api == CODECAPI_AVScenarioInfo || *Api == CODECAPI_AVEncVideoROIEnabled || *Api == CODECAPI_AVEncVideoLTRBufferControl || - *Api == CODECAPI_AVEncVideoMarkLTRFrame || *Api == CODECAPI_AVEncVideoUseLTRFrame || - *Api == CODECAPI_AVEncVideoEnableFramePsnrYuv || *Api == CODECAPI_AVEncVideoEnableSpatialAdaptiveQuantization || - *Api == CODECAPI_AVEncVideoOutputQPMapBlockSize || *Api == CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize ) + *Api == CODECAPI_AVEncVideoMarkLTRFrame || *Api == CODECAPI_AVEncVideoUseLTRFrame ) { hr = S_OK; return hr; @@ -337,6 +335,34 @@ CDX12EncHMFT::IsSupported( const GUID *Api ) return hr; } } + + if( m_EncoderCapabilities.m_PSNRStatsSupport.bits.supports_y_channel ) + { + if( *Api == CODECAPI_AVEncVideoEnableFramePsnrYuv ) + { + hr = S_OK; + return hr; + } + } + + if( m_EncoderCapabilities.m_HWSupportStatsQPMapOutput.bits.supported ) + { + if( *Api == CODECAPI_AVEncVideoOutputQPMapBlockSize ) + { + hr = S_OK; + return hr; + } + } + + if( m_EncoderCapabilities.m_HWSupportStatsRCBitAllocationMapOutput.bits.supported ) + { + if( *Api == CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize ) + { + hr = S_OK; + return hr; + } + } + done: return hr; } @@ -775,12 +801,17 @@ CDX12EncHMFT::GetValue( const GUID *Api, VARIANT *Value ) else if( *Api == CODECAPI_AVEncVideoOutputQPMapBlockSize ) { Value->vt = VT_UI4; - Value->ulVal = m_uiVideoOutputQPMapBlockSize; + Value->ulVal = m_EncoderCapabilities.m_HWSupportStatsQPMapOutput.bits.supported ? + (ULONG) ( 1 << m_EncoderCapabilities.m_HWSupportStatsQPMapOutput.bits.log2_values_block_size ) : + 0; } else if( *Api == CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize ) { Value->vt = VT_UI4; - Value->ulVal = m_uiVideoOutputBitsUsedMapBlockSize; + Value->ulVal = + m_EncoderCapabilities.m_HWSupportStatsRCBitAllocationMapOutput.bits.supported ? + (ULONG) ( 1 << m_EncoderCapabilities.m_HWSupportStatsRCBitAllocationMapOutput.bits.log2_values_block_size ) : + 0; } else { @@ -1407,6 +1438,13 @@ CDX12EncHMFT::SetValue( const GUID *Api, VARIANT *Value ) { CHECKHR_GOTO( E_INVALIDARG, done ); } + if( !m_EncoderCapabilities.m_PSNRStatsSupport.bits.supports_y_channel && Value->ulVal ) + { + MFE_ERROR( "[dx12 hmft 0x%p] User tried to enable CODECAPI_AVEncVideoEnableFramePsnrYuv, but this encoder does NOT " + "support this feature.", + this ); + CHECKHR_GOTO( E_INVALIDARG, done ); + } m_bVideoEnableFramePsnrYuv = Value->ulVal ? TRUE : FALSE; } else if( *Api == CODECAPI_AVEncVideoEnableSpatialAdaptiveQuantization ) @@ -1421,19 +1459,54 @@ CDX12EncHMFT::SetValue( const GUID *Api, VARIANT *Value ) else if( *Api == CODECAPI_AVEncVideoOutputQPMapBlockSize ) { debug_printf( "[dx12 hmft 0x%p] SET CODECAPI_AVEncVideoOutputQPMapBlockSize - %u\n", this, Value->ulVal ); - if( Value->vt != VT_UI4 || ( Value->ulVal & ( Value->ulVal - 1 ) ) ) + if( Value->vt != VT_UI4 ) { CHECKHR_GOTO( E_INVALIDARG, done ); } + if( !m_EncoderCapabilities.m_HWSupportStatsQPMapOutput.bits.supported && Value->ulVal ) + { + MFE_ERROR( "[dx12 hmft 0x%p] User tried to set CODECAPI_AVEncVideoOutputQPMapBlockSize as nonzero: %d, but this encoder " + "does NOT support this feature.", + this, + Value->ulVal ); + CHECKHR_GOTO( E_INVALIDARG, done ); + } + if( m_EncoderCapabilities.m_HWSupportStatsQPMapOutput.bits.supported && Value->ulVal && + ( Value->ulVal != (ULONG) ( 1 << m_EncoderCapabilities.m_HWSupportStatsQPMapOutput.bits.log2_values_block_size ) ) ) + { + MFE_ERROR( "[dx12 hmft 0x%p] User MUST set CODECAPI_AVEncVideoOutputQPMapBlockSize as %d to enable this feature, or 0 to " + "disable this feature.", + this, + ( 1 << m_EncoderCapabilities.m_HWSupportStatsQPMapOutput.bits.log2_values_block_size ) ); + CHECKHR_GOTO( E_INVALIDARG, done ); + } m_uiVideoOutputQPMapBlockSize = Value->ulVal; } else if( *Api == CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize ) { debug_printf( "[dx12 hmft 0x%p] SET CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize - %u\n", this, Value->ulVal ); - if( Value->vt != VT_UI4 || ( Value->ulVal & ( Value->ulVal - 1 ) ) ) + if( Value->vt != VT_UI4 ) { CHECKHR_GOTO( E_INVALIDARG, done ); } + if( !m_EncoderCapabilities.m_HWSupportStatsRCBitAllocationMapOutput.bits.supported && Value->ulVal ) + { + MFE_ERROR( "[dx12 hmft 0x%p] User tried to set CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize as nonzero: %d, but this " + "encoder does not support this feature.", + this, + Value->ulVal ); + CHECKHR_GOTO( E_INVALIDARG, done ); + } + if( m_EncoderCapabilities.m_HWSupportStatsRCBitAllocationMapOutput.bits.supported && Value->ulVal && + ( Value->ulVal != + (ULONG) ( 1 << m_EncoderCapabilities.m_HWSupportStatsRCBitAllocationMapOutput.bits.log2_values_block_size ) ) ) + { + MFE_ERROR( "[dx12 hmft 0x%p] User MUST set CODECAPI_AVEncVideoOutputBitsUsedMapBlockSize as %d to enable this feature, or " + "0 to disable this feature.", + this, + ( 1 << m_EncoderCapabilities.m_HWSupportStatsRCBitAllocationMapOutput.bits.log2_values_block_size ) ); + CHECKHR_GOTO( E_INVALIDARG, done ); + } m_uiVideoOutputBitsUsedMapBlockSize = Value->ulVal; } else