Skip to content

Commit 7620be4

Browse files
committed
Merge branch 'master' of github.com:mltframework/mlt
2 parents 42541f3 + b7bf8df commit 7620be4

1 file changed

Lines changed: 203 additions & 20 deletions

File tree

src/modules/openfx/mlt_openfx.c

Lines changed: 203 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,26 @@ static inline float f16_to_f32(uint16_t h)
7474
return f;
7575
}
7676

77+
static int mltofx_source_prefers_top_left_origin(const OfxPlugin *plugin,
78+
const char *depth_format,
79+
int is_source)
80+
{
81+
if (!plugin || !plugin->pluginIdentifier || !depth_format)
82+
return 0;
83+
84+
// GMIC's byte-depth path expects top-left memory addressing for Source.
85+
if (is_source && !strncmp(plugin->pluginIdentifier, "eu.gmic.", 8)
86+
&& !strcmp(depth_format, kOfxBitDepthByte)) {
87+
return 1;
88+
}
89+
90+
// NTSC-rs crashes without top-left addressing for Source, but only in the 16-bit path.
91+
if (!strncmp(plugin->pluginIdentifier, "wtf.vala:NtscRs", 15)) {
92+
return strcmp(depth_format, kOfxBitDepthByte);
93+
}
94+
return 0;
95+
}
96+
7797
uint16_t *mltofx_rgba64_to_half(const uint16_t *src, int n_pixels)
7898
{
7999
int count = n_pixels * 4;
@@ -766,6 +786,92 @@ static OfxStatus paramGetPropertySet(OfxParamHandle param, OfxPropertySetHandle
766786
return kOfxStatOK;
767787
}
768788

789+
static void mltofx_initialize_param_value_from_default(mlt_properties param)
790+
{
791+
if (!param)
792+
return;
793+
794+
char *param_type = mlt_properties_get(param, "t");
795+
mlt_properties param_props = mlt_properties_get_properties(param, "p");
796+
if (!param_type || !param_props)
797+
return;
798+
799+
if (strcmp(param_type, kOfxParamTypeInteger) == 0
800+
|| strcmp(param_type, kOfxParamTypeBoolean) == 0
801+
|| strcmp(param_type, kOfxParamTypeInteger2D) == 0
802+
|| strcmp(param_type, kOfxParamTypeInteger3D) == 0) {
803+
int count = 1;
804+
if (strcmp(param_type, kOfxParamTypeInteger2D) == 0)
805+
count = 2;
806+
else if (strcmp(param_type, kOfxParamTypeInteger3D) == 0)
807+
count = 3;
808+
for (int i = 0; i < count; ++i) {
809+
int value = 0;
810+
if (propGetInt((OfxPropertySetHandle) param_props, kOfxParamPropDefault, i, &value)
811+
== kOfxStatOK) {
812+
propSetInt((OfxPropertySetHandle) param_props, "MltOfxParamValue", i, value);
813+
}
814+
}
815+
} else if (strcmp(param_type, kOfxParamTypeDouble) == 0
816+
|| strcmp(param_type, kOfxParamTypeDouble2D) == 0
817+
|| strcmp(param_type, kOfxParamTypeDouble3D) == 0
818+
|| strcmp(param_type, kOfxParamTypeRGB) == 0
819+
|| strcmp(param_type, kOfxParamTypeRGBA) == 0) {
820+
int count = 1;
821+
if (strcmp(param_type, kOfxParamTypeDouble2D) == 0)
822+
count = 2;
823+
else if (strcmp(param_type, kOfxParamTypeDouble3D) == 0
824+
|| strcmp(param_type, kOfxParamTypeRGB) == 0)
825+
count = 3;
826+
else if (strcmp(param_type, kOfxParamTypeRGBA) == 0)
827+
count = 4;
828+
for (int i = 0; i < count; ++i) {
829+
double value = 0.0;
830+
if (propGetDouble((OfxPropertySetHandle) param_props, kOfxParamPropDefault, i, &value)
831+
== kOfxStatOK) {
832+
propSetDouble((OfxPropertySetHandle) param_props, "MltOfxParamValue", i, value);
833+
}
834+
}
835+
} else if (strcmp(param_type, kOfxParamTypeString) == 0
836+
|| strcmp(param_type, kOfxParamTypeStrChoice) == 0) {
837+
char *value = NULL;
838+
if (propGetString((OfxPropertySetHandle) param_props, kOfxParamPropDefault, 0, &value)
839+
== kOfxStatOK
840+
&& value) {
841+
propSetString((OfxPropertySetHandle) param_props, "MltOfxParamValue", 0, value);
842+
}
843+
} else if (strcmp(param_type, kOfxParamTypeChoice) == 0) {
844+
int default_index = 0;
845+
if (propGetInt((OfxPropertySetHandle) param_props, kOfxParamPropDefault, 0, &default_index)
846+
== kOfxStatOK) {
847+
char *label = NULL;
848+
if (propGetString((OfxPropertySetHandle) param_props,
849+
kOfxParamPropChoiceOption,
850+
default_index,
851+
&label)
852+
== kOfxStatOK
853+
&& label) {
854+
propSetString((OfxPropertySetHandle) param_props, "MltOfxParamValue", 0, label);
855+
}
856+
}
857+
}
858+
}
859+
860+
static void mltofx_initialize_param_values(mlt_properties iparams)
861+
{
862+
if (!iparams)
863+
return;
864+
865+
int count = mlt_properties_count(iparams);
866+
for (int i = 1; i < count; ++i) {
867+
char *name = mlt_properties_get_name(iparams, i);
868+
if (!name)
869+
continue;
870+
mlt_properties param = mlt_properties_get_properties(iparams, name);
871+
mltofx_initialize_param_value_from_default(param);
872+
}
873+
}
874+
769875
static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
770876
{
771877
mlt_properties param = (mlt_properties) paramHandle;
@@ -780,7 +886,7 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
780886
if (status != kOfxStatOK) {
781887
status = propGetInt((OfxPropertySetHandle) param_props, "OfxParamPropDefault", 0, value);
782888
if (status != kOfxStatOK)
783-
return kOfxStatErrUnknown;
889+
*value = 0;
784890
}
785891
} else if (strcmp(param_type, kOfxParamTypeChoice) == 0) {
786892
// MltOfxParamValue stores the string label; convert to integer index for the OFX plugin.
@@ -810,12 +916,12 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
810916
0,
811917
value);
812918
if (status != kOfxStatOK)
813-
return kOfxStatErrUnknown;
919+
*value = 0;
814920
}
815921
} else {
816922
status = propGetInt((OfxPropertySetHandle) param_props, "OfxParamPropDefault", 0, value);
817923
if (status != kOfxStatOK)
818-
return kOfxStatErrUnknown;
924+
*value = 0;
819925
}
820926
} else if (strcmp(param_type, kOfxParamTypeDouble) == 0) {
821927
double *value = va_arg(ap, double *);
@@ -827,7 +933,7 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
827933
0,
828934
value);
829935
if (status != kOfxStatOK)
830-
return kOfxStatErrUnknown;
936+
*value = 0.0;
831937
}
832938
} else if (strcmp(param_type, kOfxParamTypeString) == 0
833939
|| strcmp(param_type, kOfxParamTypeStrChoice) == 0) {
@@ -840,7 +946,7 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
840946
0,
841947
value);
842948
if (status != kOfxStatOK)
843-
return kOfxStatErrUnknown;
949+
*value = "";
844950
}
845951
} else if (strcmp(param_type, kOfxParamTypeRGBA) == 0) {
846952
double *red = va_arg(ap, double *);
@@ -875,8 +981,12 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
875981
"OfxParamPropDefault",
876982
3,
877983
alpha);
878-
if (status != kOfxStatOK)
879-
return kOfxStatErrUnknown;
984+
if (status != kOfxStatOK) {
985+
*red = 0.0;
986+
*green = 0.0;
987+
*blue = 0.0;
988+
*alpha = 1.0;
989+
}
880990
}
881991
} else if (strcmp(param_type, kOfxParamTypeRGB) == 0) {
882992
double *red = va_arg(ap, double *);
@@ -903,8 +1013,11 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
9031013
"OfxParamPropDefault",
9041014
2,
9051015
blue);
906-
if (status != kOfxStatOK)
907-
return kOfxStatErrUnknown;
1016+
if (status != kOfxStatOK) {
1017+
*red = 0.0;
1018+
*green = 0.0;
1019+
*blue = 0.0;
1020+
}
9081021
}
9091022
} else if (strcmp(param_type, kOfxParamTypeDouble2D) == 0) {
9101023
double *X = va_arg(ap, double *);
@@ -922,8 +1035,10 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
9221035
"OfxParamPropDefault",
9231036
1,
9241037
Y);
925-
if (status != kOfxStatOK)
926-
return kOfxStatErrUnknown;
1038+
if (status != kOfxStatOK) {
1039+
*X = 0.0;
1040+
*Y = 0.0;
1041+
}
9271042
}
9281043
} else if (strcmp(param_type, kOfxParamTypeInteger2D) == 0) {
9291044
int *X = va_arg(ap, int *);
@@ -937,8 +1052,10 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
9371052
status = propGetInt((OfxPropertySetHandle) param_props, "OfxParamPropDefault", 0, X);
9381053
if (status == kOfxStatOK)
9391054
status = propGetInt((OfxPropertySetHandle) param_props, "OfxParamPropDefault", 1, Y);
940-
if (status != kOfxStatOK)
941-
return kOfxStatErrUnknown;
1055+
if (status != kOfxStatOK) {
1056+
*X = 0;
1057+
*Y = 0;
1058+
}
9421059
}
9431060
} else if (strcmp(param_type, kOfxParamTypeDouble3D) == 0) {
9441061
double *X = va_arg(ap, double *);
@@ -964,8 +1081,11 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
9641081
"OfxParamPropDefault",
9651082
2,
9661083
Z);
967-
if (status != kOfxStatOK)
968-
return kOfxStatErrUnknown;
1084+
if (status != kOfxStatOK) {
1085+
*X = 0.0;
1086+
*Y = 0.0;
1087+
*Z = 0.0;
1088+
}
9691089
}
9701090
} else if (strcmp(param_type, kOfxParamTypeInteger3D) == 0) {
9711091
int *X = va_arg(ap, int *);
@@ -984,8 +1104,11 @@ static OfxStatus paramGetValueImpl(OfxParamHandle paramHandle, va_list ap)
9841104
status = propGetInt((OfxPropertySetHandle) param_props, "OfxParamPropDefault", 1, Y);
9851105
if (status == kOfxStatOK)
9861106
status = propGetInt((OfxPropertySetHandle) param_props, "OfxParamPropDefault", 2, Z);
987-
if (status != kOfxStatOK)
988-
return kOfxStatErrUnknown;
1107+
if (status != kOfxStatOK) {
1108+
*X = 0;
1109+
*Y = 0;
1110+
*Z = 0;
1111+
}
9891112
}
9901113
}
9911114

@@ -2095,6 +2218,53 @@ static void mltofx_apply_cached_clip_preferences(mlt_properties image_effect)
20952218
mltofx_apply_clip_preferences(image_effect, pref_args);
20962219
}
20972220

2221+
static void mltofx_set_mask_clip_disconnected(mlt_properties image_effect)
2222+
{
2223+
if (!image_effect)
2224+
return;
2225+
2226+
mlt_properties mask_clip = NULL;
2227+
mlt_properties mask_clip_props = NULL;
2228+
clipGetHandle((OfxImageEffectHandle) image_effect,
2229+
"Mask",
2230+
(OfxImageClipHandle *) &mask_clip,
2231+
(OfxPropertySetHandle *) &mask_clip_props);
2232+
if (!mask_clip_props)
2233+
return;
2234+
2235+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImageClipPropConnected, 0, 0);
2236+
propSetString((OfxPropertySetHandle) mask_clip_props,
2237+
kOfxImageEffectPropComponents,
2238+
0,
2239+
kOfxImageComponentNone);
2240+
propSetString((OfxPropertySetHandle) mask_clip_props,
2241+
kOfxImageClipPropUnmappedComponents,
2242+
0,
2243+
kOfxImageComponentNone);
2244+
propSetString((OfxPropertySetHandle) mask_clip_props,
2245+
kOfxImageEffectPropPixelDepth,
2246+
0,
2247+
kOfxBitDepthNone);
2248+
propSetString((OfxPropertySetHandle) mask_clip_props,
2249+
kOfxImageClipPropUnmappedPixelDepth,
2250+
0,
2251+
kOfxBitDepthNone);
2252+
propSetDouble((OfxPropertySetHandle) mask_clip_props, kOfxImagePropPixelAspectRatio, 0, 1.0);
2253+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImagePropBounds, 0, 0);
2254+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImagePropBounds, 1, 0);
2255+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImagePropBounds, 2, 0);
2256+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImagePropBounds, 3, 0);
2257+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImagePropRegionOfDefinition, 0, 0);
2258+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImagePropRegionOfDefinition, 1, 0);
2259+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImagePropRegionOfDefinition, 2, 0);
2260+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImagePropRegionOfDefinition, 3, 0);
2261+
propSetInt((OfxPropertySetHandle) mask_clip_props, kOfxImageEffectPropRenderQualityDraft, 0, 0);
2262+
propSetInt((OfxPropertySetHandle) mask_clip_props,
2263+
"uk.co.thefoundry.OfxImageEffectPropView",
2264+
0,
2265+
0);
2266+
}
2267+
20982268
const void *MltOfxfetchSuite(OfxPropertySetHandle host, const char *suiteName, int suiteVersion)
20992269
{
21002270
mlt_log_debug(NULL, "[openfx] fetchSuite: `%s` v%d\n", suiteName, suiteVersion);
@@ -2366,8 +2536,8 @@ void mltofx_set_source_clip_data(OfxPlugin *plugin,
23662536

23672537
int row_bytes = width * depth_byte_size;
23682538
uint8_t *image_origin = image;
2369-
int gmic = !strncmp(plugin->pluginIdentifier, "eu.gmic.", 8);
2370-
if (!gmic && !top_left_origin && row_bytes > 0 && height > 0) {
2539+
int top_left_compat = mltofx_source_prefers_top_left_origin(plugin, depth_format, 1);
2540+
if (!top_left_compat && !top_left_origin && row_bytes > 0 && height > 0) {
23712541
// OFX CPU images are addressed from lower-left. Point data at the
23722542
// first byte of the last scanline and use negative row bytes.
23732543
image_origin = image + ((size_t) (height - 1) * (size_t) row_bytes);
@@ -2466,6 +2636,8 @@ void mltofx_set_source_clip_data(OfxPlugin *plugin,
24662636

24672637
propSetInt((OfxPropertySetHandle) clip_prop, kOfxImageClipPropConnected, 0, 1);
24682638

2639+
mltofx_set_mask_clip_disconnected(image_effect);
2640+
24692641
// Preserve plugin-selected clip preferences across clip data refreshes.
24702642
mltofx_apply_cached_clip_preferences(image_effect);
24712643
}
@@ -2512,7 +2684,8 @@ void mltofx_set_output_clip_data(OfxPlugin *plugin,
25122684

25132685
int row_bytes = width * depth_byte_size;
25142686
uint8_t *image_origin = image;
2515-
if (!top_left_origin && row_bytes > 0 && height > 0) {
2687+
int top_left_compat = mltofx_source_prefers_top_left_origin(plugin, depth_format, 0);
2688+
if (!top_left_compat && !top_left_origin && row_bytes > 0 && height > 0) {
25162689
// OFX CPU images are addressed from lower-left. Point data at the
25172690
// first byte of the last scanline and use negative row bytes.
25182691
image_origin = image + ((size_t) (height - 1) * (size_t) row_bytes);
@@ -2608,6 +2781,10 @@ void mltofx_set_output_clip_data(OfxPlugin *plugin,
26082781
0,
26092782
pixel_aspect_ratio);
26102783

2784+
propSetInt((OfxPropertySetHandle) clip_prop, kOfxImageClipPropConnected, 0, 1);
2785+
2786+
mltofx_set_mask_clip_disconnected(image_effect);
2787+
26112788
// Preserve plugin-selected clip preferences across clip data refreshes.
26122789
mltofx_apply_cached_clip_preferences(image_effect);
26132790
}
@@ -2774,6 +2951,8 @@ void *mltofx_fetch_params(OfxPlugin *plugin, mlt_properties params, mlt_properti
27742951
propSetString((OfxPropertySetHandle) clip_props, kOfxImagePropField, 0, kOfxImageFieldNone);
27752952
}
27762953

2954+
mltofx_set_mask_clip_disconnected(image_effect);
2955+
27772956
clip = NULL, clip_props = NULL;
27782957
clipGetHandle((OfxImageEffectHandle) image_effect,
27792958
"Output",
@@ -3092,6 +3271,10 @@ void *mltofx_fetch_params(OfxPlugin *plugin, mlt_properties params, mlt_properti
30923271
}
30933272
}
30943273

3274+
// Seed runtime param values from OFX defaults so plugins read stable values
3275+
// even when the user has not overridden a parameter.
3276+
mltofx_initialize_param_values(iparams);
3277+
30953278
mlt_properties_close(clips);
30963279
mlt_properties_close(iparams);
30973280
mlt_properties_close(props);

0 commit comments

Comments
 (0)