Files
UnrealEngine/Engine/Plugins/Media/WmfMedia/Shaders/Private/MediaHardwareVideoDecoding.usf
2025-05-18 13:04:45 +08:00

118 lines
3.2 KiB
HLSL

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
MediaHardwareVideoDecoding.usf: Shaders to convert various media decoder outputs to RGBA
=============================================================================*/
#include "/Engine/Private/Common.ush"
#include "/Engine/Private/GammaCorrectionCommon.ush"
#include "/Engine/Private/ColorUtils.ush"
static const float2 kQuadPos[6] =
{
float2(-1.0, 1.0),
float2( 1.0, 1.0),
float2( 1.0,-1.0),
float2(-1.0,-1.0),
float2( 1.0,-1.0),
float2(-1.0, 1.0),
};
static const float2 kQuadUVs[6] =
{
float2(0.0, 0.0),
float2(1.0, 0.0),
float2(1.0, 1.0),
float2(0.0, 1.0),
float2(1.0, 1.0),
float2(0.0, 0.0),
};
static const float4 kYCoCgOffsets = float4(-0.50196078431373, -0.50196078431373, 0, 0);
Texture2D TextureY;
Texture2D TextureUV;
SamplerState PointClampedSamplerY;
SamplerState BilinearClampedSamplerUV;
SamplerState BilinearClampedSamplerUVAlpha;
float4x4 ColorTransform;
uint SrgbToLinear;
void MainVS(in uint GlobalVertexId : SV_VertexID
, out float2 TexCoord : TEXCOORD0
, out float4 OutPosition : SV_POSITION)
{
// Output vertex position.
OutPosition = float4(kQuadPos[GlobalVertexId], 0, 1);
// Output top left originated UV of the vertex.
TexCoord = kQuadUVs[GlobalVertexId].xy;
}
void NV12ConvertPS(in noperspective float2 InUV : TEXCOORD0
, in float4 SvPosition : SV_POSITION
, out float4 OutColor : SV_Target0)
{
float3 YUV;
YUV.x = TextureY.Sample(PointClampedSamplerY, InUV).x;
YUV.yz = TextureUV.Sample(BilinearClampedSamplerUV, InUV).xy;
OutColor.xyz = YuvToRgb(YUV, ColorTransform, SrgbToLinear);
// no alpha support
OutColor.w = 1.0;
}
void PassThroughPS(in noperspective float2 InUV : TEXCOORD0
, in float4 SvPosition : SV_POSITION
, out float4 OutColor : SV_Target0)
{
OutColor = TextureY.Sample(BilinearClampedSamplerUV, InUV);
}
void Y416ConvertPS(in noperspective float2 InUV : TEXCOORD0
, in float4 SvPosition : SV_POSITION
, out float4 OutColor : SV_Target0)
{
float4 AVYU = TextureY.Sample(BilinearClampedSamplerUV, InUV);
OutColor.rgb = YuvToRgb(AVYU.yzw, ColorTransform, SrgbToLinear);
OutColor.a = AVYU.x;
}
void YCoCgConvertPS(in noperspective float2 InUV : TEXCOORD0
, in float4 SvPosition : SV_POSITION
, out float4 OutColor : SV_Target0)
{
float4 CoCgSY = TextureY.Sample(BilinearClampedSamplerUV, InUV);
CoCgSY += kYCoCgOffsets;
float Scale = (CoCgSY.z * (255.0 / 8.0)) + 1.0;
float Co = CoCgSY.x / Scale;
float Cg = CoCgSY.y / Scale;
float Y = CoCgSY.w;
OutColor = float4(Y + Co - Cg, Y + Cg, Y - Co - Cg, 1.0);
OutColor.xyz = sRGBToLinear(OutColor.xyz);
}
void YCoCgAlphaConvertPS(in noperspective float2 InUV : TEXCOORD0
, in float4 SvPosition : SV_POSITION
, out float4 OutColor : SV_Target0)
{
float4 CoCgSY = TextureY.Sample(BilinearClampedSamplerUV, InUV);
float Alpha = TextureUV.Sample(BilinearClampedSamplerUVAlpha, InUV).x;
CoCgSY += kYCoCgOffsets;
float Scale = (CoCgSY.z * (255.0 / 8.0)) + 1.0;
float Co = CoCgSY.x / Scale;
float Cg = CoCgSY.y / Scale;
float Y = CoCgSY.w;
OutColor = float4(Y + Co - Cg, Y + Cg, Y - Co - Cg, Alpha);
OutColor.xyz = sRGBToLinear(OutColor.xyz);
}