mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 04:42:18 +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;
|
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
|
float4 PSPlanar420A_Reverse(VertTexPos frag_in) : TARGET
|
||||||
{
|
{
|
||||||
int3 xy0_luma = int3(frag_in.pos.xy, 0);
|
int3 xy0_luma = int3(frag_in.pos.xy, 0);
|
||||||
@ -511,7 +524,7 @@ float4 PSPlanar422_10LE_Reverse(FragPosWide frag_in) : TARGET
|
|||||||
yuv *= 65535. / 1023.;
|
yuv *= 65535. / 1023.;
|
||||||
float3 rgb = YUV_to_RGB(yuv);
|
float3 rgb = YUV_to_RGB(yuv);
|
||||||
rgb = srgb_nonlinear_to_linear(rgb);
|
rgb = srgb_nonlinear_to_linear(rgb);
|
||||||
return float4(rgb, 1.0);
|
return float4(rgb, 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 PSPlanar422A_Reverse(FragPosWide frag_in) : TARGET
|
float4 PSPlanar422A_Reverse(FragPosWide frag_in) : TARGET
|
||||||
@ -548,7 +561,7 @@ float4 PSPlanar444_12LE_Reverse(FragPos frag_in) : TARGET
|
|||||||
yuv *= 65535. / 4095.;
|
yuv *= 65535. / 4095.;
|
||||||
float3 rgb = YUV_to_RGB(yuv);
|
float3 rgb = YUV_to_RGB(yuv);
|
||||||
rgb = srgb_nonlinear_to_linear(rgb);
|
rgb = srgb_nonlinear_to_linear(rgb);
|
||||||
return float4(rgb, 1.0);
|
return float4(rgb, 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 PSPlanar444A_Reverse(FragPos frag_in) : TARGET
|
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 yuv = float3(y, cb, cr);
|
||||||
float3 rgb = YUV_to_RGB(yuv);
|
float3 rgb = YUV_to_RGB(yuv);
|
||||||
rgb = srgb_nonlinear_to_linear(rgb);
|
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
|
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 pq = YUV_to_RGB(yuv);
|
||||||
float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
|
float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
|
||||||
float3 rgb = rec2020_to_rec709(hdr2020);
|
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
|
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 hlg = YUV_to_RGB(yuv);
|
||||||
float3 hdr2020 = hlg_to_linear(hlg, hlg_exponent) * maximum_over_sdr_white_nits;
|
float3 hdr2020 = hlg_to_linear(hlg, hlg_exponent) * maximum_over_sdr_white_nits;
|
||||||
float3 rgb = rec2020_to_rec709(hdr2020);
|
float3 rgb = rec2020_to_rec709(hdr2020);
|
||||||
return float4(rgb, 1.0);
|
return float4(rgb, 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
float4 PSP010_SRGB_Reverse(VertTexPos frag_in) : TARGET
|
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 yuv = float3(y, cbcr);
|
||||||
float3 rgb = YUV_to_RGB(yuv);
|
float3 rgb = YUV_to_RGB(yuv);
|
||||||
rgb = srgb_nonlinear_to_linear(rgb);
|
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
|
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 pq = YUV_to_RGB(yuv);
|
||||||
float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
|
float3 hdr2020 = st2084_to_linear(pq) * maximum_over_sdr_white_nits;
|
||||||
float3 rgb = rec2020_to_rec709(hdr2020);
|
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
|
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 hlg = YUV_to_RGB(yuv);
|
||||||
float3 hdr2020 = hlg_to_linear(hlg, hlg_exponent) * maximum_over_sdr_white_nits;
|
float3 hdr2020 = hlg_to_linear(hlg, hlg_exponent) * maximum_over_sdr_white_nits;
|
||||||
float3 rgb = rec2020_to_rec709(hdr2020);
|
float3 rgb = rec2020_to_rec709(hdr2020);
|
||||||
return float4(rgb, 1.0);
|
return float4(rgb, 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
float3 PSY800_Limited(FragPos frag_in) : TARGET
|
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
|
technique I40A_Reverse
|
||||||
{
|
{
|
||||||
pass
|
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
|
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) {
|
switch (trc) {
|
||||||
case VIDEO_FORMAT_RGBA:
|
case VIDEO_TRC_PQ:
|
||||||
return GS_RGBA;
|
case VIDEO_TRC_HLG:
|
||||||
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;
|
return GS_RGBA16F;
|
||||||
default:
|
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 video_trc trc)
|
||||||
{
|
{
|
||||||
enum gs_color_space space = GS_CS_SRGB;
|
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
|
space = (trc == VIDEO_TRC_SRGB) ? GS_CS_SRGB_16F
|
||||||
: GS_CS_709_EXTENDED;
|
: 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)
|
void set_deinterlace_texture_size(obs_source_t *source)
|
||||||
{
|
{
|
||||||
const enum gs_color_format format =
|
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) {
|
if (source->async_gpu_conversion) {
|
||||||
source->async_prev_texrender =
|
source->async_prev_texrender =
|
||||||
|
@ -1546,6 +1546,7 @@ enum convert_type {
|
|||||||
CONVERT_NONE,
|
CONVERT_NONE,
|
||||||
CONVERT_NV12,
|
CONVERT_NV12,
|
||||||
CONVERT_420,
|
CONVERT_420,
|
||||||
|
CONVERT_420_PQ,
|
||||||
CONVERT_420_A,
|
CONVERT_420_A,
|
||||||
CONVERT_422,
|
CONVERT_422,
|
||||||
CONVERT_422P10LE,
|
CONVERT_422P10LE,
|
||||||
@ -1572,7 +1573,7 @@ static inline enum convert_type get_convert_type(enum video_format format,
|
|||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case VIDEO_FORMAT_I420:
|
case VIDEO_FORMAT_I420:
|
||||||
return CONVERT_420;
|
return (trc == VIDEO_TRC_PQ) ? CONVERT_420_PQ : CONVERT_420;
|
||||||
case VIDEO_FORMAT_NV12:
|
case VIDEO_FORMAT_NV12:
|
||||||
return CONVERT_NV12;
|
return CONVERT_NV12;
|
||||||
case VIDEO_FORMAT_I444:
|
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_width[0] = frame->width;
|
||||||
source->async_convert_height[0] = frame->height;
|
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;
|
source->async_channel_count = 1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1935,6 +1937,7 @@ static inline bool init_gpu_conversion(struct obs_source *source,
|
|||||||
return set_packed422_sizes(source, frame);
|
return set_packed422_sizes(source, frame);
|
||||||
|
|
||||||
case CONVERT_420:
|
case CONVERT_420:
|
||||||
|
case CONVERT_420_PQ:
|
||||||
return set_planar420_sizes(source, frame);
|
return set_planar420_sizes(source, frame);
|
||||||
|
|
||||||
case CONVERT_422:
|
case CONVERT_422:
|
||||||
@ -2026,7 +2029,8 @@ bool set_async_texture_size(struct obs_source *source,
|
|||||||
source->async_texrender = NULL;
|
source->async_texrender = NULL;
|
||||||
source->async_prev_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) &&
|
const bool async_gpu_conversion = (cur != CONVERT_NONE) &&
|
||||||
init_gpu_conversion(source, frame);
|
init_gpu_conversion(source, frame);
|
||||||
source->async_gpu_conversion = async_gpu_conversion;
|
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_RGB_LIMITED:
|
||||||
case CONVERT_BGR3:
|
case CONVERT_BGR3:
|
||||||
case CONVERT_420:
|
case CONVERT_420:
|
||||||
|
case CONVERT_420_PQ:
|
||||||
case CONVERT_422:
|
case CONVERT_422:
|
||||||
case CONVERT_422P10LE:
|
case CONVERT_422P10LE:
|
||||||
case CONVERT_NV12:
|
case CONVERT_NV12:
|
||||||
@ -2107,7 +2112,8 @@ static const char *select_conversion_technique(enum video_format format,
|
|||||||
return "YVYU_Reverse";
|
return "YVYU_Reverse";
|
||||||
|
|
||||||
case VIDEO_FORMAT_I420:
|
case VIDEO_FORMAT_I420:
|
||||||
return "I420_Reverse";
|
return (trc == VIDEO_TRC_PQ) ? "I420_PQ_Reverse"
|
||||||
|
: "I420_Reverse";
|
||||||
|
|
||||||
case VIDEO_FORMAT_NV12:
|
case VIDEO_FORMAT_NV12:
|
||||||
return "NV12_Reverse";
|
return "NV12_Reverse";
|
||||||
|
Loading…
Reference in New Issue
Block a user