Add limited range rendering for rendering YUV non-full range sources

This commit is contained in:
Palana 2014-04-24 00:24:51 +02:00
parent 9f43e6c257
commit 065379bffa
4 changed files with 47 additions and 8 deletions

View file

@ -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));
}

View file

@ -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;

View file

@ -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:

View file

@ -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;
};