merged effects into node structure

This commit is contained in:
itsmattkc
2019-04-12 21:50:52 +10:00
parent 4e4d2b1881
commit b21745f694
127 changed files with 1674 additions and 867 deletions
+1 -1
View File
@@ -127,7 +127,7 @@ void AutoCutSilenceDialog::cut_silence() {
Clip* clip = clips_.at(j);
// Check if this clip is an audio footage clip
if (clip->type() == Track::kTypeAudio
if (clip->type() == olive::kTypeAudio
&& clip->media() != nullptr
&& clip->media_stream()->preview_done) { // TODO provide warning for preview not being done
+10 -10
View File
@@ -33,7 +33,7 @@
#include "panels/timeline.h"
#include "undo/undo.h"
#include "undo/undostack.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "project/media.h"
SpeedDialog::SpeedDialog(QWidget *parent, QVector<Clip*> clips) : QDialog(parent) {
@@ -103,7 +103,7 @@ int SpeedDialog::exec() {
// get default frame rate/percentage
clip_percent = c->speed().value;
if (c->type() == Track::kTypeVideo) {
if (c->type() == olive::kTypeVideo) {
bool process_video = true;
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
FootageStream* ms = c->media_stream();
@@ -131,7 +131,7 @@ int SpeedDialog::exec() {
enable_frame_rate = true;
}
} else if (c->type() == Track::kTypeAudio) {
} else if (c->type() == olive::kTypeAudio) {
maintain_pitch->setEnabled(true);
if (!multiple_audio) {
@@ -192,7 +192,7 @@ void SpeedDialog::percent_update() {
Clip* c = clips_.at(i);
// get frame rate
if (frame_rate->isEnabled() && c->type() == Track::kTypeVideo) {
if (frame_rate->isEnabled() && c->type() == olive::kTypeVideo) {
double clip_fr = c->media_frame_rate() * percent->value();
if (got_fr) {
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
@@ -236,7 +236,7 @@ void SpeedDialog::duration_update() {
}
// get frame rate
if (frame_rate->isEnabled() && c->type() == Track::kTypeVideo) {
if (frame_rate->isEnabled() && c->type() == olive::kTypeVideo) {
double clip_fr = c->media_frame_rate() * clip_pc;
if (got_fr) {
if (!qIsNaN(fr_val) && !qFuzzyCompare(fr_val, clip_fr)) {
@@ -276,7 +276,7 @@ void SpeedDialog::frame_rate_update() {
old_pc_val = qSNaN();
}
if (c->type() == Track::kTypeVideo) {
if (c->type() == olive::kTypeVideo) {
// what would the new speed be based on this frame rate
double new_clip_speed = frame_rate->value() / c->media_frame_rate();
if (!got_pc_val) {
@@ -301,7 +301,7 @@ void SpeedDialog::frame_rate_update() {
for (int i=0;i<clips_.size();i++) {
Clip* c = clips_.at(i);
if (c->type() == Track::kTypeAudio) {
if (c->type() == olive::kTypeAudio) {
long new_clip_len = (qIsNaN(old_pc_val) || qIsNaN(pc_val)) ?
c->length() : qRound((c->length() * c->speed().value) / pc_val);
@@ -376,7 +376,7 @@ void SpeedDialog::accept() {
}
// set maintain audio pitch if the user made a selection
if (c->type() == Track::kTypeAudio
if (c->type() == olive::kTypeAudio
&& maintain_pitch->checkState() != Qt::PartiallyChecked
&& c->speed().maintain_audio_pitch != maintain_pitch->isChecked()) {
audio_pitch_action->AddSetting(c, maintain_pitch->isChecked());
@@ -418,7 +418,7 @@ void SpeedDialog::accept() {
if (i > 0 && !qFuzzyCompare(cached_speed, c->speed().value)) {
can_change_all = false;
}
if (c->type() == Track::kTypeVideo) {
if (c->type() == olive::kTypeVideo) {
if (qIsNaN(cached_fr)) {
cached_fr = c->media_frame_rate();
} else if (!qFuzzyCompare(cached_fr, c->media_frame_rate())) {
@@ -431,7 +431,7 @@ void SpeedDialog::accept() {
// make changes
for (int i=0;i<clips_.size();i++) {
Clip* c = clips_.at(i);
if (c->type() == Track::kTypeVideo) {
if (c->type() == olive::kTypeVideo) {
set_speed(ca, c, frame_rate->value() / c->media_frame_rate(), ripple->isChecked(), earliest_point, longest_ripple);
} else if (can_change_all) {
set_speed(ca, c, frame_rate->value() / cached_fr, ripple->isChecked(), earliest_point, longest_ripple);
+1 -1
View File
@@ -27,7 +27,7 @@
#include "global/config.h"
#include "global/timing.h"
#include "effects/effectrow.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "undo/undo.h"
#include "timeline/clip.h"
#include "timeline/sequence.h"
-1
View File
@@ -26,7 +26,6 @@
#include <QVector>
#include "effects/keyframe.h"
#include "undo/undo.h"
#include "undo/undostack.h"
#include "nodes/nodedatatypes.h"
+2 -2
View File
@@ -22,9 +22,9 @@
#include "ui/labelslider.h"
#include "effects/fields/doublefield.h"
#include "effects/effect.h"
#include "nodes/node.h"
EffectGizmo::EffectGizmo(Effect *parent, int type) :
EffectGizmo::EffectGizmo(Node *parent, int type) :
QObject(parent),
x_field1(nullptr),
x_field_multi1(1.0),
+2 -2
View File
@@ -39,12 +39,12 @@ enum GizmoType {
#include <QColor>
class DoubleField;
class Effect;
class Node;
class EffectGizmo : public QObject {
Q_OBJECT
public:
EffectGizmo(Effect* parent, int type);
EffectGizmo(Node* parent, int type);
QVector<QVector3D> world_pos;
QVector<QPoint> screen_pos;
+82 -143
View File
@@ -24,13 +24,36 @@
#include <QXmlStreamReader>
#include <QDebug>
#include "effects/effect.h"
#include "nodes/node.h"
#include "effects/transition.h"
#include "global/path.h"
#include "panels/panels.h"
#include "panels/effectcontrols.h"
#include "global/config.h"
#include "effects/internal/transformeffect.h"
#include "effects/internal/texteffect.h"
#include "effects/internal/timecodeeffect.h"
#include "effects/internal/solideffect.h"
#include "effects/internal/audionoiseeffect.h"
#include "effects/internal/toneeffect.h"
#include "effects/internal/volumeeffect.h"
#include "effects/internal/paneffect.h"
#include "effects/internal/shakeeffect.h"
#include "effects/internal/cornerpineffect.h"
#include "effects/internal/vsthost.h"
#include "effects/internal/fillleftrighteffect.h"
#include "effects/internal/richtexteffect.h"
#include "effects/internal/crossdissolvetransition.h"
#include "effects/internal/linearfadetransition.h"
#include "effects/internal/logarithmicfadetransition.h"
#include "effects/internal/exponentialfadetransition.h"
#include "nodes/nodes/nodemedia.h"
#include "nodes/nodes/nodeimageoutput.h"
#include "nodes/nodes/nodeshader.h"
QMutex olive::effects_loaded;
void load_internal_effects() {
@@ -38,103 +61,35 @@ void load_internal_effects() {
qWarning() << "Shaders are disabled, some effects may be nonfunctional";
}
EffectMeta em;
olive::node_library.resize(kInvalidNode);
olive::node_library.fill(nullptr);
// load internal effects
em.path = ":/internalshaders";
em.type = EFFECT_TYPE_EFFECT;
em.subtype = Track::kTypeAudio;
em.name = "Volume";
em.internal = EFFECT_INTERNAL_VOLUME;
olive::effects.append(em);
em.name = "Pan";
em.internal = EFFECT_INTERNAL_PAN;
olive::effects.append(em);
em.name = "VST Plugin 2.x";
em.internal = EFFECT_INTERNAL_VST;
olive::effects.append(em);
em.name = "Tone";
em.internal = EFFECT_INTERNAL_TONE;
olive::effects.append(em);
em.name = "Noise";
em.internal = EFFECT_INTERNAL_NOISE;
olive::effects.append(em);
em.name = "Fill Left/Right";
em.internal = EFFECT_INTERNAL_FILLLEFTRIGHT;
olive::effects.append(em);
em.subtype = Track::kTypeVideo;
em.name = "Transform";
em.category = "Distort";
em.internal = EFFECT_INTERNAL_TRANSFORM;
olive::effects.append(em);
em.name = "Corner Pin";
em.internal = EFFECT_INTERNAL_CORNERPIN;
olive::effects.append(em);
/*em.name = "Mask";
em.internal = EFFECT_INTERNAL_MASK;
olive::effects.append(em);*/
em.name = "Shake";
em.internal = EFFECT_INTERNAL_SHAKE;
olive::effects.append(em);
em.name = "Text";
em.category = "Render";
em.internal = EFFECT_INTERNAL_TEXT;
olive::effects.append(em);
em.name = "Rich Text";
em.category = "Render";
em.internal = EFFECT_INTERNAL_RICHTEXT;
olive::effects.append(em);
em.name = "Timecode";
em.internal = EFFECT_INTERNAL_TIMECODE;
olive::effects.append(em);
em.name = "Solid";
em.internal = EFFECT_INTERNAL_SOLID;
olive::effects.append(em);
// internal transitions
em.type = EFFECT_TYPE_TRANSITION;
em.category = "";
em.name = "Cross Dissolve";
em.internal = TRANSITION_INTERNAL_CROSSDISSOLVE;
olive::effects.append(em);
em.subtype = Track::kTypeAudio;
em.name = "Linear Fade";
em.internal = TRANSITION_INTERNAL_LINEARFADE;
olive::effects.append(em);
em.name = "Exponential Fade";
em.internal = TRANSITION_INTERNAL_EXPONENTIALFADE;
olive::effects.append(em);
em.name = "Logarithmic Fade";
em.internal = TRANSITION_INTERNAL_LOGARITHMICFADE;
olive::effects.append(em);
olive::node_library[kTransformEffect] = std::make_shared<TransformEffect>(nullptr);
olive::node_library[kTextInput] = std::make_shared<TextEffect>(nullptr);
olive::node_library[kSolidInput] = std::make_shared<SolidEffect>(nullptr);
olive::node_library[kNoiseInput] = std::make_shared<AudioNoiseEffect>(nullptr);
olive::node_library[kVolumeEffect] = std::make_shared<VolumeEffect>(nullptr);
olive::node_library[kPanEffect] = std::make_shared<PanEffect>(nullptr);
olive::node_library[kToneInput] = std::make_shared<ToneEffect>(nullptr);
olive::node_library[kShakeEffect] = std::make_shared<ShakeEffect>(nullptr);
olive::node_library[kTimecodeEffect] = std::make_shared<TimecodeEffect>(nullptr);
olive::node_library[kFillLeftRightEffect] = std::make_shared<FillLeftRightEffect>(nullptr);
olive::node_library[kVstEffect] = std::make_shared<VSTHost>(nullptr);
olive::node_library[kCornerPinEffect] = std::make_shared<CornerPinEffect>(nullptr);
olive::node_library[kRichTextInput] = std::make_shared<RichTextEffect>(nullptr);
olive::node_library[kMediaInput] = std::make_shared<NodeMedia>(nullptr);
olive::node_library[kImageOutput] = std::make_shared<NodeImageOutput>(nullptr);
olive::node_library[kCrossDissolveTransition] = std::make_shared<CrossDissolveTransition>(nullptr);
olive::node_library[kLinearFadeTransition] = std::make_shared<LinearFadeTransition>(nullptr);
olive::node_library[kExponentialFadeTransition] = std::make_shared<ExponentialFadeTransition>(nullptr);
olive::node_library[kLogarithmicFadeTransition] = std::make_shared<LogarithmicFadeTransition>(nullptr);
}
void load_shader_effects_worker(const QString& effects_path) {
QDir effects_dir(effects_path);
if (effects_dir.exists()) {
QList<QString> entries = effects_dir.entryList({"*.xml", "*.blend"},
QList<QString> entries = effects_dir.entryList({"*.xml"},
QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
for (int i=0;i<entries.size();i++) {
@@ -144,60 +99,44 @@ void load_shader_effects_worker(const QString& effects_path) {
} else {
QString file_url = QDir(effects_path).filePath(entries.at(i));
if (file_url.endsWith(".blend", Qt::CaseInsensitive)) {
QFile file(file_url);
// Load blending mode shaders from file
QList<QString> blend_mode_entries = effects_dir.entryList(QStringList("*.blend"), QDir::Files);
for (int i=0;i<blend_mode_entries.size();i++) {
BlendMode b;
b.loaded = false;
b.url = effects_dir.filePath(blend_mode_entries.at(i));
b.name = QFileInfo(b.url).baseName();
olive::blend_modes.append(b);
}
} else {
QFile file(file_url);
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Could not open" << entries.at(i);
return;
}
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
if (reader.name() == "effect") {
QString effect_name = "";
QString effect_cat = "";
const QXmlStreamAttributes attr = reader.attributes();
for (int j=0;j<attr.size();j++) {
if (attr.at(j).name() == "name") {
effect_name = attr.at(j).value().toString();
} else if (attr.at(j).name() == "category") {
effect_cat = attr.at(j).value().toString();
}
}
if (!effect_name.isEmpty()) {
EffectMeta em;
em.type = EFFECT_TYPE_EFFECT;
em.subtype = Track::kTypeVideo;
em.name = effect_name;
em.category = effect_cat;
em.filename = file.fileName();
em.path = effects_path;
em.internal = -1;
olive::effects.append(em);
} else {
qCritical() << "Invalid effect found in" << entries.at(i);
}
break;
}
reader.readNext();
}
file.close();
if (!file.open(QIODevice::ReadOnly)) {
qCritical() << "Could not open" << entries.at(i);
return;
}
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
if (reader.name() == "effect") {
QString effect_name;
QString effect_cat;
QString effect_id;
const QXmlStreamAttributes attr = reader.attributes();
for (int j=0;j<attr.size();j++) {
if (attr.at(j).name() == "name") {
effect_name = attr.at(j).value().toString();
} else if (attr.at(j).name() == "category") {
effect_cat = attr.at(j).value().toString();
} else if (attr.at(j).name() == "id") {
effect_id = attr.at(j).value().toString();
}
}
if (!effect_name.isEmpty() && !effect_id.isEmpty()) {
olive::node_library.append(std::make_shared<NodeShader>(nullptr,
effect_name,
effect_id,
effect_cat,
file_url));
} else {
qCritical() << "Invalid effect found in" << entries.at(i);
}
break;
}
reader.readNext();
}
file.close();
}
}
}
+5 -5
View File
@@ -32,12 +32,12 @@
#include "panels/effectcontrols.h"
#include "panels/viewer.h"
#include "panels/grapheditor.h"
#include "effect.h"
#include "nodes/node.h"
#include "ui/viewerwidget.h"
#include "ui/keyframenavigator.h"
#include "ui/clickablelabel.h"
EffectRow::EffectRow(Effect *parent,
EffectRow::EffectRow(Node *parent,
const QString &id,
const QString &name,
bool savable,
@@ -77,7 +77,7 @@ bool EffectRow::IsKeyframing() {
}
void EffectRow::SetKeyframingInternal(bool b) {
if (GetParentEffect()->meta->type != EFFECT_TYPE_TRANSITION) {
if (GetParentEffect()->type() != EFFECT_TYPE_TRANSITION) {
keyframing_ = b;
emit KeyframingSetChanged(keyframing_);
}
@@ -315,9 +315,9 @@ void EffectRow::SetKeyframeOnAllFields(ComboAction* ca) {
panel_effect_controls->update_keyframes();
}
Effect *EffectRow::GetParentEffect()
Node *EffectRow::GetParentEffect()
{
return static_cast<Effect*>(parent());
return static_cast<Node*>(parent());
}
const QString &EffectRow::name() {
+3 -3
View File
@@ -24,7 +24,7 @@
#include <QObject>
#include <QVector>
class Effect;
class Node;
class QGridLayout;
class EffectField;
class QLabel;
@@ -83,7 +83,7 @@ public:
* Whether keyframing can be enabled on this row or not. This is true by default. Some values you may want to prevent
* the user from keyframing (e.g. the filename of a VST plugin), which can be done by setting this to false.
*/
EffectRow(Effect* parent,
EffectRow(Node* parent,
const QString& id,
const QString& name,
bool savable = true,
@@ -126,7 +126,7 @@ public:
*
* @return The parent Effect object that this row is attached to.
*/
Effect* GetParentEffect();
Node* GetParentEffect();
/**
* @brief Return the row's name
+2 -1
View File
@@ -22,7 +22,8 @@
#include <QCheckBox>
#include "effects/effect.h"
#include "nodes/node.h"
#include "undo/undo.h"
BoolField::BoolField(EffectRow *parent) :
EffectField(parent, EffectField::EFFECT_FIELD_BOOL)
+2 -1
View File
@@ -23,7 +23,8 @@
#include <QColor>
#include "ui/colorbutton.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "undo/undo.h"
ColorField::ColorField(EffectRow* parent) :
EffectField(parent, EffectField::EFFECT_FIELD_COLOR)
+2 -1
View File
@@ -22,8 +22,9 @@
#include <QDebug>
#include "effects/effect.h"
#include "nodes/node.h"
#include "ui/comboboxex.h"
#include "undo/undo.h"
ComboField::ComboField(EffectRow* parent) :
EffectField(parent, EffectField::EFFECT_FIELD_COMBO)
+2 -1
View File
@@ -20,7 +20,8 @@
#include "doublefield.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "undo/undo.h"
DoubleField::DoubleField(EffectRow* parent) :
EffectField(parent, EffectField::EFFECT_FIELD_DOUBLE),
+2
View File
@@ -24,6 +24,8 @@
#include "../effectfield.h"
#include "ui/labelslider.h"
class KeyframeDataChange;
/**
* @brief The DoubleField class
*
+2 -1
View File
@@ -23,7 +23,8 @@
#include <QDebug>
#include "ui/embeddedfilechooser.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "undo/undo.h"
FileField::FileField(EffectRow* parent) :
EffectField(parent, EffectField::EFFECT_FIELD_FILE)
+2 -1
View File
@@ -24,7 +24,8 @@
#include <QDebug>
#include "ui/comboboxex.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "undo/undo.h"
// NOTE/TODO: This shares a lot of similarity with ComboInput, and could probably be a derived class of it
+2 -1
View File
@@ -23,9 +23,10 @@
#include <QtMath>
#include <QDebug>
#include "effects/effect.h"
#include "nodes/node.h"
#include "ui/texteditex.h"
#include "global/config.h"
#include "undo/undo.h"
StringField::StringField(EffectRow* parent, bool rich_text) :
EffectField(parent, EffectField::EFFECT_FIELD_STRING),
+31 -1
View File
@@ -23,7 +23,7 @@
#include <QDateTime>
#include <QtMath>
AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
AudioNoiseEffect::AudioNoiseEffect(Clip* c) : Node(c) {
amount_val = new DoubleInput(this, "amount", tr("Amount"));
amount_val->SetMinimum(0);
amount_val->SetDefault(20);
@@ -33,6 +33,36 @@ AudioNoiseEffect::AudioNoiseEffect(Clip* c, const EffectMeta *em) : Effect(c, em
mix_val->SetValueAt(0, true);
}
QString AudioNoiseEffect::name()
{
return tr("Noise");
}
QString AudioNoiseEffect::id()
{
return "org.olivevideoeditor.Olive.noise";
}
QString AudioNoiseEffect::description()
{
return tr("Generate audio noise that can be mixed with this clip.");
}
EffectType AudioNoiseEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType AudioNoiseEffect::subtype()
{
return olive::kTypeAudio;
}
NodePtr AudioNoiseEffect::Create(Clip *c)
{
return std::make_shared<AudioNoiseEffect>(c);
}
void AudioNoiseEffect::process_audio(double timecode_start,
double timecode_end,
float **samples,
+11 -3
View File
@@ -21,12 +21,20 @@
#ifndef AUDIONOISEEFFECT_H
#define AUDIONOISEEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
class AudioNoiseEffect : public Effect {
class AudioNoiseEffect : public Node {
Q_OBJECT
public:
AudioNoiseEffect(Clip* c, const EffectMeta* em);
AudioNoiseEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
+37 -2
View File
@@ -24,8 +24,8 @@
#include "timeline/clip.h"
#include "global/debug.h"
CornerPinEffect::CornerPinEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag | Effect::ShaderFlag);
CornerPinEffect::CornerPinEffect(Clip* c) : Node(c) {
SetFlags(Node::CoordsFlag | Node::ShaderFlag);
top_left = new Vec2Input(this, "topleft", tr("Top Left"));
@@ -58,6 +58,41 @@ CornerPinEffect::CornerPinEffect(Clip* c, const EffectMeta *em) : Effect(c, em)
shader_frag_path_ = "cornerpin.frag";
}
QString CornerPinEffect::name()
{
return tr("Corner Pin");
}
QString CornerPinEffect::id()
{
return "org.olivevideoeditor.Olive.cornerpin";
}
QString CornerPinEffect::category()
{
return tr("Distort");
}
QString CornerPinEffect::description()
{
return tr("Distort/warp this clip by pinning each of its four corners.");
}
EffectType CornerPinEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType CornerPinEffect::subtype()
{
return olive::kTypeVideo;
}
NodePtr CornerPinEffect::Create(Clip *c)
{
return std::make_shared<CornerPinEffect>(c);
}
void CornerPinEffect::process_coords(double timecode, GLTextureCoords &coords, int) {
coords.vertex_top_left += top_left->GetVector2DAt(timecode);
coords.vertex_top_right += top_right->GetVector2DAt(timecode);
+12 -3
View File
@@ -21,12 +21,21 @@
#ifndef CORNERPINEFFECT_H
#define CORNERPINEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
class CornerPinEffect : public Effect {
class CornerPinEffect : public Node {
Q_OBJECT
public:
CornerPinEffect(Clip* c, const EffectMeta* em);
CornerPinEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
void process_coords(double timecode, GLTextureCoords& coords, int data);
void process_shader(double timecode, GLTextureCoords& coords, int iterations);
void gizmo_draw(double timecode, GLTextureCoords& coords);
+37 -2
View File
@@ -22,8 +22,43 @@
#include <QOpenGLFunctions>
CrossDissolveTransition::CrossDissolveTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {
SetFlags(Effect::CoordsFlag);
CrossDissolveTransition::CrossDissolveTransition(Clip* c) : Transition(c) {
SetFlags(Node::CoordsFlag);
}
QString CrossDissolveTransition::name()
{
return tr("Cross Dissolve");
}
QString CrossDissolveTransition::id()
{
return "org.olivevideoeditor.Olive.crossdissolve";
}
QString CrossDissolveTransition::category()
{
return tr("Dissolves");
}
QString CrossDissolveTransition::description()
{
return tr("Dissolve clips evenly.");
}
EffectType CrossDissolveTransition::type()
{
return EFFECT_TYPE_TRANSITION;
}
olive::TrackType CrossDissolveTransition::subtype()
{
return olive::kTypeVideo;
}
NodePtr CrossDissolveTransition::Create(Clip *c)
{
return std::make_shared<CrossDissolveTransition>(c);
}
void CrossDissolveTransition::process_coords(double progress, GLTextureCoords& coords, int data) {
+11 -2
View File
@@ -25,8 +25,17 @@
class CrossDissolveTransition : public Transition {
public:
CrossDissolveTransition(Clip *c, Clip *s, const EffectMeta* em);
void process_coords(double timecode, GLTextureCoords &, int data);
CrossDissolveTransition(Clip *c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_coords(double timecode, GLTextureCoords &, int data) override;
};
#endif // CROSSDISSOLVETRANSITION_H
+1 -1
View File
@@ -25,7 +25,7 @@
class CubeTransition : public Transition {
public:
CubeTransition(Clip* c, Clip* s, const EffectMeta* em);
CubeTransition(Clip* c, Clip* s);
void process_coords(double timecode, GLTextureCoords &, int data);
};
+34 -1
View File
@@ -22,7 +22,40 @@
#include <QtMath>
ExponentialFadeTransition::ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
ExponentialFadeTransition::ExponentialFadeTransition(Clip* c) :
Transition(c)
{
}
QString ExponentialFadeTransition::name()
{
return tr("Exponential Fade");
}
QString ExponentialFadeTransition::id()
{
return "org.olivevideoeditor.Olive.exponentialfade";
}
QString ExponentialFadeTransition::description()
{
return tr("An exponential audio fade that starts slow and ends fast.");
}
EffectType ExponentialFadeTransition::type()
{
return EFFECT_TYPE_TRANSITION;
}
olive::TrackType ExponentialFadeTransition::subtype()
{
return olive::kTypeAudio;
}
NodePtr ExponentialFadeTransition::Create(Clip *c)
{
return std::make_shared<ExponentialFadeTransition>(c);
}
void ExponentialFadeTransition::process_audio(double timecode_start,
double timecode_end,
+9 -1
View File
@@ -25,7 +25,15 @@
class ExponentialFadeTransition : public Transition {
public:
ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
ExponentialFadeTransition(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
+31 -1
View File
@@ -25,12 +25,42 @@ enum FillType {
FILL_TYPE_RIGHT
};
FillLeftRightEffect::FillLeftRightEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
FillLeftRightEffect::FillLeftRightEffect(Clip* c) : Node(c) {
fill_type = new ComboInput(this, "type", tr("Type"));
fill_type->AddItem(tr("Fill Left with Right"), FILL_TYPE_LEFT);
fill_type->AddItem(tr("Fill Right with Left"), FILL_TYPE_RIGHT);
}
QString FillLeftRightEffect::name()
{
return tr("Fill Left/Right");
}
QString FillLeftRightEffect::id()
{
return "org.olivevideoeditor.Olive.fillleftright";
}
QString FillLeftRightEffect::description()
{
return tr("Replaces either the left or right channel with the other");
}
EffectType FillLeftRightEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType FillLeftRightEffect::subtype()
{
return olive::kTypeAudio;
}
NodePtr FillLeftRightEffect::Create(Clip *c)
{
return std::make_shared<FillLeftRightEffect>(c);
}
void FillLeftRightEffect::process_audio(double timecode_start,
double timecode_end,
float **samples,
+11 -3
View File
@@ -21,12 +21,20 @@
#ifndef FILLLEFTRIGHTEFFECT_H
#define FILLLEFTRIGHTEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
class FillLeftRightEffect : public Effect {
class FillLeftRightEffect : public Node {
Q_OBJECT
public:
FillLeftRightEffect(Clip* c, const EffectMeta* em);
FillLeftRightEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
+31 -1
View File
@@ -20,7 +20,37 @@
#include "linearfadetransition.h"
LinearFadeTransition::LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
LinearFadeTransition::LinearFadeTransition(Clip* c) : Transition(c) {}
QString LinearFadeTransition::name()
{
return tr("Linear Fade");
}
QString LinearFadeTransition::id()
{
return "org.olivevideoeditor.Olive.linearfade";
}
QString LinearFadeTransition::description()
{
return tr("An linear audio fade that fades evenly at a constant rate.");
}
EffectType LinearFadeTransition::type()
{
return EFFECT_TYPE_TRANSITION;
}
olive::TrackType LinearFadeTransition::subtype()
{
return olive::kTypeAudio;
}
NodePtr LinearFadeTransition::Create(Clip *c)
{
return std::make_shared<LinearFadeTransition>(c);
}
void LinearFadeTransition::process_audio(double timecode_start,
double timecode_end,
+9 -1
View File
@@ -25,7 +25,15 @@
class LinearFadeTransition : public Transition {
public:
LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
LinearFadeTransition(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
+34 -1
View File
@@ -22,7 +22,40 @@
#include <QtMath>
LogarithmicFadeTransition::LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
LogarithmicFadeTransition::LogarithmicFadeTransition(Clip* c) :
Transition(c)
{
}
QString LogarithmicFadeTransition::name()
{
return tr("Logarithmic Fade");
}
QString LogarithmicFadeTransition::id()
{
return "org.olivevideoeditor.Olive.logarithmicfade";
}
QString LogarithmicFadeTransition::description()
{
return tr("An logarithmic audio fade that starts fast and ends slow.");
}
EffectType LogarithmicFadeTransition::type()
{
return EFFECT_TYPE_TRANSITION;
}
olive::TrackType LogarithmicFadeTransition::subtype()
{
return olive::kTypeAudio;
}
NodePtr LogarithmicFadeTransition::Create(Clip *c)
{
return std::make_shared<LogarithmicFadeTransition>(c);
}
void LogarithmicFadeTransition::process_audio(double timecode_start,
double timecode_end,
+9 -1
View File
@@ -25,7 +25,15 @@
class LogarithmicFadeTransition : public Transition {
public:
LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
LogarithmicFadeTransition(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip* c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
+31 -1
View File
@@ -28,13 +28,43 @@
#include "ui/labelslider.h"
#include "ui/collapsiblewidget.h"
PanEffect::PanEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
PanEffect::PanEffect(Clip* c) : Node(c) {
pan_val = new DoubleInput(this, "pan", tr("Pan"));
pan_val->SetMinimum(-100);
pan_val->SetDefault(0);
pan_val->SetMaximum(100);
}
QString PanEffect::name()
{
return tr("Pan");
}
QString PanEffect::id()
{
return "org.olivevideoeditor.Olive.pan";
}
QString PanEffect::description()
{
return tr("Modifying the panning on a stereo audio clip.");
}
EffectType PanEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType PanEffect::subtype()
{
return olive::kTypeAudio;
}
NodePtr PanEffect::Create(Clip *c)
{
return std::make_shared<PanEffect>(c);
}
void PanEffect::process_audio(double timecode_start,
double timecode_end,
float **samples,
+11 -3
View File
@@ -21,12 +21,20 @@
#ifndef PANEFFECT_H
#define PANEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
class PanEffect : public Effect {
class PanEffect : public Node {
Q_OBJECT
public:
PanEffect(Clip* c, const EffectMeta* em);
PanEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
+38 -3
View File
@@ -34,10 +34,10 @@ enum AutoscrollDirection {
SCROLL_RIGHT,
};
RichTextEffect::RichTextEffect(Clip *c, const EffectMeta *em) :
Effect(c, em)
RichTextEffect::RichTextEffect(Clip *c) :
Node(c)
{
SetFlags(Effect::SuperimposeFlag);
SetFlags(Node::SuperimposeFlag);
text_val = new StringInput(this, "text", tr("Text"));
@@ -82,6 +82,41 @@ RichTextEffect::RichTextEffect(Clip *c, const EffectMeta *em) :
"</html>");
}
QString RichTextEffect::name()
{
return tr("Rich Text");
}
QString RichTextEffect::id()
{
return "org.olivevideoeditor.Olive.richtext";
}
QString RichTextEffect::category()
{
return tr("Render");
}
QString RichTextEffect::description()
{
return tr("Render formatted rich text over a clip.");
}
EffectType RichTextEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType RichTextEffect::subtype()
{
return olive::kTypeVideo;
}
NodePtr RichTextEffect::Create(Clip *c)
{
return std::make_shared<RichTextEffect>(c);
}
void RichTextEffect::redraw(double timecode)
{
QPainter p(&img);
+13 -3
View File
@@ -21,13 +21,23 @@
#ifndef RICHTEXTEFFECT_H
#define RICHTEXTEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
class RichTextEffect : public Effect {
class RichTextEffect : public Node {
Q_OBJECT
public:
RichTextEffect(Clip* c, const EffectMeta *em);
RichTextEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void redraw(double timecode) override;
protected:
virtual bool AlwaysUpdate() override;
private:
+37 -2
View File
@@ -32,8 +32,8 @@
#include "panels/timeline.h"
#include "global/debug.h"
ShakeEffect::ShakeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag);
ShakeEffect::ShakeEffect(Clip* c) : Node(c) {
SetFlags(Node::CoordsFlag);
intensity_val = new DoubleInput(this, "intensity", tr("Intensity"));
intensity_val->SetMinimum(0);
@@ -79,3 +79,38 @@ void ShakeEffect::process_coords(double timecode, GLTextureCoords& coords, int)
coords.matrix.rotate(QQuaternion::fromEulerAngles(0.0f, 0.0f, rotoff));
}
QString ShakeEffect::name()
{
return tr("Shake");
}
QString ShakeEffect::id()
{
return "org.olivevideoeditor.Olive.shake";
}
QString ShakeEffect::category()
{
return tr("Distort");
}
QString ShakeEffect::description()
{
return tr("Simulate a camera shake movement.");
}
EffectType ShakeEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType ShakeEffect::subtype()
{
return olive::kTypeVideo;
}
NodePtr ShakeEffect::Create(Clip *c)
{
return std::make_shared<ShakeEffect>(c);
}
+11 -3
View File
@@ -21,16 +21,24 @@
#ifndef SHAKEEFFECT_H
#define SHAKEEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
#define RANDOM_VAL_SIZE 30
class ShakeEffect : public Effect {
class ShakeEffect : public Node {
Q_OBJECT
public:
ShakeEffect(Clip* c, const EffectMeta* em);
ShakeEffect(Clip* c);
virtual void process_coords(double timecode, GLTextureCoords& coords, int data) override;
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
DoubleInput* intensity_val;
DoubleInput* rotation_val;
DoubleInput* frequency_val;
+38 -3
View File
@@ -34,10 +34,10 @@ const int SMPTE_BARS = 7;
const int SMPTE_STRIP_COUNT = 3;
const int SMPTE_LOWER_BARS = 4;
SolidEffect::SolidEffect(Clip* c, const EffectMeta* em) :
Effect(c, em)
SolidEffect::SolidEffect(Clip* c) :
Node(c)
{
SetFlags(Effect::SuperimposeFlag);
SetFlags(Node::SuperimposeFlag);
// Field for solid type
solid_type = new ComboInput(this, "type", tr("Type"));
@@ -69,6 +69,41 @@ SolidEffect::SolidEffect(Clip* c, const EffectMeta* em) :
fragPath = ":/shaders/solideffect.frag";*/
}
QString SolidEffect::name()
{
return tr("Solid");
}
QString SolidEffect::id()
{
return "org.olivevideoeditor.Olive.solid";
}
QString SolidEffect::category()
{
return tr("Render");
}
QString SolidEffect::description()
{
return tr("Render a solid color over this clip.");
}
EffectType SolidEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType SolidEffect::subtype()
{
return olive::kTypeVideo;
}
NodePtr SolidEffect::Create(Clip *c)
{
return std::make_shared<SolidEffect>(c);
}
void SolidEffect::redraw(double timecode) {
int w = img.width();
int h = img.height();
+12 -3
View File
@@ -21,11 +21,11 @@
#ifndef SOLIDEFFECT_H
#define SOLIDEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
#include <QImage>
class SolidEffect : public Effect {
class SolidEffect : public Node {
Q_OBJECT
public:
enum SolidType {
@@ -34,7 +34,16 @@ public:
SOLID_TYPE_CHECKERBOARD
};
SolidEffect(Clip* c, const EffectMeta *em);
SolidEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void redraw(double timecode) override;
void SetType(SolidType type);
+38 -3
View File
@@ -42,10 +42,10 @@
#include "ui/blur.h"
#include "global/config.h"
TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
Effect(c, em)
TextEffect::TextEffect(Clip* c) :
Node(c)
{
SetFlags(Effect::SuperimposeFlag);
SetFlags(Node::SuperimposeFlag);
text_val = new StringInput(this, "text", tr("Text"), false);
@@ -121,6 +121,41 @@ TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
shader_frag_path_ = "dropshadow.frag";
}
QString TextEffect::name()
{
return tr("Text");
}
QString TextEffect::id()
{
return "org.olivevideoeditor.Olive.text";
}
QString TextEffect::category()
{
return tr("Render");
}
QString TextEffect::description()
{
return tr("Generate simple text over this clip");
}
EffectType TextEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType TextEffect::subtype()
{
return olive::kTypeVideo;
}
NodePtr TextEffect::Create(Clip *c)
{
return std::make_shared<TextEffect>(c);
}
void TextEffect::redraw(double timecode) {
QColor bkg = set_color_button->GetColorAt(timecode);
bkg.setAlpha(0);
+12 -3
View File
@@ -21,15 +21,24 @@
#ifndef TEXTEFFECT_H
#define TEXTEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
#include <QFont>
#include <QImage>
class TextEffect : public Effect {
class TextEffect : public Node {
Q_OBJECT
public:
TextEffect(Clip* c, const EffectMeta *em);
TextEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void redraw(double timecode) override;
private slots:
void outline_enable(bool);
+38 -3
View File
@@ -42,10 +42,10 @@
#include "ui/colorbutton.h"
#include "global/config.h"
TimecodeEffect::TimecodeEffect(Clip* c, const EffectMeta* em) :
Effect(c, em)
TimecodeEffect::TimecodeEffect(Clip* c) :
Node(c)
{
SetFlags(Effect::SuperimposeFlag);
SetFlags(Node::SuperimposeFlag);
tc_select = new ComboInput(this, "tc_selector", tr("Timecode"));
tc_select->AddItem(tr("Sequence"), true);
@@ -74,6 +74,41 @@ TimecodeEffect::TimecodeEffect(Clip* c, const EffectMeta* em) :
prepend_text = new StringInput(this, "prepend", tr("Prepend"), false);
}
QString TimecodeEffect::name()
{
return tr("Timecode");
}
QString TimecodeEffect::id()
{
return "org.olivevideoeditor.Olive.timecode";
}
QString TimecodeEffect::category()
{
return tr("Render");
}
QString TimecodeEffect::description()
{
return tr("Render the media or sequence timecode on this clip.");
}
EffectType TimecodeEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType TimecodeEffect::subtype()
{
return olive::kTypeVideo;
}
NodePtr TimecodeEffect::Create(Clip *c)
{
return std::make_shared<TimecodeEffect>(c);
}
void TimecodeEffect::redraw(double timecode) {
Sequence* sequence = parent_clip->track()->sequence();
+12 -3
View File
@@ -21,15 +21,24 @@
#ifndef TIMECODEEFFECT_H
#define TIMECODEEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
#include <QFont>
#include <QImage>
class TimecodeEffect : public Effect {
class TimecodeEffect : public Node {
Q_OBJECT
public:
TimecodeEffect(Clip* c, const EffectMeta *em);
TimecodeEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void redraw(double timecode) override;
DoubleInput* scale_val;
ColorInput* color_val;
+31 -1
View File
@@ -27,7 +27,7 @@
#include "timeline/clip.h"
#include "timeline/sequence.h"
ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_MIN) {
ToneEffect::ToneEffect(Clip* c) : Node(c), sinX(INT_MIN) {
type_val = new ComboInput(this, "type", tr("Type"));
type_val->AddItem(tr("Sine"), TONE_TYPE_SINE);
@@ -45,6 +45,36 @@ ToneEffect::ToneEffect(Clip* c, const EffectMeta *em) : Effect(c, em), sinX(INT_
mix_val->SetValueAt(0, true);
}
QString ToneEffect::name()
{
return tr("Tone");
}
QString ToneEffect::id()
{
return "org.olivevideoeditor.Olive.tone";
}
QString ToneEffect::description()
{
return tr("Generate a sine wave tone to mix into this clip's audio.");
}
EffectType ToneEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType ToneEffect::subtype()
{
return olive::kTypeAudio;
}
NodePtr ToneEffect::Create(Clip *c)
{
return std::make_shared<ToneEffect>(c);
}
void ToneEffect::process_audio(double timecode_start,
double timecode_end,
float **samples,
+13 -4
View File
@@ -21,12 +21,20 @@
#ifndef TONEEFFECT_H
#define TONEEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
class ToneEffect : public Effect {
class ToneEffect : public Node {
Q_OBJECT
public:
ToneEffect(Clip* c, const EffectMeta* em);
ToneEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
@@ -34,11 +42,12 @@ public:
int channel_count,
int type) override;
private:
ComboInput* type_val;
DoubleInput* freq_val;
DoubleInput* amount_val;
BoolInput* mix_val;
private:
int sinX;
};
+37 -2
View File
@@ -43,8 +43,8 @@
#include "panels/viewer.h"
#include "ui/viewerwidget.h"
TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em) {
SetFlags(Effect::CoordsFlag);
TransformEffect::TransformEffect(Clip* c) : Node(c) {
SetFlags(Node::CoordsFlag);
position = new Vec2Input(this, "pos", tr("Position"));
@@ -125,6 +125,41 @@ TransformEffect::TransformEffect(Clip* c, const EffectMeta* em) : Effect(c, em)
refresh();
}
QString TransformEffect::name()
{
return tr("Transform");
}
QString TransformEffect::id()
{
return "org.olivevideoeditor.Olive.transform";
}
QString TransformEffect::category()
{
return tr("Distort");
}
QString TransformEffect::description()
{
return tr("Transform the position, scale, and rotation of this clip.");
}
EffectType TransformEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType TransformEffect::subtype()
{
return olive::kTypeVideo;
}
NodePtr TransformEffect::Create(Clip *c)
{
return std::make_shared<TransformEffect>(c);
}
void TransformEffect::refresh() {
if (parent_clip != nullptr && parent_clip->track()->sequence() != nullptr) {
+12 -3
View File
@@ -21,12 +21,21 @@
#ifndef TRANSFORMEFFECT_H
#define TRANSFORMEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
class TransformEffect : public Effect {
class TransformEffect : public Node {
Q_OBJECT
public:
TransformEffect(Clip* c, const EffectMeta* em);
TransformEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void refresh() override;
virtual void process_coords(double timecode, GLTextureCoords& coords, int data) override;
+50 -19
View File
@@ -27,24 +27,55 @@
#include "ui/collapsiblewidget.h"
#include "global/debug.h"
VoidEffect::VoidEffect(Clip* c, const QString& n) : Effect(c, nullptr) {
QString display_name;
if (n.isEmpty()) {
display_name = tr("(unknown)");
} else {
display_name = n;
VoidEffect::VoidEffect(Clip* c, const QString& n, const QString& id) :
Node(c),
display_name_(n),
id_(id)
{
if (display_name_.isEmpty()) {
display_name_ = tr("(unknown)");
}
new LabelWidget(this, tr("Missing Effect"), display_name);
name = display_name;
void_meta.type = EFFECT_TYPE_EFFECT;
meta = &void_meta;
new LabelWidget(this, tr("Missing Effect"), display_name_);
}
EffectPtr VoidEffect::copy(Clip* c) {
EffectPtr copy = std::make_shared<VoidEffect>(c, name);
QString VoidEffect::name()
{
return display_name_;
}
QString VoidEffect::id()
{
return id_;
}
QString VoidEffect::description()
{
return QString();
}
EffectType VoidEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType VoidEffect::subtype()
{
return olive::kTypeVideo;
}
bool VoidEffect::IsCreatable()
{
return false;
}
NodePtr VoidEffect::Create(Clip *)
{
return nullptr;
}
NodePtr VoidEffect::copy(Clip* c) {
NodePtr copy = std::make_shared<VoidEffect>(c, display_name_, id_);
copy->SetEnabled(IsEnabled());
copy_field_keyframes(copy);
return copy;
@@ -53,7 +84,7 @@ EffectPtr VoidEffect::copy(Clip* c) {
void VoidEffect::load(QXmlStreamReader &stream) {
QString tag = stream.name().toString();
QXmlStreamWriter writer(&bytes);
QXmlStreamWriter writer(&bytes_);
// copy XML from reader to writer
while (!stream.atEnd() && !(stream.name() == tag && stream.isEndElement())) {
@@ -75,18 +106,18 @@ void VoidEffect::load(QXmlStreamReader &stream) {
}
void VoidEffect::save(QXmlStreamWriter &stream) {
if (!name.isEmpty()) {
stream.writeAttribute("name", name);
if (!display_name_.isEmpty()) {
stream.writeAttribute("name", display_name_);
stream.writeAttribute("enabled", QString::number(IsEnabled()));
// force xml writer to expand <effect> tag, ignored when loading
stream.writeStartElement("void");
stream.writeEndElement();
if (!bytes.isEmpty()) {
if (!bytes_.isEmpty()) {
// write stored data
QIODevice* device = stream.device();
device->write(bytes);
device->write(bytes_);
}
}
}
+15 -6
View File
@@ -27,19 +27,28 @@
* isn't lost if the user saves over the project.
*/
#include "effects/effect.h"
#include "nodes/node.h"
class VoidEffect : public Effect {
class VoidEffect : public Node {
Q_OBJECT
public:
VoidEffect(Clip* c, const QString& n);
VoidEffect(Clip* c, const QString& n, const QString &id);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual bool IsCreatable() override;
virtual NodePtr Create(Clip *c) override;
virtual NodePtr copy(Clip* c) override;
virtual EffectPtr copy(Clip* c) override;
virtual void load(QXmlStreamReader &stream) override;
virtual void save(QXmlStreamWriter &stream) override;
private:
QByteArray bytes;
EffectMeta void_meta;
QByteArray bytes_;
QString display_name_;
QString id_;
};
#endif // VOIDEFFECT_H
+31 -1
View File
@@ -28,7 +28,7 @@
#include "ui/labelslider.h"
#include "ui/collapsiblewidget.h"
VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
VolumeEffect::VolumeEffect(Clip* c) : Node(c) {
volume_val = new DoubleInput(this, "volume", tr("Volume"));
// set defaults
@@ -36,6 +36,36 @@ VolumeEffect::VolumeEffect(Clip* c, const EffectMeta *em) : Effect(c, em) {
volume_val->SetDisplayType(LabelSlider::Decibel);
}
QString VolumeEffect::name()
{
return tr("Volume");
}
QString VolumeEffect::id()
{
return "org.olivevideoeditor.Olive.volume";
}
QString VolumeEffect::description()
{
return tr("Adjust the volume of this clip's audio");
}
EffectType VolumeEffect::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType VolumeEffect::subtype()
{
return olive::kTypeAudio;
}
NodePtr VolumeEffect::Create(Clip *c)
{
return std::make_shared<VolumeEffect>(c);
}
void VolumeEffect::process_audio(double timecode_start,
double timecode_end,
float **samples,
+12 -3
View File
@@ -21,12 +21,20 @@
#ifndef VOLUMEEFFECT_H
#define VOLUMEEFFECT_H
#include "effects/effect.h"
#include "nodes/node.h"
class VolumeEffect : public Effect {
class VolumeEffect : public Node {
Q_OBJECT
public:
VolumeEffect(Clip* c, const EffectMeta* em);
VolumeEffect(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
@@ -34,6 +42,7 @@ public:
int channel_count,
int type) override;
private:
DoubleInput* volume_val;
};
+33 -3
View File
@@ -227,8 +227,8 @@ void VSTHost::send_data_cache_to_plugin()
dispatcher(plugin, effSetChunk, 0, int32_t(data_cache.size()), static_cast<void*>(data_cache.data()), 0);
}
VSTHost::VSTHost(Clip* c, const EffectMeta *em) :
Effect(c, em),
VSTHost::VSTHost(Clip* c) :
Node(c),
plugin(nullptr),
dialog(nullptr),
input_cache(BLOCK_SIZE),
@@ -249,6 +249,36 @@ VSTHost::~VSTHost() {
freePlugin();
}
QString VSTHost::name()
{
return tr("VST Plugin 2.x");
}
QString VSTHost::id()
{
return "org.olivevideoeditor.Olive.vst2x";
}
QString VSTHost::description()
{
return tr("Use a VST 2.x plugin on this clip's audio.");
}
EffectType VSTHost::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType VSTHost::subtype()
{
return olive::kTypeAudio;
}
NodePtr VSTHost::Create(Clip *c)
{
return std::make_shared<VSTHost>(c);
}
void VSTHost::process_audio(double timecode_start,
double timecode_end,
float **samples,
@@ -291,7 +321,7 @@ void VSTHost::custom_load(QXmlStreamReader &stream) {
}
void VSTHost::save(QXmlStreamWriter &stream) {
Effect::save(stream);
Node::save(stream);
if (plugin != nullptr) {
char* p = nullptr;
int32_t length = int32_t(dispatcher(plugin, effGetChunk, 0, 0, &p, 0));
+12 -4
View File
@@ -24,7 +24,7 @@
#include <QDialog>
#include <QLibrary>
#include "effects/effect.h"
#include "nodes/node.h"
#include "include/vestige.h"
// Plugin's dispatcher function
@@ -46,11 +46,19 @@ private:
void destroy();
};
class VSTHost : public Effect {
class VSTHost : public Node {
Q_OBJECT
public:
VSTHost(Clip* c, const EffectMeta* em);
~VSTHost();
VSTHost(Clip* c);
virtual ~VSTHost() override;
virtual QString name() override;
virtual QString id() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
virtual void process_audio(double timecode_start,
double timecode_end,
float **samples,
+22 -24
View File
@@ -40,27 +40,34 @@
#include <QMessageBox>
#include <QCoreApplication>
Transition::Transition(Clip *c, Clip *s, const EffectMeta* em) :
Effect(c, em),
secondary_clip(s)
Transition::Transition(Clip *c) :
Node(c),
secondary_clip(nullptr)
{
length_field = new DoubleInput(this, "length", tr("Length"), false, false);
length_field->SetDefault(30);
length_field->SetMinimum(1);
length_field->SetDisplayType(LabelSlider::FrameNumber);
length_field->SetFrameRate(parent_clip->track()->sequence() == nullptr ?
parent_clip->cached_frame_rate() : parent_clip->track()->sequence()->frame_rate);
if (parent_clip != nullptr) {
length_field->SetFrameRate(parent_clip->track()->sequence() == nullptr ?
parent_clip->cached_frame_rate() : parent_clip->track()->sequence()->frame_rate);
}
connect(length_field, SIGNAL(Changed()), this, SLOT(UpdateMaximumLength()));
}
TransitionPtr Transition::copy(Clip *c, Clip *s) {
return Transition::Create(c, s, meta, get_true_length());
NodePtr Transition::copy(Clip *c) {
NodePtr node = Node::copy(c);
static_cast<Transition*>(node.get())->set_length(get_true_length());
return node;
}
void Transition::save(QXmlStreamWriter &stream) {
stream.writeAttribute("length", QString::number(get_true_length()));
Effect::save(stream);
Node::save(stream);
}
void Transition::set_length(int l) {
@@ -96,17 +103,18 @@ Clip* Transition::get_closed_clip() {
return nullptr;
}
TransitionPtr Transition::CreateFromMeta(Clip* c, Clip* s, const EffectMeta* em) {
/*
TransitionPtr Transition::CreateFromMeta(Clip* c, Clip* s) {
if (!em->filename.isEmpty()) {
// load effect from file
return TransitionPtr(new Transition(c, s, em));
} else if (em->internal >= 0 && em->internal < TRANSITION_INTERNAL_COUNT) {
// must be an internal effect
switch (em->internal) {
case TRANSITION_INTERNAL_CROSSDISSOLVE: return TransitionPtr(new CrossDissolveTransition(c, s, em));
case TRANSITION_INTERNAL_LINEARFADE: return TransitionPtr(new LinearFadeTransition(c, s, em));
case TRANSITION_INTERNAL_EXPONENTIALFADE: return TransitionPtr(new ExponentialFadeTransition(c, s, em));
case TRANSITION_INTERNAL_LOGARITHMICFADE: return TransitionPtr(new LogarithmicFadeTransition(c, s, em));
case kCrossDissolveTransition: return TransitionPtr(new CrossDissolveTransition(c, s, em));
case kLinearFadeTransition: return TransitionPtr(new LinearFadeTransition(c, s, em));
case kExponentialFadeTransition: return TransitionPtr(new ExponentialFadeTransition(c, s, em));
case kLogarithmicFadeTransition: return TransitionPtr(new LogarithmicFadeTransition(c, s, em));
//case TRANSITION_INTERNAL_CUBE: return TransitionPtr(new CubeTransition(c, s, em));
}
} else {
@@ -118,6 +126,7 @@ TransitionPtr Transition::CreateFromMeta(Clip* c, Clip* s, const EffectMeta* em)
}
return nullptr;
}
*/
void Transition::UpdateMaximumLength()
{
@@ -154,14 +163,3 @@ long Transition::GetMaximumEmptySpaceOnClip(Clip *c)
return maximum_transition_length;
}
TransitionPtr Transition::Create(Clip* c, Clip* s, const EffectMeta* em, long length) {
TransitionPtr t(CreateFromMeta(c, s, em));
if (t != nullptr) {
if (length > 0) {
t->set_length(length);
}
return t;
}
return nullptr;
}
+7 -15
View File
@@ -21,7 +21,8 @@
#ifndef TRANSITION_H
#define TRANSITION_H
#include "effect.h"
#include "nodes/node.h"
#include "nodes/inputs.h"
enum TransitionType {
kTransitionNone,
@@ -29,23 +30,16 @@ enum TransitionType {
kTransitionClosing
};
enum TransitionInternal {
TRANSITION_INTERNAL_CROSSDISSOLVE,
TRANSITION_INTERNAL_LINEARFADE,
TRANSITION_INTERNAL_EXPONENTIALFADE,
TRANSITION_INTERNAL_LOGARITHMICFADE,
//TRANSITION_INTERNAL_CUBE,
TRANSITION_INTERNAL_COUNT
};
class Transition;
using TransitionPtr = std::shared_ptr<Transition>;
class Transition : public Effect {
class Transition : public Node {
Q_OBJECT
public:
Transition(Clip* c, Clip* s, const EffectMeta* em);
virtual TransitionPtr copy(Clip* c, Clip* s);
Transition(Clip* c);
virtual NodePtr copy(Clip* c) override;
Clip* secondary_clip;
virtual void save(QXmlStreamWriter& stream) override;
@@ -57,8 +51,6 @@ public:
Clip* get_opened_clip();
Clip* get_closed_clip();
static TransitionPtr Create(Clip* c, Clip* s, const EffectMeta* em, long length = 0);
static TransitionPtr CreateFromMeta(Clip *c, Clip *s, const EffectMeta* em);
private:
DoubleInput* length_field;
+2 -1
View File
@@ -21,8 +21,9 @@
#include "clipboard.h"
#include "timeline/clip.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "effects/transition.h"
#include "undo/undo.h"
Clipboard::Clipboard() :
type_(CLIPBOARD_TYPE_CLIP)
+1
View File
@@ -24,6 +24,7 @@
#include <QVector>
#include "effects/transition.h"
#include "project/media.h"
using VoidPtr = std::shared_ptr<void>;
+6 -6
View File
@@ -389,15 +389,15 @@ void OliveGlobal::PasteInternal(Sequence *s, bool insert)
Clip* c = selected_clips.at(i);
for (int j=0;j<olive::clipboard.Count();j++) {
EffectPtr e = std::static_pointer_cast<Effect>(olive::clipboard.Get(j));
if (c->type() == e->meta->subtype) {
NodePtr e = std::static_pointer_cast<Node>(olive::clipboard.Get(j));
if (c->type() == e->subtype()) {
int found = -1;
if (ask_conflict) {
replace = false;
skip = false;
}
for (int k=0;k<c->effects.size();k++) {
if (c->effects.at(k)->meta == e->meta) {
if (c->effects.at(k)->id() == e->id()) {
found = k;
break;
}
@@ -407,7 +407,7 @@ void OliveGlobal::PasteInternal(Sequence *s, bool insert)
box.setWindowTitle(tr("Effect already exists"));
box.setText(tr("Clip '%1' already contains a '%2' effect. "
"Would you like to replace it with the pasted one or add it as a separate effect?")
.arg(c->name(), e->meta->name));
.arg(c->name(), e->name()));
box.setIcon(QMessageBox::Icon::Question);
box.addButton(tr("Add"), QMessageBox::YesRole);
@@ -432,9 +432,9 @@ void OliveGlobal::PasteInternal(Sequence *s, bool insert)
} else if (found >= 0 && replace) {
ca->append(new EffectDeleteCommand(c->effects.at(found).get()));
ca->append(new AddEffectCommand(c, e->copy(c), nullptr, found));
ca->append(new AddEffectCommand(c, e->copy(c), kInvalidNode, found));
} else {
ca->append(new AddEffectCommand(c, e->copy(c), nullptr));
ca->append(new AddEffectCommand(c, e->copy(c), kInvalidNode));
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
#include "boolinput.h"
BoolInput::BoolInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
BoolInput::BoolInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
BoolField* bool_field = new BoolField(this);
+1 -1
View File
@@ -7,7 +7,7 @@ class BoolInput : public EffectRow
{
Q_OBJECT
public:
BoolInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
BoolInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Get the boolean value at a given timecode
+2 -2
View File
@@ -1,6 +1,6 @@
#include "colorinput.h"
ColorInput::ColorInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
ColorInput::ColorInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
AddField(new ColorField(this));
@@ -10,5 +10,5 @@ ColorInput::ColorInput(Effect* parent, const QString& id, const QString& name, b
QColor ColorInput::GetColorAt(double timecode)
{
static_cast<ColorField*>(Field(0))->GetColorAt(timecode);
return static_cast<ColorField*>(Field(0))->GetColorAt(timecode);
}
+1 -1
View File
@@ -7,7 +7,7 @@ class ColorInput : public EffectRow
{
Q_OBJECT
public:
ColorInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
ColorInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Get the color value at a given timecode
+1 -1
View File
@@ -1,6 +1,6 @@
#include "comboinput.h"
ComboInput::ComboInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
ComboInput::ComboInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
ComboField* combo_field = new ComboField(this);
+1 -1
View File
@@ -7,7 +7,7 @@ class ComboInput : public EffectRow
{
Q_OBJECT
public:
ComboInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
ComboInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Add an item to this ComboInput
+1 -1
View File
@@ -1,6 +1,6 @@
#include "fileinput.h"
FileInput::FileInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
FileInput::FileInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
AddField(new FileField(this));
+1 -1
View File
@@ -7,7 +7,7 @@ class FileInput : public EffectRow
{
Q_OBJECT
public:
FileInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
FileInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Get the filename at the given timecode
+1 -1
View File
@@ -1,6 +1,6 @@
#include "fontinput.h"
FontInput::FontInput(Effect* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
FontInput::FontInput(Node* parent, const QString& id, const QString& name, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
AddField(new FontField(this));
+1 -1
View File
@@ -7,7 +7,7 @@ class FontInput : public EffectRow
{
Q_OBJECT
public:
FontInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
FontInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
/**
* @brief Get the font family name at the given timecode
+1 -1
View File
@@ -1,6 +1,6 @@
#include "stringinput.h"
StringInput::StringInput(Effect* parent, const QString& id, const QString& name, bool rich_text, bool savable, bool keyframable) :
StringInput::StringInput(Node* parent, const QString& id, const QString& name, bool rich_text, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable)
{
AddField(new StringField(this, rich_text));
+1 -1
View File
@@ -7,7 +7,7 @@ class StringInput : public EffectRow
{
Q_OBJECT
public:
StringInput(Effect* parent,
StringInput(Node* parent,
const QString& id,
const QString& name,
bool rich_text = true,
+5 -5
View File
@@ -4,7 +4,7 @@
#include <QVector4D>
#include <QDebug>
VecInput::VecInput(Effect* parent, const QString& id, const QString& name, int values, bool savable, bool keyframable) :
VecInput::VecInput(Node* parent, const QString& id, const QString& name, int values, bool savable, bool keyframable) :
EffectRow(parent, id, name, savable, keyframable),
single_value_mode_(false),
values_(values)
@@ -79,7 +79,7 @@ void VecInput::SetSingleValueMode(bool on)
}
}
DoubleInput::DoubleInput(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
DoubleInput::DoubleInput(Node *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
VecInput(parent, id, name, 1, savable, keyframable)
{
}
@@ -89,7 +89,7 @@ double DoubleInput::GetDoubleAt(double timecode)
return static_cast<DoubleField*>(Field(0))->GetDoubleAt(timecode);
}
Vec2Input::Vec2Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
Vec2Input::Vec2Input(Node *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
VecInput(parent, id, name, 2, savable, keyframable)
{
}
@@ -121,7 +121,7 @@ void Vec2Input::SetValueAt(double timecode, const QVariant &value)
static_cast<DoubleField*>(Field(1))->SetValueAt(timecode, vec2.y());
}
Vec3Input::Vec3Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
Vec3Input::Vec3Input(Node *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
VecInput(parent, id, name, 3, savable, keyframable)
{
}
@@ -156,7 +156,7 @@ void Vec3Input::SetValueAt(double timecode, const QVariant &value)
static_cast<DoubleField*>(Field(2))->SetValueAt(timecode, vec3.z());
}
Vec4Input::Vec4Input(Effect *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
Vec4Input::Vec4Input(Node *parent, const QString &id, const QString &name, bool savable, bool keyframable) :
VecInput(parent, id, name, 4, savable, keyframable)
{
}
+5 -5
View File
@@ -9,7 +9,7 @@ class VecInput : public EffectRow
{
Q_OBJECT
public:
VecInput(Effect* parent, const QString& id, const QString& name, int values, bool savable = true, bool keyframable = true);
VecInput(Node* parent, const QString& id, const QString& name, int values, bool savable = true, bool keyframable = true);
void SetMinimum(double minimum);
void SetMaximum(double maximum);
@@ -43,14 +43,14 @@ private:
class DoubleInput : public VecInput
{
public:
DoubleInput(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
DoubleInput(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
double GetDoubleAt(double timecode);
};
class Vec2Input : public VecInput {
public:
Vec2Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
Vec2Input(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
QVector2D GetVector2DAt(double timecode);
virtual QVariant GetValueAt(double timecode) override;
@@ -59,7 +59,7 @@ public:
class Vec3Input : public VecInput {
public:
Vec3Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
Vec3Input(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
QVector3D GetVector3DAt(double timecode);
virtual QVariant GetValueAt(double timecode) override;
@@ -68,7 +68,7 @@ public:
class Vec4Input : public VecInput {
public:
Vec4Input(Effect* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
Vec4Input(Node* parent, const QString& id, const QString& name, bool savable = true, bool keyframable = true);
QVector4D GetVector4DAt(double timecode);
virtual QVariant GetValueAt(double timecode) override;
+129 -142
View File
@@ -18,7 +18,7 @@
***/
#include "effect.h"
#include "node.h"
#include <QCheckBox>
#include <QGridLayout>
@@ -50,61 +50,47 @@
#include "global/math.h"
#include "global/clipboard.h"
#include "global/config.h"
#include "transition.h"
#include "effects/transition.h"
#include "undo/undostack.h"
#include "rendering/shadergenerators.h"
#include "global/timing.h"
#include "nodes/nodes.h"
#include "effects/internal/transformeffect.h"
#include "effects/internal/texteffect.h"
#include "effects/internal/timecodeeffect.h"
#include "effects/internal/solideffect.h"
#include "effects/internal/audionoiseeffect.h"
#include "effects/internal/toneeffect.h"
#include "effects/internal/volumeeffect.h"
#include "effects/internal/paneffect.h"
#include "effects/internal/shakeeffect.h"
#include "effects/internal/cornerpineffect.h"
#include "effects/internal/vsthost.h"
#include "effects/internal/fillleftrighteffect.h"
#include "effects/internal/richtexteffect.h"
QVector<NodePtr> olive::node_library;
QVector<EffectMeta> olive::effects;
QVector<BlendMode> olive::blend_modes;
QString olive::generated_blending_shader;
EffectPtr Effect::Create(Clip* c, const EffectMeta* em) {
if (em->internal >= 0 && em->internal < EFFECT_INTERNAL_COUNT) {
// must be an internal effect
switch (em->internal) {
case EFFECT_INTERNAL_TRANSFORM: return std::make_shared<TransformEffect>(c, em);
case EFFECT_INTERNAL_TEXT: return std::make_shared<TextEffect>(c, em);
case EFFECT_INTERNAL_TIMECODE: return std::make_shared<TimecodeEffect>(c, em);
case EFFECT_INTERNAL_SOLID: return std::make_shared<SolidEffect>(c, em);
case EFFECT_INTERNAL_NOISE: return std::make_shared<AudioNoiseEffect>(c, em);
case EFFECT_INTERNAL_VOLUME: return std::make_shared<VolumeEffect>(c, em);
case EFFECT_INTERNAL_PAN: return std::make_shared<PanEffect>(c, em);
case EFFECT_INTERNAL_TONE: return std::make_shared<ToneEffect>(c, em);
case EFFECT_INTERNAL_SHAKE: return std::make_shared<ShakeEffect>(c, em);
case EFFECT_INTERNAL_CORNERPIN: return std::make_shared<CornerPinEffect>(c, em);
case EFFECT_INTERNAL_FILLLEFTRIGHT: return std::make_shared<FillLeftRightEffect>(c, em);
case EFFECT_INTERNAL_VST: return std::make_shared<VSTHost>(c, em);
case EFFECT_INTERNAL_RICHTEXT: return std::make_shared<RichTextEffect>(c, em);
}
} else if (!em->filename.isEmpty()) {
// load effect from file
return std::make_shared<NodeShader>(c, em);
} else {
/*
NodePtr Node::Create(Clip* c) {
// must be an internal effect
switch (em->internal) {
case kTransformEffect: return std::make_shared<TransformEffect>(c, em);
case kTextInput: return std::make_shared<TextEffect>(c, em);
case kTimecodeEffect: return std::make_shared<TimecodeEffect>(c, em);
case kSolidInput: return std::make_shared<SolidEffect>(c, em);
case kNoiseInput: return std::make_shared<AudioNoiseEffect>(c, em);
case kVolumeEffect: return std::make_shared<VolumeEffect>(c, em);
case kPanEffect: return std::make_shared<PanEffect>(c, em);
case kToneInput: return std::make_shared<ToneEffect>(c, em);
case kShakeEffect: return std::make_shared<ShakeEffect>(c, em);
case kCornerPinEffect: return std::make_shared<CornerPinEffect>(c, em);
case kFillLeftRightEffect: return std::make_shared<FillLeftRightEffect>(c, em);
case kVstEffect: return std::make_shared<VSTHost>(c, em);
case kRichTextInput: return std::make_shared<RichTextEffect>(c, em);
case kMediaInput: return std::make_shared<NodeMedia>(c, em);
case kShaderEffect: return std::make_shared<NodeShader>(c, em);
case kImageOutput: return std::make_shared<NodeImageOutput>(c, em);
default:
qCritical() << "Invalid effect data";
QMessageBox::critical(olive::MainWindow,
QCoreApplication::translate("Effect", "Invalid effect"),
QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be corrupt. Try reinstalling it or Olive.").arg(em->name));
QCoreApplication::translate("Effect", "No candidate for effect '%1'. This effect may be "
"corrupt. Try reinstalling it or Olive.").arg(em->name));
return nullptr;
}
return nullptr;
}
*/
const EffectMeta* Effect::GetInternalMeta(int internal_id, int type) {
/*
const EffectMeta* Node::GetInternalMeta(int internal_id, int type) {
for (int i=0;i<olive::effects.size();i++) {
if (olive::effects.at(i).internal == internal_id && olive::effects.at(i).type == type) {
return &olive::effects.at(i);
@@ -112,10 +98,10 @@ const EffectMeta* Effect::GetInternalMeta(int internal_id, int type) {
}
return nullptr;
}
*/
Effect::Effect(Clip* c, const EffectMeta *em) :
Node::Node(Clip* c) :
parent_clip(c),
meta(em),
flags_(0),
shader_program_(nullptr),
texture(0),
@@ -127,14 +113,10 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
enabled_(true),
expanded_(true),
texture_ctx(nullptr)
{
if (em != nullptr) {
// set up UI from effect metadata
name = em->name;
}
{
}
Effect::~Effect() {
Node::~Node() {
if (isOpen) {
close();
}
@@ -150,13 +132,23 @@ Effect::~Effect() {
}
}
void Effect::AddRow(EffectRow *row)
QString Node::category()
{
return QString();
}
bool Node::IsCreatable()
{
return true;
}
void Node::AddRow(EffectRow *row)
{
row->setParent(this);
rows.append(row);
}
void Effect::copy_field_keyframes(EffectPtr e) {
void Node::copy_field_keyframes(NodePtr e) {
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
EffectRow* copy_row = e->rows.at(i);
@@ -177,40 +169,43 @@ void Effect::copy_field_keyframes(EffectPtr e) {
}
}
EffectRow* Effect::row(int i) {
EffectRow* Node::row(int i) {
return rows.at(i);
}
int Effect::row_count() {
int Node::row_count() {
return rows.size();
}
EffectGizmo *Effect::add_gizmo(int type) {
EffectGizmo *Node::add_gizmo(int type) {
EffectGizmo* gizmo = new EffectGizmo(this, type);
gizmos.append(gizmo);
return gizmo;
}
EffectGizmo *Effect::gizmo(int i) {
EffectGizmo *Node::gizmo(int i) {
return gizmos.at(i);
}
int Effect::gizmo_count() {
int Node::gizmo_count() {
return gizmos.size();
}
void Effect::refresh() {}
void Node::refresh() {}
void Effect::FieldChanged() {
update_ui(false);
void Node::FieldChanged() {
// Update the UI if a field has been modified, but don't both if this effect is inactive
if (parent_clip != nullptr) {
update_ui(false);
}
}
void Effect::delete_self() {
void Node::delete_self() {
olive::undo_stack.push(new EffectDeleteCommand(this));
update_ui(true);
}
void Effect::move_up() {
void Node::move_up() {
int index_of_effect = parent_clip->IndexOfEffect(this);
if (index_of_effect == 0) {
return;
@@ -225,7 +220,7 @@ void Effect::move_up() {
panel_sequence_viewer->viewer_widget()->frame_update();
}
void Effect::move_down() {
void Node::move_down() {
int index_of_effect = parent_clip->IndexOfEffect(this);
if (index_of_effect == parent_clip->effects.size()-1) {
return;
@@ -240,7 +235,7 @@ void Effect::move_down() {
panel_sequence_viewer->viewer_widget()->frame_update();
}
void Effect::save_to_file() {
void Node::save_to_file() {
// save effect settings to file
QString file = QFileDialog::getSaveFileName(olive::MainWindow,
tr("Save Effect Settings"),
@@ -270,7 +265,7 @@ void Effect::save_to_file() {
}
}
void Effect::load_from_file() {
void Node::load_from_file() {
// load effect settings from file
QString file = QFileDialog::getOpenFileName(olive::MainWindow,
tr("Load Effect Settings"),
@@ -296,31 +291,31 @@ void Effect::load_from_file() {
}
}
bool Effect::AlwaysUpdate()
bool Node::AlwaysUpdate()
{
return false;
}
bool Effect::IsEnabled() {
bool Node::IsEnabled() {
return enabled_;
}
bool Effect::IsExpanded()
bool Node::IsExpanded()
{
return expanded_;
}
void Effect::SetExpanded(bool e)
void Node::SetExpanded(bool e)
{
expanded_ = e;
}
void Effect::SetEnabled(bool b) {
void Node::SetEnabled(bool b) {
enabled_ = b;
emit EnabledChanged(b);
}
void Effect::load(QXmlStreamReader& stream) {
void Node::load(QXmlStreamReader& stream) {
/*
int row_count = 0;
@@ -412,9 +407,9 @@ void Effect::load(QXmlStreamReader& stream) {
*/
}
void Effect::custom_load(QXmlStreamReader &) {}
void Node::custom_load(QXmlStreamReader &) {}
void Effect::save(QXmlStreamWriter& stream) {
void Node::save(QXmlStreamWriter& stream) {
/*
stream.writeAttribute("name", meta->category + "/" + meta->name);
stream.writeAttribute("enabled", QString::number(IsEnabled()));
@@ -451,7 +446,7 @@ void Effect::save(QXmlStreamWriter& stream) {
*/
}
void Effect::load_from_string(const QByteArray &s) {
void Node::load_from_string(const QByteArray &s) {
// clear existing keyframe data
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
@@ -465,6 +460,8 @@ void Effect::load_from_string(const QByteArray &s) {
// write settings with xml writer
QXmlStreamReader stream(s);
bool found_id = false;
while (!stream.atEnd()) {
stream.readNext();
@@ -475,16 +472,9 @@ void Effect::load_from_string(const QByteArray &s) {
const QXmlStreamAttributes& attributes = stream.attributes();
for (int i=0;i<attributes.size();i++) {
const QXmlStreamAttribute& attr = attributes.at(i);
if (attr.name() == "name") {
if (Effect::GetMetaFromName(attr.value().toString()) == meta) {
// pass off to standard loading function
load(stream);
} else {
QMessageBox::critical(olive::MainWindow,
tr("Load Settings Failed"),
tr("This settings file doesn't match this effect."),
QMessageBox::Ok);
}
if (attr.name() == "id") {
load(stream);
found_id = true;
break;
}
}
@@ -493,9 +483,16 @@ void Effect::load_from_string(const QByteArray &s) {
break;
}
}
if (!found_id) {
QMessageBox::critical(olive::MainWindow,
tr("Load Settings Failed"),
tr("This settings file doesn't match this effect."),
QMessageBox::Ok);
}
}
QByteArray Effect::save_to_string() {
QByteArray Node::save_to_string() {
QByteArray save_data;
// write settings to string with xml writer
@@ -515,11 +512,12 @@ QByteArray Effect::save_to_string() {
return save_data;
}
bool Effect::is_open() {
bool Node::is_open() {
return isOpen;
}
void Effect::validate_meta_path() {
void Node::validate_meta_path() {
/*
if (!meta->path.isEmpty() || (shader_vert_path_.isEmpty() && shader_frag_path_.isEmpty())) return;
QList<QString> effects_paths = get_effects_paths();
const QString& test_fn = shader_vert_path_.isEmpty() ? shader_frag_path_ : shader_vert_path_;
@@ -534,9 +532,11 @@ void Effect::validate_meta_path() {
return;
}
}
*/
}
void Effect::open() {
void Node::open() {
/*
if (isOpen) {
qWarning() << "Tried to open an effect that was already open";
close();
@@ -548,7 +548,7 @@ void Effect::open() {
validate_meta_path();
QString frag_shader_str;
QString frag_file_url = QDir(meta->path).filePath(shader_frag_path_);
QString frag_file_url = QDir(file).filePath(shader_frag_path_);
QFile frag_file(frag_file_url);
if (frag_file.open(QFile::ReadOnly)) {
frag_shader_str = frag_file.readAll();
@@ -570,41 +570,16 @@ void Effect::open() {
shader_program_ = olive::shader::GetPipeline(shader_func, frag_shader_str);
}
/*
bool shader_compiled = true;
if (!shader_vert_path_.isEmpty()) {
if (shader_program_->addShaderFromSourceFile(QOpenGLShader::Vertex, meta->path + "/" + shader_vert_path_)) {
qInfo() << "Vertex shader added successfully";
} else {
shader_compiled = false;
qWarning() << "Vertex shader could not be added";
}
}
if (!shader_frag_path_.isEmpty()) {
if (shader_program_->addShaderFromSourceFile(QOpenGLShader::Fragment, meta->path + "/" + shader_frag_path_)) {
qInfo() << "Fragment shader added successfully";
} else {
shader_compiled = false;
qWarning() << "Fragment shader could not be added";
}
}
if (shader_compiled) {
if (shader_program_->link()) {
qInfo() << "Shader program linked successfully";
} else {
qWarning() << "Shader program failed to link";
}
}
*/
isOpen = true;
}
} else {
isOpen = true;
}
*/
isOpen = true;
}
void Effect::close() {
void Node::close() {
if (!isOpen) {
qWarning() << "Tried to close an effect that was already closed";
}
@@ -613,43 +588,43 @@ void Effect::close() {
isOpen = false;
}
bool Effect::is_shader_linked() {
bool Node::is_shader_linked() {
return shader_program_ != nullptr && shader_program_->isLinked();
}
QOpenGLShaderProgram *Effect::GetShaderPipeline()
QOpenGLShaderProgram *Node::GetShaderPipeline()
{
return shader_program_.get();
}
int Effect::Flags()
int Node::Flags()
{
return flags_;
}
void Effect::SetFlags(int flags)
void Node::SetFlags(int flags)
{
flags_ = flags;
}
int Effect::getIterations() {
int Node::getIterations() {
return iterations;
}
void Effect::setIterations(int i) {
void Node::setIterations(int i) {
iterations = i;
}
void Effect::process_image(double, uint8_t *, uint8_t *, int){}
void Node::process_image(double, uint8_t *, uint8_t *, int){}
EffectPtr Effect::copy(Clip *c) {
EffectPtr copy = Effect::Create(c, meta);
NodePtr Node::copy(Clip *c) {
NodePtr copy = Create(c);
copy->SetEnabled(IsEnabled());
copy_field_keyframes(copy);
return copy;
}
void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
void Node::process_shader(double timecode, GLTextureCoords&, int iteration) {
/*
shader_program_->bind();
@@ -704,9 +679,9 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
*/
}
void Effect::process_coords(double, GLTextureCoords&, int) {}
void Node::process_coords(double, GLTextureCoords&, int) {}
GLuint Effect::process_superimpose(QOpenGLContext* ctx, double timecode) {
GLuint Node::process_superimpose(QOpenGLContext* ctx, double timecode) {
bool dimensions_changed = false;
bool redrew_image = false;
@@ -760,11 +735,11 @@ GLuint Effect::process_superimpose(QOpenGLContext* ctx, double timecode) {
return texture;
}
void Effect::process_audio(double, double, float **, int, int, int) {}
void Node::process_audio(double, double, float **, int, int, int) {}
void Effect::gizmo_draw(double, GLTextureCoords &) {}
void Node::gizmo_draw(double, GLTextureCoords &) {}
void Effect::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, double timecode, bool done) {
void Node::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, double timecode, bool done) {
// Loop through each gizmo to find `gizmo`
for (int i=0;i<gizmos.size();i++) {
@@ -833,7 +808,7 @@ void Effect::gizmo_move(EffectGizmo* gizmo, int x_movement, int y_movement, doub
}
}
void Effect::gizmo_world_to_screen(const QMatrix4x4& matrix, const QMatrix4x4& projection) {
void Node::gizmo_world_to_screen(const QMatrix4x4& matrix, const QMatrix4x4& projection) {
for (int i=0;i<gizmos.size();i++) {
EffectGizmo* g = gizmos.at(i);
@@ -854,21 +829,21 @@ void Effect::gizmo_world_to_screen(const QMatrix4x4& matrix, const QMatrix4x4& p
}
}
bool Effect::are_gizmos_enabled() {
bool Node::are_gizmos_enabled() {
return (gizmos.size() > 0);
}
double Effect::Now()
double Node::Now()
{
return playhead_to_clip_seconds(parent_clip, parent_clip->track()->sequence()->playhead);
}
long Effect::NowInFrames()
long Node::NowInFrames()
{
return playhead_to_clip_frame(parent_clip, parent_clip->track()->sequence()->playhead);
}
void Effect::redraw(double) {
void Node::redraw(double) {
/*
// run javascript
QPainter p(&img);
@@ -912,7 +887,7 @@ void Effect::redraw(double) {
*/
}
bool Effect::valueHasChanged(double timecode) {
bool Node::valueHasChanged(double timecode) {
if (cachedValues.isEmpty()) {
for (int i=0;i<row_count();i++) {
@@ -943,7 +918,7 @@ bool Effect::valueHasChanged(double timecode) {
}
}
void Effect::delete_texture() {
void Node::delete_texture() {
if (texture_ctx != nullptr) {
texture_ctx->functions()->glDeleteTextures(1, &texture);
texture = 0;
@@ -951,7 +926,18 @@ void Effect::delete_texture() {
}
}
const EffectMeta* Effect::GetMetaFromName(const QString& input) {
int GetNodeLibraryIndexFromId(const QString& id) {
for (int i=0;i<olive::node_library.size();i++) {
if (olive::node_library.at(i)->id() == id) {
return i;
}
}
return -1;
}
/*
const EffectMeta* Node::GetMetaFromName(const QString& input) {
int split_index = input.indexOf('/');
QString category;
if (split_index > -1) {
@@ -968,3 +954,4 @@ const EffectMeta* Effect::GetMetaFromName(const QString& input) {
}
return nullptr;
}
*/
+50 -61
View File
@@ -40,44 +40,45 @@
#include <QXmlStreamWriter>
#include <random>
#include "ui/collapsiblewidget.h"
#include "effectrow.h"
#include "effectgizmo.h"
#include "timeline/tracktypes.h"
#include "rendering/qopenglshaderprogramptr.h"
#include "nodes/inputs.h"
#include "inputs.h"
#include "effects/effectgizmo.h"
class EffectGizmo;
class KeyframeDataChange;
class Clip;
using ClipPtr = std::shared_ptr<Clip>;
class Effect;
using EffectPtr = std::shared_ptr<Effect>;
class Node;
using NodePtr = std::shared_ptr<Node>;
struct EffectMeta {
QString name;
QString category;
QString filename;
QString path;
QString tooltip;
int internal;
int type;
int subtype;
enum NodeType {
kTransformEffect,
kTextInput,
kSolidInput,
kNoiseInput,
kVolumeEffect,
kPanEffect,
kToneInput,
kShakeEffect,
kTimecodeEffect,
kMaskEffect,
kFillLeftRightEffect,
kVstEffect,
kCornerPinEffect,
kRichTextInput,
kMediaInput,
kShaderEffect,
kImageOutput,
kCrossDissolveTransition,
kLinearFadeTransition,
kExponentialFadeTransition,
kLogarithmicFadeTransition,
kInvalidNode
};
struct BlendMode {
QString name;
QString url;
QString function_name;
bool loaded;
};
namespace olive {
extern QVector<EffectMeta> effects;
extern QVector<BlendMode> blend_modes;
// TODO weird place to put this?
extern QString generated_blending_shader;
}
double log_volume(double linear);
enum EffectType {
@@ -92,24 +93,6 @@ enum EffectKeyframeType {
EFFECT_KEYFRAME_HOLD
};
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_RICHTEXT,
EFFECT_INTERNAL_COUNT
};
struct GLTextureCoords {
QMatrix4x4 matrix;
@@ -123,20 +106,25 @@ struct GLTextureCoords {
QVector2D texture_bottom_left;
QVector2D texture_bottom_right;
int blendmode;
float opacity;
};
class Effect : public QObject {
class Node : public QObject {
Q_OBJECT
public:
Effect(Clip *c, const EffectMeta* em);
~Effect();
Node(Clip *c);
~Node();
Clip* parent_clip;
const EffectMeta* meta;
int id;
QString name;
virtual QString name() = 0;
virtual QString id() = 0;
virtual QString category();
virtual QString description() = 0;
virtual EffectType type() = 0;
virtual olive::TrackType subtype() = 0;
virtual bool IsCreatable();
virtual NodePtr Create(Clip *c) = 0;
void AddRow(EffectRow* row);
@@ -152,8 +140,8 @@ public:
virtual void refresh();
virtual EffectPtr copy(Clip* c);
void copy_field_keyframes(EffectPtr e);
virtual NodePtr copy(Clip* c);
void copy_field_keyframes(NodePtr e);
virtual void load(QXmlStreamReader& stream);
virtual void custom_load(QXmlStreamReader& stream);
@@ -233,9 +221,6 @@ public:
return distribution(generator);
}
static EffectPtr Create(Clip *c, const EffectMeta *em);
static const EffectMeta* GetInternalMeta(int internal_id, int type);
static const EffectMeta* GetMetaFromName(const QString& input);
public slots:
void FieldChanged();
void SetEnabled(bool b);
@@ -287,4 +272,8 @@ private:
void validate_meta_path();
};
namespace olive {
extern QVector<NodePtr> node_library;
}
#endif // EFFECT_H
+1 -1
View File
@@ -8,7 +8,7 @@ NodeGraph::NodeGraph() :
}
Effect *NodeGraph::OutputNode()
Node *NodeGraph::OutputNode()
{
return output_node_.get();
}
+5 -5
View File
@@ -1,7 +1,7 @@
#ifndef NODEGRAPH_H
#define NODEGRAPH_H
#include "effects/effect.h"
#include "nodes/node.h"
class NodeGraph
{
@@ -15,7 +15,7 @@ public:
*
* @param node
*/
void AddNode(EffectPtr node);
void AddNode(NodePtr node);
/**
* @brief Process the graph
@@ -39,15 +39,15 @@ public:
*
* The node to set as the output node. The graph takes ownership of the node and the user cannot delete it.
*/
void SetOutputNode(EffectPtr node);
void SetOutputNode(NodePtr node);
/**
* @brief Returns the currently set output node
*/
Effect* OutputNode();
Node* OutputNode();
private:
EffectPtr output_node_;
NodePtr output_node_;
};
#endif // NODEGRAPH_H
+37 -1
View File
@@ -1,6 +1,42 @@
#include "nodeimageoutput.h"
NodeImageOutput::NodeImageOutput()
NodeImageOutput::NodeImageOutput(Clip *c) :
Node(c)
{
}
QString NodeImageOutput::name()
{
return tr("Image Output");
}
QString NodeImageOutput::id()
{
return "org.olivevideoeditor.Olive.imageoutput";
}
QString NodeImageOutput::category()
{
return tr("Outputs");
}
QString NodeImageOutput::description()
{
return tr("Used for outputting images outside of the node graph.");
}
EffectType NodeImageOutput::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType NodeImageOutput::subtype()
{
return olive::kTypeVideo;
}
NodePtr NodeImageOutput::Create(Clip *c)
{
return std::make_shared<NodeImageOutput>(c);
}
+12 -3
View File
@@ -1,11 +1,20 @@
#ifndef NODEIMAGEOUTPUT_H
#define NODEIMAGEOUTPUT_H
#include "nodes/node.h"
class NodeImageOutput
class NodeImageOutput : public Node
{
public:
NodeImageOutput();
NodeImageOutput(Clip* c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
};
#endif // NODEIMAGEOUTPUT_H
#endif // NODEIMAGEOUTPUT_H
+36 -1
View File
@@ -1,6 +1,41 @@
#include "nodemedia.h"
NodeMedia::NodeMedia()
NodeMedia::NodeMedia(Clip* c) :
Node(c)
{
}
QString NodeMedia::name()
{
return tr("Media");
}
QString NodeMedia::id()
{
return "org.olivevideoeditor.Olive.media";
}
QString NodeMedia::category()
{
return tr("Inputs");
}
QString NodeMedia::description()
{
return tr("Retrieve frames from a media source.");
}
EffectType NodeMedia::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType NodeMedia::subtype()
{
return olive::kTypeVideo;
}
NodePtr NodeMedia::Create(Clip *c)
{
return std::make_shared<NodeMedia>(c);
}
+12 -2
View File
@@ -1,10 +1,20 @@
#ifndef MEDIANODE_H
#define MEDIANODE_H
class NodeMedia
#include "nodes/node.h"
class NodeMedia : public Node
{
public:
NodeMedia();
NodeMedia(Clip *c);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual NodePtr Create(Clip *c) override;
};
#endif // MEDIANODE_H
+58 -23
View File
@@ -1,10 +1,18 @@
#include "nodeshader.h"
NodeShader::NodeShader(Clip* c, const EffectMeta *em) :
Effect(c, em)
NodeShader::NodeShader(Clip* c,
const QString &name,
const QString &id,
const QString &category,
const QString &filename) :
Node(c),
name_(name),
id_(id),
category_(category),
filename_(filename)
{
if (em != nullptr && !em->filename.isEmpty() && em->internal == -1) {
QFile effect_file(em->filename);
if (!filename_.isEmpty()) {
QFile effect_file(filename_);
if (effect_file.open(QFile::ReadOnly)) {
QXmlStreamReader reader(&effect_file);
@@ -29,7 +37,7 @@ NodeShader::NodeShader(Clip* c, const EffectMeta *em) :
}
if (id.isEmpty() || name.isEmpty() || type == olive::nodes::kInvalid) {
qCritical() << "Couldn't load field from" << em->filename << "- ID, type, and name cannot be empty.";
qCritical() << "Couldn't load field from" << filename_ << "- ID, type, and name cannot be empty.";
} else {
EffectRow* field = nullptr;
@@ -158,29 +166,56 @@ NodeShader::NodeShader(Clip* c, const EffectMeta *em) :
shader_function_name_ = attr.value().toString();
}
}
}/* else if (reader.name() == "superimpose" && reader.isStartElement()) {
enable_superimpose = true;
const QXmlStreamAttributes& attributes = reader.attributes();
for (int i=0;i<attributes.size();i++) {
const QXmlStreamAttribute& attr = attributes.at(i);
if (attr.name() == "script") {
QFile script_file(get_effects_dir() + "/" + attr.value().toString());
if (script_file.open(QFile::ReadOnly)) {
script = script_file.readAll();
} else {
qCritical() << "Failed to open superimpose script file for" << em->filename;
enable_superimpose = false;
}
break;
}
}
}*/
} else if (reader.name() == "description" && reader.isStartElement()) {
reader.readNext();
description_ = reader.text().toString();
}
reader.readNext();
}
effect_file.close();
} else {
qCritical() << "Failed to open effect file" << em->filename;
qCritical() << "Failed to open effect file" << filename;
}
}
}
QString NodeShader::name()
{
return name_;
}
QString NodeShader::id()
{
return id_;
}
QString NodeShader::category()
{
return category_;
}
QString NodeShader::description()
{
return description_;
}
EffectType NodeShader::type()
{
return EFFECT_TYPE_EFFECT;
}
olive::TrackType NodeShader::subtype()
{
return olive::kTypeVideo;
}
bool NodeShader::IsCreatable()
{
return !filename_.isEmpty();
}
NodePtr NodeShader::Create(Clip *)
{
Q_ASSERT(false);
}
+23 -3
View File
@@ -1,12 +1,32 @@
#ifndef NODESHADER_H
#define NODESHADER_H
#include "effects/effect.h"
#include "nodes/node.h"
class NodeShader : public Effect {
class NodeShader : public Node {
Q_OBJECT
public:
NodeShader(Clip *c, const EffectMeta *em);
NodeShader(Clip *c,
const QString& name,
const QString& id,
const QString& category,
const QString& filename);
virtual QString name() override;
virtual QString id() override;
virtual QString category() override;
virtual QString description() override;
virtual EffectType type() override;
virtual olive::TrackType subtype() override;
virtual bool IsCreatable() override;
virtual NodePtr Create(Clip *c) override;
private:
QString name_;
QString id_;
QString category_;
QString description_;
QString filename_;
};
#endif // NODESHADER_H
+1 -1
View File
@@ -1,6 +1,6 @@
#include "buttonwidget.h"
ButtonWidget::ButtonWidget(Effect* parent, const QString& name, const QString& text) :
ButtonWidget::ButtonWidget(Node* parent, const QString& name, const QString& text) :
EffectRow(parent, nullptr, name, false, false)
{
ButtonField* button_field = new ButtonField(this, text);
+1 -1
View File
@@ -6,7 +6,7 @@
class ButtonWidget : public EffectRow
{
public:
ButtonWidget(Effect* parent, const QString& name, const QString& text);
ButtonWidget(Node* parent, const QString& name, const QString& text);
/**
* @brief Wrapper for ButtonField::SetCheckable.
+1 -1
View File
@@ -1,6 +1,6 @@
#include "labelwidget.h"
LabelWidget::LabelWidget(Effect *parent, const QString &name, const QString &text) :
LabelWidget::LabelWidget(Node *parent, const QString &name, const QString &text) :
EffectRow(parent, nullptr, name, false, false)
{
AddField(new LabelField(this, text));
+1 -1
View File
@@ -6,7 +6,7 @@
class LabelWidget : public EffectRow
{
public:
LabelWidget(Effect* parent, const QString& name, const QString& text);
LabelWidget(Node* parent, const QString& name, const QString& text);
};
#endif // LABELWIDGET_H
+5 -4
View File
@@ -106,7 +106,6 @@ SOURCES += \
effects/internal/logarithmicfadetransition.cpp \
effects/internal/cornerpineffect.cpp \
global/math.cpp \
effects/effect.cpp \
effects/effectrow.cpp \
effects/effectgizmo.cpp \
ui/resizablescrollbar.cpp \
@@ -207,7 +206,8 @@ SOURCES += \
nodes/nodes/nodemedia.cpp \
nodes/nodes/nodeshader.cpp \
decoders/ffmpegdecoder.cpp \
decoders/decoder.cpp
decoders/decoder.cpp \
nodes/node.cpp
HEADERS += \
ui/mainwindow.h \
@@ -265,7 +265,6 @@ HEADERS += \
effects/internal/logarithmicfadetransition.h \
effects/internal/cornerpineffect.h \
global/math.h \
effects/effect.h \
effects/effectrow.h \
effects/internal/cubetransition.h \
effects/effectgizmo.h \
@@ -371,7 +370,9 @@ HEADERS += \
nodes/nodes/nodeshader.h \
nodes/nodes.h \
decoders/ffmpegdecoder.h \
decoders/decoder.h
decoders/decoder.h \
nodes/node.h \
timeline/tracktypes.h
FORMS +=
+25 -24
View File
@@ -32,7 +32,7 @@
#include <QApplication>
#include "panels/panels.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "effects/effectloaders.h"
#include "effects/transition.h"
#include "timeline/clip.h"
@@ -95,24 +95,24 @@ void EffectControls::menu_select(QAction* q) {
for (int i=0;i<selected_clips_.size();i++) {
Clip* c = selected_clips_.at(i);
if (c->type() == effect_menu_subtype) {
const EffectMeta* meta = reinterpret_cast<const EffectMeta*>(q->data().value<quintptr>());
NodeType node_type = static_cast<NodeType>(q->data().toInt());
if (effect_menu_type == EFFECT_TYPE_TRANSITION) {
if (c->opening_transition == nullptr) {
ca->append(new AddTransitionCommand(c,
nullptr,
nullptr,
meta,
node_type,
olive::config.default_transition_length));
}
if (c->closing_transition == nullptr) {
ca->append(new AddTransitionCommand(nullptr,
c,
nullptr,
meta,
node_type,
olive::config.default_transition_length));
}
} else {
ca->append(new AddEffectCommand(c, nullptr, meta));
ca->append(new AddEffectCommand(c, nullptr, node_type));
}
}
}
@@ -138,7 +138,7 @@ void EffectControls::scroll_to_frame(long frame) {
scroll_to_frame_internal(horizontalScrollBar, frame - keyframeView->visible_in, zoom, keyframeView->width());
}
void EffectControls::show_effect_menu(int type, Track::Type subtype) {
void EffectControls::show_effect_menu(EffectType type, olive::TrackType subtype) {
effect_menu_type = type;
effect_menu_subtype = subtype;
@@ -147,24 +147,25 @@ void EffectControls::show_effect_menu(int type, Track::Type subtype) {
Menu effects_menu(this);
effects_menu.setToolTipsVisible(true);
for (int i=0;i<olive::effects.size();i++) {
const EffectMeta& em = olive::effects.at(i);
for (int i=0;i<olive::node_library.size();i++) {
if (em.type == type && em.subtype == subtype) {
NodePtr node = olive::node_library.at(i);
if (node != nullptr && node->type() == type && node->subtype() == subtype) {
QAction* action = new QAction(&effects_menu);
action->setText(em.name);
action->setData(reinterpret_cast<quintptr>(&em));
if (!em.tooltip.isEmpty()) {
action->setToolTip(em.tooltip);
action->setText(node->name());
action->setData(i);
if (!node->description().isEmpty()) {
action->setToolTip(node->description());
}
QMenu* parent = &effects_menu;
if (!em.category.isEmpty()) {
if (!node->category().isEmpty()) {
bool found = false;
for (int j=0;j<effects_menu.actions().size();j++) {
QAction* action = effects_menu.actions().at(j);
if (action->menu() != nullptr) {
if (action->menu()->title() == em.category) {
if (action->menu()->title() == node->category()) {
parent = action->menu();
found = true;
break;
@@ -174,12 +175,12 @@ void EffectControls::show_effect_menu(int type, Track::Type subtype) {
if (!found) {
parent = new Menu(&effects_menu);
parent->setToolTipsVisible(true);
parent->setTitle(em.category);
parent->setTitle(node->category());
bool found = false;
for (int i=0;i<effects_menu.actions().size();i++) {
QAction* comp_action = effects_menu.actions().at(i);
if (comp_action->text() > em.category) {
if (comp_action->text() > node->category()) {
effects_menu.insertMenu(comp_action, parent);
found = true;
break;
@@ -444,19 +445,19 @@ bool EffectControls::focused()
}
void EffectControls::video_effect_click() {
show_effect_menu(EFFECT_TYPE_EFFECT, Track::kTypeVideo);
show_effect_menu(EFFECT_TYPE_EFFECT, olive::kTypeVideo);
}
void EffectControls::audio_effect_click() {
show_effect_menu(EFFECT_TYPE_EFFECT, Track::kTypeAudio);
show_effect_menu(EFFECT_TYPE_EFFECT, olive::kTypeAudio);
}
void EffectControls::video_transition_click() {
show_effect_menu(EFFECT_TYPE_TRANSITION, Track::kTypeVideo);
show_effect_menu(EFFECT_TYPE_TRANSITION, olive::kTypeVideo);
}
void EffectControls::audio_transition_click() {
show_effect_menu(EFFECT_TYPE_TRANSITION, Track::kTypeAudio);
show_effect_menu(EFFECT_TYPE_TRANSITION, olive::kTypeAudio);
}
void EffectControls::resizeEvent(QResizeEvent*) {
@@ -491,12 +492,12 @@ void EffectControls::LoadEvent()
QVBoxLayout* layout = nullptr;
EffectUI* container = open_effects_.at(i);
Effect* e = open_effects_.at(i)->GetEffect();
Node* e = open_effects_.at(i)->GetEffect();
if (e->meta->subtype == Track::kTypeVideo) {
if (e->subtype() == olive::kTypeVideo) {
vcontainer->setVisible(true);
layout = video_effect_layout;
} else if (e->meta->subtype == Track::kTypeAudio) {
} else if (e->subtype() == olive::kTypeAudio) {
acontainer->setVisible(true);
layout = audio_effect_layout;
}
+2 -2
View File
@@ -94,14 +94,14 @@ protected:
virtual void ClearEvent() override;
virtual void LoadEvent() override;
private:
void show_effect_menu(int type, Track::Type subtype);
void show_effect_menu(EffectType type, olive::TrackType subtype);
void load_keyframes();
void UpdateTitle();
void setup_ui();
int effect_menu_type;
Track::Type effect_menu_subtype;
olive::TrackType effect_menu_subtype;
QString panel_name;
QWidget* video_effect_area;
+9 -9
View File
@@ -76,7 +76,7 @@ void EffectsPanel::Load() {
Clip* c = selected_clips_.at(i);
// Create a list of the effects we'll open
QVector<Effect*> effects_to_open;
QVector<Node*> effects_to_open;
// Determine based on the current selections whether to load all effects or just the transitions
bool whole_clip_is_selected = c->IsSelected();
@@ -100,7 +100,7 @@ void EffectsPanel::Load() {
// Check if we've already opened an effect of this type before
bool already_opened = false;
for (int k=0;k<open_effects_.size();k++) {
if (open_effects_.at(k)->GetEffect()->meta == effects_to_open.at(j)->meta
if (open_effects_.at(k)->GetEffect()->id() == effects_to_open.at(j)->id()
&& !open_effects_.at(k)->IsAttachedToClip(c)) {
open_effects_.at(k)->AddAdditionalEffect(effects_to_open.at(j));
@@ -137,7 +137,7 @@ void EffectsPanel::Load() {
LoadEvent();
}
bool EffectsPanel::IsEffectSelected(Effect *e)
bool EffectsPanel::IsEffectSelected(Node *e)
{
for (int i=0;i<open_effects_.size();i++) {
if (open_effects_.at(i)->GetEffect() == e && open_effects_.at(i)->IsSelected()) {
@@ -174,9 +174,9 @@ void EffectsPanel::copy(bool del) {
for (int i=0;i<open_effects_.size();i++) {
if (open_effects_.at(i)->IsSelected()) {
Effect* e = open_effects_.at(i)->GetEffect();
Node* e = open_effects_.at(i)->GetEffect();
if (e->meta->type == EFFECT_TYPE_EFFECT) {
if (e->type() == EFFECT_TYPE_EFFECT) {
if (!cleared) {
olive::clipboard.Clear();
@@ -205,12 +205,12 @@ void EffectsPanel::copy(bool del) {
}
}
void EffectsPanel::DeleteEffect(ComboAction* ca, Effect* effect_ref) {
if (effect_ref->meta->type == EFFECT_TYPE_EFFECT) {
void EffectsPanel::DeleteEffect(ComboAction* ca, Node* effect_ref) {
if (effect_ref->type() == EFFECT_TYPE_EFFECT) {
ca->append(new EffectDeleteCommand(effect_ref));
} else if (effect_ref->meta->type == EFFECT_TYPE_TRANSITION) {
} else if (effect_ref->type() == EFFECT_TYPE_TRANSITION) {
// Retrieve shared ptr for this transition
@@ -258,7 +258,7 @@ void EffectsPanel::DeleteSelectedEffects() {
}
}
void EffectsPanel::open_effect(Effect* e) {
void EffectsPanel::open_effect(Node* e) {
EffectUI* container = new EffectUI(e);
connect(container, SIGNAL(CutRequested()), this, SLOT(cut()));
+3 -3
View File
@@ -18,7 +18,7 @@ public:
virtual bool focused() override;
bool IsEffectSelected(Effect* e);
bool IsEffectSelected(Node* e);
void DeleteSelectedEffects();
public slots:
@@ -32,8 +32,8 @@ protected:
QVector<EffectUI*> open_effects_;
private:
void Load();
void open_effect(Effect *e);
void DeleteEffect(ComboAction* ca, Effect* effect_ref);
void open_effect(Node *e);
void DeleteEffect(ComboAction* ca, Node* effect_ref);
private slots:
void deselect_all_effects(QWidget*);
};
+2 -2
View File
@@ -30,7 +30,7 @@
#include "timeline/timelinetools.h"
#include "ui/labelslider.h"
#include "ui/graphview.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "effects/effectfields.h"
#include "effects/effectrow.h"
#include "timeline/clip.h"
@@ -210,7 +210,7 @@ void GraphEditor::set_row(EffectRow *r) {
if (found_vals) {
row = r;
current_row_desc->setText(row->GetParentEffect()->parent_clip->name()
+ " :: " + row->GetParentEffect()->meta->name
+ " :: " + row->GetParentEffect()->name()
+ " :: " + row->name());
header->set_visible_in(r->GetParentEffect()->parent_clip->timeline_in());
+20 -20
View File
@@ -221,10 +221,10 @@ void Timeline::SetSequence(SequencePtr sequence)
return;
}
sequence_ = sequence;
sequence_ = sequence;
update_sequence();
video_area->SetTrackList(sequence_.get(), Track::kTypeVideo);
audio_area->SetTrackList(sequence_.get(), Track::kTypeAudio);
video_area->SetTrackList(sequence_.get(), olive::kTypeVideo);
audio_area->SetTrackList(sequence_.get(), olive::kTypeAudio);
repaint_timeline();
emit SequenceChanged(sequence_);
@@ -276,14 +276,14 @@ void Timeline::add_transition() {
for (int i=0;i<selected_clips.size();i++) {
Clip* c = selected_clips.at(i);
int transition_to_add = (c->type() == Track::kTypeVideo) ? TRANSITION_INTERNAL_CROSSDISSOLVE
: TRANSITION_INTERNAL_LINEARFADE;
NodeType transition_to_add = (c->type() == olive::kTypeVideo) ? kCrossDissolveTransition
: kLinearFadeTransition;
if (c->opening_transition == nullptr) {
ca->append(new AddTransitionCommand(c,
nullptr,
nullptr,
Effect::GetInternalMeta(transition_to_add, EFFECT_TYPE_TRANSITION),
transition_to_add,
olive::config.default_transition_length));
adding = true;
}
@@ -292,7 +292,7 @@ void Timeline::add_transition() {
ca->append(new AddTransitionCommand(nullptr,
c,
nullptr,
Effect::GetInternalMeta(transition_to_add, EFFECT_TYPE_TRANSITION),
transition_to_add,
olive::config.default_transition_length));
adding = true;
}
@@ -873,23 +873,23 @@ void Timeline::transition_tool_click() {
Menu transition_menu(this);
for (int i=0;i<olive::effects.size();i++) {
const EffectMeta& em = olive::effects.at(i);
if (em.type == EFFECT_TYPE_TRANSITION && em.subtype == Track::kTypeVideo) {
QAction* a = transition_menu.addAction(em.name);
for (int i=0;i<olive::node_library.size();i++) {
NodePtr node = olive::node_library.at(i);
if (node->type() == EFFECT_TYPE_TRANSITION && node->subtype() == olive::kTypeVideo) {
QAction* a = transition_menu.addAction(node->name());
a->setObjectName("v");
a->setData(reinterpret_cast<quintptr>(&em));
a->setData(i);
}
}
transition_menu.addSeparator();
for (int i=0;i<olive::effects.size();i++) {
const EffectMeta& em = olive::effects.at(i);
if (em.type == EFFECT_TYPE_TRANSITION && em.subtype == Track::kTypeAudio) {
QAction* a = transition_menu.addAction(em.name);
for (int i=0;i<olive::node_library.size();i++) {
NodePtr node = olive::node_library.at(i);
if (node->type() == EFFECT_TYPE_TRANSITION && node->subtype() == olive::kTypeVideo) {
QAction* a = transition_menu.addAction(node->name());
a->setObjectName("a");
a->setData(reinterpret_cast<quintptr>(&em));
a->setData(i);
}
}
@@ -901,12 +901,12 @@ void Timeline::transition_tool_click() {
}
void Timeline::transition_menu_select(QAction* a) {
transition_tool_meta = reinterpret_cast<const EffectMeta*>(a->data().value<quintptr>());
transition_tool_meta = static_cast<NodeType>(a->data().toInt());
if (a->objectName() == "v") {
transition_tool_side = Track::kTypeVideo;
transition_tool_side = olive::kTypeVideo;
} else {
transition_tool_side = Track::kTypeAudio;
transition_tool_side = olive::kTypeAudio;
}
timeline_area->setCursor(Qt::CrossCursor);
+2 -2
View File
@@ -114,8 +114,8 @@ public:
bool transition_tool_proc;
Clip* transition_tool_open_clip;
Clip* transition_tool_close_clip;
const EffectMeta* transition_tool_meta;
Track::Type transition_tool_side;
NodeType transition_tool_meta;
olive::TrackType transition_tool_side;
// hand tool variables
bool hand_moving;
+3 -3
View File
@@ -752,7 +752,7 @@ void Viewer::set_media(Media* m) {
new_sequence->frame_rate = video_stream.video_frame_rate * footage->speed;
}
ClipPtr c = std::make_shared<Clip>(new_sequence->GetTrackList(Track::kTypeVideo)->First());
ClipPtr c = std::make_shared<Clip>(new_sequence->GetTrackList(olive::kTypeVideo)->First());
c->set_media(media, video_stream.file_index);
c->set_timeline_in(0);
c->set_timeline_out(footage->get_length_in_frames(new_sequence->frame_rate));
@@ -760,7 +760,7 @@ void Viewer::set_media(Media* m) {
// FIXME: Move this magic number to Config
c->set_timeline_out(150);
}
Track* track = new_sequence->GetTrackList(Track::kTypeVideo)->First();
Track* track = new_sequence->GetTrackList(olive::kTypeVideo)->First();
c->set_track(track);
c->set_clip_in(0);
c->refresh();
@@ -774,7 +774,7 @@ void Viewer::set_media(Media* m) {
const FootageStream& audio_stream = footage->audio_tracks.at(0);
new_sequence->audio_frequency = audio_stream.audio_frequency;
Track* track = new_sequence->GetTrackList(Track::kTypeAudio)->First();
Track* track = new_sequence->GetTrackList(olive::kTypeAudio)->First();
ClipPtr c = std::make_shared<Clip>(track);
c->set_media(media, audio_stream.file_index);
c->set_timeline_in(0);
+25 -18
View File
@@ -60,7 +60,7 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
QString tag = stream.name().toString();
// variables to store effect metadata in
int effect_id = -1;
QString effect_id;
QString effect_name;
bool effect_enabled = true;
long effect_length = -1;
@@ -68,10 +68,10 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
// loop through attributes for effect metadata
for (int j=0;j<stream.attributes().size();j++) {
const QXmlStreamAttribute& attr = stream.attributes().at(j);
if (attr.name() == "id") {
effect_id = attr.value().toInt();
} else if (attr.name() == "enabled") {
if (attr.name() == "enabled") {
effect_enabled = (attr.value() == "1");
} else if (attr.name() == "id") {
effect_id = attr.value().toString();
} else if (attr.name() == "name") {
effect_name = attr.value().toString();
} else if (attr.name() == "length") {
@@ -116,30 +116,35 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
// for all the effects to finish loading
olive::effects_loaded.lock();
const EffectMeta* meta = nullptr;
NodeType type = kInvalidNode;
// find effect with this name
if (!effect_name.isEmpty()) {
meta = Effect::GetMetaFromName(effect_name);
if (!effect_id.isEmpty()) {
for (int i=0;i<olive::node_library.size();i++) {
if (i != kInvalidNode && olive::node_library.at(i)->id() == effect_id) {
type = static_cast<NodeType>(i);
break;
}
}
}
olive::effects_loaded.unlock();
int type;
TransitionType ttype;
if (tag == "opening") {
type = kTransitionOpening;
ttype = kTransitionOpening;
} else if (tag == "closing") {
type = kTransitionClosing;
ttype = kTransitionClosing;
} else {
type = kTransitionNone;
ttype = kTransitionNone;
}
// effect construction
if (cancelled_) return;
if (type == kTransitionNone) {
if (meta == nullptr) {
if (ttype == kTransitionNone) {
if (type == kInvalidNode) {
// create void effect
EffectPtr ve(new VoidEffect(c, effect_name));
NodePtr ve = std::make_shared<VoidEffect>(c, effect_name, effect_id);
ve->SetEnabled(effect_enabled);
ve->load(stream);
@@ -147,7 +152,7 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
c->effects.append(ve);
} else {
EffectPtr e(Effect::Create(c, meta));
NodePtr e = olive::node_library[type]->Create(c);
e->SetEnabled(effect_enabled);
e->load(stream);
@@ -156,14 +161,16 @@ void LoadThread::load_effect(QXmlStreamReader& stream, Clip* c) {
c->effects.append(e);
}
} else {
TransitionPtr t = Transition::Create(c, nullptr, meta);
if (effect_length > -1) t->set_length(effect_length);
TransitionPtr t = std::static_pointer_cast<Transition>(olive::node_library[type]->Create(c));
if (effect_length > -1) {
t->set_length(effect_length);
}
t->SetEnabled(effect_enabled);
t->load(stream);
t->moveToThread(QApplication::instance()->thread());
if (type == kTransitionOpening) {
if (ttype == kTransitionOpening) {
c->opening_transition = t;
} else {
c->closing_transition = t;
+6 -6
View File
@@ -62,7 +62,7 @@ void apply_audio_effects(Clip* clip, double timecode_start, AVFrame* frame, int
timecode_end = timecode_start + samples_to_seconds(nb_samples, frame->channels, frame->sample_rate);
for (int j=0;j<clip->effects.size();j++) {
Effect* e = clip->effects.at(j).get();
Node* e = clip->effects.at(j).get();
if (e->IsEnabled()) {
e->process_audio(timecode_start, timecode_end, reinterpret_cast<float**>(frame->data), nb_samples, nb_channels, kTransitionNone);
}
@@ -805,7 +805,7 @@ void Cacher::CacheVideoWorker() {
void Cacher::Reset() {
// if we seek to a whole other place in the timeline, we'll need to reset the cache with new values
if (clip->media() == nullptr) {
if (clip->type() == Track::kTypeAudio) {
if (clip->type() == olive::kTypeAudio) {
// a null-media audio clip is usually an auto-generated sound clip such as Tone or Noise
reached_end = false;
audio_target_frame = playhead_;
@@ -871,7 +871,7 @@ Cacher::Cacher(Clip* c) :
void Cacher::OpenWorker() {
// set some defaults for the audio cacher
if (clip->type() == Track::kTypeAudio) {
if (clip->type() == olive::kTypeAudio) {
audio_reset_ = false;
frame_sample_index_ = -1;
audio_buffer_write = 0;
@@ -879,7 +879,7 @@ void Cacher::OpenWorker() {
reached_end = false;
if (clip->media() == nullptr) {
if (clip->type() == Track::kTypeAudio) {
if (clip->type() == olive::kTypeAudio) {
frame_ = av_frame_alloc();
frame_->format = kDestSampleFmt;
frame_->channel_layout = clip->track()->sequence()->audio_layout;
@@ -1127,7 +1127,7 @@ void Cacher::OpenWorker() {
}
void Cacher::CacheWorker() {
if (clip->type() == Track::kTypeVideo) {
if (clip->type() == olive::kTypeVideo) {
// clip is a video track, start caching video
CacheVideoWorker();
} else {
@@ -1218,7 +1218,7 @@ void Cacher::Open()
caching_ = true;
queued_ = false;
start((clip->type() == Track::kTypeVideo) ? QThread::HighPriority : QThread::TimeCriticalPriority);
start((clip->type() == olive::kTypeVideo) ? QThread::HighPriority : QThread::TimeCriticalPriority);
}
void Cacher::Cache(long playhead, bool scrubbing, QVector<Clip*>& nests, int playback_speed)
+25 -22
View File
@@ -34,7 +34,7 @@ extern "C" {
#include "timeline/clip.h"
#include "timeline/sequence.h"
#include "project/media.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "project/footage.h"
#include "effects/transition.h"
#include "ui/collapsiblewidget.h"
@@ -110,7 +110,6 @@ void olive::rendering::Blit(QOpenGLShaderProgram* pipeline, bool flipped, QMatri
pipeline->setUniformValue("mvp_matrix", matrix);
pipeline->setUniformValue("texture", 0);
GLuint vertex_location = pipeline->attributeLocation("a_position");
m_vbo.bind();
func->glEnableVertexAttribArray(vertex_location);
@@ -176,7 +175,7 @@ GLuint draw_clip(QOpenGLContext* ctx,
void process_effect(QOpenGLContext* ctx,
QOpenGLShaderProgram* pipeline,
Clip* c,
Effect* e,
Node* e,
double timecode,
GLTextureCoords& coords,
GLuint& composite_texture,
@@ -184,11 +183,11 @@ void process_effect(QOpenGLContext* ctx,
bool& texture_failed,
int data) {
if (e->IsEnabled()) {
if (e->Flags() & Effect::CoordsFlag) {
if (e->Flags() & Node::CoordsFlag) {
e->process_coords(timecode, coords, data);
}
bool can_process_shaders = ((e->Flags() & Effect::ShaderFlag) && olive::runtime_config.shaders_are_enabled);
if (can_process_shaders || (e->Flags() & Effect::SuperimposeFlag)) {
bool can_process_shaders = ((e->Flags() & Node::ShaderFlag) && olive::runtime_config.shaders_are_enabled);
if (can_process_shaders || (e->Flags() & Node::SuperimposeFlag)) {
if (!e->is_open()) {
e->open();
@@ -201,7 +200,7 @@ void process_effect(QOpenGLContext* ctx,
fbo_switcher = !fbo_switcher;
}
}
if (e->Flags() & Effect::SuperimposeFlag) {
if (e->Flags() & Node::SuperimposeFlag) {
GLuint superimpose_texture = e->process_superimpose(ctx, timecode);
if (superimpose_texture == 0) {
@@ -227,7 +226,7 @@ void process_effect(QOpenGLContext* ctx,
}
GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
GLuint final_fbo = params.type == Track::kTypeVideo ? params.main_buffer->buffer() : 0;
GLuint final_fbo = params.type == olive::kTypeVideo ? params.main_buffer->buffer() : 0;
Sequence* s = params.seq;
long playhead = s->playhead;
@@ -240,7 +239,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
playhead = rescale_frame_number(playhead, params.nests.at(i)->track()->sequence()->frame_rate, s->frame_rate);
}
if (params.type == Track::kTypeVideo && !params.nests.last()->fbo.isEmpty()) {
if (params.type == olive::kTypeVideo && !params.nests.last()->fbo.isEmpty()) {
params.nests.last()->fbo.at(0).BindBuffer();
params.ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
final_fbo = params.nests.last()->fbo.at(0).buffer();
@@ -270,7 +269,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
Footage* m = c->media()->to_footage();
// does the clip have a valid media source?
if (!m->invalid && !(c->type() == Track::kTypeAudio && !is_audio_device_set())) {
if (!m->invalid && !(c->type() == olive::kTypeAudio && !is_audio_device_set())) {
// is the media process and ready?
if (m->ready) {
@@ -287,7 +286,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
clip_is_active = true;
// increment audio track count
if (c->type() == Track::kTypeAudio) audio_track_count++;
if (c->type() == olive::kTypeAudio) audio_track_count++;
} else if (c->IsOpen()) {
@@ -321,7 +320,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
// track sorting is only necessary for video clips
// audio clips are mixed equally, so we skip sorting for those
if (params.type == Track::kTypeVideo) {
if (params.type == olive::kTypeVideo) {
// insertion sort by track
for (int j=0;j<current_clips.size();j++) {
@@ -344,7 +343,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
QMatrix4x4 projection;
if (params.type == Track::kTypeVideo) {
if (params.type == olive::kTypeVideo) {
// set default coordinates based on the sequence, with 0 in the direct center
params.ctx->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@@ -370,7 +369,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
if (got_mutex && c->IsOpen()) {
// if clip is a video clip
if (c->type() == Track::kTypeVideo) {
if (c->type() == olive::kTypeVideo) {
// textureID variable contains texture to be drawn on screen at the end
GLuint textureID = 0;
@@ -504,7 +503,6 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
coords.texture_top_right = QVector2D(1.0f, 0.0f);
coords.texture_bottom_left = QVector2D(0.0f, 1.0f);
coords.texture_bottom_right = QVector2D(1.0f, 1.0f);
coords.blendmode = -1;
coords.opacity = 1.0;
// == EFFECT CODE START ==
@@ -515,7 +513,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
// run through all of the clip's effects
for (int j=0;j<c->effects.size();j++) {
Effect* e = c->effects.at(j).get();
Node* e = c->effects.at(j).get();
process_effect(params.ctx, params.pipeline, c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, kTransitionNone);
}
@@ -685,9 +683,11 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
// copy front buffer to back buffer (only if we're using a blending mode)
/*
if (coords.blendmode >= 0) {
draw_clip(params.ctx, params.pipeline, back_buffer_2, comp_texture, true);
}
*/
@@ -700,7 +700,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, final_fbo);
// Check if we're using a blend mode (< 0 means no blend mode)
if (coords.blendmode < 0) {
//if (coords.blendmode < 0) {
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1);
@@ -708,7 +708,9 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
} else {
//} else {
/*
// load background texture into texture unit 0
params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
@@ -739,7 +741,9 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
}
*/
//}
// unbind framebuffer
params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
@@ -750,7 +754,7 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams &params) {
// == END FINAL DRAW ON SEQUENCE BUFFER ==
}
}
} else if (c->type() == Track::kTypeAudio) {
} else if (c->type() == olive::kTypeAudio) {
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_SEQUENCE) {
params.nests.append(c);
compose_sequence(params);
@@ -795,11 +799,10 @@ void olive::rendering::compose_audio(Viewer* viewer, Sequence* seq, int playback
params.viewer = viewer;
params.ctx = nullptr;
params.seq = seq;
params.type = Track::kTypeAudio;
params.type = olive::kTypeAudio;
params.gizmos = nullptr;
params.wait_for_mutexes = wait_for_mutexes;
params.playback_speed = playback_speed;
params.blend_mode_program = nullptr;
compose_sequence(params);
}
+4 -17
View File
@@ -28,7 +28,7 @@
namespace OCIO = OCIO_NAMESPACE::v1;
#include "timeline/sequence.h"
#include "effects/effect.h"
#include "nodes/node.h"
#include "panels/viewer.h"
/**
@@ -80,16 +80,16 @@ struct ComposeSequenceParams {
/**
* @brief Set compose mode to video or audio
*
* Accepts Track::kTypeVideo to render video, Track::kTypeAudio if this function should render audio.
* Accepts olive::kTypeVideo to render video, olive::kTypeAudio if this function should render audio.
*/
Track::Type type;
olive::TrackType type;
/**
* @brief Set to the Effect whose gizmos were chosen to be drawn on screen
*
* The currently active Effect that compose_sequence() will update the gizmos of.
*/
Effect* gizmos;
Node* gizmos;
/**
* @brief A variable that compose_sequence() will set to **TRUE** if any of the clips couldn't be shown.
@@ -138,19 +138,6 @@ struct ComposeSequenceParams {
*/
int playback_speed;
/**
* @brief Blending mode shader
*
* Used only for video rendering. Never accessed with audio rendering.
*
* A program containing the current active
* blending mode shader that can be bound during rendering. Must be compiled and linked beforehand. See
* RenderThread::blend_mode_program for how this is properly set up.
*
* \see ComposeSequenceParams::video
*/
QOpenGLShaderProgram* blend_mode_program;
/**
* @brief Premultiply alpha shader
*

Some files were not shown because too many files have changed in this diff Show More