Sfoglia il codice sorgente

libobs: Add support for reading NV12/YUY2 PQ/HLG

8-bit HDR shouldn't exist, but OBS looks broken, so just support it.
jpark37 3 anni fa
parent
commit
bb02620169
2 ha cambiato i file con 102 aggiunte e 2 eliminazioni
  1. 86 0
      libobs/data/format_conversion.effect
  2. 16 2
      libobs/obs-source.c

+ 86 - 0
libobs/data/format_conversion.effect

@@ -449,6 +449,34 @@ float3 PSYUY2_Reverse(FragTex frag_in) : TARGET
 	return rgb;
 }
 
+float4 PSYUY2_PQ_Reverse(FragTex frag_in) : TARGET
+{
+	float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
+	float2 y01 = y2uv.zx;
+	float2 cbcr = y2uv.yw;
+	float leftover = frac(frag_in.uv.x);
+	float y = (leftover < 0.5) ? y01.x : y01.y;
+	float3 yuv = float3(y, cbcr);	
+	float3 pq = YUV_to_RGB(yuv);
+	float3 hdr2020 = st2084_to_linear_eetf(pq, hdr_lw, hdr_lmax) * maximum_over_sdr_white_nits;
+	float3 rgb = rec2020_to_rec709(hdr2020);
+	return float4(rgb, 1.);
+}
+
+float4 PSYUY2_HLG_Reverse(FragTex frag_in) : TARGET
+{
+	float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
+	float2 y01 = y2uv.zx;
+	float2 cbcr = y2uv.yw;
+	float leftover = frac(frag_in.uv.x);
+	float y = (leftover < 0.5) ? y01.x : y01.y;
+	float3 yuv = float3(y, cbcr);
+	float3 hlg = YUV_to_RGB(yuv);
+	float3 hdr2020 = hlg_to_linear(hlg, hlg_exponent) * maximum_over_sdr_white_nits;
+	float3 rgb = rec2020_to_rec709(hdr2020);
+	return float4(rgb, 1.);
+}
+
 float3 PSYVYU_Reverse(FragTex frag_in) : TARGET
 {
 	float4 y2uv = image.Load(int3(frag_in.uv.xy, 0));
@@ -614,6 +642,28 @@ float3 PSNV12_Reverse(VertTexPos frag_in) : TARGET
 	return rgb;
 }
 
+float4 PSNV12_PQ_Reverse(VertTexPos frag_in) : TARGET
+{
+	float y = image.Load(int3(frag_in.pos.xy, 0)).x;
+	float2 cbcr = image1.Load(int3(frag_in.uv, 0)).xy;
+	float3 yuv = float3(y, cbcr);
+	float3 pq = YUV_to_RGB(yuv);
+	float3 hdr2020 = st2084_to_linear_eetf(pq, hdr_lw, hdr_lmax) * maximum_over_sdr_white_nits;
+	float3 rgb = rec2020_to_rec709(hdr2020);
+	return float4(rgb, 1.);
+}
+
+float4 PSNV12_HLG_Reverse(VertTexPos frag_in) : TARGET
+{
+	float y = image.Load(int3(frag_in.pos.xy, 0)).x;
+	float2 cbcr = image1.Load(int3(frag_in.uv, 0)).xy;
+	float3 yuv = float3(y, cbcr);
+	float3 hlg = YUV_to_RGB(yuv);
+	float3 hdr2020 = hlg_to_linear(hlg, hlg_exponent) * maximum_over_sdr_white_nits;
+	float3 rgb = rec2020_to_rec709(hdr2020);
+	return float4(rgb, 1.);
+}
+
 float4 PSI010_SRGB_Reverse(VertTexPos frag_in) : TARGET
 {
 	float ratio = 65535. / 1023.;
@@ -952,6 +1002,24 @@ technique YUY2_Reverse
 	}
 }
 
+technique YUY2_PQ_Reverse
+{
+	pass
+	{
+		vertex_shader = VSTexPosHalf_Reverse(id);
+		pixel_shader  = PSYUY2_PQ_Reverse(frag_in);
+	}
+}
+
+technique YUY2_HLG_Reverse
+{
+	pass
+	{
+		vertex_shader = VSTexPosHalf_Reverse(id);
+		pixel_shader  = PSYUY2_HLG_Reverse(frag_in);
+	}
+}
+
 technique YVYU_Reverse
 {
 	pass
@@ -1078,6 +1146,24 @@ technique NV12_Reverse
 	}
 }
 
+technique NV12_PQ_Reverse
+{
+	pass
+	{
+		vertex_shader = VSTexPosHalfHalf_Reverse(id);
+		pixel_shader  = PSNV12_PQ_Reverse(frag_in);
+	}
+}
+
+technique NV12_HLG_Reverse
+{
+	pass
+	{
+		vertex_shader = VSTexPosHalfHalf_Reverse(id);
+		pixel_shader  = PSNV12_HLG_Reverse(frag_in);
+	}
+}
+
 technique I010_SRGB_Reverse
 {
 	pass

+ 16 - 2
libobs/obs-source.c

@@ -2078,7 +2078,14 @@ static const char *select_conversion_technique(enum video_format format,
 		return "UYVY_Reverse";
 
 	case VIDEO_FORMAT_YUY2:
-		return "YUY2_Reverse";
+		switch (trc) {
+		case VIDEO_TRC_PQ:
+			return "YUY2_PQ_Reverse";
+		case VIDEO_TRC_HLG:
+			return "YUY2_HLG_Reverse";
+		default:
+			return "YUY2_Reverse";
+		}
 
 	case VIDEO_FORMAT_YVYU:
 		return "YVYU_Reverse";
@@ -2094,7 +2101,14 @@ static const char *select_conversion_technique(enum video_format format,
 		}
 
 	case VIDEO_FORMAT_NV12:
-		return "NV12_Reverse";
+		switch (trc) {
+		case VIDEO_TRC_PQ:
+			return "NV12_PQ_Reverse";
+		case VIDEO_TRC_HLG:
+			return "NV12_HLG_Reverse";
+		default:
+			return "NV12_Reverse";
+		}
 
 	case VIDEO_FORMAT_I444:
 		return "I444_Reverse";