mediafoundation: fix slice capability check, and fix the slice mb mode, remove slice mode 2
Reviewed-by: Sil Vilerino <sivileri@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35554>
This commit is contained in:
committed by
Marge Bot
parent
8b15d0f31f
commit
2bb9f691e8
@@ -383,53 +383,40 @@ CDX12EncHMFT::GetParameterRange( const GUID *Api, VARIANT *ValueMin, VARIANT *Va
|
||||
}
|
||||
else if( *Api == CODECAPI_AVEncSliceControlMode )
|
||||
{
|
||||
static_assert( PIPE_VIDEO_SLICE_MODE_BLOCKS == 0 );
|
||||
static_assert( PIPE_VIDEO_SLICE_MODE_MAX_SLICE_SIZE == 1 );
|
||||
static_assert( PIPE_VIDEO_SLICE_MODE_AUTO == 2 );
|
||||
bool bSliceModeMB = m_EncoderCapabilities.m_bHWSupportSliceModeMB;
|
||||
bool bSliceModeMBRow = m_EncoderCapabilities.m_bHWSupportSliceModeMBRow;
|
||||
|
||||
// If PIPE_VIDEO_SLICE_MODE_BLOCKS is not supported, return error.
|
||||
if( m_EncoderCapabilities.m_HWSupportedSliceModes.HasAll( PIPE_VIDEO_SLICE_MODE_BLOCKS,
|
||||
PIPE_VIDEO_SLICE_MODE_MAX_SLICE_SIZE,
|
||||
PIPE_VIDEO_SLICE_MODE_AUTO ) )
|
||||
if( !( bSliceModeMB || bSliceModeMBRow ) )
|
||||
{
|
||||
ValueMin->vt = VT_UI4;
|
||||
ValueMin->ulVal = 0;
|
||||
|
||||
ValueMax->vt = VT_UI4;
|
||||
ValueMax->ulVal = 2;
|
||||
|
||||
SteppingDelta->vt = VT_UI4;
|
||||
SteppingDelta->ulVal = 1;
|
||||
}
|
||||
else if( m_EncoderCapabilities.m_HWSupportedSliceModes.HasAll( PIPE_VIDEO_SLICE_MODE_BLOCKS,
|
||||
PIPE_VIDEO_SLICE_MODE_MAX_SLICE_SIZE ) )
|
||||
{
|
||||
ValueMin->vt = VT_UI4;
|
||||
ValueMin->ulVal = 0;
|
||||
|
||||
ValueMax->vt = VT_UI4;
|
||||
ValueMax->ulVal = 1;
|
||||
|
||||
SteppingDelta->vt = VT_UI4;
|
||||
SteppingDelta->ulVal = 1;
|
||||
}
|
||||
else if( m_EncoderCapabilities.m_HWSupportedSliceModes.HasAll( PIPE_VIDEO_SLICE_MODE_BLOCKS ) )
|
||||
{
|
||||
ValueMin->vt = VT_UI4;
|
||||
ValueMin->ulVal = 0;
|
||||
|
||||
ValueMax->vt = VT_UI4;
|
||||
ValueMax->ulVal = 0;
|
||||
|
||||
SteppingDelta->vt = VT_UI4;
|
||||
SteppingDelta->ulVal = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Nothing is supported.
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
ULONG min = 0;
|
||||
ULONG max = 2;
|
||||
ULONG delta = 2;
|
||||
|
||||
if( bSliceModeMB && !bSliceModeMBRow )
|
||||
{
|
||||
min = 0;
|
||||
max = 0;
|
||||
delta = 1;
|
||||
}
|
||||
else if( !bSliceModeMB && bSliceModeMBRow )
|
||||
{
|
||||
min = 2;
|
||||
max = 2;
|
||||
delta = 1;
|
||||
}
|
||||
|
||||
ValueMin->vt = VT_UI4;
|
||||
ValueMin->ulVal = min;
|
||||
|
||||
ValueMax->vt = VT_UI4;
|
||||
ValueMax->ulVal = max;
|
||||
|
||||
SteppingDelta->vt = VT_UI4;
|
||||
SteppingDelta->ulVal = delta;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
else if( *Api == CODECAPI_AVEncSliceControlSize )
|
||||
|
||||
@@ -436,17 +436,24 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo
|
||||
{
|
||||
pPicInfo->slice_mode = PIPE_VIDEO_SLICE_MODE_BLOCKS;
|
||||
uint32_t blocks_per_slice = m_uiSliceControlSize;
|
||||
pPicInfo->num_slice_descriptors = ( height_in_blocks * width_in_blocks ) / blocks_per_slice;
|
||||
pPicInfo->num_slice_descriptors = static_cast<uint32_t>(
|
||||
std::ceil( ( height_in_blocks * width_in_blocks ) / static_cast<double>( blocks_per_slice ) ) );
|
||||
uint32_t slice_starting_mb = 0;
|
||||
CHECKBOOL_GOTO( pPicInfo->num_slice_descriptors <= m_EncoderCapabilities.m_uiMaxHWSupportedMaxSlices,
|
||||
MF_E_UNEXPECTED,
|
||||
done );
|
||||
for( uint32_t i = 0; i < pPicInfo->num_slice_descriptors; i++ )
|
||||
CHECKBOOL_GOTO( pPicInfo->num_slice_descriptors >= 1, MF_E_UNEXPECTED, done );
|
||||
|
||||
uint32_t total_blocks = height_in_blocks * width_in_blocks;
|
||||
uint32_t i = 0;
|
||||
for( i = 0; i < pPicInfo->num_slice_descriptors - 1; i++ )
|
||||
{
|
||||
pPicInfo->slices_descriptors[i].macroblock_address = slice_starting_mb;
|
||||
pPicInfo->slices_descriptors[i].num_macroblocks = blocks_per_slice;
|
||||
slice_starting_mb += blocks_per_slice;
|
||||
}
|
||||
pPicInfo->slices_descriptors[i].macroblock_address = slice_starting_mb;
|
||||
pPicInfo->slices_descriptors[i].num_macroblocks = total_blocks - slice_starting_mb;
|
||||
}
|
||||
else if( SLICE_CONTROL_MODE_BITS == m_uiSliceControlMode )
|
||||
{
|
||||
@@ -463,12 +470,18 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo
|
||||
CHECKBOOL_GOTO( pPicInfo->num_slice_descriptors <= m_EncoderCapabilities.m_uiMaxHWSupportedMaxSlices,
|
||||
MF_E_UNEXPECTED,
|
||||
done );
|
||||
for( uint32_t i = 0; i < pPicInfo->num_slice_descriptors; i++ )
|
||||
CHECKBOOL_GOTO( pPicInfo->num_slice_descriptors >= 1, MF_E_UNEXPECTED, done );
|
||||
|
||||
uint32_t total_blocks = height_in_blocks * width_in_blocks;
|
||||
uint32_t i = 0;
|
||||
for( i = 0; i < pPicInfo->num_slice_descriptors - 1; i++ )
|
||||
{
|
||||
pPicInfo->slices_descriptors[i].macroblock_address = slice_starting_mb;
|
||||
pPicInfo->slices_descriptors[i].num_macroblocks = blocks_per_slice;
|
||||
slice_starting_mb += blocks_per_slice;
|
||||
}
|
||||
pPicInfo->slices_descriptors[i].macroblock_address = slice_starting_mb;
|
||||
pPicInfo->slices_descriptors[i].num_macroblocks = total_blocks - slice_starting_mb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,17 +434,24 @@ CDX12EncHMFT::PrepareForEncodeHelper( LPDX12EncodeContext pDX12EncodeContext, bo
|
||||
{
|
||||
pPicInfo->slice_mode = PIPE_VIDEO_SLICE_MODE_BLOCKS;
|
||||
uint32_t blocks_per_slice = m_uiSliceControlSize;
|
||||
pPicInfo->num_slice_descriptors = ( height_in_blocks * width_in_blocks ) / blocks_per_slice;
|
||||
pPicInfo->num_slice_descriptors = static_cast<uint32_t>(
|
||||
std::ceil( ( height_in_blocks * width_in_blocks ) / static_cast<double>( blocks_per_slice ) ) );
|
||||
uint32_t slice_starting_mb = 0;
|
||||
CHECKBOOL_GOTO( pPicInfo->num_slice_descriptors <= m_EncoderCapabilities.m_uiMaxHWSupportedMaxSlices,
|
||||
MF_E_UNEXPECTED,
|
||||
done );
|
||||
for( uint32_t i = 0; i < pPicInfo->num_slice_descriptors; i++ )
|
||||
CHECKBOOL_GOTO( pPicInfo->num_slice_descriptors >= 1, MF_E_UNEXPECTED, done );
|
||||
|
||||
uint32_t total_blocks = height_in_blocks * width_in_blocks;
|
||||
uint32_t i = 0;
|
||||
for( i = 0; i < pPicInfo->num_slice_descriptors; i++ )
|
||||
{
|
||||
pPicInfo->slices_descriptors[i].slice_segment_address = slice_starting_mb;
|
||||
pPicInfo->slices_descriptors[i].num_ctu_in_slice = blocks_per_slice;
|
||||
slice_starting_mb += blocks_per_slice;
|
||||
}
|
||||
pPicInfo->slices_descriptors[i].slice_segment_address = slice_starting_mb;
|
||||
pPicInfo->slices_descriptors[i].num_ctu_in_slice = total_blocks - slice_starting_mb;
|
||||
}
|
||||
else if( SLICE_CONTROL_MODE_BITS == m_uiSliceControlMode )
|
||||
{
|
||||
|
||||
@@ -141,10 +141,12 @@ encoder_capabilities::initialize( pipe_screen *pScreen, pipe_video_profile video
|
||||
m_HWSupportMotionGPUMaps.value =
|
||||
pScreen->get_video_param( pScreen, videoProfile, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_ENC_MOTION_VECTOR_MAPS );
|
||||
|
||||
// TODO: We should get the supported slice mode from pipe, but currently, it doesn't support.
|
||||
// Currently, dx12MFT only support mode_blocks, so we initialize it like this.
|
||||
m_HWSupportedSliceModes = EnumMask<pipe_video_slice_mode> { PIPE_VIDEO_SLICE_MODE_BLOCKS };
|
||||
uint32_t supportedSliceStructures =
|
||||
pScreen->get_video_param( pScreen, videoProfile, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_ENC_SLICES_STRUCTURE );
|
||||
|
||||
m_bHWSupportSliceModeMB = ( ( supportedSliceStructures & PIPE_VIDEO_CAP_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ) != 0 );
|
||||
m_bHWSupportSliceModeBits = ( ( supportedSliceStructures & PIPE_VIDEO_CAP_SLICE_STRUCTURE_MAX_SLICE_SIZE ) != 0 );
|
||||
m_bHWSupportSliceModeMBRow = ( ( supportedSliceStructures & PIPE_VIDEO_CAP_SLICE_STRUCTURE_EQUAL_MULTI_ROWS ) != 0 );
|
||||
|
||||
m_TwoPassSupport.value =
|
||||
pScreen->get_video_param( pScreen, videoProfile, PIPE_VIDEO_ENTRYPOINT_ENCODE, PIPE_VIDEO_CAP_ENC_TWO_PASS );
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <wtypes.h>
|
||||
#include "enum_mask.h"
|
||||
#include "pipe_headers.h"
|
||||
|
||||
class encoder_capabilities
|
||||
@@ -126,7 +125,9 @@ class encoder_capabilities
|
||||
union pipe_enc_cap_motion_vector_map m_HWSupportMotionGPUMaps = {};
|
||||
|
||||
// Supported slice mode
|
||||
EnumMask<pipe_video_slice_mode> m_HWSupportedSliceModes {};
|
||||
bool m_bHWSupportSliceModeMB = false;
|
||||
bool m_bHWSupportSliceModeBits = false;
|
||||
bool m_bHWSupportSliceModeMBRow = false;
|
||||
|
||||
// Two pass encode
|
||||
union pipe_enc_cap_two_pass m_TwoPassSupport = {};
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright © Microsoft 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 (including the next
|
||||
* paragraph) 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
template <typename T>
|
||||
concept EnumType = std::is_enum_v<T>;
|
||||
|
||||
template <EnumType Enum>
|
||||
class EnumMask
|
||||
{
|
||||
using UnderlyingType = std::underlying_type_t<Enum>;
|
||||
|
||||
public:
|
||||
explicit constexpr EnumMask( std::initializer_list<Enum> values )
|
||||
{
|
||||
for( auto v : values )
|
||||
{
|
||||
m_mask |= MakeValue( v );
|
||||
}
|
||||
}
|
||||
|
||||
constexpr bool HasAll( Enum v )
|
||||
{
|
||||
return m_mask & MakeValue( v );
|
||||
}
|
||||
|
||||
template <EnumType... Enums>
|
||||
constexpr bool HasAll( Enum v, Enums... values )
|
||||
{
|
||||
return HasAll( v ) && HasAll( values... );
|
||||
}
|
||||
|
||||
private:
|
||||
constexpr UnderlyingType MakeValue( Enum v )
|
||||
{
|
||||
return 1 << (UnderlyingType) v;
|
||||
}
|
||||
|
||||
UnderlyingType m_mask {};
|
||||
};
|
||||
@@ -60,6 +60,16 @@ TEST( MediaFoundationEntrypoint, VerifyBasicCodecAPI )
|
||||
ULONG ulValuesCount;
|
||||
CHECKHR_GOTO( spCodecAPI->GetParameterValues( &CODECAPI_AVEncVideoLTRBufferControl, &pValues, &ulValuesCount ), done );
|
||||
}
|
||||
{
|
||||
VARIANT vMin;
|
||||
VARIANT vMax;
|
||||
VARIANT vDelta;
|
||||
CHECKHR_GOTO( spCodecAPI->GetParameterRange( &CODECAPI_AVEncSliceControlMode, &vMin, &vMax, &vDelta ), done );
|
||||
ASSERT_TRUE( vMin.vt == VT_UI4 && vMax.vt == VT_UI4 && vDelta.vt == VT_UI4 );
|
||||
ASSERT_TRUE( vMin.ulVal <= 2u && vMax.ulVal <= 2u );
|
||||
ASSERT_TRUE( vMin.ulVal <= vMax.ulVal );
|
||||
ASSERT_TRUE( vDelta.ulVal >= 1u && vDelta.ulVal <= 2u );
|
||||
}
|
||||
|
||||
done:
|
||||
ASSERT_HRESULT_SUCCEEDED( hr );
|
||||
|
||||
Reference in New Issue
Block a user