Merge pull request #152 from olive-editor/cacheinterrupt
merge cache interrupts
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <QOpenGLFunctions>
|
||||
|
||||
CrossDissolveTransition::CrossDissolveTransition(Clip* c, const EffectMeta* em) : Transition(c, em) {
|
||||
CrossDissolveTransition::CrossDissolveTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {
|
||||
enable_coords = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
class CrossDissolveTransition : public Transition {
|
||||
public:
|
||||
CrossDissolveTransition(Clip* c, const EffectMeta* em);
|
||||
CrossDissolveTransition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
void process_coords(double timecode, GLTextureCoords &);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
ExponentialFadeTransition::ExponentialFadeTransition(Clip* c, const EffectMeta* em) : Transition(c, em) {}
|
||||
ExponentialFadeTransition::ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
|
||||
|
||||
void ExponentialFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) {
|
||||
double interval = (timecode_end-timecode_start)/nb_bytes;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
class ExponentialFadeTransition : public Transition {
|
||||
public:
|
||||
ExponentialFadeTransition(Clip* c, const EffectMeta* em);
|
||||
ExponentialFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "linearfadetransition.h"
|
||||
|
||||
LinearFadeTransition::LinearFadeTransition(Clip* c, const EffectMeta* em) : Transition(c, em) {}
|
||||
LinearFadeTransition::LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
|
||||
|
||||
void LinearFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) {
|
||||
double interval = (timecode_end-timecode_start)/nb_bytes;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
class LinearFadeTransition : public Transition {
|
||||
public:
|
||||
LinearFadeTransition(Clip* c, const EffectMeta* em);
|
||||
LinearFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <QtMath>
|
||||
|
||||
LogarithmicFadeTransition::LogarithmicFadeTransition(Clip* c, const EffectMeta* em) : Transition(c, em) {}
|
||||
LogarithmicFadeTransition::LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em) : Transition(c, s, em) {}
|
||||
|
||||
void LogarithmicFadeTransition::process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int type) {
|
||||
double interval = (timecode_end-timecode_start)/nb_bytes;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
class LogarithmicFadeTransition : public Transition {
|
||||
public:
|
||||
LogarithmicFadeTransition(Clip* c, const EffectMeta* em);
|
||||
LogarithmicFadeTransition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
|
||||
};
|
||||
|
||||
|
||||
@@ -67,10 +67,10 @@ void EffectControls::menu_select(QAction* q) {
|
||||
const EffectMeta* meta = reinterpret_cast<const EffectMeta*>(q->data().value<quintptr>());
|
||||
if (transition_menu) {
|
||||
if (c->get_opening_transition() == NULL) {
|
||||
ca->append(new AddTransitionCommand(c, meta, TA_OPENING_TRANSITION, 30));
|
||||
ca->append(new AddTransitionCommand(c, NULL, meta, TA_OPENING_TRANSITION, 30));
|
||||
}
|
||||
if (c->get_closing_transition() == NULL) {
|
||||
ca->append(new AddTransitionCommand(c, meta, TA_CLOSING_TRANSITION, 30));
|
||||
ca->append(new AddTransitionCommand(c, NULL, meta, TA_CLOSING_TRANSITION, 30));
|
||||
}
|
||||
} else {
|
||||
ca->append(new AddEffectCommand(c, meta));
|
||||
|
||||
+10
-5
@@ -1076,7 +1076,8 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
int effect_id = -1;
|
||||
QString effect_name;
|
||||
bool effect_enabled = true;
|
||||
long effect_length = -1;
|
||||
long effect_pre_length = -1;
|
||||
long effect_post_length = -1;
|
||||
for (int j=0;j<stream.attributes().size();j++) {
|
||||
const QXmlStreamAttribute& attr = stream.attributes().at(j);
|
||||
if (attr.name() == "id") {
|
||||
@@ -1086,7 +1087,9 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
} else if (attr.name() == "name") {
|
||||
effect_name = attr.value().toString();
|
||||
} else if (attr.name() == "length") {
|
||||
effect_length = attr.value().toLong();
|
||||
effect_pre_length = attr.value().toLong();
|
||||
} else if (attr.name() == "postlength") { // backwards compatibility
|
||||
effect_post_length = attr.value().toLong();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1132,9 +1135,12 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
QString tag = stream.name().toString();
|
||||
|
||||
if (tag == "opening" || tag == "closing") {
|
||||
int transition_index = create_transition(c, meta);
|
||||
// TODO replace NULL/s with somethingn else
|
||||
|
||||
int transition_index = create_transition(c, NULL, meta);
|
||||
Transition* t = c->sequence->transitions.at(transition_index);
|
||||
if (effect_length > -1) t->length = effect_length;
|
||||
if (effect_pre_length > -1) t->length = effect_pre_length;
|
||||
if (effect_post_length > -1) t->length2 = effect_post_length;
|
||||
t->set_enabled(effect_enabled);
|
||||
t->load(stream);
|
||||
|
||||
@@ -1145,7 +1151,6 @@ bool Project::load_worker(QFile& f, QXmlStreamReader& stream, int type) {
|
||||
}
|
||||
} else {
|
||||
Effect* e = create_effect(c, meta);
|
||||
if (effect_length > -1) e->length = effect_length;
|
||||
e->set_enabled(effect_enabled);
|
||||
e->load(stream);
|
||||
|
||||
|
||||
+2
-2
@@ -355,11 +355,11 @@ void Timeline::add_transition() {
|
||||
Clip* c = sequence->clips.at(i);
|
||||
if (c != NULL && is_clip_selected(c, true)) {
|
||||
if (c->get_opening_transition() == NULL) {
|
||||
ca->append(new AddTransitionCommand(c, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE), TA_OPENING_TRANSITION, 30));
|
||||
ca->append(new AddTransitionCommand(c, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE), TA_OPENING_TRANSITION, 30));
|
||||
adding = true;
|
||||
}
|
||||
if (c->get_closing_transition() == NULL) {
|
||||
ca->append(new AddTransitionCommand(c, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE), TA_OPENING_TRANSITION, 30));
|
||||
ca->append(new AddTransitionCommand(c, NULL, get_internal_meta(TRANSITION_INTERNAL_LINEARFADE), TA_OPENING_TRANSITION, 30));
|
||||
adding = true;
|
||||
}
|
||||
}
|
||||
|
||||
+47
-24
@@ -426,7 +426,7 @@ void cache_video_worker(Clip* c, long playhead) {
|
||||
limit *= 2;
|
||||
}
|
||||
|
||||
if (c->queue.size() < limit) {
|
||||
if (c->queue.size() < limit) {
|
||||
bool reverse = (c->reverse && !c->ignore_reverse);
|
||||
c->ignore_reverse = false;
|
||||
|
||||
@@ -445,6 +445,10 @@ void cache_video_worker(Clip* c, long playhead) {
|
||||
smallest_pts = target_pts;
|
||||
}
|
||||
|
||||
if (c->multithreaded && c->cacher->interrupt) { // ignore interrupts for now
|
||||
c->cacher->interrupt = false;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
AVFrame* frame = av_frame_alloc();
|
||||
|
||||
@@ -452,6 +456,10 @@ void cache_video_worker(Clip* c, long playhead) {
|
||||
MediaStream* ms = media->get_stream_from_file_index(true, c->media_stream);
|
||||
|
||||
while ((retr_ret = av_buffersink_get_frame(c->buffersink_ctx, frame)) == AVERROR(EAGAIN)) {
|
||||
/*if (c->multithreaded && c->cacher->interrupt) { // abort
|
||||
return;
|
||||
}*/
|
||||
|
||||
AVFrame* send_frame = c->frame;
|
||||
read_ret = (c->use_existing_frame) ? 0 : retrieve_next_frame(c, send_frame);
|
||||
c->use_existing_frame = false;
|
||||
@@ -464,9 +472,9 @@ void cache_video_worker(Clip* c, long playhead) {
|
||||
send_it = true;
|
||||
} else if (media->get_stream_from_file_index(true, c->media_stream)->infinite_length) {
|
||||
send_it = true;
|
||||
} else {
|
||||
} else {
|
||||
dout << "skipped adding a frame to the queue - fpts:" << send_frame->pts << "target:" << target_pts;
|
||||
}
|
||||
}
|
||||
|
||||
if (send_it) {
|
||||
if ((send_ret = av_buffersrc_add_frame_flags(c->buffersrc_ctx, send_frame, AV_BUFFERSRC_FLAG_KEEP_REF)) < 0) {
|
||||
@@ -506,8 +514,7 @@ void cache_video_worker(Clip* c, long playhead) {
|
||||
if (!ms->infinite_length && !reverse && c->queue.size() == limit) {
|
||||
// see if we got the frame we needed (used for speed ups primarily)
|
||||
bool found = false;
|
||||
for (int i=0;i<c->queue.size();i++) {
|
||||
// TODO/NOTE: this will not work on clips that are sped up AND reversed
|
||||
for (int i=0;i<c->queue.size();i++) {
|
||||
if (c->queue.at(i)->pts >= target_pts) {
|
||||
found = true;
|
||||
break;
|
||||
@@ -524,11 +531,17 @@ void cache_video_worker(Clip* c, long playhead) {
|
||||
c->queue_lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (c->multithreaded && c->cacher->interrupt) { // abort
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reset_cache(Clip* c, long target_frame) {
|
||||
dout << "reset cache called";
|
||||
|
||||
// if we seek to a whole other place in the timeline, we'll need to reset the cache with new values
|
||||
switch (c->media_type) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
@@ -549,6 +562,8 @@ void reset_cache(Clip* c, long target_frame) {
|
||||
int64_t timebase_half_second = qRound64(av_q2d(av_inv_q(c->stream->time_base)));
|
||||
if (c->reverse) seek_ts -= timebase_half_second;
|
||||
|
||||
dout << "reset ts:" << target_ts;
|
||||
|
||||
while (true) {
|
||||
// flush ffmpeg codecs
|
||||
avcodec_flush_buffers(c->codecCtx);
|
||||
@@ -865,25 +880,25 @@ void open_clip_worker(Clip* clip) {
|
||||
dout << "[INFO] Clip opened on track" << clip->track;
|
||||
}
|
||||
|
||||
void cache_clip_worker(Clip* clip, long playhead, bool reset, bool scrubbing, QVector<Clip*> nests) {
|
||||
if (reset) {
|
||||
// note: for video, playhead is in "internal clip" frames - for audio, it's the timeline playhead
|
||||
reset_cache(clip, playhead);
|
||||
clip->audio_reset = false;
|
||||
}
|
||||
void cache_clip_worker(Clip* clip, long playhead, bool reset, bool scrubbing, QVector<Clip*> nests) {
|
||||
if (reset) {
|
||||
// note: for video, playhead is in "internal clip" frames - for audio, it's the timeline playhead
|
||||
reset_cache(clip, playhead);
|
||||
clip->audio_reset = false;
|
||||
}
|
||||
|
||||
switch (clip->media_type) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
cache_video_worker(clip, playhead);
|
||||
} else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
cache_audio_worker(clip, scrubbing, nests);
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_TONE:
|
||||
cache_audio_worker(clip, scrubbing, nests);
|
||||
break;
|
||||
}
|
||||
switch (clip->media_type) {
|
||||
case MEDIA_TYPE_FOOTAGE:
|
||||
if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
cache_video_worker(clip, playhead);
|
||||
} else if (clip->stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
|
||||
cache_audio_worker(clip, scrubbing, nests);
|
||||
}
|
||||
break;
|
||||
case MEDIA_TYPE_TONE:
|
||||
cache_audio_worker(clip, scrubbing, nests);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void close_clip_worker(Clip* clip) {
|
||||
@@ -912,6 +927,7 @@ void Cacher::run() {
|
||||
clip->finished_opening = false;
|
||||
clip->open = true;
|
||||
caching = true;
|
||||
interrupt = false;
|
||||
|
||||
open_clip_worker(clip);
|
||||
|
||||
@@ -920,7 +936,14 @@ void Cacher::run() {
|
||||
if (!caching) {
|
||||
break;
|
||||
} else {
|
||||
cache_clip_worker(clip, playhead, reset, scrubbing, nests);
|
||||
while (true) {
|
||||
cache_clip_worker(clip, playhead, reset, scrubbing, nests);
|
||||
if (clip->multithreaded && clip->cacher->interrupt) {
|
||||
clip->cacher->interrupt = false;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
long playhead;
|
||||
bool reset;
|
||||
bool scrubbing;
|
||||
bool interrupt;
|
||||
QVector<Clip*> nests;
|
||||
|
||||
private:
|
||||
|
||||
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#include <QOpenGLFramebufferObject>
|
||||
|
||||
#ifdef QT_DEBUG
|
||||
//#define GCF_DEBUG
|
||||
#define GCF_DEBUG
|
||||
#endif
|
||||
|
||||
bool texture_failed = false;
|
||||
@@ -102,6 +102,7 @@ void cache_clip(Clip* clip, long playhead, bool reset, bool scrubbing, QVector<C
|
||||
clip->cacher->reset = reset;
|
||||
clip->cacher->nests = nests;
|
||||
clip->cacher->scrubbing = scrubbing;
|
||||
if (reset && clip->queue.size() > 0) clip->cacher->interrupt = true;
|
||||
|
||||
clip->can_cache.wakeAll();
|
||||
} else {
|
||||
@@ -120,6 +121,7 @@ void get_clip_frame(Clip* c, long playhead) {
|
||||
target_pts *= 2;
|
||||
second_pts *= 2;
|
||||
}
|
||||
|
||||
AVFrame* target_frame = NULL;
|
||||
|
||||
bool reset = false;
|
||||
|
||||
+12
-12
@@ -65,8 +65,9 @@ Clip* Clip::copy(Sequence* s) {
|
||||
copy->effects.append(effects.at(i)->copy(copy));
|
||||
}
|
||||
|
||||
if (opening_transition != -1) copy->opening_transition = this->sequence->transitions.at(opening_transition)->copy(copy);
|
||||
if (closing_transition != -1) copy->closing_transition = this->sequence->transitions.at(closing_transition)->copy(copy);
|
||||
// TODO make a replacemennt for this somehow
|
||||
//if (opening_transition != -1) copy->opening_transition = this->sequence->transitions.at(opening_transition)->copy(copy);
|
||||
//if (closing_transition != -1) copy->closing_transition = this->sequence->transitions.at(closing_transition)->copy(copy);
|
||||
|
||||
copy->recalculateMaxLength();
|
||||
|
||||
@@ -178,21 +179,20 @@ Clip::~Clip() {
|
||||
}
|
||||
|
||||
long Clip::get_timeline_in_with_transition() {
|
||||
/*if (opening_transition != NULL && opening_transition->tlink != NULL) {
|
||||
return timeline_in - this->sequence->transitions(opening_transition)->tlink->length;
|
||||
} else {
|
||||
return timeline_in;
|
||||
}*/
|
||||
return 0;
|
||||
if (get_opening_transition() != NULL && get_opening_transition()->secondary_clip != NULL) {
|
||||
// we must be the secondary clip, so return (timeline in - length)
|
||||
return timeline_in - get_opening_transition()->length;
|
||||
}
|
||||
return timeline_in;
|
||||
}
|
||||
|
||||
long Clip::get_timeline_out_with_transition() {
|
||||
/*if (closing_transition != NULL && closing_transition->tlink != NULL) {
|
||||
return timeline_out + closing_transition->tlink->length;
|
||||
if (get_closing_transition() != NULL && get_closing_transition()->secondary_clip != NULL) {
|
||||
// we must be the primary clip, so return (timeline out + length2)
|
||||
return timeline_out + get_closing_transition()->length2;
|
||||
} else {
|
||||
return timeline_out;
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// timeline functions
|
||||
|
||||
+16
-14
@@ -467,26 +467,28 @@ void Effect::field_changed() {
|
||||
}
|
||||
|
||||
void Effect::show_context_menu(const QPoint& pos) {
|
||||
QMenu menu(mainWindow);
|
||||
if (meta->type == EFFECT_TYPE_EFFECT) {
|
||||
QMenu menu(mainWindow);
|
||||
|
||||
int index = get_index_in_clip();
|
||||
int index = get_index_in_clip();
|
||||
|
||||
if (index > 0) {
|
||||
QAction* move_up = menu.addAction("Move &Up");
|
||||
connect(move_up, SIGNAL(triggered(bool)), this, SLOT(move_up()));
|
||||
}
|
||||
if (index > 0) {
|
||||
QAction* move_up = menu.addAction("Move &Up");
|
||||
connect(move_up, SIGNAL(triggered(bool)), this, SLOT(move_up()));
|
||||
}
|
||||
|
||||
if (index < parent_clip->effects.size() - 1) {
|
||||
QAction* move_down = menu.addAction("Move &Down");
|
||||
connect(move_down, SIGNAL(triggered(bool)), this, SLOT(move_down()));
|
||||
}
|
||||
if (index < parent_clip->effects.size() - 1) {
|
||||
QAction* move_down = menu.addAction("Move &Down");
|
||||
connect(move_down, SIGNAL(triggered(bool)), this, SLOT(move_down()));
|
||||
}
|
||||
|
||||
menu.addSeparator();
|
||||
menu.addSeparator();
|
||||
|
||||
QAction* del_action = menu.addAction("D&elete");
|
||||
connect(del_action, SIGNAL(triggered(bool)), this, SLOT(delete_self()));
|
||||
QAction* del_action = menu.addAction("D&elete");
|
||||
connect(del_action, SIGNAL(triggered(bool)), this, SLOT(delete_self()));
|
||||
|
||||
menu.exec(container->title_bar->mapToGlobal(pos));
|
||||
menu.exec(container->title_bar->mapToGlobal(pos));
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::delete_self() {
|
||||
|
||||
@@ -111,6 +111,7 @@ public:
|
||||
Clip* parent_clip;
|
||||
const EffectMeta* meta;
|
||||
long length; // used only for transitions
|
||||
long length2; // used only for transitions
|
||||
int id;
|
||||
QString name;
|
||||
CollapsibleWidget* container;
|
||||
|
||||
+12
-12
@@ -80,12 +80,12 @@ QVariant EffectField::get_previous_data() {
|
||||
|
||||
QVariant EffectField::get_current_data() {
|
||||
switch (type) {
|
||||
case EFFECT_FIELD_DOUBLE: return static_cast<LabelSlider*>(ui_element)->value(); break;
|
||||
case EFFECT_FIELD_COLOR: return static_cast<ColorButton*>(ui_element)->get_color(); break;
|
||||
case EFFECT_FIELD_STRING: return static_cast<TextEditEx*>(ui_element)->getPlainTextEx(); break;
|
||||
case EFFECT_FIELD_BOOL: return static_cast<QCheckBox*>(ui_element)->isChecked(); break;
|
||||
case EFFECT_FIELD_COMBO: return static_cast<ComboBoxEx*>(ui_element)->currentIndex(); break;
|
||||
case EFFECT_FIELD_FONT: return static_cast<FontCombobox*>(ui_element)->currentText(); break;
|
||||
case EFFECT_FIELD_DOUBLE: return static_cast<LabelSlider*>(ui_element)->value();
|
||||
case EFFECT_FIELD_COLOR: return static_cast<ColorButton*>(ui_element)->get_color();
|
||||
case EFFECT_FIELD_STRING: return static_cast<TextEditEx*>(ui_element)->getPlainTextEx();
|
||||
case EFFECT_FIELD_BOOL: return static_cast<QCheckBox*>(ui_element)->isChecked();
|
||||
case EFFECT_FIELD_COMBO: return static_cast<ComboBoxEx*>(ui_element)->currentIndex();
|
||||
case EFFECT_FIELD_FONT: return static_cast<FontCombobox*>(ui_element)->currentText();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
@@ -100,12 +100,12 @@ long EffectField::timecodeToFrame(double timecode) {
|
||||
|
||||
void EffectField::set_current_data(const QVariant& data) {
|
||||
switch (type) {
|
||||
case EFFECT_FIELD_DOUBLE: return static_cast<LabelSlider*>(ui_element)->set_value(data.toDouble(), false); break;
|
||||
case EFFECT_FIELD_COLOR: return static_cast<ColorButton*>(ui_element)->set_color(data.value<QColor>()); break;
|
||||
case EFFECT_FIELD_STRING: return static_cast<TextEditEx*>(ui_element)->setPlainTextEx(data.toString()); break;
|
||||
case EFFECT_FIELD_BOOL: return static_cast<QCheckBox*>(ui_element)->setChecked(data.toBool()); break;
|
||||
case EFFECT_FIELD_COMBO: return static_cast<ComboBoxEx*>(ui_element)->setCurrentIndexEx(data.toInt()); break;
|
||||
case EFFECT_FIELD_FONT: return static_cast<FontCombobox*>(ui_element)->setCurrentTextEx(data.toString()); break;
|
||||
case EFFECT_FIELD_DOUBLE: return static_cast<LabelSlider*>(ui_element)->set_value(data.toDouble(), false);
|
||||
case EFFECT_FIELD_COLOR: return static_cast<ColorButton*>(ui_element)->set_color(data.value<QColor>());
|
||||
case EFFECT_FIELD_STRING: return static_cast<TextEditEx*>(ui_element)->setPlainTextEx(data.toString());
|
||||
case EFFECT_FIELD_BOOL: return static_cast<QCheckBox*>(ui_element)->setChecked(data.toBool());
|
||||
case EFFECT_FIELD_COMBO: return static_cast<ComboBoxEx*>(ui_element)->setCurrentIndexEx(data.toInt());
|
||||
case EFFECT_FIELD_FONT: return static_cast<FontCombobox*>(ui_element)->setCurrentTextEx(data.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -12,27 +12,27 @@
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
Transition::Transition(Clip* c, const EffectMeta* em) : Effect(c, em) {
|
||||
Transition::Transition(Clip* c, Clip* s, const EffectMeta* em) : Effect(c, em), secondary_clip(s) {
|
||||
add_row("Length:")->add_field(EFFECT_FIELD_DOUBLE);
|
||||
}
|
||||
|
||||
int Transition::copy(Clip *c) {
|
||||
int copy_index = create_transition(c, meta);
|
||||
int Transition::copy(Clip *c, Clip* s) {
|
||||
int copy_index = create_transition(c, s, meta);
|
||||
c->sequence->transitions.at(copy_index)->length = length;
|
||||
return copy_index;
|
||||
}
|
||||
|
||||
Transition* get_transition_from_meta(Clip* c, const EffectMeta* em) {
|
||||
Transition* get_transition_from_meta(Clip* c, Clip* s, const EffectMeta* em) {
|
||||
if (!em->filename.isEmpty()) {
|
||||
// load effect from file
|
||||
return new Transition(c, em);
|
||||
return 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 new CrossDissolveTransition(c, em);
|
||||
case TRANSITION_INTERNAL_LINEARFADE: return new LinearFadeTransition(c, em);
|
||||
case TRANSITION_INTERNAL_EXPONENTIALFADE: return new ExponentialFadeTransition(c, em);
|
||||
case TRANSITION_INTERNAL_LOGARITHMICFADE: return new LogarithmicFadeTransition(c, em);
|
||||
case TRANSITION_INTERNAL_CROSSDISSOLVE: return new CrossDissolveTransition(c, s, em);
|
||||
case TRANSITION_INTERNAL_LINEARFADE: return new LinearFadeTransition(c, s, em);
|
||||
case TRANSITION_INTERNAL_EXPONENTIALFADE: return new ExponentialFadeTransition(c, s, em);
|
||||
case TRANSITION_INTERNAL_LOGARITHMICFADE: return new LogarithmicFadeTransition(c, s, em);
|
||||
}
|
||||
} else {
|
||||
dout << "[ERROR] Invalid transition data";
|
||||
@@ -41,8 +41,8 @@ Transition* get_transition_from_meta(Clip* c, const EffectMeta* em) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int create_transition(Clip* c, const EffectMeta* em) {
|
||||
Transition* t = get_transition_from_meta(c, em);
|
||||
int create_transition(Clip* c, Clip* s, const EffectMeta* em) {
|
||||
Transition* t = get_transition_from_meta(c, s, em);
|
||||
if (t != NULL) {
|
||||
c->sequence->transitions.append(t);
|
||||
return c->sequence->transitions.size() - 1;
|
||||
|
||||
@@ -13,12 +13,13 @@
|
||||
#define TRANSITION_INTERNAL_LOGARITHMICFADE 3
|
||||
#define TRANSITION_INTERNAL_COUNT 4
|
||||
|
||||
int create_transition(Clip* c, const EffectMeta* em);
|
||||
int create_transition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
|
||||
class Transition : public Effect {
|
||||
public:
|
||||
Transition(Clip* c, const EffectMeta* em);
|
||||
int copy(Clip* c);
|
||||
Transition(Clip* c, Clip* s, const EffectMeta* em);
|
||||
int copy(Clip* c, Clip* s);
|
||||
Clip* secondary_clip;
|
||||
};
|
||||
|
||||
#endif // TRANSITION_H
|
||||
|
||||
+7
-3
@@ -224,8 +224,9 @@ void AddEffectCommand::redo() {
|
||||
mainWindow->setWindowModified(true);
|
||||
}
|
||||
|
||||
AddTransitionCommand::AddTransitionCommand(Clip* c, const EffectMeta *itransition, int itype, int ilength) :
|
||||
AddTransitionCommand::AddTransitionCommand(Clip* c, Clip *s, const EffectMeta *itransition, int itype, int ilength) :
|
||||
clip(c),
|
||||
secondary(s),
|
||||
transition(itransition),
|
||||
type(itype),
|
||||
length(ilength),
|
||||
@@ -234,15 +235,18 @@ AddTransitionCommand::AddTransitionCommand(Clip* c, const EffectMeta *itransitio
|
||||
|
||||
void AddTransitionCommand::undo() {
|
||||
clip->sequence->hard_delete_transition(clip, type);
|
||||
if (secondary != NULL) secondary->sequence->hard_delete_transition(secondary, (type == TA_OPENING_TRANSITION) ? TA_CLOSING_TRANSITION : TA_OPENING_TRANSITION);
|
||||
mainWindow->setWindowModified(old_project_changed);
|
||||
}
|
||||
|
||||
void AddTransitionCommand::redo() {
|
||||
if (type == TA_OPENING_TRANSITION) {
|
||||
clip->opening_transition = create_transition(clip, transition);
|
||||
clip->opening_transition = create_transition(clip, secondary, transition);
|
||||
if (secondary != NULL) secondary->closing_transition = clip->opening_transition;
|
||||
if (length > 0) clip->get_opening_transition()->length = length;
|
||||
} else {
|
||||
clip->closing_transition = create_transition(clip, transition);
|
||||
clip->closing_transition = create_transition(clip, secondary, transition);
|
||||
if (secondary != NULL) secondary->opening_transition = clip->closing_transition;
|
||||
if (length > 0) clip->get_closing_transition()->length = length;
|
||||
}
|
||||
mainWindow->setWindowModified(true);
|
||||
|
||||
+2
-1
@@ -101,11 +101,12 @@ private:
|
||||
|
||||
class AddTransitionCommand : public QUndoCommand {
|
||||
public:
|
||||
AddTransitionCommand(Clip* c, const EffectMeta* itransition, int itype, int ilength);
|
||||
AddTransitionCommand(Clip* c, Clip* s, const EffectMeta* itransition, int itype, int ilength);
|
||||
void undo();
|
||||
void redo();
|
||||
private:
|
||||
Clip* clip;
|
||||
Clip* secondary;
|
||||
const EffectMeta* transition;
|
||||
int type;
|
||||
int length;
|
||||
|
||||
@@ -1015,8 +1015,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
|
||||
pre = post;
|
||||
post = temp;
|
||||
}
|
||||
ca->append(new AddTransitionCommand(pre, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - pre->timeline_in));
|
||||
ca->append(new AddTransitionCommand(post, panel_timeline->transition_tool_meta, opposite_type, post->timeline_out - transition_start));
|
||||
ca->append(new AddTransitionCommand(pre, post, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - pre->timeline_in));
|
||||
} else {
|
||||
if (transition_start < c->timeline_in || transition_end > c->timeline_out) {
|
||||
// delete shit over there and extend timeline in
|
||||
@@ -1036,7 +1035,7 @@ void TimelineWidget::mouseReleaseEvent(QMouseEvent *event) {
|
||||
ca->append(new MoveClipAction(c, qMin(transition_start, c->timeline_in), qMax(transition_end, c->timeline_out), c->clip_in, c->track));
|
||||
}
|
||||
|
||||
ca->append(new AddTransitionCommand(c, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start));
|
||||
ca->append(new AddTransitionCommand(c, NULL, panel_timeline->transition_tool_meta, panel_timeline->transition_tool_type, transition_end - transition_start));
|
||||
}
|
||||
|
||||
push_undo = true;
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
|
||||
format.setDepthBufferSize(24);
|
||||
setFormat(format);
|
||||
|
||||
// error handler - retries after 50ms if we couldn't get the entire image
|
||||
// error handler - retries after 500ms if we couldn't get the entire image
|
||||
retry_timer.setInterval(50);
|
||||
connect(&retry_timer, SIGNAL(timeout()), this, SLOT(retry()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user