windows frei0r support done

This commit is contained in:
itsmattkc
2019-01-20 21:06:21 +11:00
parent 80b77a382b
commit d5eab3673c
15 changed files with 305 additions and 136 deletions
+6 -6
View File
@@ -50,10 +50,7 @@ bool shaders_are_enabled = true;
QVector<EffectMeta> effects;
Effect* create_effect(Clip* c, const EffectMeta* em) {
if (!em->filename.isEmpty()) {
// load effect from file
return new Effect(c, em);
} else if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) {
if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) {
// must be an internal effect
switch (em->internal) {
case EFFECT_INTERNAL_TRANSFORM: return new TransformEffect(c, em);
@@ -72,6 +69,9 @@ Effect* create_effect(Clip* c, const EffectMeta* em) {
#endif
case EFFECT_INTERNAL_FREI0R: return new Frei0rEffect(c, em);
}
} else if (!em->filename.isEmpty()) {
// load effect from file
return new Effect(c, em);
} else {
qCritical() << "Invalid effect data";
QMessageBox::critical(mainWindow,
@@ -118,7 +118,7 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
// set up UI from effect file
container->setText(em->name);
if (!em->filename.isEmpty()) {
if (!em->filename.isEmpty() && em->internal == -1) {
QFile effect_file(em->filename);
if (effect_file.open(QFile::ReadOnly)) {
QXmlStreamReader reader(&effect_file);
@@ -563,7 +563,7 @@ void Effect::load(QXmlStreamReader& stream) {
void Effect::custom_load(QXmlStreamReader &) {}
void Effect::save(QXmlStreamWriter& stream) {
stream.writeAttribute("name", meta->name);
stream.writeAttribute("name", meta->category + "/" + meta->name);
stream.writeAttribute("enabled", QString::number(is_enabled()));
for (int i=0;i<rows.size();i++) {
+29 -27
View File
@@ -41,35 +41,37 @@ double log_volume(double linear);
Effect* create_effect(Clip* c, const EffectMeta *em);
const EffectMeta* get_internal_meta(int internal_id, int type);
#define EFFECT_TYPE_INVALID 0
#define EFFECT_TYPE_VIDEO 1
#define EFFECT_TYPE_AUDIO 2
#define EFFECT_TYPE_EFFECT 3
#define EFFECT_TYPE_TRANSITION 4
enum EffectType {
EFFECT_TYPE_INVALID,
EFFECT_TYPE_VIDEO,
EFFECT_TYPE_AUDIO,
EFFECT_TYPE_EFFECT,
EFFECT_TYPE_TRANSITION
};
#define EFFECT_KEYFRAME_LINEAR 0
#define EFFECT_KEYFRAME_HOLD 1
#define EFFECT_KEYFRAME_BEZIER 2
enum EffectKeyframeType {
EFFECT_KEYFRAME_LINEAR,
EFFECT_KEYFRAME_BEZIER,
EFFECT_KEYFRAME_HOLD
};
#define EFFECT_INTERNAL_TRANSFORM 0
#define EFFECT_INTERNAL_TEXT 1
#define EFFECT_INTERNAL_SOLID 2
#define EFFECT_INTERNAL_NOISE 3
#define EFFECT_INTERNAL_VOLUME 4
#define EFFECT_INTERNAL_PAN 5
#define EFFECT_INTERNAL_TONE 6
#define EFFECT_INTERNAL_SHAKE 7
#define EFFECT_INTERNAL_TIMECODE 8
#define EFFECT_INTERNAL_MASK 9
#define EFFECT_INTERNAL_FILLLEFTRIGHT 10
#define EFFECT_INTERNAL_VST 11
#define EFFECT_INTERNAL_CORNERPIN 12
#define EFFECT_INTERNAL_FREI0R 13
#define EFFECT_INTERNAL_COUNT 14
#define KEYFRAME_TYPE_LINEAR 0
#define KEYFRAME_TYPE_BEZIER 1
#define KEYFRAME_TYPE_HOLD 2
enum EffectInternal {
EFFECT_INTERNAL_TRANSFORM,
EFFECT_INTERNAL_TEXT,
EFFECT_INTERNAL_SOLID,
EFFECT_INTERNAL_NOISE,
EFFECT_INTERNAL_VOLUME,
EFFECT_INTERNAL_PAN,
EFFECT_INTERNAL_TONE,
EFFECT_INTERNAL_SHAKE,
EFFECT_INTERNAL_TIMECODE,
EFFECT_INTERNAL_MASK,
EFFECT_INTERNAL_FILLLEFTRIGHT,
EFFECT_INTERNAL_VST,
EFFECT_INTERNAL_CORNERPIN,
EFFECT_INTERNAL_FREI0R,
EFFECT_INTERNAL_COUNT
};
struct GLTextureCoords {
int grid_size;
+44 -44
View File
@@ -86,53 +86,53 @@ EffectField::EffectField(EffectRow *parent, int t, const QString &i) :
connect(efc, SIGNAL(changed()), this, SLOT(ui_element_change()));
}
break;
}
}
}
double EffectField::get_validated_keyframe_handle(int key, bool post) {
int comp_key = -1;
int comp_key = -1;
// find keyframe before or after this one
for (int i=0;i<keyframes.size();i++) {
if (i != key
&& ((keyframes.at(i).time > keyframes.at(key).time) == post)
&& (comp_key == -1
|| ((keyframes.at(i).time < keyframes.at(comp_key).time) == post))) {
// compare with next keyframe for post or previous frame for pre
comp_key = i;
}
}
// find keyframe before or after this one
for (int i=0;i<keyframes.size();i++) {
if (i != key
&& ((keyframes.at(i).time > keyframes.at(key).time) == post)
&& (comp_key == -1
|| ((keyframes.at(i).time < keyframes.at(comp_key).time) == post))) {
// compare with next keyframe for post or previous frame for pre
comp_key = i;
}
}
double adjusted_key = post ? keyframes.at(key).post_handle_x : keyframes.at(key).pre_handle_x;
double adjusted_key = post ? keyframes.at(key).post_handle_x : keyframes.at(key).pre_handle_x;
// if this is the earliest/latest keyframe, no validation is required
if (comp_key == -1) {
return adjusted_key;
}
// if this is the earliest/latest keyframe, no validation is required
if (comp_key == -1) {
return adjusted_key;
}
double comp = keyframes.at(comp_key).time - keyframes.at(key).time;
double comp = keyframes.at(comp_key).time - keyframes.at(key).time;
// if comp keyframe is bezier, validate with its accompanying handle
if (keyframes.at(comp_key).type == KEYFRAME_TYPE_BEZIER) {
double relative_comp_handle = comp + (post ? keyframes.at(comp_key).pre_handle_x : keyframes.at(comp_key).post_handle_x);
// return an average
if ((post && keyframes.at(key).post_handle_x > relative_comp_handle)
|| (!post && keyframes.at(key).pre_handle_x < relative_comp_handle)) {
adjusted_key = (adjusted_key + relative_comp_handle)*0.5;
}
}
// if comp keyframe is bezier, validate with its accompanying handle
if (keyframes.at(comp_key).type == EFFECT_KEYFRAME_BEZIER) {
double relative_comp_handle = comp + (post ? keyframes.at(comp_key).pre_handle_x : keyframes.at(comp_key).post_handle_x);
// return an average
if ((post && keyframes.at(key).post_handle_x > relative_comp_handle)
|| (!post && keyframes.at(key).pre_handle_x < relative_comp_handle)) {
adjusted_key = (adjusted_key + relative_comp_handle)*0.5;
}
}
// don't let handle go beyond the compare keyframe's time
if (post == (adjusted_key > comp)) {
return comp;
}
// don't let handle go beyond the compare keyframe's time
if (post == (adjusted_key > comp)) {
return comp;
}
if (post == (adjusted_key < 0)) {
return 0;
}
if (post == (adjusted_key < 0)) {
return 0;
}
// original value is valid
return adjusted_key;
// original value is valid
return adjusted_key;
}
QVariant EffectField::get_previous_data() {
@@ -162,7 +162,7 @@ QVariant EffectField::get_current_data() {
}
double EffectField::frameToTimecode(long frame) {
return ((double) frame / parent_row->parent_effect->parent_clip->sequence->frame_rate);
return (double(frame) / parent_row->parent_effect->parent_clip->sequence->frame_rate);
}
long EffectField::timecodeToFrame(double timecode) {
@@ -242,22 +242,22 @@ QVariant EffectField::validate_keyframe_data(double timecode, bool async) {
double before_dbl = before_key.data.toDouble();
double after_dbl = after_key.data.toDouble();
if (before_key.type == KEYFRAME_TYPE_HOLD) {
if (before_key.type == EFFECT_KEYFRAME_HOLD) {
// hold
value = before_dbl;
} else if (before_key.type == KEYFRAME_TYPE_BEZIER || after_key.type == KEYFRAME_TYPE_BEZIER) {
} else if (before_key.type == EFFECT_KEYFRAME_BEZIER || after_key.type == EFFECT_KEYFRAME_BEZIER) {
// bezier interpolation
if (before_key.type == KEYFRAME_TYPE_BEZIER && after_key.type == KEYFRAME_TYPE_BEZIER) {
if (before_key.type == EFFECT_KEYFRAME_BEZIER && after_key.type == EFFECT_KEYFRAME_BEZIER) {
// cubic bezier
double t = cubic_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time);
double t = cubic_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time);
value = cubic_from_t(before_dbl, before_dbl+before_key.post_handle_y, after_dbl+after_key.pre_handle_y, after_dbl, t);
} else if (after_key.type == KEYFRAME_TYPE_LINEAR) { // quadratic bezier
} else if (after_key.type == EFFECT_KEYFRAME_LINEAR) { // quadratic bezier
// last keyframe is the bezier one
double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time);
double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, before_key.time+get_validated_keyframe_handle(before_keyframe, true), after_key.time);
value = quad_from_t(before_dbl, before_dbl+before_key.post_handle_y, after_dbl, t);
} else {
// this keyframe is the bezier one
double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time);
double t = quad_t_from_x(timecode*parent_row->parent_effect->parent_clip->sequence->frame_rate, before_key.time, after_key.time+get_validated_keyframe_handle(after_keyframe, false), after_key.time);
value = quad_from_t(before_dbl, after_dbl+after_key.pre_handle_y, after_dbl, t);
}
} else {
+58 -6
View File
@@ -11,6 +11,9 @@
#include <QDebug>
#include <frei0r/frei0r.h>
typedef void (*f0rGetPluginInfo)(f0r_plugin_info_t* info);
void load_internal_effects() {
if (!shaders_are_enabled) qWarning() << "Shaders are disabled, some effects may be nonfunctional";
@@ -48,12 +51,6 @@ void load_internal_effects() {
em.subtype = EFFECT_TYPE_VIDEO;
// TEMPORARY begin
em.name = "Frei0r Plugin";
em.internal = EFFECT_INTERNAL_FREI0R;
effects.append(em);
// TEMPORARY end
em.name = "Transform";
em.category = "Distort";
em.internal = EFFECT_INTERNAL_TRANSFORM;
@@ -165,6 +162,60 @@ void init_effects() {
init_thread->start();
}
void load_frei0r_effects() {
QList<QString> effect_dirs = get_effects_paths();
int lim = effect_dirs.size();
// add extra search paths for frei0r effects
for (int i=0;i<lim;i++) {
effect_dirs.append(QDir(effect_dirs.at(i)).filePath("frei0r"));
}
// add defined paths for frei0r plugins on unix
#if defined(__APPLE__) || defined(__linux__)
#endif
// search for paths
EffectMeta em;
em.category = "Frei0r";
em.type = EFFECT_TYPE_EFFECT;
em.subtype = EFFECT_TYPE_VIDEO;
em.internal = EFFECT_INTERNAL_FREI0R;
for (int i=0;i<effect_dirs.size();i++) {
QDir search_dir(effect_dirs.at(i));
if (search_dir.exists()) {
QList<QString> entry_list = search_dir.entryList(QStringList("*.dll"));
for (int j=0;j<entry_list.size();j++) {
HMODULE effect = LoadLibrary(reinterpret_cast<const wchar_t*>(search_dir.filePath(entry_list.at(j)).utf16()));
if (effect != nullptr) {
f0rGetPluginInfo get_info_func = reinterpret_cast<f0rGetPluginInfo>(GetProcAddress(effect, "f0r_get_plugin_info"));
if (get_info_func != nullptr) {
f0r_plugin_info_t info;
get_info_func(&info);
if (info.plugin_type == F0R_PLUGIN_TYPE_FILTER
&& info.color_model == F0R_COLOR_MODEL_RGBA8888) {
em.name = info.name;
em.path = effect_dirs.at(i);
em.filename = entry_list.at(j);
effects.append(em);
}
// qDebug() << "Found:" << info.name << "by" << info.author;
}
FreeLibrary(effect);
}
// qDebug() << search_dir.filePath(entry_list.at(j));
}
}
}
}
EffectInit::EffectInit() {
panel_effect_controls->effects_loaded.lock();
}
@@ -173,6 +224,7 @@ void EffectInit::run() {
qInfo() << "Initializing effects...";
load_internal_effects();
load_shader_effects();
load_frei0r_effects();
panel_effect_controls->effects_loaded.unlock();
qInfo() << "Finished initializing effects";
}
+1 -1
View File
@@ -197,7 +197,7 @@ void EffectRow::set_keyframe_now(ComboAction* ca) {
}
}
if (exist_key == -1) {
key.type = (f->keyframes.size() == 0) ? KEYFRAME_TYPE_LINEAR : f->keyframes.at(closest_key).type;
key.type = (f->keyframes.size() == 0) ? EFFECT_KEYFRAME_LINEAR : f->keyframes.at(closest_key).type;
key.data = f->get_current_data();//f->keyframes.at(closest_key).data;
unsafe_keys[i] = f->keyframes.size();
f->keyframes.append(key);