mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-17 06:01:12 +00:00
Centralize colorspace and color range handling
This commit is contained in:
@@ -80,8 +80,8 @@ D3D11VARenderer::D3D11VARenderer(int decoderSelectionPass)
|
||||
m_SwapChain(nullptr),
|
||||
m_DeviceContext(nullptr),
|
||||
m_RenderTargetView(nullptr),
|
||||
m_LastColorSpace(AVCOL_SPC_UNSPECIFIED),
|
||||
m_LastColorRange(AVCOL_RANGE_UNSPECIFIED),
|
||||
m_LastColorSpace(-1),
|
||||
m_LastFullRange(false),
|
||||
m_AllowTearing(false),
|
||||
m_VideoGenericPixelShader(nullptr),
|
||||
m_VideoBt601LimPixelShader(nullptr),
|
||||
@@ -673,11 +673,14 @@ void D3D11VARenderer::renderOverlay(Overlay::OverlayType type)
|
||||
|
||||
void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||
{
|
||||
bool fullRange = isFrameFullRange(frame);
|
||||
int colorspace = getFrameColorspace(frame);
|
||||
|
||||
// We have purpose-built shaders for the common Rec 601 (SDR) and Rec 2020 (HDR) cases
|
||||
if (frame->color_range == AVCOL_RANGE_MPEG && frame->colorspace == AVCOL_SPC_SMPTE170M) {
|
||||
if (!fullRange && colorspace == COLORSPACE_REC_601) {
|
||||
m_DeviceContext->PSSetShader(m_VideoBt601LimPixelShader, nullptr, 0);
|
||||
}
|
||||
else if (frame->color_range == AVCOL_RANGE_MPEG && frame->colorspace == AVCOL_SPC_BT2020_NCL) {
|
||||
else if (!fullRange && colorspace == COLORSPACE_REC_2020) {
|
||||
m_DeviceContext->PSSetShader(m_VideoBt2020LimPixelShader, nullptr, 0);
|
||||
}
|
||||
else {
|
||||
@@ -685,14 +688,14 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||
m_DeviceContext->PSSetShader(m_VideoGenericPixelShader, nullptr, 0);
|
||||
|
||||
// If nothing has changed since last frame, we're done
|
||||
if (frame->colorspace == m_LastColorSpace && frame->color_range == m_LastColorRange) {
|
||||
if (colorspace == m_LastColorSpace && fullRange == m_LastFullRange) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Falling back to generic video pixel shader for %d:%d",
|
||||
frame->colorspace,
|
||||
frame->color_range);
|
||||
"Falling back to generic video pixel shader for %d (%s range)",
|
||||
colorspace,
|
||||
fullRange ? "full" : "limited");
|
||||
|
||||
D3D11_BUFFER_DESC constDesc = {};
|
||||
constDesc.ByteWidth = sizeof(CSC_CONST_BUF);
|
||||
@@ -701,41 +704,21 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||
constDesc.CPUAccessFlags = 0;
|
||||
constDesc.MiscFlags = 0;
|
||||
|
||||
// This handles the case where the color range is unknown,
|
||||
// so that we use Limited color range which is the default
|
||||
// behavior for Moonlight.
|
||||
CSC_CONST_BUF constBuf = {};
|
||||
bool fullRange = (frame->color_range == AVCOL_RANGE_JPEG);
|
||||
const float* rawCscMatrix;
|
||||
switch (frame->colorspace) {
|
||||
case AVCOL_SPC_SMPTE170M:
|
||||
case AVCOL_SPC_BT470BG:
|
||||
switch (colorspace) {
|
||||
case COLORSPACE_REC_601:
|
||||
rawCscMatrix = fullRange ? k_CscMatrix_Bt601Full : k_CscMatrix_Bt601Lim;
|
||||
break;
|
||||
case AVCOL_SPC_BT709:
|
||||
case COLORSPACE_REC_709:
|
||||
rawCscMatrix = fullRange ? k_CscMatrix_Bt709Full : k_CscMatrix_Bt709Lim;
|
||||
break;
|
||||
case AVCOL_SPC_BT2020_NCL:
|
||||
case AVCOL_SPC_BT2020_CL:
|
||||
case COLORSPACE_REC_2020:
|
||||
rawCscMatrix = fullRange ? k_CscMatrix_Bt2020Full : k_CscMatrix_Bt2020Lim;
|
||||
break;
|
||||
default:
|
||||
// Sunshine doesn't always populate this data correctly,
|
||||
// so fallback to assuming they're sending what we asked for.
|
||||
switch (getDecoderColorspace()) {
|
||||
case COLORSPACE_REC_601:
|
||||
rawCscMatrix = fullRange ? k_CscMatrix_Bt601Full : k_CscMatrix_Bt601Lim;
|
||||
break;
|
||||
case COLORSPACE_REC_709:
|
||||
rawCscMatrix = fullRange ? k_CscMatrix_Bt709Full : k_CscMatrix_Bt709Lim;
|
||||
break;
|
||||
case COLORSPACE_REC_2020:
|
||||
rawCscMatrix = fullRange ? k_CscMatrix_Bt2020Full : k_CscMatrix_Bt2020Lim;
|
||||
break;
|
||||
default:
|
||||
SDL_assert(false);
|
||||
return;
|
||||
}
|
||||
SDL_assert(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to adjust our raw CSC matrix to be column-major and with float3 vectors
|
||||
@@ -769,8 +752,8 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||
}
|
||||
}
|
||||
|
||||
m_LastColorSpace = frame->colorspace;
|
||||
m_LastColorRange = frame->color_range;
|
||||
m_LastColorSpace = colorspace;
|
||||
m_LastFullRange = fullRange;
|
||||
}
|
||||
|
||||
void D3D11VARenderer::renderVideo(AVFrame* frame)
|
||||
|
||||
Reference in New Issue
Block a user