source-mirror: Fix scaling issues and allow keeping original size

Scaling was previously incorrectly rendering the source with another effect forced onto it, resulting in slower rendering and some sources that would no longer render properly.

Additionally the new option allows the user to have the source render at the original resolution in order to allow previously applied transform to stay identical. The rescaling however will no longer apply to filters after this source then, thus the speed bonus is lost.

Also categorized the localization file and adds descriptions for existing and new properties for Source Mirror.
This commit is contained in:
Michael Fabian 'Xaymar' Dirks 2018-01-19 04:13:32 +01:00
parent 5e0b387dc1
commit 662199fb4a
3 changed files with 69 additions and 29 deletions

View file

@ -1,8 +1,27 @@
# Generic
Advanced="Advanced"
# Filter - Blur
Filter.Blur="Blur"
Filter.Blur.Type="Type"
Filter.Blur.Type.Description="The type of blur to apply:\n- 'Box' smoothes pixels equally.\n- 'Gaussian' applies a gaussian curve to the smoothed pixels.\n- 'Bilateral' is an edge detection variant of 'Gaussian'."
Filter.Blur.Type.Box="Box"
Filter.Blur.Type.Gaussian="Gaussian"
Filter.Blur.Type.Bilateral="Bilateral"
Filter.Blur.Size="Size (Pixel)"
Filter.Blur.Size.Description="Area size of the blur, large sizes may cause:\n- Skipped frames\n- Frame loss or drops\n- Input lag\n- GPU overheating\n- or other issues."
Filter.Blur.Bilateral.Smoothing="Smoothing"
Filter.Blur.Bilateral.Sharpness="Sharpness"
Filter.Blur.ColorFormat="Color Format"
# Filter - Displacement
Filter.Displacement="Displacement Mapping" Filter.Displacement="Displacement Mapping"
Filter.Displacement.File="File" Filter.Displacement.File="File"
Filter.Displacement.File.Types="Images (*.png *.jpeg *.jpg *.bmp *.tga);;All Files (*)" Filter.Displacement.File.Types="Images (*.png *.jpeg *.jpg *.bmp *.tga);;All Files (*)"
Filter.Displacement.Ratio="Ratio" Filter.Displacement.Ratio="Ratio"
Filter.Displacement.Scale="Scale" Filter.Displacement.Scale="Scale"
# Filter - Shape
Filter.Shape="Shape" Filter.Shape="Shape"
Filter.Shape.Loop="Repeat last Point" Filter.Shape.Loop="Repeat last Point"
Filter.Shape.Points="Points" Filter.Shape.Points="Points"
@ -10,6 +29,8 @@ Filter.Shape.Point.X="Point %llu X"
Filter.Shape.Point.Y="Point %llu Y" Filter.Shape.Point.Y="Point %llu Y"
Filter.Shape.Point.U="Point %llu U" Filter.Shape.Point.U="Point %llu U"
Filter.Shape.Point.V="Point %llu V" Filter.Shape.Point.V="Point %llu V"
# Filter - Transform
Filter.Transform="3D Transform" Filter.Transform="3D Transform"
Filter.Transform.Camera="Camera" Filter.Transform.Camera="Camera"
Filter.Transform.Camera.Description="Projection mode used by the camera." Filter.Transform.Camera.Description="Projection mode used by the camera."
@ -43,27 +64,23 @@ Filter.Transform.Rotation.Description="Euler rotation of the rendered quad, appl
Filter.Transform.Rotation.X="Pitch (X)" Filter.Transform.Rotation.X="Pitch (X)"
Filter.Transform.Rotation.Y="Yaw (Y)" Filter.Transform.Rotation.Y="Yaw (Y)"
Filter.Transform.Rotation.Z="Roll (Z)" Filter.Transform.Rotation.Z="Roll (Z)"
Filter.Blur="Blur"
Filter.Blur.Type="Type" # Source - Mirror
Filter.Blur.Type.Description="The type of blur to apply:\n- 'Box' smoothes pixels equally.\n- 'Gaussian' applies a gaussian curve to the smoothed pixels.\n- 'Bilateral' is an edge detection variant of 'Gaussian'."
Filter.Blur.Type.Box="Box"
Filter.Blur.Type.Gaussian="Gaussian"
Filter.Blur.Type.Bilateral="Bilateral"
Filter.Blur.Size="Size (Pixel)"
Filter.Blur.Size.Description="Area size of the blur, large sizes may cause:\n- Skipped frames\n- Frame loss or drops\n- Input lag\n- GPU overheating\n- or other issues."
Filter.Blur.Bilateral.Smoothing="Smoothing"
Filter.Blur.Bilateral.Sharpness="Sharpness"
Filter.Blur.ColorFormat="Color Format"
Source.Mirror="Source Mirror" Source.Mirror="Source Mirror"
Source.Mirror.Source="Source" Source.Mirror.Source="Source"
Source.Mirror.Source.Description="Which Source should be mirrored?"
Source.Mirror.Source.Size="Source Size" Source.Mirror.Source.Size="Source Size"
Source.Mirror.Source.Size.Description="The size of the source being mirrored. (Automatically updated)"
Source.Mirror.Scaling="Rescale Source" Source.Mirror.Scaling="Rescale Source"
Source.Mirror.Scaling.Description="Should the source be rescaled?"
Source.Mirror.Scaling.Method="Filter" Source.Mirror.Scaling.Method="Filter"
Source.Mirror.Scaling.Method.Description="Which filter should be used for rescaling?"
Source.Mirror.Scaling.Method.Point="Point" Source.Mirror.Scaling.Method.Point="Point"
Source.Mirror.Scaling.Method.Bilinear="Bilinear" Source.Mirror.Scaling.Method.Bilinear="Bilinear"
Source.Mirror.Scaling.Method.BilinearLowRes="Bilinear (Low Resolution)" Source.Mirror.Scaling.Method.BilinearLowRes="Bilinear (Low Resolution)"
Source.Mirror.Scaling.Method.Bicubic="Bicubic" Source.Mirror.Scaling.Method.Bicubic="Bicubic"
Source.Mirror.Scaling.Method.Lanczos="Lanczos" Source.Mirror.Scaling.Method.Lanczos="Lanczos"
Source.Mirror.Scaling.Size="Size" Source.Mirror.Scaling.Size="Size"
Source.Mirror.Scaling.Size.Description="What size should we rescale to? (WxH format)"
Advanced="Advanced" Source.Mirror.Scaling.TransformKeepOriginal="Use Original Size for Transforms"
Source.Mirror.Scaling.TransformKeepOriginal.Description="Should the filter not modify the size of the source?"

View file

@ -34,6 +34,7 @@
#define P_SCALING_METHOD_BICUBIC "Source.Mirror.Scaling.Method.Bicubic" #define P_SCALING_METHOD_BICUBIC "Source.Mirror.Scaling.Method.Bicubic"
#define P_SCALING_METHOD_LANCZOS "Source.Mirror.Scaling.Method.Lanczos" #define P_SCALING_METHOD_LANCZOS "Source.Mirror.Scaling.Method.Lanczos"
#define P_SCALING_SIZE "Source.Mirror.Scaling.Size" #define P_SCALING_SIZE "Source.Mirror.Scaling.Size"
#define P_SCALING_TRANSFORMKEEPORIGINAL "Source.Mirror.Scaling.TransformKeepOriginal"
enum class ScalingMethod : int64_t { enum class ScalingMethod : int64_t {
Point, Point,
@ -154,6 +155,9 @@ obs_properties_t * Source::MirrorAddon::get_properties(void *ptr) {
OBS_TEXT_DEFAULT); OBS_TEXT_DEFAULT);
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_SIZE))); obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_SIZE)));
p = obs_properties_add_bool(pr, P_SCALING_TRANSFORMKEEPORIGINAL, P_TRANSLATE(P_SCALING_TRANSFORMKEEPORIGINAL));
obs_property_set_long_description(p, P_TRANSLATE(P_DESC(P_SCALING_TRANSFORMKEEPORIGINAL)));
return pr; return pr;
} }
@ -201,6 +205,7 @@ Source::Mirror::Mirror(obs_data_t* data, obs_source_t* src) {
m_rescale = false; m_rescale = false;
m_width = m_height = 1; m_width = m_height = 1;
m_renderTarget = std::make_unique<GS::RenderTarget>(GS_RGBA, GS_ZS_NONE); m_renderTarget = std::make_unique<GS::RenderTarget>(GS_RGBA, GS_ZS_NONE);
m_renderTargetScale = std::make_unique<GS::RenderTarget>(GS_RGBA, GS_ZS_NONE);
m_scalingEffect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT); m_scalingEffect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
update(data); update(data);
@ -211,7 +216,7 @@ Source::Mirror::~Mirror() {
} }
uint32_t Source::Mirror::get_width() { uint32_t Source::Mirror::get_width() {
if (m_rescale && m_width > 0) if (m_rescale && m_width > 0 && !m_keepOriginalSize)
return m_width; return m_width;
if (m_target && m_target != m_source) if (m_target && m_target != m_source)
return obs_source_get_width(m_target); return obs_source_get_width(m_target);
@ -219,7 +224,7 @@ uint32_t Source::Mirror::get_width() {
} }
uint32_t Source::Mirror::get_height() { uint32_t Source::Mirror::get_height() {
if (m_rescale && m_height > 0) if (m_rescale && m_height > 0 && !m_keepOriginalSize)
return m_height; return m_height;
if (m_target && m_target != m_source) if (m_target && m_target != m_source)
return obs_source_get_height(m_target); return obs_source_get_height(m_target);
@ -282,6 +287,8 @@ void Source::Mirror::update(obs_data_t* data) {
m_scalingEffect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT); m_scalingEffect = obs_get_base_effect(obs_base_effect::OBS_EFFECT_DEFAULT);
break; break;
} }
m_keepOriginalSize = obs_data_get_bool(data, P_SCALING_TRANSFORMKEEPORIGINAL);
} }
} }
@ -310,27 +317,41 @@ void Source::Mirror::video_render(gs_effect_t* effect) {
// Store original Source Texture // Store original Source Texture
try { try {
vec4 black; vec4_zero(&black); vec4 black; vec4_zero(&black);
auto op = m_renderTarget->Render(m_width, m_height); auto op = m_renderTarget->Render(sw, sh);
gs_ortho(0, sw, 0, sh, 0, 1); gs_ortho(0, sw, 0, sh, 0, 1);
gs_clear(GS_CLEAR_COLOR, &black, 0, 0); gs_clear(GS_CLEAR_COLOR, &black, 0, 0);
gs_eparam_t *scale_param = gs_effect_get_param_by_name(m_scalingEffect, "base_dimension_i"); obs_source_video_render(m_target);
if (scale_param) {
struct vec2 base_res_i = {
1.0f / (float)sw,
1.0f / (float)sh
};
gs_effect_set_vec2(scale_param, &base_res_i);
}
while (gs_effect_loop(m_scalingEffect, "Draw")) {
obs_source_video_render(m_target);
}
} catch (...) { } catch (...) {
return; return;
} }
while (gs_effect_loop(obs_get_base_effect(OBS_EFFECT_DEFAULT), "Draw")) { gs_eparam_t *scale_param = gs_effect_get_param_by_name(m_scalingEffect, "base_dimension_i");
obs_source_draw(m_renderTarget->GetTextureObject(), 0, 0, m_width, m_height, false); if (scale_param) {
struct vec2 base_res_i = {
1.0f / (float)sw,
1.0f / (float)sh
};
gs_effect_set_vec2(scale_param, &base_res_i);
}
if (m_keepOriginalSize) {
{
vec4 black; vec4_zero(&black);
auto op = m_renderTargetScale->Render(m_width, m_height);
gs_ortho(0, m_width, 0, m_height, 0, 1);
gs_clear(GS_CLEAR_COLOR, &black, 0, 0);
while (gs_effect_loop(m_scalingEffect, "Draw")) {
obs_source_draw(m_renderTarget->GetTextureObject(), 0, 0, m_width, m_height, false);
}
}
while (gs_effect_loop(obs_get_base_effect(OBS_EFFECT_DEFAULT), "Draw")) {
obs_source_draw(m_renderTargetScale->GetTextureObject(), 0, 0, sw, sh, false);
}
} else {
while (gs_effect_loop(m_scalingEffect, "Draw")) {
obs_source_draw(m_renderTarget->GetTextureObject(), 0, 0, m_width, m_height, false);
}
} }
} else { } else {
obs_source_video_render(m_target); obs_source_video_render(m_target);

View file

@ -70,8 +70,10 @@ namespace Source {
std::string m_targetName; std::string m_targetName;
bool m_rescale = false; bool m_rescale = false;
bool m_keepOriginalSize = false;
uint32_t m_width, m_height; uint32_t m_width, m_height;
std::unique_ptr<GS::RenderTarget> m_renderTarget; std::unique_ptr<GS::RenderTarget> m_renderTarget;
std::unique_ptr<GS::RenderTarget> m_renderTargetScale;
gs_effect_t* m_scalingEffect; gs_effect_t* m_scalingEffect;
}; };
}; };