Skip to content

Commit

Permalink
[Windows][dxva] Modify Renderer DXVA to react to source changes durin…
Browse files Browse the repository at this point in the history
…g playback.

Compare attributes of new frame with old frame. Differences could require a different conversion, re-enumerate conversions and choose the best one again.

Similar to the replaced code, does not react to:
- VSR setting change
- High precision processing setting change
- Source dimensions or input dxgi format changes - in practice doesn't seem to have an effect on D1D11 enumerator interfaces behavior , but enumerator should be reopened.
To be added in future changes.
  • Loading branch information
CrystalP committed Jul 16, 2023
1 parent b57eabb commit f70256a
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ struct ProcessorConversion
}

const std::string ToString() const;

bool operator!=(const ProcessorConversion& other) const
{
return m_inputFormat != other.m_inputFormat ||
m_inputCS != other.m_inputCS && m_outputFormat != other.m_outputFormat ||
m_outputCS != other.m_outputCS;
}
};

using ProcessorConversions = std::vector<ProcessorConversion>;
Expand All @@ -116,6 +123,8 @@ struct SupportedConversionsArgs
bool m_fullRange{false};
bool m_hdrOutput{false};

SupportedConversionsArgs() = default;

SupportedConversionsArgs(const VideoPicture& picture, bool isHdrOutput)
{
m_colorPrimaries = static_cast<AVColorPrimaries>(picture.color_primaries);
Expand All @@ -134,6 +143,12 @@ struct SupportedConversionsArgs
m_hdrOutput(hdrOutput)
{
}

bool operator!=(const SupportedConversionsArgs& other) const
{
return m_colorPrimaries != other.m_colorPrimaries || m_colorTransfer != other.m_colorTransfer ||
m_fullRange != other.m_fullRange || m_hdrOutput != other.m_hdrOutput;
}
};

class CEnumeratorHD : public ID3DResource
Expand Down
58 changes: 46 additions & 12 deletions xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererDXVA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ bool CRendererDXVA::Configure(const VideoPicture& picture, float fps, unsigned o
{
m_format = picture.videoBuffer->GetFormat();
const DXGI_FORMAT dxgi_format = GetDXGIFormat(m_format, __super::GetDXGIFormat(picture));
bool tryVSR{false};

if (DX::Windowing()->SupportsVideoSuperResolution())
{
Expand All @@ -133,7 +132,7 @@ bool CRendererDXVA::Configure(const VideoPicture& picture, float fps, unsigned o
if (settings && settings->GetBool(CSettings::SETTING_VIDEOPLAYER_USESUPERRESOLUTION) &&
CProcessorHD::IsSuperResolutionSuitable(picture))
{
tryVSR = true;
m_tryVSR = true;
}
}

Expand All @@ -153,21 +152,24 @@ bool CRendererDXVA::Configure(const VideoPicture& picture, float fps, unsigned o
dxgi_format, CProcessorHD::AvToDxgiColorSpace(DXVA::DXGIColorSpaceArgs(picture)));
}

const ProcessorConversions conversions = m_enumerator->SupportedConversions(
DXVA::SupportedConversionsArgs(picture, systemUsesHDR));
m_conversionsArgs = SupportedConversionsArgs{picture, systemUsesHDR};
const ProcessorConversions conversions =
m_enumerator->SupportedConversions(m_conversionsArgs);
if (!conversions.empty())
{
ProcessorConversion chosenConversion = ChooseConversion(conversions, picture, tryVSR);
const ProcessorConversion chosenConversion = ChooseConversion(
conversions, picture.colorBits,
static_cast<AVColorTransferCharacteristic>(picture.color_transfer), m_tryVSR);
m_intermediateTargetFormat = chosenConversion.m_outputFormat;
m_conversion = chosenConversion;

CLog::LogF(LOGINFO, "chosen conversion: {}", chosenConversion.ToString());
CLog::LogF(LOGINFO, "chosen conversion: {}", m_conversion.ToString());

// create processor
m_processor = std::make_unique<DXVA::CProcessorHD>();
if (m_processor->Open(picture, m_enumerator) &&
m_processor->SetConversion(chosenConversion))
if (m_processor->Open(picture, m_enumerator) && m_processor->SetConversion(m_conversion))
{
if (tryVSR)
if (m_tryVSR)
m_processor->TryEnableVideoSuperResolution();

return true;
Expand Down Expand Up @@ -197,6 +199,37 @@ void CRendererDXVA::CheckVideoParameters()
{
__super::CheckVideoParameters();

CRenderBuffer* buf = m_renderBuffers[m_iBufferIndex];
if (m_enumerator)
{
const SupportedConversionsArgs args{buf->primaries, buf->color_transfer, buf->full_range,
DX::Windowing()->IsHDROutput()};

if (m_conversionsArgs != args)
{
CLog::LogF(LOGINFO, "source format change detected");

const ProcessorConversions conversions = m_enumerator->SupportedConversions(args);
// TODO case no supported conversion: add support in WinRenderer to fallback to a render method with support
// For now, keep using the current conversion. Results won't be ideal but a black screen is avoided
const ProcessorConversion conversion =
conversions.empty()
? m_conversion
: ChooseConversion(conversions, buf->bits, buf->color_transfer, m_tryVSR);

if (m_conversion != conversion)
{
CLog::LogF(LOGINFO, "new conversion: {}", conversion.ToString());

m_processor->SetConversion(conversion);
m_intermediateTargetFormat = conversion.m_outputFormat;

m_conversion = conversion;
}
m_conversionsArgs = args;
}
}

CreateIntermediateTarget(HasHQScaler() ? m_sourceWidth : m_viewWidth,
HasHQScaler() ? m_sourceHeight : m_viewHeight, false,
m_intermediateTargetFormat);
Expand Down Expand Up @@ -469,7 +502,8 @@ bool CRendererDXVA::CRenderBufferImpl::UploadToTexture()
}

ProcessorConversion CRendererDXVA::ChooseConversion(const ProcessorConversions& conversions,
const VideoPicture& picture,
unsigned int sourceBits,
AVColorTransferCharacteristic colorTransfer,
bool tryVSR) const
{
assert(conversions.size() > 0);
Expand All @@ -482,8 +516,8 @@ ProcessorConversion CRendererDXVA::ChooseConversion(const ProcessorConversions&

const auto settings = CServiceBroker::GetSettingsComponent()->GetSettings();
if (settings && settings->GetBool(CSettings::SETTING_VIDEOPLAYER_HIGHPRECISIONPROCESSING))
if (picture.colorBits > 8 && (picture.color_transfer == AVCOL_TRC_SMPTE2084 ||
picture.color_transfer == AVCOL_TRC_ARIB_STD_B67))
if (sourceBits > 8 &&
(colorTransfer == AVCOL_TRC_SMPTE2084 || colorTransfer == AVCOL_TRC_ARIB_STD_B67))
tryHQ = true;
}

Expand Down
6 changes: 5 additions & 1 deletion xbmc/cores/VideoPlayer/VideoRenderers/windows/RendererDXVA.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,16 @@ class CRendererDXVA : public CRendererHQ
* \return
*/
DXVA::ProcessorConversion ChooseConversion(const DXVA::ProcessorConversions& conversions,
const VideoPicture& picture,
unsigned int sourceBits,
AVColorTransferCharacteristic colorTransfer,
bool tryVSR) const;

std::unique_ptr<DXVA::CProcessorHD> m_processor;
std::shared_ptr<DXVA::CEnumeratorHD> m_enumerator;
DXGI_FORMAT m_intermediateTargetFormat{DXGI_FORMAT_UNKNOWN};
DXVA::ProcessorConversion m_conversion;
DXVA::SupportedConversionsArgs m_conversionsArgs;
bool m_tryVSR{false};
};

class CRendererDXVA::CRenderBufferImpl : public CRenderBuffer
Expand Down

0 comments on commit f70256a

Please sign in to comment.