1 /*
2  * Modern effects for a modern Streamer
3  * Copyright (C) 2017-2018 Michael Fabian Dirks
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 
20 #pragma once
21 #include "common.hpp"
22 #include <chrono>
23 #include <functional>
24 #include <list>
25 #include <map>
26 #include "gfx/blur/gfx-blur-base.hpp"
27 #include "gfx/gfx-source-texture.hpp"
28 #include "obs/gs/gs-effect.hpp"
29 #include "obs/gs/gs-helper.hpp"
30 #include "obs/gs/gs-rendertarget.hpp"
31 #include "obs/gs/gs-texture.hpp"
32 #include "obs/obs-source-factory.hpp"
33 
34 namespace streamfx::filter::blur {
35 	enum class mask_type : int64_t {
36 		Region,
37 		Image,
38 		Source,
39 	};
40 
41 	class blur_instance : public obs::source_instance {
42 		// Effects
43 		gs::effect _effect_mask;
44 
45 		// Input
46 		std::shared_ptr<gs::rendertarget> _source_rt;
47 		std::shared_ptr<gs::texture>      _source_texture;
48 		bool                              _source_rendered;
49 
50 		// Rendering
51 		std::shared_ptr<gs::texture>      _output_texture;
52 		std::shared_ptr<gs::rendertarget> _output_rt;
53 		bool                              _output_rendered;
54 
55 		// Blur
56 		std::shared_ptr<::gfx::blur::base> _blur;
57 		double_t                           _blur_size;
58 		double_t                           _blur_angle;
59 		std::pair<double_t, double_t>      _blur_center;
60 		bool                               _blur_step_scaling;
61 		std::pair<double_t, double_t>      _blur_step_scale;
62 
63 		// Masking
64 		struct {
65 			bool      enabled;
66 			mask_type type;
67 			struct {
68 				float_t left;
69 				float_t top;
70 				float_t right;
71 				float_t bottom;
72 				float_t feather;
73 				float_t feather_shift;
74 				bool    invert;
75 			} region;
76 			struct {
77 				std::string                  path;
78 				std::string                  path_old;
79 				std::shared_ptr<gs::texture> texture;
80 			} image;
81 			struct {
82 				std::string                          name_old;
83 				std::string                          name;
84 				bool                                 is_scene;
85 				std::shared_ptr<gfx::source_texture> source_texture;
86 				std::shared_ptr<gs::texture>         texture;
87 			} source;
88 			struct {
89 				float_t r;
90 				float_t g;
91 				float_t b;
92 				float_t a;
93 			} color;
94 			float_t multiplier;
95 		} _mask;
96 
97 		public:
98 		blur_instance(obs_data_t* settings, obs_source_t* self);
99 		~blur_instance();
100 
101 		public:
102 		virtual void load(obs_data_t* settings) override;
103 		virtual void migrate(obs_data_t* settings, uint64_t version) override;
104 		virtual void update(obs_data_t* settings) override;
105 
106 		virtual void video_tick(float_t time) override;
107 		virtual void video_render(gs_effect_t* effect) override;
108 
109 		private:
110 		bool apply_mask_parameters(gs::effect effect, gs_texture_t* original_texture, gs_texture_t* blurred_texture);
111 	};
112 
113 	class blur_factory : public obs::source_factory<filter::blur::blur_factory, filter::blur::blur_instance> {
114 		std::vector<std::string> _translation_cache;
115 
116 		public:
117 		blur_factory();
118 		virtual ~blur_factory();
119 
120 		virtual const char* get_name() override;
121 
122 		virtual void get_defaults2(obs_data_t* settings) override;
123 
124 		virtual obs_properties_t* get_properties2(filter::blur::blur_instance* data) override;
125 
126 		std::string translate_string(const char* format, ...);
127 
128 		public: // Singleton
129 		static void initialize();
130 
131 		static void finalize();
132 
133 		static std::shared_ptr<blur_factory> get();
134 	};
135 } // namespace streamfx::filter::blur
136