1 /*
2 * Modern effects for a modern Streamer
3 * Copyright (C) 2017 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 #include "plugin.hpp"
21 #include <fstream>
22 #include <stdexcept>
23 #include "configuration.hpp"
24 #include "obs/gs/gs-vertexbuffer.hpp"
25 #include "obs/obs-source-tracker.hpp"
26
27 #ifdef ENABLE_ENCODER_FFMPEG
28 #include "encoders/encoder-ffmpeg.hpp"
29 #endif
30
31 #ifdef ENABLE_FILTER_BLUR
32 #include "filters/filter-blur.hpp"
33 #endif
34 #ifdef ENABLE_FILTER_COLOR_GRADE
35 #include "filters/filter-color-grade.hpp"
36 #endif
37 #ifdef ENABLE_FILTER_DISPLACEMENT
38 #include "filters/filter-displacement.hpp"
39 #endif
40 #ifdef ENABLE_FILTER_DYNAMIC_MASK
41 #include "filters/filter-dynamic-mask.hpp"
42 #endif
43 #ifdef ENABLE_FILTER_NVIDIA_FACE_TRACKING
44 #include "filters/filter-nv-face-tracking.hpp"
45 #endif
46 #ifdef ENABLE_FILTER_SDF_EFFECTS
47 #include "filters/filter-sdf-effects.hpp"
48 #endif
49 #ifdef ENABLE_FILTER_SHADER
50 #include "filters/filter-shader.hpp"
51 #endif
52 #ifdef ENABLE_FILTER_TRANSFORM
53 #include "filters/filter-transform.hpp"
54 #endif
55
56 #ifdef ENABLE_SOURCE_MIRROR
57 #include "sources/source-mirror.hpp"
58 #endif
59 #ifdef ENABLE_SOURCE_SHADER
60 #include "sources/source-shader.hpp"
61 #endif
62
63 #ifdef ENABLE_TRANSITION_SHADER
64 #include "transitions/transition-shader.hpp"
65 #endif
66
67 #ifdef ENABLE_FRONTEND
68 #include "ui/ui.hpp"
69 #endif
70
71 #ifdef ENABLE_UPDATER
72 #include "updater.hpp"
73 //static std::shared_ptr<streamfx::updater> _updater;
74 #endif
75
76 static std::shared_ptr<util::threadpool> _threadpool;
77 static std::shared_ptr<gs::vertex_buffer> _gs_fstri_vb;
78
obs_module_load(void)79 MODULE_EXPORT bool obs_module_load(void)
80 try {
81 DLOG_INFO("Loading Version %s", STREAMFX_VERSION_STRING);
82
83 // Initialize global configuration.
84 streamfx::configuration::initialize();
85
86 // Initialize global Thread Pool.
87 _threadpool = std::make_shared<util::threadpool>();
88
89 // Initialize Source Tracker
90 obs::source_tracker::initialize();
91
92 // GS Stuff
93 {
94 _gs_fstri_vb = std::make_shared<gs::vertex_buffer>(uint32_t(3), uint8_t(1));
95 {
96 auto vtx = _gs_fstri_vb->at(0);
97 vec3_set(vtx.position, 0, 0, 0);
98 vec4_set(vtx.uv[0], 0, 0, 0, 0);
99 }
100 {
101 auto vtx = _gs_fstri_vb->at(1);
102 vec3_set(vtx.position, 2, 0, 0);
103 vec4_set(vtx.uv[0], 2, 0, 0, 0);
104 }
105 {
106 auto vtx = _gs_fstri_vb->at(2);
107 vec3_set(vtx.position, 0, 2, 0);
108 vec4_set(vtx.uv[0], 0, 2, 0, 0);
109 }
110 _gs_fstri_vb->update();
111 }
112
113 // Encoders
114 {
115 #ifdef ENABLE_ENCODER_FFMPEG
116 using namespace streamfx::encoder::ffmpeg;
117 ffmpeg_manager::initialize();
118 #endif
119 }
120
121 // Filters
122 {
123 #ifdef ENABLE_FILTER_BLUR
124 streamfx::filter::blur::blur_factory::initialize();
125 #endif
126 #ifdef ENABLE_FILTER_COLOR_GRADE
127 streamfx::filter::color_grade::color_grade_factory::initialize();
128 #endif
129 #ifdef ENABLE_FILTER_DISPLACEMENT
130 streamfx::filter::displacement::displacement_factory::initialize();
131 #endif
132 #ifdef ENABLE_FILTER_DYNAMIC_MASK
133 streamfx::filter::dynamic_mask::dynamic_mask_factory::initialize();
134 #endif
135 #ifdef ENABLE_FILTER_NVIDIA_FACE_TRACKING
136 streamfx::filter::nvidia::face_tracking_factory::initialize();
137 #endif
138 #ifdef ENABLE_FILTER_SDF_EFFECTS
139 streamfx::filter::sdf_effects::sdf_effects_factory::initialize();
140 #endif
141 #ifdef ENABLE_FILTER_SHADER
142 streamfx::filter::shader::shader_factory::initialize();
143 #endif
144 #ifdef ENABLE_FILTER_TRANSFORM
145 streamfx::filter::transform::transform_factory::initialize();
146 #endif
147 }
148
149 // Sources
150 {
151 #ifdef ENABLE_SOURCE_MIRROR
152 streamfx::source::mirror::mirror_factory::initialize();
153 #endif
154 #ifdef ENABLE_SOURCE_SHADER
155 streamfx::source::shader::shader_factory::initialize();
156 #endif
157 }
158
159 // Transitions
160 {
161 #ifdef ENABLE_TRANSITION_SHADER
162 streamfx::transition::shader::shader_factory::initialize();
163 #endif
164 }
165
166 // Frontend
167 #ifdef ENABLE_FRONTEND
168 streamfx::ui::handler::initialize();
169 #endif
170
171 DLOG_INFO("Loaded Version %s", STREAMFX_VERSION_STRING);
172 return true;
173 } catch (...) {
174 DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
175 return false;
176 }
177
obs_module_unload(void)178 MODULE_EXPORT void obs_module_unload(void)
179 try {
180 DLOG_INFO("Unloading Version %s", STREAMFX_VERSION_STRING);
181
182 // Frontend
183 #ifdef ENABLE_FRONTEND
184 streamfx::ui::handler::finalize();
185 #endif
186
187 // Transitions
188 {
189 #ifdef ENABLE_TRANSITION_SHADER
190 streamfx::transition::shader::shader_factory::finalize();
191 #endif
192 }
193
194 // Sources
195 {
196 #ifdef ENABLE_SOURCE_MIRROR
197 streamfx::source::mirror::mirror_factory::finalize();
198 #endif
199 #ifdef ENABLE_SOURCE_SHADER
200 streamfx::source::shader::shader_factory::finalize();
201 #endif
202 }
203
204 // Filters
205 {
206 #ifdef ENABLE_FILTER_BLUR
207 streamfx::filter::blur::blur_factory::finalize();
208 #endif
209 #ifdef ENABLE_FILTER_COLOR_GRADE
210 streamfx::filter::color_grade::color_grade_factory::finalize();
211 #endif
212 #ifdef ENABLE_FILTER_DISPLACEMENT
213 streamfx::filter::displacement::displacement_factory::finalize();
214 #endif
215 #ifdef ENABLE_FILTER_DYNAMIC_MASK
216 streamfx::filter::dynamic_mask::dynamic_mask_factory::finalize();
217 #endif
218 #ifdef ENABLE_FILTER_NVIDIA_FACE_TRACKING
219 streamfx::filter::nvidia::face_tracking_factory::finalize();
220 #endif
221 #ifdef ENABLE_FILTER_SDF_EFFECTS
222 streamfx::filter::sdf_effects::sdf_effects_factory::finalize();
223 #endif
224 #ifdef ENABLE_FILTER_SHADER
225 streamfx::filter::shader::shader_factory::finalize();
226 #endif
227 #ifdef ENABLE_FILTER_TRANSFORM
228 streamfx::filter::transform::transform_factory::finalize();
229 #endif
230 }
231
232 // Encoders
233 {
234 #ifdef ENABLE_ENCODER_FFMPEG
235 streamfx::encoder::ffmpeg::ffmpeg_manager::finalize();
236 #endif
237 }
238
239 // GS Stuff
240 {
241 _gs_fstri_vb.reset();
242 }
243
244 // Finalize Source Tracker
245 obs::source_tracker::finalize();
246
247 // // Auto-Updater
248 //#ifdef ENABLE_UPDATER
249 // _updater.reset();
250 //#endif
251
252 // Finalize Thread Pool
253 _threadpool.reset();
254
255 // Finalize Configuration
256 streamfx::configuration::finalize();
257
258 DLOG_INFO("Unloaded Version %s", STREAMFX_VERSION_STRING);
259 } catch (...) {
260 DLOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
261 }
262
threadpool()263 std::shared_ptr<util::threadpool> streamfx::threadpool()
264 {
265 return _threadpool;
266 }
267
gs_draw_fullscreen_tri()268 void streamfx::gs_draw_fullscreen_tri()
269 {
270 gs_load_vertexbuffer(_gs_fstri_vb->update(false));
271 gs_draw(GS_TRIS, 0, 3); //_gs_fstri_vb->size());
272 }
273
data_file_path(std::string_view file)274 std::filesystem::path streamfx::data_file_path(std::string_view file)
275 {
276 const char* root_path = obs_get_module_data_path(obs_current_module());
277 if (root_path) {
278 auto ret = std::filesystem::u8path(root_path);
279 ret.append(file.data());
280 return ret;
281 } else {
282 throw std::runtime_error("obs_get_module_data_path returned nullptr");
283 }
284 }
285
config_file_path(std::string_view file)286 std::filesystem::path streamfx::config_file_path(std::string_view file)
287 {
288 char* root_path = obs_module_get_config_path(obs_current_module(), file.data());
289 if (root_path) {
290 auto ret = std::filesystem::u8path(root_path);
291 bfree(root_path);
292 return ret;
293 } else {
294 throw std::runtime_error("obs_module_get_config_path returned nullptr");
295 }
296 }
297