mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-19 20:32:15 +02:00
libobs: Add support for reading I420 PQ
Not normally a valid combination, but Xbox writes 8-bit HDR videos.
This commit is contained in:
parent
ed835810b4
commit
2a0d8d1c9c
@ -477,6 +477,19 @@ float3 PSPlanar420_Reverse(VertTexPos frag_in) : TARGET
|
||||
return rgb;
|
||||
}
|
||||
|
||||
float4 PSPlanar420_PQ_Reverse(VertTexPos frag_in) : TARGET
|
||||
{
|
||||
float y = image.Load(int3(frag_in.pos.xy, 0)).x;
|
||||
int3 xy0_chroma = int3(frag_in.uv, 0);
|
||||
float cb = image1.Load(xy0_chroma).x;
|
||||
float cr = image2.Load(xy0_chroma).x;
|
||||
float3 yuv = float3(y, cb, cr);
|
||||
float3 pq = YUV_to_RGB(yuv);
|
||||
float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
|
||||
float3 rgb = rec2020_to_rec709(hdr2020);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float4 PSPlanar420A_Reverse(VertTexPos frag_in) : TARGET
|
||||
{
|
||||
int3 xy0_luma = int3(frag_in.pos.xy, 0);
|
||||
@ -511,7 +524,7 @@ float4 PSPlanar422_10LE_Reverse(FragPosWide frag_in) : TARGET
|
||||
yuv *= 65535. / 1023.;
|
||||
float3 rgb = YUV_to_RGB(yuv);
|
||||
rgb = srgb_nonlinear_to_linear(rgb);
|
||||
return float4(rgb, 1.0);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float4 PSPlanar422A_Reverse(FragPosWide frag_in) : TARGET
|
||||
@ -548,7 +561,7 @@ float4 PSPlanar444_12LE_Reverse(FragPos frag_in) : TARGET
|
||||
yuv *= 65535. / 4095.;
|
||||
float3 rgb = YUV_to_RGB(yuv);
|
||||
rgb = srgb_nonlinear_to_linear(rgb);
|
||||
return float4(rgb, 1.0);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float4 PSPlanar444A_Reverse(FragPos frag_in) : TARGET
|
||||
@ -603,7 +616,7 @@ float4 PSI010_SRGB_Reverse(VertTexPos frag_in) : TARGET
|
||||
float3 yuv = float3(y, cb, cr);
|
||||
float3 rgb = YUV_to_RGB(yuv);
|
||||
rgb = srgb_nonlinear_to_linear(rgb);
|
||||
return float4(rgb, 1.0);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float4 PSI010_PQ_2020_709_Reverse(VertTexPos frag_in) : TARGET
|
||||
@ -617,7 +630,7 @@ float4 PSI010_PQ_2020_709_Reverse(VertTexPos frag_in) : TARGET
|
||||
float3 pq = YUV_to_RGB(yuv);
|
||||
float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
|
||||
float3 rgb = rec2020_to_rec709(hdr2020);
|
||||
return float4(rgb, 1.0);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float4 PSI010_HLG_2020_709_Reverse(VertTexPos frag_in) : TARGET
|
||||
@ -631,7 +644,7 @@ float4 PSI010_HLG_2020_709_Reverse(VertTexPos frag_in) : TARGET
|
||||
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.0);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float4 PSP010_SRGB_Reverse(VertTexPos frag_in) : TARGET
|
||||
@ -641,7 +654,7 @@ float4 PSP010_SRGB_Reverse(VertTexPos frag_in) : TARGET
|
||||
float3 yuv = float3(y, cbcr);
|
||||
float3 rgb = YUV_to_RGB(yuv);
|
||||
rgb = srgb_nonlinear_to_linear(rgb);
|
||||
return float4(rgb, 1.0);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float4 PSP010_PQ_2020_709_Reverse(VertTexPos frag_in) : TARGET
|
||||
@ -652,7 +665,7 @@ float4 PSP010_PQ_2020_709_Reverse(VertTexPos frag_in) : TARGET
|
||||
float3 pq = YUV_to_RGB(yuv);
|
||||
float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
|
||||
float3 rgb = rec2020_to_rec709(hdr2020);
|
||||
return float4(rgb, 1.0);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float4 PSP010_HLG_2020_709_Reverse(VertTexPos frag_in) : TARGET
|
||||
@ -663,7 +676,7 @@ float4 PSP010_HLG_2020_709_Reverse(VertTexPos frag_in) : TARGET
|
||||
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.0);
|
||||
return float4(rgb, 1.);
|
||||
}
|
||||
|
||||
float3 PSY800_Limited(FragPos frag_in) : TARGET
|
||||
@ -943,6 +956,15 @@ technique I420_Reverse
|
||||
}
|
||||
}
|
||||
|
||||
technique I420_PQ_Reverse
|
||||
{
|
||||
pass
|
||||
{
|
||||
vertex_shader = VSTexPosHalfHalf_Reverse(id);
|
||||
pixel_shader = PSPlanar420_PQ_Reverse(frag_in);
|
||||
}
|
||||
}
|
||||
|
||||
technique I40A_Reverse
|
||||
{
|
||||
pass
|
||||
|
@ -879,25 +879,31 @@ static inline bool frame_out_of_bounds(const obs_source_t *source, uint64_t ts)
|
||||
}
|
||||
|
||||
static inline enum gs_color_format
|
||||
convert_video_format(enum video_format format)
|
||||
convert_video_format(enum video_format format, enum video_trc trc)
|
||||
{
|
||||
switch (format) {
|
||||
case VIDEO_FORMAT_RGBA:
|
||||
return GS_RGBA;
|
||||
case VIDEO_FORMAT_BGRA:
|
||||
case VIDEO_FORMAT_I40A:
|
||||
case VIDEO_FORMAT_I42A:
|
||||
case VIDEO_FORMAT_YUVA:
|
||||
case VIDEO_FORMAT_AYUV:
|
||||
return GS_BGRA;
|
||||
case VIDEO_FORMAT_I010:
|
||||
case VIDEO_FORMAT_P010:
|
||||
case VIDEO_FORMAT_I210:
|
||||
case VIDEO_FORMAT_I412:
|
||||
case VIDEO_FORMAT_YA2L:
|
||||
switch (trc) {
|
||||
case VIDEO_TRC_PQ:
|
||||
case VIDEO_TRC_HLG:
|
||||
return GS_RGBA16F;
|
||||
default:
|
||||
return GS_BGRX;
|
||||
switch (format) {
|
||||
case VIDEO_FORMAT_RGBA:
|
||||
return GS_RGBA;
|
||||
case VIDEO_FORMAT_BGRA:
|
||||
case VIDEO_FORMAT_I40A:
|
||||
case VIDEO_FORMAT_I42A:
|
||||
case VIDEO_FORMAT_YUVA:
|
||||
case VIDEO_FORMAT_AYUV:
|
||||
return GS_BGRA;
|
||||
case VIDEO_FORMAT_I010:
|
||||
case VIDEO_FORMAT_P010:
|
||||
case VIDEO_FORMAT_I210:
|
||||
case VIDEO_FORMAT_I412:
|
||||
case VIDEO_FORMAT_YA2L:
|
||||
return GS_RGBA16F;
|
||||
default:
|
||||
return GS_BGRX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -905,7 +911,7 @@ static inline enum gs_color_space convert_video_space(enum video_format format,
|
||||
enum video_trc trc)
|
||||
{
|
||||
enum gs_color_space space = GS_CS_SRGB;
|
||||
if (convert_video_format(format) == GS_RGBA16F) {
|
||||
if (convert_video_format(format, trc) == GS_RGBA16F) {
|
||||
space = (trc == VIDEO_TRC_SRGB) ? GS_CS_SRGB_16F
|
||||
: GS_CS_709_EXTENDED;
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ void deinterlace_process_last_frame(obs_source_t *s, uint64_t sys_time)
|
||||
void set_deinterlace_texture_size(obs_source_t *source)
|
||||
{
|
||||
const enum gs_color_format format =
|
||||
convert_video_format(source->async_format);
|
||||
convert_video_format(source->async_format, source->async_trc);
|
||||
|
||||
if (source->async_gpu_conversion) {
|
||||
source->async_prev_texrender =
|
||||
|
@ -1546,6 +1546,7 @@ enum convert_type {
|
||||
CONVERT_NONE,
|
||||
CONVERT_NV12,
|
||||
CONVERT_420,
|
||||
CONVERT_420_PQ,
|
||||
CONVERT_420_A,
|
||||
CONVERT_422,
|
||||
CONVERT_422P10LE,
|
||||
@ -1572,7 +1573,7 @@ static inline enum convert_type get_convert_type(enum video_format format,
|
||||
{
|
||||
switch (format) {
|
||||
case VIDEO_FORMAT_I420:
|
||||
return CONVERT_420;
|
||||
return (trc == VIDEO_TRC_PQ) ? CONVERT_420_PQ : CONVERT_420;
|
||||
case VIDEO_FORMAT_NV12:
|
||||
return CONVERT_NV12;
|
||||
case VIDEO_FORMAT_I444:
|
||||
@ -1874,7 +1875,8 @@ static inline bool set_rgb_limited_sizes(struct obs_source *source,
|
||||
{
|
||||
source->async_convert_width[0] = frame->width;
|
||||
source->async_convert_height[0] = frame->height;
|
||||
source->async_texture_formats[0] = convert_video_format(frame->format);
|
||||
source->async_texture_formats[0] =
|
||||
convert_video_format(frame->format, frame->trc);
|
||||
source->async_channel_count = 1;
|
||||
return true;
|
||||
}
|
||||
@ -1935,6 +1937,7 @@ static inline bool init_gpu_conversion(struct obs_source *source,
|
||||
return set_packed422_sizes(source, frame);
|
||||
|
||||
case CONVERT_420:
|
||||
case CONVERT_420_PQ:
|
||||
return set_planar420_sizes(source, frame);
|
||||
|
||||
case CONVERT_422:
|
||||
@ -2026,7 +2029,8 @@ bool set_async_texture_size(struct obs_source *source,
|
||||
source->async_texrender = NULL;
|
||||
source->async_prev_texrender = NULL;
|
||||
|
||||
const enum gs_color_format format = convert_video_format(frame->format);
|
||||
const enum gs_color_format format =
|
||||
convert_video_format(frame->format, frame->trc);
|
||||
const bool async_gpu_conversion = (cur != CONVERT_NONE) &&
|
||||
init_gpu_conversion(source, frame);
|
||||
source->async_gpu_conversion = async_gpu_conversion;
|
||||
@ -2064,6 +2068,7 @@ static void upload_raw_frame(gs_texture_t *tex[MAX_AV_PLANES],
|
||||
case CONVERT_RGB_LIMITED:
|
||||
case CONVERT_BGR3:
|
||||
case CONVERT_420:
|
||||
case CONVERT_420_PQ:
|
||||
case CONVERT_422:
|
||||
case CONVERT_422P10LE:
|
||||
case CONVERT_NV12:
|
||||
@ -2107,7 +2112,8 @@ static const char *select_conversion_technique(enum video_format format,
|
||||
return "YVYU_Reverse";
|
||||
|
||||
case VIDEO_FORMAT_I420:
|
||||
return "I420_Reverse";
|
||||
return (trc == VIDEO_TRC_PQ) ? "I420_PQ_Reverse"
|
||||
: "I420_Reverse";
|
||||
|
||||
case VIDEO_FORMAT_NV12:
|
||||
return "NV12_Reverse";
|
||||
|
Loading…
Reference in New Issue
Block a user