obs-filters: Add HDR bypass for various filters
Not sure how to implement controls for HDR, so skip unless SDR for now.
This commit is contained in:
parent
8b9fb03d06
commit
e1b84f6bd6
@ -5,6 +5,7 @@
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define SETTING_SDR_ONLY_INFO "sdr_only_info"
|
||||
#define SETTING_OPACITY "opacity"
|
||||
#define SETTING_CONTRAST "contrast"
|
||||
#define SETTING_BRIGHTNESS "brightness"
|
||||
@ -15,6 +16,7 @@
|
||||
#define SETTING_SMOOTHNESS "smoothness"
|
||||
#define SETTING_SPILL "spill"
|
||||
|
||||
#define TEXT_SDR_ONLY_INFO obs_module_text("SdrOnlyInfo")
|
||||
#define TEXT_OPACITY obs_module_text("Opacity")
|
||||
#define TEXT_CONTRAST obs_module_text("Contrast")
|
||||
#define TEXT_BRIGHTNESS obs_module_text("Brightness")
|
||||
@ -365,36 +367,60 @@ static void chroma_key_render_v1(void *data, gs_effect_t *effect)
|
||||
|
||||
static void chroma_key_render_v2(void *data, gs_effect_t *effect)
|
||||
{
|
||||
UNUSED_PARAMETER(effect);
|
||||
|
||||
struct chroma_key_filter_data_v2 *filter = data;
|
||||
obs_source_t *target = obs_filter_get_target(filter->context);
|
||||
uint32_t width = obs_source_get_base_width(target);
|
||||
uint32_t height = obs_source_get_base_height(target);
|
||||
struct vec2 pixel_size;
|
||||
|
||||
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
|
||||
OBS_ALLOW_DIRECT_RENDERING))
|
||||
return;
|
||||
const enum gs_color_space preferred_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
vec2_set(&pixel_size, 1.0f / (float)width, 1.0f / (float)height);
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(preferred_spaces), preferred_spaces);
|
||||
if (source_space == GS_CS_709_EXTENDED) {
|
||||
obs_source_skip_video_filter(filter->context);
|
||||
} else {
|
||||
const enum gs_color_format format =
|
||||
gs_get_format_from_space(source_space);
|
||||
if (obs_source_process_filter_begin_with_color_space(
|
||||
filter->context, format, source_space,
|
||||
OBS_ALLOW_DIRECT_RENDERING)) {
|
||||
vec2_set(&pixel_size, 1.0f / (float)width,
|
||||
1.0f / (float)height);
|
||||
|
||||
gs_effect_set_float(filter->opacity_param, filter->opacity);
|
||||
gs_effect_set_float(filter->contrast_param, filter->contrast);
|
||||
gs_effect_set_float(filter->brightness_param, filter->brightness);
|
||||
gs_effect_set_float(filter->gamma_param, filter->gamma);
|
||||
gs_effect_set_vec2(filter->chroma_param, &filter->chroma);
|
||||
gs_effect_set_vec2(filter->pixel_size_param, &pixel_size);
|
||||
gs_effect_set_float(filter->similarity_param, filter->similarity);
|
||||
gs_effect_set_float(filter->smoothness_param, filter->smoothness);
|
||||
gs_effect_set_float(filter->spill_param, filter->spill);
|
||||
gs_effect_set_float(filter->opacity_param,
|
||||
filter->opacity);
|
||||
gs_effect_set_float(filter->contrast_param,
|
||||
filter->contrast);
|
||||
gs_effect_set_float(filter->brightness_param,
|
||||
filter->brightness);
|
||||
gs_effect_set_float(filter->gamma_param, filter->gamma);
|
||||
gs_effect_set_vec2(filter->chroma_param,
|
||||
&filter->chroma);
|
||||
gs_effect_set_vec2(filter->pixel_size_param,
|
||||
&pixel_size);
|
||||
gs_effect_set_float(filter->similarity_param,
|
||||
filter->similarity);
|
||||
gs_effect_set_float(filter->smoothness_param,
|
||||
filter->smoothness);
|
||||
gs_effect_set_float(filter->spill_param, filter->spill);
|
||||
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
|
||||
obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
|
||||
obs_source_process_filter_end(filter->context,
|
||||
filter->effect, 0, 0);
|
||||
|
||||
gs_blend_state_pop();
|
||||
|
||||
UNUSED_PARAMETER(effect);
|
||||
gs_blend_state_pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool key_type_changed(obs_properties_t *props, obs_property_t *p,
|
||||
@ -450,6 +476,9 @@ static obs_properties_t *chroma_key_properties_v2(void *data)
|
||||
{
|
||||
obs_properties_t *props = obs_properties_create();
|
||||
|
||||
obs_properties_add_text(props, SETTING_SDR_ONLY_INFO,
|
||||
TEXT_SDR_ONLY_INFO, OBS_TEXT_INFO);
|
||||
|
||||
obs_property_t *p = obs_properties_add_list(props, SETTING_COLOR_TYPE,
|
||||
TEXT_COLOR_TYPE,
|
||||
OBS_COMBO_TYPE_LIST,
|
||||
@ -508,6 +537,24 @@ static void chroma_key_defaults_v2(obs_data_t *settings)
|
||||
obs_data_set_default_int(settings, SETTING_SPILL, 100);
|
||||
}
|
||||
|
||||
static enum gs_color_space
|
||||
chroma_key_get_color_space(void *data, size_t count,
|
||||
const enum gs_color_space *preferred_spaces)
|
||||
{
|
||||
const enum gs_color_space potential_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
struct chroma_key_filter_data_v2 *const filter = data;
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(potential_spaces), potential_spaces);
|
||||
|
||||
return source_space;
|
||||
}
|
||||
|
||||
struct obs_source_info chroma_key_filter = {
|
||||
.id = "chroma_key_filter",
|
||||
.type = OBS_SOURCE_TYPE_FILTER,
|
||||
@ -533,4 +580,5 @@ struct obs_source_info chroma_key_filter_v2 = {
|
||||
.update = chroma_key_update_v2,
|
||||
.get_properties = chroma_key_properties_v2,
|
||||
.get_defaults = chroma_key_defaults_v2,
|
||||
.video_get_color_space = chroma_key_get_color_space,
|
||||
};
|
||||
|
@ -6,10 +6,12 @@
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define SETTING_SDR_ONLY_INFO "sdr_only_info"
|
||||
#define SETTING_IMAGE_PATH "image_path"
|
||||
#define SETTING_CLUT_AMOUNT "clut_amount"
|
||||
#define SETTING_PASSTHROUGH_ALPHA "passthrough_alpha"
|
||||
|
||||
#define TEXT_SDR_ONLY_INFO obs_module_text("SdrOnlyInfo")
|
||||
#define TEXT_IMAGE_PATH obs_module_text("Path")
|
||||
#define TEXT_AMOUNT obs_module_text("Amount")
|
||||
#define TEXT_PASSTHROUGH_ALPHA obs_module_text("PassthroughAlpha")
|
||||
@ -403,6 +405,8 @@ static obs_properties_t *color_grade_filter_properties(void *data)
|
||||
if (slash)
|
||||
dstr_resize(&path, slash - path.array + 1);
|
||||
|
||||
obs_properties_add_text(props, SETTING_SDR_ONLY_INFO,
|
||||
TEXT_SDR_ONLY_INFO, OBS_TEXT_INFO);
|
||||
obs_properties_add_path(props, SETTING_IMAGE_PATH, TEXT_IMAGE_PATH,
|
||||
OBS_PATH_FILE, filter_str.array, path.array);
|
||||
obs_properties_add_float_slider(props, SETTING_CLUT_AMOUNT, TEXT_AMOUNT,
|
||||
@ -444,48 +448,85 @@ static void color_grade_filter_destroy(void *data)
|
||||
|
||||
static void color_grade_filter_render(void *data, gs_effect_t *effect)
|
||||
{
|
||||
UNUSED_PARAMETER(effect);
|
||||
|
||||
struct lut_filter_data *filter = data;
|
||||
obs_source_t *target = obs_filter_get_target(filter->context);
|
||||
gs_eparam_t *param;
|
||||
|
||||
if (!target || !filter->target || !filter->effect) {
|
||||
obs_source_skip_video_filter(filter->context);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
|
||||
OBS_ALLOW_DIRECT_RENDERING)) {
|
||||
return;
|
||||
const enum gs_color_space preferred_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(preferred_spaces), preferred_spaces);
|
||||
if (source_space == GS_CS_709_EXTENDED) {
|
||||
obs_source_skip_video_filter(filter->context);
|
||||
} else {
|
||||
const enum gs_color_format format =
|
||||
gs_get_format_from_space(source_space);
|
||||
if (obs_source_process_filter_begin_with_color_space(
|
||||
filter->context, format, source_space,
|
||||
OBS_ALLOW_DIRECT_RENDERING)) {
|
||||
gs_eparam_t *param = gs_effect_get_param_by_name(
|
||||
filter->effect, filter->clut_texture_name);
|
||||
gs_effect_set_texture_srgb(param, filter->target);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"clut_amount");
|
||||
gs_effect_set_float(param, filter->clut_amount);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"clut_scale");
|
||||
gs_effect_set_vec3(param, &filter->clut_scale);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"clut_offset");
|
||||
gs_effect_set_vec3(param, &filter->clut_offset);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"domain_min");
|
||||
gs_effect_set_vec3(param, &filter->domain_min);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"domain_max");
|
||||
gs_effect_set_vec3(param, &filter->domain_max);
|
||||
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
|
||||
obs_source_process_filter_tech_end(filter->context,
|
||||
filter->effect, 0, 0,
|
||||
filter->tech_name);
|
||||
|
||||
gs_blend_state_pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
filter->clut_texture_name);
|
||||
gs_effect_set_texture_srgb(param, filter->target);
|
||||
static enum gs_color_space
|
||||
color_grade_filter_get_color_space(void *data, size_t count,
|
||||
const enum gs_color_space *preferred_spaces)
|
||||
{
|
||||
const enum gs_color_space potential_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "clut_amount");
|
||||
gs_effect_set_float(param, filter->clut_amount);
|
||||
struct lut_filter_data *const filter = data;
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(potential_spaces), potential_spaces);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "clut_scale");
|
||||
gs_effect_set_vec3(param, &filter->clut_scale);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "clut_offset");
|
||||
gs_effect_set_vec3(param, &filter->clut_offset);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "domain_min");
|
||||
gs_effect_set_vec3(param, &filter->domain_min);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "domain_max");
|
||||
gs_effect_set_vec3(param, &filter->domain_max);
|
||||
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
|
||||
obs_source_process_filter_tech_end(filter->context, filter->effect, 0,
|
||||
0, filter->tech_name);
|
||||
|
||||
gs_blend_state_pop();
|
||||
|
||||
UNUSED_PARAMETER(effect);
|
||||
return source_space;
|
||||
}
|
||||
|
||||
struct obs_source_info color_grade_filter = {
|
||||
@ -499,4 +540,5 @@ struct obs_source_info color_grade_filter = {
|
||||
.get_defaults = color_grade_filter_defaults,
|
||||
.get_properties = color_grade_filter_properties,
|
||||
.video_render = color_grade_filter_render,
|
||||
.video_get_color_space = color_grade_filter_get_color_space,
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define SETTING_SDR_ONLY_INFO "sdr_only_info"
|
||||
#define SETTING_OPACITY "opacity"
|
||||
#define SETTING_CONTRAST "contrast"
|
||||
#define SETTING_BRIGHTNESS "brightness"
|
||||
@ -14,6 +15,7 @@
|
||||
#define SETTING_SIMILARITY "similarity"
|
||||
#define SETTING_SMOOTHNESS "smoothness"
|
||||
|
||||
#define TEXT_SDR_ONLY_INFO obs_module_text("SdrOnlyInfo")
|
||||
#define TEXT_OPACITY obs_module_text("Opacity")
|
||||
#define TEXT_CONTRAST obs_module_text("Contrast")
|
||||
#define TEXT_BRIGHTNESS obs_module_text("Brightness")
|
||||
@ -321,28 +323,50 @@ static void color_key_render_v1(void *data, gs_effect_t *effect)
|
||||
|
||||
static void color_key_render_v2(void *data, gs_effect_t *effect)
|
||||
{
|
||||
UNUSED_PARAMETER(effect);
|
||||
|
||||
struct color_key_filter_data_v2 *filter = data;
|
||||
|
||||
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
|
||||
OBS_ALLOW_DIRECT_RENDERING))
|
||||
return;
|
||||
const enum gs_color_space preferred_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
gs_effect_set_float(filter->opacity_param, filter->opacity);
|
||||
gs_effect_set_float(filter->contrast_param, filter->contrast);
|
||||
gs_effect_set_float(filter->brightness_param, filter->brightness);
|
||||
gs_effect_set_float(filter->gamma_param, filter->gamma);
|
||||
gs_effect_set_vec4(filter->key_color_param, &filter->key_color);
|
||||
gs_effect_set_float(filter->similarity_param, filter->similarity);
|
||||
gs_effect_set_float(filter->smoothness_param, filter->smoothness);
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(preferred_spaces), preferred_spaces);
|
||||
if (source_space == GS_CS_709_EXTENDED) {
|
||||
obs_source_skip_video_filter(filter->context);
|
||||
} else {
|
||||
const enum gs_color_format format =
|
||||
gs_get_format_from_space(source_space);
|
||||
if (obs_source_process_filter_begin_with_color_space(
|
||||
filter->context, format, source_space,
|
||||
OBS_ALLOW_DIRECT_RENDERING)) {
|
||||
gs_effect_set_float(filter->opacity_param,
|
||||
filter->opacity);
|
||||
gs_effect_set_float(filter->contrast_param,
|
||||
filter->contrast);
|
||||
gs_effect_set_float(filter->brightness_param,
|
||||
filter->brightness);
|
||||
gs_effect_set_float(filter->gamma_param, filter->gamma);
|
||||
gs_effect_set_vec4(filter->key_color_param,
|
||||
&filter->key_color);
|
||||
gs_effect_set_float(filter->similarity_param,
|
||||
filter->similarity);
|
||||
gs_effect_set_float(filter->smoothness_param,
|
||||
filter->smoothness);
|
||||
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
|
||||
obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
|
||||
obs_source_process_filter_end(filter->context,
|
||||
filter->effect, 0, 0);
|
||||
|
||||
gs_blend_state_pop();
|
||||
|
||||
UNUSED_PARAMETER(effect);
|
||||
gs_blend_state_pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool key_type_changed(obs_properties_t *props, obs_property_t *p,
|
||||
@ -398,6 +422,9 @@ static obs_properties_t *color_key_properties_v2(void *data)
|
||||
{
|
||||
obs_properties_t *props = obs_properties_create();
|
||||
|
||||
obs_properties_add_text(props, SETTING_SDR_ONLY_INFO,
|
||||
TEXT_SDR_ONLY_INFO, OBS_TEXT_INFO);
|
||||
|
||||
obs_property_t *p = obs_properties_add_list(props, SETTING_COLOR_TYPE,
|
||||
TEXT_COLOR_TYPE,
|
||||
OBS_COMBO_TYPE_LIST,
|
||||
@ -454,6 +481,24 @@ static void color_key_defaults_v2(obs_data_t *settings)
|
||||
obs_data_set_default_int(settings, SETTING_SMOOTHNESS, 50);
|
||||
}
|
||||
|
||||
static enum gs_color_space
|
||||
color_key_get_color_space(void *data, size_t count,
|
||||
const enum gs_color_space *preferred_spaces)
|
||||
{
|
||||
const enum gs_color_space potential_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
struct color_key_filter_data_v2 *const filter = data;
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(potential_spaces), potential_spaces);
|
||||
|
||||
return source_space;
|
||||
}
|
||||
|
||||
struct obs_source_info color_key_filter = {
|
||||
.id = "color_key_filter",
|
||||
.type = OBS_SOURCE_TYPE_FILTER,
|
||||
@ -479,4 +524,5 @@ struct obs_source_info color_key_filter_v2 = {
|
||||
.update = color_key_update_v2,
|
||||
.get_properties = color_key_properties_v2,
|
||||
.get_defaults = color_key_defaults_v2,
|
||||
.video_get_color_space = color_key_get_color_space,
|
||||
};
|
||||
|
@ -2,11 +2,13 @@
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define SETTING_SDR_ONLY_INFO "sdr_only_info"
|
||||
#define SETTING_LUMA_MAX "luma_max"
|
||||
#define SETTING_LUMA_MIN "luma_min"
|
||||
#define SETTING_LUMA_MAX_SMOOTH "luma_max_smooth"
|
||||
#define SETTING_LUMA_MIN_SMOOTH "luma_min_smooth"
|
||||
|
||||
#define TEXT_SDR_ONLY_INFO obs_module_text("SdrOnlyInfo")
|
||||
#define TEXT_LUMA_MAX obs_module_text("Luma.LumaMax")
|
||||
#define TEXT_LUMA_MIN obs_module_text("Luma.LumaMin")
|
||||
#define TEXT_LUMA_MAX_SMOOTH obs_module_text("Luma.LumaMaxSmooth")
|
||||
@ -119,26 +121,45 @@ static void luma_key_render_internal(void *data, bool premultiplied)
|
||||
{
|
||||
struct luma_key_filter_data *filter = data;
|
||||
|
||||
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
|
||||
OBS_ALLOW_DIRECT_RENDERING))
|
||||
return;
|
||||
const enum gs_color_space preferred_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
gs_effect_set_float(filter->luma_max_param, filter->luma_max);
|
||||
gs_effect_set_float(filter->luma_min_param, filter->luma_min);
|
||||
gs_effect_set_float(filter->luma_max_smooth_param,
|
||||
filter->luma_max_smooth);
|
||||
gs_effect_set_float(filter->luma_min_smooth_param,
|
||||
filter->luma_min_smooth);
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(preferred_spaces), preferred_spaces);
|
||||
if (source_space == GS_CS_709_EXTENDED) {
|
||||
obs_source_skip_video_filter(filter->context);
|
||||
} else {
|
||||
const enum gs_color_format format =
|
||||
gs_get_format_from_space(source_space);
|
||||
if (obs_source_process_filter_begin_with_color_space(
|
||||
filter->context, format, source_space,
|
||||
OBS_ALLOW_DIRECT_RENDERING)) {
|
||||
gs_effect_set_float(filter->luma_max_param,
|
||||
filter->luma_max);
|
||||
gs_effect_set_float(filter->luma_min_param,
|
||||
filter->luma_min);
|
||||
gs_effect_set_float(filter->luma_max_smooth_param,
|
||||
filter->luma_max_smooth);
|
||||
gs_effect_set_float(filter->luma_min_smooth_param,
|
||||
filter->luma_min_smooth);
|
||||
|
||||
if (premultiplied) {
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
}
|
||||
if (premultiplied) {
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE,
|
||||
GS_BLEND_INVSRCALPHA);
|
||||
}
|
||||
|
||||
obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
|
||||
obs_source_process_filter_end(filter->context,
|
||||
filter->effect, 0, 0);
|
||||
|
||||
if (premultiplied) {
|
||||
gs_blend_state_pop();
|
||||
if (premultiplied) {
|
||||
gs_blend_state_pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,6 +181,8 @@ static obs_properties_t *luma_key_properties(void *data)
|
||||
{
|
||||
obs_properties_t *props = obs_properties_create();
|
||||
|
||||
obs_properties_add_text(props, SETTING_SDR_ONLY_INFO,
|
||||
TEXT_SDR_ONLY_INFO, OBS_TEXT_INFO);
|
||||
obs_properties_add_float_slider(props, SETTING_LUMA_MAX, TEXT_LUMA_MAX,
|
||||
0, 1, 0.0001);
|
||||
obs_properties_add_float_slider(props, SETTING_LUMA_MAX_SMOOTH,
|
||||
@ -181,6 +204,24 @@ static void luma_key_defaults(obs_data_t *settings)
|
||||
obs_data_set_default_double(settings, SETTING_LUMA_MIN_SMOOTH, 0.0);
|
||||
}
|
||||
|
||||
static enum gs_color_space
|
||||
luma_key_get_color_space(void *data, size_t count,
|
||||
const enum gs_color_space *preferred_spaces)
|
||||
{
|
||||
const enum gs_color_space potential_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
struct luma_key_filter_data *const filter = data;
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(potential_spaces), potential_spaces);
|
||||
|
||||
return source_space;
|
||||
}
|
||||
|
||||
struct obs_source_info luma_key_filter = {
|
||||
.id = "luma_key_filter",
|
||||
.type = OBS_SOURCE_TYPE_FILTER,
|
||||
@ -206,4 +247,5 @@ struct obs_source_info luma_key_filter_v2 = {
|
||||
.update = luma_key_update,
|
||||
.get_properties = luma_key_properties,
|
||||
.get_defaults = luma_key_defaults,
|
||||
.video_get_color_space = luma_key_get_color_space,
|
||||
};
|
||||
|
@ -8,12 +8,14 @@
|
||||
|
||||
/* clang-format off */
|
||||
|
||||
#define SETTING_SDR_ONLY_INFO "sdr_only_info"
|
||||
#define SETTING_TYPE "type"
|
||||
#define SETTING_IMAGE_PATH "image_path"
|
||||
#define SETTING_COLOR "color"
|
||||
#define SETTING_OPACITY "opacity"
|
||||
#define SETTING_STRETCH "stretch"
|
||||
|
||||
#define TEXT_SDR_ONLY_INFO obs_module_text("SdrOnlyInfo")
|
||||
#define TEXT_TYPE obs_module_text("Type")
|
||||
#define TEXT_IMAGE_PATH obs_module_text("Path")
|
||||
#define TEXT_COLOR obs_module_text("Color")
|
||||
@ -156,6 +158,9 @@ static obs_properties_t *mask_filter_properties_internal(bool use_float_opacity)
|
||||
dstr_cat(&filter_str, TEXT_PATH_ALL_FILES);
|
||||
dstr_cat(&filter_str, " (*.*)");
|
||||
|
||||
obs_properties_add_text(props, SETTING_SDR_ONLY_INFO,
|
||||
TEXT_SDR_ONLY_INFO, OBS_TEXT_INFO);
|
||||
|
||||
p = obs_properties_add_list(props, SETTING_TYPE, TEXT_TYPE,
|
||||
OBS_COMBO_TYPE_LIST,
|
||||
OBS_COMBO_FORMAT_STRING);
|
||||
@ -264,6 +269,8 @@ static void mask_filter_tick(void *data, float seconds)
|
||||
|
||||
static void mask_filter_render(void *data, gs_effect_t *effect)
|
||||
{
|
||||
UNUSED_PARAMETER(effect);
|
||||
|
||||
struct mask_filter_data *filter = data;
|
||||
obs_source_t *target = obs_filter_get_target(filter->context);
|
||||
gs_eparam_t *param;
|
||||
@ -275,60 +282,100 @@ static void mask_filter_render(void *data, gs_effect_t *effect)
|
||||
return;
|
||||
}
|
||||
|
||||
if (filter->lock_aspect) {
|
||||
struct vec2 source_size;
|
||||
struct vec2 mask_size;
|
||||
struct vec2 mask_temp;
|
||||
float source_aspect;
|
||||
float mask_aspect;
|
||||
bool size_to_x;
|
||||
float fix;
|
||||
const enum gs_color_space preferred_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
source_size.x = (float)obs_source_get_base_width(target);
|
||||
source_size.y = (float)obs_source_get_base_height(target);
|
||||
mask_size.x = (float)gs_texture_get_width(filter->target);
|
||||
mask_size.y = (float)gs_texture_get_height(filter->target);
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(preferred_spaces), preferred_spaces);
|
||||
if (source_space == GS_CS_709_EXTENDED) {
|
||||
obs_source_skip_video_filter(filter->context);
|
||||
} else {
|
||||
if (filter->lock_aspect) {
|
||||
struct vec2 source_size;
|
||||
struct vec2 mask_size;
|
||||
struct vec2 mask_temp;
|
||||
float source_aspect;
|
||||
float mask_aspect;
|
||||
bool size_to_x;
|
||||
float fix;
|
||||
|
||||
source_aspect = source_size.x / source_size.y;
|
||||
mask_aspect = mask_size.x / mask_size.y;
|
||||
size_to_x = (source_aspect < mask_aspect);
|
||||
source_size.x =
|
||||
(float)obs_source_get_base_width(target);
|
||||
source_size.y =
|
||||
(float)obs_source_get_base_height(target);
|
||||
mask_size.x =
|
||||
(float)gs_texture_get_width(filter->target);
|
||||
mask_size.y =
|
||||
(float)gs_texture_get_height(filter->target);
|
||||
|
||||
fix = size_to_x ? (source_size.x / mask_size.x)
|
||||
: (source_size.y / mask_size.y);
|
||||
source_aspect = source_size.x / source_size.y;
|
||||
mask_aspect = mask_size.x / mask_size.y;
|
||||
size_to_x = (source_aspect < mask_aspect);
|
||||
|
||||
vec2_mulf(&mask_size, &mask_size, fix);
|
||||
vec2_div(&mul_val, &source_size, &mask_size);
|
||||
vec2_mulf(&source_size, &source_size, 0.5f);
|
||||
vec2_mulf(&mask_temp, &mask_size, 0.5f);
|
||||
vec2_sub(&add_val, &source_size, &mask_temp);
|
||||
vec2_neg(&add_val, &add_val);
|
||||
vec2_div(&add_val, &add_val, &mask_size);
|
||||
fix = size_to_x ? (source_size.x / mask_size.x)
|
||||
: (source_size.y / mask_size.y);
|
||||
|
||||
vec2_mulf(&mask_size, &mask_size, fix);
|
||||
vec2_div(&mul_val, &source_size, &mask_size);
|
||||
vec2_mulf(&source_size, &source_size, 0.5f);
|
||||
vec2_mulf(&mask_temp, &mask_size, 0.5f);
|
||||
vec2_sub(&add_val, &source_size, &mask_temp);
|
||||
vec2_neg(&add_val, &add_val);
|
||||
vec2_div(&add_val, &add_val, &mask_size);
|
||||
}
|
||||
|
||||
const enum gs_color_format format =
|
||||
gs_get_format_from_space(source_space);
|
||||
if (obs_source_process_filter_begin_with_color_space(
|
||||
filter->context, format, source_space,
|
||||
OBS_ALLOW_DIRECT_RENDERING)) {
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"target");
|
||||
gs_effect_set_texture_srgb(param, filter->target);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"color");
|
||||
gs_effect_set_vec4(param, &filter->color);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"mul_val");
|
||||
gs_effect_set_vec2(param, &mul_val);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect,
|
||||
"add_val");
|
||||
gs_effect_set_vec2(param, &add_val);
|
||||
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
|
||||
obs_source_process_filter_end(filter->context,
|
||||
filter->effect, 0, 0);
|
||||
|
||||
gs_blend_state_pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!obs_source_process_filter_begin(filter->context, GS_RGBA,
|
||||
OBS_ALLOW_DIRECT_RENDERING))
|
||||
return;
|
||||
static enum gs_color_space
|
||||
mask_filter_get_color_space(void *data, size_t count,
|
||||
const enum gs_color_space *preferred_spaces)
|
||||
{
|
||||
const enum gs_color_space potential_spaces[] = {
|
||||
GS_CS_SRGB,
|
||||
GS_CS_SRGB_16F,
|
||||
GS_CS_709_EXTENDED,
|
||||
};
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "target");
|
||||
gs_effect_set_texture_srgb(param, filter->target);
|
||||
struct mask_filter_data *const filter = data;
|
||||
const enum gs_color_space source_space = obs_source_get_color_space(
|
||||
obs_filter_get_parent(filter->context),
|
||||
OBS_COUNTOF(potential_spaces), potential_spaces);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "color");
|
||||
gs_effect_set_vec4(param, &filter->color);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "mul_val");
|
||||
gs_effect_set_vec2(param, &mul_val);
|
||||
|
||||
param = gs_effect_get_param_by_name(filter->effect, "add_val");
|
||||
gs_effect_set_vec2(param, &add_val);
|
||||
|
||||
gs_blend_state_push();
|
||||
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
|
||||
|
||||
obs_source_process_filter_end(filter->context, filter->effect, 0, 0);
|
||||
|
||||
gs_blend_state_pop();
|
||||
|
||||
UNUSED_PARAMETER(effect);
|
||||
return source_space;
|
||||
}
|
||||
|
||||
struct obs_source_info mask_filter = {
|
||||
@ -358,4 +405,5 @@ struct obs_source_info mask_filter_v2 = {
|
||||
.get_properties = mask_filter_properties_v2,
|
||||
.video_tick = mask_filter_tick,
|
||||
.video_render = mask_filter_render,
|
||||
.video_get_color_space = mask_filter_get_color_space,
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user