Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 55 additions & 10 deletions src/modules/openfx/factory.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,33 +252,78 @@ static void scan_ofx_dir(mlt_repository repository, const char *dir, int *dli, i
if (!plugin_ptr)
break;

int detected = mltofx_detect_plugin(plugin_ptr);

if (!detected)
const char *plugin_id = plugin_ptr->pluginIdentifier;
if (!plugin_id || !plugin_id[0]) {
mlt_log_warning(
NULL,
"[openfx] skipping plugin with missing identifier in bundle `%s` "
"(index=%d)\n",
name,
i);
continue;
}

char *s = NULL;
size_t pluginIdentifier_len = strlen(plugin_ptr->pluginIdentifier);
size_t pluginIdentifier_len = strlen(plugin_id);
s = malloc(pluginIdentifier_len + 8);
sprintf(s, "openfx.%s", plugin_ptr->pluginIdentifier);

// if colon `:` exists in plugin identifier
// change it to accent sign `^` because `:`
// can cause issues with mlt if put in filter
// name
sprintf(s, "openfx.%s", plugin_id);
Comment thread
bmatherly marked this conversation as resolved.
Outdated
// if colon `:` exists in plugin identifier change it to accent
// sign `^` because `:` can cause issues with mlt if put in
// filter name
char *str_ptr = strchr(s, ':');
while (str_ptr != NULL) {
*str_ptr++ = '^';
str_ptr = strchr(str_ptr, ':');
}

int diagnostics = mltofx_discovery_diagnostics_enabled(plugin_id);
if (diagnostics) {
mlt_log_info(NULL,
"[openfx] discovered plugin `%s` in bundle `%s` (index=%d)\n",
plugin_id ? plugin_id : "(null)",
name,
i);
}

// Skip duplicate service keys before detect/register work.
if (mlt_properties_get_properties(mltofx_context, s) != NULL) {
if (diagnostics) {
mlt_log_info(NULL,
"[openfx] skipped plugin `%s` (index=%d): duplicate service "
"`%s` already registered\n",
plugin_id ? plugin_id : "(null)",
i,
s);
}
free(s);
continue;
}

int detected = mltofx_detect_plugin(plugin_ptr);

if (!detected) {
if (diagnostics) {
mlt_log_info(NULL,
"[openfx] skipped plugin `%s`: detection rejected it\n",
plugin_id ? plugin_id : "(null)");
}
free(s);
continue;
}

mlt_properties p = mlt_properties_new();
mlt_properties_set_properties(mltofx_context, s, p);
mlt_properties_close(p);
mlt_properties_set(p, "dli", dl_n);
mlt_properties_set_int(p, "index", i);
Comment thread
bmatherly marked this conversation as resolved.
MLT_REGISTER(mlt_service_filter_type, s, filter_openfx_init);
MLT_REGISTER_METADATA(mlt_service_filter_type, s, metadata, "filter_openfx.yml");
if (diagnostics) {
mlt_log_info(NULL,
"[openfx] added plugin `%s` as filter `%s`\n",
plugin_id ? plugin_id : "(null)",
s);
}
free(s);
}
} else if (depth == 0 && name[0] != '.') {
Expand Down
113 changes: 112 additions & 1 deletion src/modules/openfx/mlt_openfx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2839,8 +2839,73 @@ void mltofx_set_output_clip_data(OfxPlugin *plugin,
mltofx_apply_cached_clip_preferences(image_effect);
}

// Logs all indexed string values for an OFX property (for discovery diagnostics).
static void mltofx_log_property_diagnostics(int diagnostics,
const char *plugin_id,
mlt_properties props,
const char *property,
const char *label)
{
if (!diagnostics || !props)
return;

int count = 0;
propGetDimension((OfxPropertySetHandle) props, property, &count);
mlt_log_info(NULL,
"[openfx] plugin `%s`: %s count=%d\n",
plugin_id ? plugin_id : "(null)",
label,
count);
for (int i = 0; i < count; ++i) {
char *value = NULL;
if (propGetString((OfxPropertySetHandle) props, property, i, &value) == kOfxStatOK) {
mlt_log_info(NULL,
"[openfx] plugin `%s`: %s[%d]=`%s`\n",
plugin_id ? plugin_id : "(null)",
label,
i,
value ? value : "(null)");
}
}
}

static void mltofx_log_clip_diagnostics(int diagnostics, const char *plugin_id, mlt_properties clips)
{
if (!diagnostics || !clips)
return;

int clip_count = mlt_properties_count(clips);
mlt_log_info(NULL,
"[openfx] plugin `%s`: clip_count=%d\n",
plugin_id ? plugin_id : "(null)",
clip_count);
for (int c = 0; c < clip_count; ++c) {
char *clip_name = mlt_properties_get_name(clips, c);
mlt_properties clip = mlt_properties_get_properties(clips, clip_name);
mlt_properties clip_props = clip ? mlt_properties_get_properties(clip, "props") : NULL;
int optional = 0;
if (clip_props
&& propGetInt((OfxPropertySetHandle) clip_props, kOfxImageClipPropOptional, 0, &optional)
!= kOfxStatOK) {
optional = mlt_properties_get_int(clip_props, kOfxImageClipPropOptional);
}
const char *role = clip_name && !strcmp(clip_name, kOfxImageEffectOutputClipName) ? "output"
: "input";
mlt_log_info(NULL,
"[openfx] plugin `%s`: clip[%d]=`%s` role=%s optional=%d\n",
plugin_id ? plugin_id : "(null)",
c,
clip_name ? clip_name : "(null)",
role,
optional);
}
}

int mltofx_detect_plugin(OfxPlugin *plugin)
{
const char *plugin_id = plugin ? plugin->pluginIdentifier : NULL;
int diagnostics = mltofx_discovery_diagnostics_enabled(plugin_id);

mlt_properties image_effect = mlt_properties_new();
mlt_properties clips = mlt_properties_new();
mlt_properties props = mlt_properties_new();
Expand All @@ -2865,6 +2930,12 @@ int mltofx_detect_plugin(OfxPlugin *plugin)
mltofx_log_status_code(status_code, "kOfxActionLoad");

if (status_code != kOfxStatOK) {
if (diagnostics) {
mlt_log_info(NULL,
"[openfx] rejected plugin `%s`: load failed status=%d\n",
plugin_id ? plugin_id : "(null)",
status_code);
}
return 0;
}
Comment thread
bmatherly marked this conversation as resolved.

Expand All @@ -2873,6 +2944,12 @@ int mltofx_detect_plugin(OfxPlugin *plugin)
mltofx_log_status_code(status_code, "kOfxActionDescribe");

if (status_code != kOfxStatOK) {
if (diagnostics) {
mlt_log_info(NULL,
"[openfx] rejected plugin `%s`: describe failed status=%d\n",
plugin_id ? plugin_id : "(null)",
status_code);
}
plugin->mainEntry(kOfxActionUnload, NULL, NULL, NULL);
return 0;
}
Comment thread
bmatherly marked this conversation as resolved.
Expand All @@ -2889,9 +2966,17 @@ int mltofx_detect_plugin(OfxPlugin *plugin)
describe_in_context_valid = 1;
}

mltofx_log_clip_diagnostics(diagnostics, plugin_id, clips);

int i = 0;
int count = 0;

mltofx_log_property_diagnostics(diagnostics,
plugin_id,
props,
kOfxImageEffectPropSupportedContexts,
"supported_context");

propGetDimension((OfxPropertySetHandle) props, kOfxImageEffectPropSupportedContexts, &count);
for (i = 0; i < count; i++) {
char *context;
Expand All @@ -2904,11 +2989,22 @@ int mltofx_detect_plugin(OfxPlugin *plugin)
}
}
if (i == count) {
if (diagnostics) {
mlt_log_info(NULL,
"[openfx] rejected plugin `%s`: missing filter context\n",
plugin_id ? plugin_id : "(null)");
}
mlt_log_debug(NULL, "[openfx] Plugin not a filter: %s\n", plugin->pluginIdentifier);
// since plugin is not filter then load fail so we must not unload it
return 0;
}
Comment thread
bmatherly marked this conversation as resolved.

mltofx_log_property_diagnostics(diagnostics,
plugin_id,
props,
kOfxImageEffectPropSupportedPixelDepths,
"supported_pixel_depth");

count = 0;

propGetDimension((OfxPropertySetHandle) props, kOfxImageEffectPropSupportedPixelDepths, &count);
Expand All @@ -2924,15 +3020,30 @@ int mltofx_detect_plugin(OfxPlugin *plugin)
}
}
if (i == count) {
if (diagnostics) {
mlt_log_info(NULL,
"[openfx] rejected plugin `%s`: no supported pixel depth\n",
plugin_id ? plugin_id : "(null)");
}
mlt_log_verbose(NULL,
"[openfx] Plugin does not support byte, short, half, or float pixels: %s\n",
plugin->pluginIdentifier);
// since no pixel depth is supported by us then plugin is load fail so we must not unload it
return 0;
Comment thread
bmatherly marked this conversation as resolved.
Outdated
}

if (describe_in_context_valid)
if (describe_in_context_valid) {
if (diagnostics) {
mlt_log_info(NULL, "[openfx] accepted plugin `%s`\n", plugin_id ? plugin_id : "(null)");
}
return 1;
}
Comment thread
bmatherly marked this conversation as resolved.

if (diagnostics) {
mlt_log_info(NULL,
"[openfx] rejected plugin `%s`: missing host feature in describeInContext\n",
plugin_id ? plugin_id : "(null)");
}

plugin->mainEntry(kOfxActionUnload, NULL, NULL, NULL);
mlt_properties_close(image_effect);
Expand Down
24 changes: 24 additions & 0 deletions src/modules/openfx/mlt_openfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,30 @@ typedef enum {
mltofx_components_rgba = 2,
} mltofx_components_mask;

// Set to 1 to print OpenFX discovery diagnostics during repository initialization.
#ifndef MLTOFX_DISCOVERY_DIAGNOSTICS
#define MLTOFX_DISCOVERY_DIAGNOSTICS 0
#endif

// Optional plugin identifier substring filter for diagnostics (example: "MergeDifference").
// Set to NULL or "" to log all detected OpenFX plugins.
#ifndef MLTOFX_DISCOVERY_DIAGNOSTICS_PLUGIN
#define MLTOFX_DISCOVERY_DIAGNOSTICS_PLUGIN NULL
#endif

static inline int mltofx_discovery_diagnostics_enabled(const char *plugin_identifier)
{
#if MLTOFX_DISCOVERY_DIAGNOSTICS
const char *filter = MLTOFX_DISCOVERY_DIAGNOSTICS_PLUGIN;
if (!filter || !filter[0])
return 1;
return plugin_identifier && strstr(plugin_identifier, filter);
#else
(void) plugin_identifier;
return 0;
#endif
}

void mltofx_init_host_properties(OfxPropertySetHandle host_properties);

void mltofx_create_instance(OfxPlugin *plugin, mlt_properties image_effect);
Expand Down
Loading