mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-17 22:23:31 +00:00
Switch D3D11VA to the shared functions for CSC matrix generation and chroma co-siting
This commit is contained in:
@@ -27,23 +27,6 @@ typedef struct _VERTEX
|
|||||||
|
|
||||||
#define CSC_MATRIX_RAW_ELEMENT_COUNT 9
|
#define CSC_MATRIX_RAW_ELEMENT_COUNT 9
|
||||||
#define CSC_MATRIX_PACKED_ELEMENT_COUNT 12
|
#define CSC_MATRIX_PACKED_ELEMENT_COUNT 12
|
||||||
|
|
||||||
static const float k_CscMatrix_Bt601[CSC_MATRIX_RAW_ELEMENT_COUNT] = {
|
|
||||||
1.0f, 1.0f, 1.0f,
|
|
||||||
0.0f, -0.3441f, 1.7720f,
|
|
||||||
1.4020f, -0.7141f, 0.0f,
|
|
||||||
};
|
|
||||||
static const float k_CscMatrix_Bt709[CSC_MATRIX_RAW_ELEMENT_COUNT] = {
|
|
||||||
1.0f, 1.0f, 1.0f,
|
|
||||||
0.0f, -0.1873f, 1.8556f,
|
|
||||||
1.5748f, -0.4681f, 0.0f,
|
|
||||||
};
|
|
||||||
static const float k_CscMatrix_Bt2020[CSC_MATRIX_RAW_ELEMENT_COUNT] = {
|
|
||||||
1.0f, 1.0f, 1.0f,
|
|
||||||
0.0f, -0.1646f, 1.8814f,
|
|
||||||
1.4746f, -0.5714f, 0.0f,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define OFFSETS_ELEMENT_COUNT 3
|
#define OFFSETS_ELEMENT_COUNT 3
|
||||||
|
|
||||||
typedef struct _CSC_CONST_BUF
|
typedef struct _CSC_CONST_BUF
|
||||||
@@ -77,8 +60,6 @@ D3D11VARenderer::D3D11VARenderer(int decoderSelectionPass)
|
|||||||
m_DecoderSelectionPass(decoderSelectionPass),
|
m_DecoderSelectionPass(decoderSelectionPass),
|
||||||
m_DevicesWithFL11Support(0),
|
m_DevicesWithFL11Support(0),
|
||||||
m_DevicesWithCodecSupport(0),
|
m_DevicesWithCodecSupport(0),
|
||||||
m_LastColorSpace(-1),
|
|
||||||
m_LastFullRange(false),
|
|
||||||
m_LastColorTrc(AVCOL_TRC_UNSPECIFIED),
|
m_LastColorTrc(AVCOL_TRC_UNSPECIFIED),
|
||||||
m_AllowTearing(false),
|
m_AllowTearing(false),
|
||||||
m_OverlayLock(0),
|
m_OverlayLock(0),
|
||||||
@@ -706,10 +687,7 @@ void D3D11VARenderer::renderOverlay(Overlay::OverlayType type)
|
|||||||
|
|
||||||
void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
||||||
{
|
{
|
||||||
bool fullRange = isFrameFullRange(frame);
|
|
||||||
int colorspace = getFrameColorspace(frame);
|
|
||||||
bool yuv444 = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_YUV444);
|
bool yuv444 = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_YUV444);
|
||||||
int bits = (m_DecoderParams.videoFormat & VIDEO_FORMAT_MASK_10BIT) ? 10 : 8;
|
|
||||||
|
|
||||||
if (yuv444) {
|
if (yuv444) {
|
||||||
// We'll need to use one of the 4:4:4 shaders for this pixel format
|
// We'll need to use one of the 4:4:4 shaders for this pixel format
|
||||||
@@ -731,7 +709,7 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If nothing has changed since last frame, we're done
|
// If nothing has changed since last frame, we're done
|
||||||
if (colorspace == m_LastColorSpace && fullRange == m_LastFullRange) {
|
if (!hasFrameFormatChanged(frame)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -743,81 +721,24 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
|||||||
constDesc.MiscFlags = 0;
|
constDesc.MiscFlags = 0;
|
||||||
|
|
||||||
CSC_CONST_BUF constBuf = {};
|
CSC_CONST_BUF constBuf = {};
|
||||||
const float* rawCscMatrix;
|
std::array<float, 9> cscMatrix;
|
||||||
switch (colorspace) {
|
std::array<float, 3> yuvOffsets;
|
||||||
case COLORSPACE_REC_601:
|
getFramePremultipliedCscConstants(frame, cscMatrix, yuvOffsets);
|
||||||
rawCscMatrix = k_CscMatrix_Bt601;
|
|
||||||
break;
|
|
||||||
case COLORSPACE_REC_709:
|
|
||||||
rawCscMatrix = k_CscMatrix_Bt709;
|
|
||||||
break;
|
|
||||||
case COLORSPACE_REC_2020:
|
|
||||||
rawCscMatrix = k_CscMatrix_Bt2020;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SDL_assert(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int range = (1 << bits);
|
std::copy(yuvOffsets.cbegin(), yuvOffsets.cend(), constBuf.offsets);
|
||||||
double yMin = (fullRange ? 0 : (16 << (bits - 8)));
|
|
||||||
double yMax = (fullRange ? (range - 1) : (235 << (bits - 8)));
|
|
||||||
double yScale = (range - 1) / (yMax - yMin);
|
|
||||||
double uvMin = (fullRange ? 0 : (16 << (bits - 8)));
|
|
||||||
double uvMax = (fullRange ? (range - 1) : (240 << (bits - 8)));
|
|
||||||
double uvScale = (range - 1) / (uvMax - uvMin);
|
|
||||||
|
|
||||||
// Calculate YUV offsets
|
// We need to adjust our CSC matrix to be column-major and with float3 vectors
|
||||||
constBuf.offsets[0] = yMin / (double)(range - 1);
|
|
||||||
constBuf.offsets[1] = (range / 2) / (double)(range - 1);
|
|
||||||
constBuf.offsets[2] = (range / 2) / (double)(range - 1);
|
|
||||||
|
|
||||||
// We need to adjust our raw CSC matrix to be column-major and with float3 vectors
|
|
||||||
// padded with a float in between each of them to adhere to HLSL requirements.
|
// padded with a float in between each of them to adhere to HLSL requirements.
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; j++) {
|
||||||
constBuf.cscMatrix[i * 4 + j] = rawCscMatrix[j * 3 + i];
|
constBuf.cscMatrix[i * 4 + j] = cscMatrix[j * 3 + i];
|
||||||
|
|
||||||
// Scale the color matrix according to the color range
|
|
||||||
constBuf.cscMatrix[i * 4 + j] *= (j == 0) ? yScale : uvScale;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (frame->chroma_location) {
|
std::array<float, 2> chromaOffset;
|
||||||
default:
|
getFrameChromaCositingOffsets(frame, chromaOffset);
|
||||||
case AVCHROMA_LOC_LEFT:
|
constBuf.chromaOffset[0] = chromaOffset[0] / m_TextureWidth;
|
||||||
constBuf.chromaOffset[0] = 0.5;
|
constBuf.chromaOffset[1] = chromaOffset[1] / m_TextureHeight;
|
||||||
constBuf.chromaOffset[1] = 0;
|
|
||||||
break;
|
|
||||||
case AVCHROMA_LOC_CENTER:
|
|
||||||
constBuf.chromaOffset[0] = 0;
|
|
||||||
constBuf.chromaOffset[1] = 0;
|
|
||||||
break;
|
|
||||||
case AVCHROMA_LOC_TOPLEFT:
|
|
||||||
constBuf.chromaOffset[0] = 0.5;
|
|
||||||
constBuf.chromaOffset[1] = 0.5;
|
|
||||||
break;
|
|
||||||
case AVCHROMA_LOC_TOP:
|
|
||||||
constBuf.chromaOffset[0] = 0;
|
|
||||||
constBuf.chromaOffset[1] = 0.5;
|
|
||||||
break;
|
|
||||||
case AVCHROMA_LOC_BOTTOMLEFT:
|
|
||||||
constBuf.chromaOffset[0] = 0.5;
|
|
||||||
constBuf.chromaOffset[1] = -0.5;
|
|
||||||
break;
|
|
||||||
case AVCHROMA_LOC_BOTTOM:
|
|
||||||
constBuf.chromaOffset[0] = 0;
|
|
||||||
constBuf.chromaOffset[1] = -0.5;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
constBuf.chromaOffset[0] /= m_TextureWidth;
|
|
||||||
constBuf.chromaOffset[1] /= m_TextureHeight;
|
|
||||||
|
|
||||||
if (yuv444) {
|
|
||||||
// 4:4:4 has no subsampling
|
|
||||||
constBuf.chromaOffset[0] = 0;
|
|
||||||
constBuf.chromaOffset[1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
D3D11_SUBRESOURCE_DATA constData = {};
|
D3D11_SUBRESOURCE_DATA constData = {};
|
||||||
constData.pSysMem = &constBuf;
|
constData.pSysMem = &constBuf;
|
||||||
@@ -833,9 +754,6 @@ void D3D11VARenderer::bindColorConversion(AVFrame* frame)
|
|||||||
hr);
|
hr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_LastColorSpace = colorspace;
|
|
||||||
m_LastFullRange = fullRange;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D11VARenderer::renderVideo(AVFrame* frame)
|
void D3D11VARenderer::renderVideo(AVFrame* frame)
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ private:
|
|||||||
UINT m_TextureHeight;
|
UINT m_TextureHeight;
|
||||||
int m_DisplayWidth;
|
int m_DisplayWidth;
|
||||||
int m_DisplayHeight;
|
int m_DisplayHeight;
|
||||||
int m_LastColorSpace;
|
|
||||||
bool m_LastFullRange;
|
|
||||||
AVColorTransferCharacteristic m_LastColorTrc;
|
AVColorTransferCharacteristic m_LastColorTrc;
|
||||||
|
|
||||||
bool m_AllowTearing;
|
bool m_AllowTearing;
|
||||||
|
|||||||
Reference in New Issue
Block a user