diff --git a/effects/internal/crossdissolvetransition.cpp b/effects/internal/crossdissolvetransition.cpp index f71c12637..dc89eb2be 100644 --- a/effects/internal/crossdissolvetransition.cpp +++ b/effects/internal/crossdissolvetransition.cpp @@ -2,7 +2,7 @@ #include -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; } diff --git a/effects/internal/crossdissolvetransition.h b/effects/internal/crossdissolvetransition.h index 907c5566b..c90fd8080 100644 --- a/effects/internal/crossdissolvetransition.h +++ b/effects/internal/crossdissolvetransition.h @@ -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 &); }; diff --git a/effects/internal/exponentialfadetransition.cpp b/effects/internal/exponentialfadetransition.cpp index 5333d311f..6182e62c7 100644 --- a/effects/internal/exponentialfadetransition.cpp +++ b/effects/internal/exponentialfadetransition.cpp @@ -2,7 +2,7 @@ #include -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; diff --git a/effects/internal/exponentialfadetransition.h b/effects/internal/exponentialfadetransition.h index 0f285503b..1259db15a 100644 --- a/effects/internal/exponentialfadetransition.h +++ b/effects/internal/exponentialfadetransition.h @@ -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); }; diff --git a/effects/internal/linearfadetransition.cpp b/effects/internal/linearfadetransition.cpp index 8b16b4247..32e18b755 100644 --- a/effects/internal/linearfadetransition.cpp +++ b/effects/internal/linearfadetransition.cpp @@ -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; diff --git a/effects/internal/linearfadetransition.h b/effects/internal/linearfadetransition.h index bfa3bd6ce..0542ce3f9 100644 --- a/effects/internal/linearfadetransition.h +++ b/effects/internal/linearfadetransition.h @@ -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); }; diff --git a/effects/internal/logarithmicfadetransition.cpp b/effects/internal/logarithmicfadetransition.cpp index d2c1c9c37..60509c77c 100644 --- a/effects/internal/logarithmicfadetransition.cpp +++ b/effects/internal/logarithmicfadetransition.cpp @@ -2,7 +2,7 @@ #include -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; diff --git a/effects/internal/logarithmicfadetransition.h b/effects/internal/logarithmicfadetransition.h index 56e9ce370..d2a887d7c 100644 --- a/effects/internal/logarithmicfadetransition.h +++ b/effects/internal/logarithmicfadetransition.h @@ -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); }; diff --git a/panels/effectcontrols.cpp b/panels/effectcontrols.cpp index 3dc92a8e8..da0368d30 100644 --- a/panels/effectcontrols.cpp +++ b/panels/effectcontrols.cpp @@ -67,10 +67,10 @@ void EffectControls::menu_select(QAction* q) { const EffectMeta* meta = reinterpret_cast(q->data().value()); 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)); diff --git a/panels/project.cpp b/panels/project.cpp index d5b6e0bf3..3ba823e07 100644 --- a/panels/project.cpp +++ b/panels/project.cpp @@ -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;jsequence->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); diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 08f790676..06d53deb9 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -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; } } diff --git a/playback/cacher.cpp b/playback/cacher.cpp index 7f233c31a..3448c287f 100644 --- a/playback/cacher.cpp +++ b/playback/cacher.cpp @@ -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;iqueue.size();i++) { - // TODO/NOTE: this will not work on clips that are sped up AND reversed + for (int i=0;iqueue.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 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 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; + } + } } } diff --git a/playback/cacher.h b/playback/cacher.h index dbfab0793..ad6060681 100644 --- a/playback/cacher.h +++ b/playback/cacher.h @@ -19,6 +19,7 @@ public: long playhead; bool reset; bool scrubbing; + bool interrupt; QVector nests; private: diff --git a/playback/playback.cpp b/playback/playback.cpp index f6db4c200..0b0842206 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -26,7 +26,7 @@ extern "C" { #include #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, QVectorcacher->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; diff --git a/project/clip.cpp b/project/clip.cpp index 1137c4fd5..60e64ec6b 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -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 diff --git a/project/effect.cpp b/project/effect.cpp index ca739d990..4826f6df8 100644 --- a/project/effect.cpp +++ b/project/effect.cpp @@ -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() { diff --git a/project/effect.h b/project/effect.h index 2f467f1b5..c9e84bf35 100644 --- a/project/effect.h +++ b/project/effect.h @@ -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; diff --git a/project/effectfield.cpp b/project/effectfield.cpp index 7cffe89e6..51f8331c5 100644 --- a/project/effectfield.cpp +++ b/project/effectfield.cpp @@ -80,12 +80,12 @@ QVariant EffectField::get_previous_data() { QVariant EffectField::get_current_data() { switch (type) { - case EFFECT_FIELD_DOUBLE: return static_cast(ui_element)->value(); break; - case EFFECT_FIELD_COLOR: return static_cast(ui_element)->get_color(); break; - case EFFECT_FIELD_STRING: return static_cast(ui_element)->getPlainTextEx(); break; - case EFFECT_FIELD_BOOL: return static_cast(ui_element)->isChecked(); break; - case EFFECT_FIELD_COMBO: return static_cast(ui_element)->currentIndex(); break; - case EFFECT_FIELD_FONT: return static_cast(ui_element)->currentText(); break; + case EFFECT_FIELD_DOUBLE: return static_cast(ui_element)->value(); + case EFFECT_FIELD_COLOR: return static_cast(ui_element)->get_color(); + case EFFECT_FIELD_STRING: return static_cast(ui_element)->getPlainTextEx(); + case EFFECT_FIELD_BOOL: return static_cast(ui_element)->isChecked(); + case EFFECT_FIELD_COMBO: return static_cast(ui_element)->currentIndex(); + case EFFECT_FIELD_FONT: return static_cast(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(ui_element)->set_value(data.toDouble(), false); break; - case EFFECT_FIELD_COLOR: return static_cast(ui_element)->set_color(data.value()); break; - case EFFECT_FIELD_STRING: return static_cast(ui_element)->setPlainTextEx(data.toString()); break; - case EFFECT_FIELD_BOOL: return static_cast(ui_element)->setChecked(data.toBool()); break; - case EFFECT_FIELD_COMBO: return static_cast(ui_element)->setCurrentIndexEx(data.toInt()); break; - case EFFECT_FIELD_FONT: return static_cast(ui_element)->setCurrentTextEx(data.toString()); break; + case EFFECT_FIELD_DOUBLE: return static_cast(ui_element)->set_value(data.toDouble(), false); + case EFFECT_FIELD_COLOR: return static_cast(ui_element)->set_color(data.value()); + case EFFECT_FIELD_STRING: return static_cast(ui_element)->setPlainTextEx(data.toString()); + case EFFECT_FIELD_BOOL: return static_cast(ui_element)->setChecked(data.toBool()); + case EFFECT_FIELD_COMBO: return static_cast(ui_element)->setCurrentIndexEx(data.toInt()); + case EFFECT_FIELD_FONT: return static_cast(ui_element)->setCurrentTextEx(data.toString()); } } diff --git a/project/transition.cpp b/project/transition.cpp index 4ff7f136c..7f67e0587 100644 --- a/project/transition.cpp +++ b/project/transition.cpp @@ -12,27 +12,27 @@ #include -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; diff --git a/project/transition.h b/project/transition.h index 8b3a69e33..6ca111433 100644 --- a/project/transition.h +++ b/project/transition.h @@ -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 diff --git a/project/undo.cpp b/project/undo.cpp index 25ab515de..fcea5fe04 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -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); diff --git a/project/undo.h b/project/undo.h index 80b177176..cb35e3d13 100644 --- a/project/undo.h +++ b/project/undo.h @@ -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; diff --git a/ui/timelinewidget.cpp b/ui/timelinewidget.cpp index e599cf5ab..de018a958 100644 --- a/ui/timelinewidget.cpp +++ b/ui/timelinewidget.cpp @@ -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; diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 30e804dd0..76f1bf13f 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -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()));