Skip to content

Commit 92c9f9e

Browse files
author
mr.fantastic
committed
Initial work on OpenFX module support
1 parent 70b3ce1 commit 92c9f9e

26 files changed

+10217
-0
lines changed

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ option(MOD_SDL2 "Enable SDL2 module" ON)
4141
option(MOD_SOX "Enable SoX module" ON)
4242
option(MOD_SPATIALAUDIO "Enable SpatialAudio module" ON)
4343
option(MOD_VIDSTAB "Enable vid.stab module (GPL)" ON)
44+
option(MOD_OPENFX "Enable OpenFX module (GPL)" ON)
4445
option(MOD_VORBIS "Enable Vorbis module" ON)
4546
option(MOD_XINE "Enable XINE module (GPL)" ON)
4647
option(MOD_XML "Enable XML module" ON)
@@ -171,6 +172,7 @@ if(NOT GPL)
171172
set(MOD_RESAMPLE OFF)
172173
set(MOD_RUBBERBAND OFF)
173174
set(MOD_VIDSTAB OFF)
175+
set(MOD_OPENFX OFF)
174176
set(MOD_XINE OFF)
175177
endif()
176178

@@ -633,6 +635,7 @@ add_feature_info("Module: SDL2" MOD_SDL2 "")
633635
add_feature_info("Module: SoX" MOD_SOX "")
634636
add_feature_info("Module: SpatialAudio" MOD_SPATIALAUDIO "")
635637
add_feature_info("Module: vid.stab" MOD_VIDSTAB "")
638+
add_feature_info("Module: OpenFX" MOD_OPENFX "")
636639
add_feature_info("Module: Vorbis" MOD_VORBIS "")
637640
add_feature_info("Module: XINE" MOD_XINE "")
638641
add_feature_info("Module: XML" MOD_XML "")

src/modules/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ if(MOD_VIDSTAB)
9292
add_subdirectory(vid.stab)
9393
endif()
9494

95+
if(MOD_OPENFX)
96+
add_subdirectory(openfx)
97+
endif()
98+
9599
if(MOD_VORBIS)
96100
add_subdirectory(vorbis)
97101
endif()

src/modules/openfx/CMakeLists.txt

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
add_library(mltopenfx MODULE
2+
factory.c
3+
mlt_openfx.c mlt_openfx.h
4+
filter_openfx.c
5+
)
6+
7+
file(GLOB YML "*.yml")
8+
add_custom_target(Other_openfx_Files SOURCES
9+
${YML}
10+
)
11+
12+
target_compile_options(mltopenfx PRIVATE ${MLT_COMPILE_OPTIONS})
13+
14+
target_link_libraries(mltopenfx PRIVATE mlt m)
15+
16+
set_target_properties(mltopenfx PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}")
17+
18+
install(TARGETS mltopenfx LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR})
19+
20+
install(FILES filter_openfx.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/openfx)

src/modules/openfx/factory.c

+285
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
/*
2+
* factory.c -- the factory method interfaces
3+
* Copyright (C) 2024 Meltytech, LLC
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 Foundation,
17+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
20+
#include "mlt_openfx.h"
21+
22+
extern OfxHost MltOfxHost;
23+
24+
static OfxStatus (*OfxSetHostFn)(const OfxHost *host);
25+
static OfxPlugin *(*OfxGetPluginFn) (int nth);
26+
static int (*OfxGetNumberOfPluginsFn) (void);
27+
static int NumberOfPlugins;
28+
mlt_properties mltofx_context;
29+
mlt_properties mltofx_dl;
30+
31+
#if defined (__linux__) || defined (__FreeBSD__)
32+
33+
#define OFX_DIRLIST_SEP_CHARS ":;"
34+
#define OFX_DIRSEP "/"
35+
#include <dirent.h>
36+
37+
static const char *getArchStr()
38+
{
39+
if(sizeof(void *) == 4) {
40+
#if defined(__linux__)
41+
return "Linux-x86";
42+
#else
43+
return "FreeBSD-x86";
44+
#endif
45+
}
46+
else {
47+
#if defined(__linux__)
48+
return "Linux-x86-64";
49+
#else
50+
return "FreeBSD-x86-64";
51+
#endif
52+
}
53+
}
54+
55+
#define OFX_ARCHSTR getArchStr()
56+
57+
#elif defined (__APPLE__)
58+
59+
#define OFX_DIRLIST_SEP_CHARS ";:"
60+
#if defined(__x86_64) || defined(__x86_64__)
61+
#define OFX_ARCHSTR "MacOS-x86-64"
62+
#else
63+
#define OFX_ARCHSTR "MacOS"
64+
#endif
65+
#define OFX_DIRSEP "/"
66+
#include <dirent.h>
67+
68+
#elif defined (WINDOWS)
69+
#define OFX_DIRLIST_SEP_CHARS ";"
70+
#ifdef _WIN64
71+
#define OFX_ARCHSTR "win64"
72+
#else
73+
#define OFX_ARCHSTR "win32"
74+
#endif
75+
#define OFX_DIRSEP "\\"
76+
77+
#include "shlobj.h"
78+
#include "tchar.h"
79+
#endif
80+
81+
extern mlt_filter filter_openfx_init(mlt_profile profile,
82+
mlt_service_type type,
83+
const char *id,
84+
char *arg);
85+
86+
static void plugin_mgr_destroy(mlt_properties p)
87+
{
88+
int cN = mlt_properties_count(mltofx_context);
89+
90+
int j;
91+
for (j = 0; j < cN; ++j)
92+
{
93+
char *id = mlt_properties_get_name (mltofx_context, j);
94+
mlt_properties pb = (mlt_properties) mlt_properties_get_data(mltofx_context, id, NULL);
95+
96+
char *dli = mlt_properties_get (pb, "dli");
97+
dli[0] = 'g';
98+
int index = mlt_properties_get_int (pb, "index");
99+
100+
OfxPlugin *(*GetPluginFn) (int nth) = mlt_properties_get_data(mltofx_dl, dli, NULL);
101+
102+
if (GetPluginFn != NULL)
103+
{
104+
OfxPlugin *pt = GetPluginFn (index);
105+
if (pt == NULL) continue;
106+
pt->mainEntry (kOfxActionUnload, NULL, NULL, NULL);
107+
}
108+
}
109+
110+
int N = mlt_properties_get_int (p, "N");
111+
112+
int i;
113+
for (i = 0; i < N; ++i)
114+
{
115+
char tstr[12] = {'\0',};
116+
sprintf (tstr, "%d", i);
117+
void *current_dlhandle = mlt_properties_get_data(mltofx_dl, tstr, NULL);
118+
dlclose (current_dlhandle);
119+
}
120+
}
121+
122+
static mlt_properties metadata(mlt_service_type type, const char *id, void *data)
123+
{
124+
char file[PATH_MAX];
125+
snprintf(file, PATH_MAX, "%s/openfx/%s", mlt_environment("MLT_DATA"), (char *) data);
126+
mlt_properties result = mlt_properties_parse_yaml(file);
127+
128+
mlt_properties pb = (mlt_properties) mlt_properties_get_data(mltofx_context, id, NULL);
129+
130+
char *dli = mlt_properties_get (pb, "dli");
131+
int index = mlt_properties_get_int (pb, "index");
132+
133+
OfxPlugin *(*GetPluginFn) (int nth) = mlt_properties_get_data(mltofx_dl, dli, NULL);
134+
OfxPlugin *pt = GetPluginFn (index);
135+
136+
dli[0] = 's';
137+
OfxStatus (*OfxSetHost)(const OfxHost *host) = mlt_properties_get_data(mltofx_dl, dli, NULL);
138+
if (OfxSetHost != NULL) OfxSetHost (&MltOfxHost);
139+
140+
mlt_properties_set (result, "identifier", id);
141+
mlt_properties_set (result, "title", id);
142+
143+
/* parameters */
144+
mlt_properties params = mlt_properties_new();
145+
mlt_properties_set_data(result,
146+
"parameters",
147+
params,
148+
0,
149+
(mlt_destructor) mlt_properties_close,
150+
NULL);
151+
152+
mltofx_fetch_params (pt, params);
153+
return result;
154+
}
155+
156+
MLT_REPOSITORY
157+
{
158+
MltOfxHost.host = (OfxPropertySetHandle) mlt_properties_new ();
159+
mltofx_init_host_properties (MltOfxHost.host);
160+
161+
char *dir, *openfx_path = getenv("OFX_PLUGIN_PATH");
162+
size_t archstr_len = strlen (OFX_ARCHSTR);
163+
164+
mltofx_context = mlt_properties_new ();
165+
mltofx_dl = mlt_properties_new ();
166+
167+
if (openfx_path)
168+
{
169+
int dli = 0;
170+
171+
for (dir = strtok(openfx_path, MLT_DIRLIST_DELIMITER); dir;
172+
dir = strtok(NULL, MLT_DIRLIST_DELIMITER))
173+
{
174+
size_t dir_len = strlen (dir);
175+
176+
DIR *d = opendir(dir);
177+
if (!d) continue;
178+
179+
struct dirent *de = readdir(d);
180+
while (de)
181+
{
182+
char *name = de->d_name;
183+
184+
char *bni = NULL;
185+
if ((bni = strstr (name, ".ofx.bundle")) != NULL)
186+
{
187+
char *barename = strndup (name, (int) (bni - name) + 4);
188+
size_t name_len = (size_t) (bni - name) + 4 + 7;
189+
/* 12b sizeof `Contents` word, 1 sizeof null byte */
190+
char *binpath = malloc(dir_len + name_len + 12 + (name_len-7) + archstr_len + 1);
191+
sprintf(binpath, "%s/%s/Contents/%s/%s", dir, name, OFX_ARCHSTR, barename);
192+
193+
void *dlhandle = dlopen (binpath, RTLD_LOCAL | RTLD_LAZY);
194+
195+
OfxSetHostFn = dlsym (dlhandle, "OfxSetHost");
196+
197+
OfxGetPluginFn = dlsym (dlhandle, "OfxGetPlugin");
198+
OfxGetNumberOfPluginsFn = dlsym (dlhandle, "OfxGetNumberOfPlugins");
199+
NumberOfPlugins = OfxGetNumberOfPluginsFn ();
200+
201+
char dl_n[16] = {'\0',};
202+
sprintf (dl_n, "%d", dli);
203+
204+
mlt_properties_set_data(mltofx_dl,
205+
dl_n,
206+
dlhandle,
207+
0,
208+
NULL,
209+
NULL);
210+
dl_n[0] = '\0';
211+
sprintf (dl_n, "gn%d", dli);
212+
mlt_properties_set_data(mltofx_dl,
213+
dl_n,
214+
OfxGetNumberOfPluginsFn,
215+
0,
216+
(mlt_destructor) mlt_properties_close,
217+
NULL);
218+
dl_n[0] = '\0';
219+
sprintf (dl_n, "s%d", dli);
220+
mlt_properties_set_data(mltofx_dl,
221+
dl_n,
222+
OfxSetHostFn,
223+
0,
224+
(mlt_destructor) mlt_properties_close,
225+
NULL);
226+
227+
dl_n[0] = '\0';
228+
sprintf (dl_n, "g%d", dli);
229+
mlt_properties_set_data(mltofx_dl,
230+
dl_n,
231+
OfxGetPluginFn,
232+
0,
233+
(mlt_destructor) mlt_properties_close,
234+
NULL);
235+
236+
dli++;
237+
238+
if (OfxGetPluginFn == NULL) goto parse_error;
239+
240+
int i;
241+
for (i = 0; i < NumberOfPlugins; ++i)
242+
{
243+
OfxPlugin *plugin_ptr = OfxGetPluginFn (i);
244+
245+
char *s = NULL;
246+
size_t pluginIdentifier_len = strlen (plugin_ptr->pluginIdentifier);
247+
s = malloc (pluginIdentifier_len + 8);
248+
sprintf (s, "openfx.%s", plugin_ptr->pluginIdentifier);
249+
250+
mlt_properties p;
251+
p = mlt_properties_new ();
252+
mlt_properties_set_data(mltofx_context,
253+
s,
254+
p,
255+
0,
256+
(mlt_destructor) mlt_properties_close,
257+
NULL);
258+
259+
mlt_properties_set(p, "dli", dl_n);
260+
mlt_properties_set_int(p, "index", i);
261+
262+
/* WIP: this is only creating them as filter I should find a way to see howto detect producers
263+
if they exists in OpenFX plugins
264+
*/
265+
MLT_REGISTER(mlt_service_filter_type, s, filter_openfx_init);
266+
MLT_REGISTER_METADATA(mlt_service_filter_type, s, metadata, "filter_openfx.yml");
267+
268+
}
269+
270+
271+
parse_error:
272+
273+
free (binpath);
274+
free (barename);
275+
}
276+
277+
de = readdir(d);
278+
}
279+
280+
}
281+
282+
mlt_properties_set_int(mltofx_dl, "N", dli);
283+
mlt_factory_register_for_clean_up(mltofx_dl, (mlt_destructor) plugin_mgr_destroy);
284+
}
285+
}

0 commit comments

Comments
 (0)