Add limited range rendering for rendering YUV non-full range sources
This commit is contained in:
parent
9f43e6c257
commit
065379bffa
@ -1,5 +1,7 @@
|
||||
uniform float4x4 ViewProj;
|
||||
uniform float4x4 color_matrix;
|
||||
uniform float3 color_range_min;
|
||||
uniform float3 color_range_max;
|
||||
uniform texture2d image;
|
||||
|
||||
sampler_state def_sampler {
|
||||
@ -29,6 +31,7 @@ float4 PSDrawBare(VertInOut vert_in) : TARGET
|
||||
float4 PSDrawMatrix(VertInOut vert_in) : TARGET
|
||||
{
|
||||
float4 yuv = image.Sample(def_sampler, vert_in.uv);
|
||||
yuv.xyz = clamp(yuv.xyz, color_range_min, color_range_max);
|
||||
return saturate(mul(float4(yuv.xyz, 1.0), color_matrix));
|
||||
}
|
||||
|
||||
|
@ -269,6 +269,9 @@ struct obs_source {
|
||||
texture_t async_texture;
|
||||
enum video_format async_format;
|
||||
float async_color_matrix[16];
|
||||
bool async_full_range;
|
||||
float async_color_range_min[3];
|
||||
float async_color_range_max[3];
|
||||
bool async_flip;
|
||||
DARRAY(struct source_frame*) video_frames;
|
||||
pthread_mutex_t video_mutex;
|
||||
|
@ -625,10 +625,15 @@ static bool update_async_texture(struct obs_source *source,
|
||||
void *ptr;
|
||||
uint32_t linesize;
|
||||
|
||||
source->async_format = frame->format;
|
||||
source->async_flip = frame->flip;
|
||||
source->async_format = frame->format;
|
||||
source->async_flip = frame->flip;
|
||||
source->async_full_range = frame->full_range;
|
||||
memcpy(source->async_color_matrix, frame->color_matrix,
|
||||
sizeof(frame->color_matrix));
|
||||
memcpy(source->async_color_range_min, frame->color_range_min,
|
||||
sizeof frame->color_range_min);
|
||||
memcpy(source->async_color_range_max, frame->color_range_max,
|
||||
sizeof frame->color_range_max);
|
||||
|
||||
if (type == CONVERT_NONE) {
|
||||
texture_setimage(tex, frame->data[0], frame->linesize[0],
|
||||
@ -661,13 +666,29 @@ static bool update_async_texture(struct obs_source *source,
|
||||
return true;
|
||||
}
|
||||
|
||||
static float const full_range_min[] = {0., 0., 0.};
|
||||
static float const full_range_max[] = {1., 1., 1.};
|
||||
|
||||
static inline void obs_source_draw_texture(struct obs_source *source,
|
||||
effect_t effect, float *color_matrix)
|
||||
effect_t effect, float *color_matrix,
|
||||
float const *color_range_min, float const *color_range_max)
|
||||
{
|
||||
texture_t tex = source->async_texture;
|
||||
eparam_t param;
|
||||
|
||||
if (color_matrix) {
|
||||
size_t const size = sizeof(float) * 3;
|
||||
|
||||
if (!color_range_min)
|
||||
color_range_min = full_range_min;
|
||||
if (!color_range_max)
|
||||
color_range_max = full_range_max;
|
||||
|
||||
param = effect_getparambyname(effect, "color_range_min");
|
||||
effect_setval(effect, param, color_range_min, size);
|
||||
param = effect_getparambyname(effect, "color_range_max");
|
||||
effect_setval(effect, param, color_range_max, size);
|
||||
|
||||
param = effect_getparambyname(effect, "color_matrix");
|
||||
effect_setval(effect, param, color_matrix, sizeof(float) * 16);
|
||||
}
|
||||
@ -680,10 +701,11 @@ static inline void obs_source_draw_texture(struct obs_source *source,
|
||||
|
||||
static void obs_source_draw_async_texture(struct obs_source *source)
|
||||
{
|
||||
effect_t effect = gs_geteffect();
|
||||
bool yuv = format_is_yuv(source->async_format);
|
||||
const char *type = yuv ? "DrawMatrix" : "Draw";
|
||||
bool def_draw = (!effect);
|
||||
effect_t effect = gs_geteffect();
|
||||
bool yuv = format_is_yuv(source->async_format);
|
||||
bool limited_range = yuv && !source->async_full_range;
|
||||
const char *type = yuv ? "DrawMatrix" : "Draw";
|
||||
bool def_draw = (!effect);
|
||||
technique_t tech;
|
||||
|
||||
if (def_draw) {
|
||||
@ -694,7 +716,9 @@ static void obs_source_draw_async_texture(struct obs_source *source)
|
||||
}
|
||||
|
||||
obs_source_draw_texture(source, effect,
|
||||
yuv ? source->async_color_matrix : NULL);
|
||||
yuv ? source->async_color_matrix : NULL,
|
||||
limited_range ? source->async_color_range_min : NULL,
|
||||
limited_range ? source->async_color_range_max : NULL);
|
||||
|
||||
if (def_draw) {
|
||||
technique_endpass(tech);
|
||||
@ -947,8 +971,14 @@ static void copy_frame_data(struct source_frame *dst,
|
||||
const struct source_frame *src)
|
||||
{
|
||||
dst->flip = src->flip;
|
||||
dst->full_range = src->full_range;
|
||||
dst->timestamp = src->timestamp;
|
||||
memcpy(dst->color_matrix, src->color_matrix, sizeof(float) * 16);
|
||||
if (!dst->full_range) {
|
||||
size_t const size = sizeof(float) * 3;
|
||||
memcpy(dst->color_range_min, src->color_range_min, size);
|
||||
memcpy(dst->color_range_max, src->color_range_max, size);
|
||||
}
|
||||
|
||||
switch (dst->format) {
|
||||
case VIDEO_FORMAT_I420:
|
||||
|
@ -166,6 +166,9 @@ struct source_frame {
|
||||
|
||||
enum video_format format;
|
||||
float color_matrix[16];
|
||||
bool full_range;
|
||||
float color_range_min[3];
|
||||
float color_range_max[3];
|
||||
bool flip;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user