diff --git a/panels/timeline.cpp b/panels/timeline.cpp index 630c943a4..dca06a26c 100644 --- a/panels/timeline.cpp +++ b/panels/timeline.cpp @@ -641,14 +641,22 @@ void Timeline::snapping_clicked(bool checked) { snapping = checked; } -Clip* Timeline::split_clip(ComboAction* ca, int p, long frame) { - return split_clip(ca, p, frame, frame); +Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame) { + return split_clip(ca, transitions, p, frame, frame); } -Clip* Timeline::split_clip(ComboAction* ca, int p, long frame, long post_in) { +Clip* Timeline::split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in) { Clip* pre = sequence->clips.at(p); if (pre != nullptr && pre->timeline_in < frame && pre->timeline_out > frame) { // guard against attempts to split at in/out points - Clip* post = pre->copy(sequence); + bool splitting_closing_dual_transition = false; + + if (transitions + && pre->get_closing_transition() != nullptr + && pre->get_closing_transition()->secondary_clip != nullptr) { + splitting_closing_dual_transition = true; + } + + Clip* post = pre->copy(sequence, transitions && !splitting_closing_dual_transition); long new_clip_length = frame - pre->timeline_in; @@ -658,11 +666,11 @@ Clip* Timeline::split_clip(ComboAction* ca, int p, long frame, long post_in) { move_clip(ca, pre, pre->timeline_in, frame, pre->clip_in, pre->track); if (pre->get_opening_transition() != nullptr) { - /*if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != nullptr) { +// if (frame < pre->timeline_in + pre->get_opening_transition()->length && pre->get_opening_transition()->secondary_clip != nullptr) { // separate shared transition - ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, nullptr)); - pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, nullptr); - }*/ +// ca->append(new SetPointer((void**) &pre->get_opening_transition()->secondary_clip, nullptr)); +// pre->get_opening_transition()->secondary_clip->closing_transition = pre->get_opening_transition()->copy(pre->get_opening_transition()->secondary_clip, nullptr); +// } if (pre->get_opening_transition()->get_true_length() > new_clip_length) { ca->append(new ModifyTransitionCommand(pre, TA_OPENING_TRANSITION, new_clip_length)); @@ -671,8 +679,24 @@ Clip* Timeline::split_clip(ComboAction* ca, int p, long frame, long post_in) { post->sequence->hard_delete_transition(post, TA_OPENING_TRANSITION); } if (pre->get_closing_transition() != nullptr) { - ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); - if (pre->get_closing_transition()->secondary_clip == nullptr) post->get_closing_transition()->set_length(qMin(long(post->get_closing_transition()->get_true_length()), post->getLength())); + if (splitting_closing_dual_transition) { + // just move closing transition to post clip + + // WORKAROUND + ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); + } else { + ca->append(new DeleteTransitionCommand(pre->sequence, pre->closing_transition)); + + if (post->get_closing_transition() != nullptr) { + if (pre->get_closing_transition()->secondary_clip == nullptr) { + post->get_closing_transition()->set_length(qMin(long(post->get_closing_transition()->get_true_length()), post->getLength())); + } + + if (post->get_closing_transition()->get_length() > post->getLength()) { + post->get_closing_transition()->set_length(post->getLength()); + } + } + } } return post; @@ -702,7 +726,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool QVector pre_clips; QVector post_clips; - Clip* post = split_clip(ca, clip, frame); + Clip* post = split_clip(ca, true, clip, frame); // if alt is not down, split clips links too if (post == nullptr) { @@ -721,7 +745,7 @@ bool Timeline::split_clip_and_relink(ComboAction *ca, int clip, long frame, bool Clip* link = sequence->clips.at(l); if ((original_clip_is_selected && is_clip_selected(link, true)) || !original_clip_is_selected) { split_cache.append(l); - Clip* s = split_clip(ca, l, frame); + Clip* s = split_clip(ca, true, l, frame); if (s != nullptr) { pre_clips.append(l); post_clips.append(s); @@ -916,7 +940,9 @@ void Timeline::relink_clips_using_ids(QVector& old_clips, QVector& n for (int j=0;jlinked.size();j++) { for (int k=0;klinked.at(j) == old_clips.at(k)) { - new_clips.at(i)->linked.append(k); + if (new_clips.at(i) != nullptr) { + new_clips.at(i)->linked.append(k); + } } } } @@ -1194,50 +1220,12 @@ bool Timeline::split_selection(ComboAction* ca) { for (int i=0;iselections.size();i++) { const Selection& s = sequence->selections.at(i); if (s.track == clip->track) { - if (clip->timeline_in < s.in && clip->timeline_out > s.out) { - Clip* split_A = clip->copy(sequence); - split_A->clip_in += (s.in - clip->timeline_in); - split_A->timeline_in = s.in; - split_A->timeline_out = s.out; - pre_splits.append(j); - post_splits.append(split_A); - - Clip* split_B = clip->copy(sequence); - split_B->clip_in += (s.out - clip->timeline_in); - split_B->timeline_in = s.out; - secondary_post_splits.append(split_B); - - if (clip->get_opening_transition() != nullptr) { - split_B->sequence->hard_delete_transition(split_B, TA_OPENING_TRANSITION); - split_A->sequence->hard_delete_transition(split_A, TA_OPENING_TRANSITION); - } - - if (clip->get_closing_transition() != nullptr) { - ca->append(new DeleteTransitionCommand(clip->sequence, clip->closing_transition)); - - split_A->sequence->hard_delete_transition(split_A, TA_CLOSING_TRANSITION); - } - - move_clip(ca, clip, clip->timeline_in, s.in, clip->clip_in, clip->track); - split = true; - } else { - Clip* post_a = split_clip(ca, j, s.in); - Clip* post_b = split_clip(ca, j, s.out); - if (post_a != nullptr) { - pre_splits.append(j); - post_splits.append(post_a); - split = true; - } - if (post_b != nullptr) { - if (post_a != nullptr) { - pre_splits.append(j); - post_splits.append(post_b); - } else { - secondary_post_splits.append(post_b); - } - split = true; - } - } + Clip* post_b = split_clip(ca, true, j, s.out); + Clip* post_a = split_clip(ca, post_b == nullptr, j, s.in); + pre_splits.append(j); + post_splits.append(post_a); + secondary_post_splits.append(post_b); + split = true; } } } @@ -1247,6 +1235,10 @@ bool Timeline::split_selection(ComboAction* ca) { // relink after splitting relink_clips_using_ids(pre_splits, post_splits); relink_clips_using_ids(pre_splits, secondary_post_splits); + + post_splits.removeAll(nullptr); + secondary_post_splits.removeAll(nullptr); + ca->append(new AddClipCommand(sequence, post_splits)); ca->append(new AddClipCommand(sequence, secondary_post_splits)); @@ -1281,7 +1273,7 @@ void Timeline::split_at_playhead() { for (int j=0;jclips.size();j++) { Clip* clip = sequence->clips.at(j); if (clip != nullptr && is_clip_selected(clip, true)) { - Clip* s = split_clip(ca, j, sequence->playhead); + Clip* s = split_clip(ca, true, j, sequence->playhead); if (s != nullptr) { pre_clips.append(j); post_clips.append(s); diff --git a/panels/timeline.h b/panels/timeline.h index a081a869c..7ce3e8f24 100644 --- a/panels/timeline.h +++ b/panels/timeline.h @@ -79,8 +79,8 @@ public: void set_zoom(bool in); void copy(bool del); void paste(bool insert); - Clip* split_clip(ComboAction* ca, int p, long frame); - Clip* split_clip(ComboAction* ca, int p, long frame, long post_in); + Clip* split_clip(ComboAction* ca, bool transitions, int p, long frame); + Clip* split_clip(ComboAction* ca, bool transitions, int p, long frame, long post_in); bool split_selection(ComboAction* ca); bool split_all_clips_at_point(ComboAction *ca, long point); bool split_clip_and_relink(ComboAction* ca, int clip, long frame, bool relink); diff --git a/playback/playback.cpp b/playback/playback.cpp index 2056a2be8..4c3ed3cc8 100644 --- a/playback/playback.cpp +++ b/playback/playback.cpp @@ -66,8 +66,6 @@ void open_clip(Clip* clip, bool multithreaded) { } void close_clip(Clip* clip, bool wait) { -// qDebug() << "closing" << clip->name; - clip->finished_opening = false; // destroy opengl texture in main thread @@ -284,7 +282,7 @@ void get_clip_frame(Clip* c, long playhead, bool& texture_failed) { } } - c->texture->setData(0, get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8, using_db_1 ? data_buffer_1 : data_buffer_2); + c->texture->setData(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8, const_cast(using_db_1 ? data_buffer_1 : data_buffer_2)); if (data_buffer_1 != target_frame->data[0]) { delete [] data_buffer_1; diff --git a/project/clip.cpp b/project/clip.cpp index f57213b2f..57041333d 100644 --- a/project/clip.cpp +++ b/project/clip.cpp @@ -44,7 +44,7 @@ Clip::Clip(Sequence* s) : reset(); } -Clip* Clip::copy(Sequence* s) { +Clip* Clip::copy(Sequence* s, bool duplicate_transitions) { Clip* copy = new Clip(s); copy->enabled = enabled; @@ -69,8 +69,10 @@ Clip* Clip::copy(Sequence* s) { copy->cached_fr = (this->sequence == nullptr) ? cached_fr : this->sequence->frame_rate; - if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip == nullptr) copy->opening_transition = get_opening_transition()->copy(copy, nullptr); - if (get_closing_transition() != nullptr && get_closing_transition()->secondary_clip == nullptr) copy->closing_transition = get_closing_transition()->copy(copy, nullptr); + if (duplicate_transitions) { + if (get_opening_transition() != nullptr && get_opening_transition()->secondary_clip == nullptr) copy->opening_transition = get_opening_transition()->copy(copy, nullptr); + if (get_closing_transition() != nullptr && get_closing_transition()->secondary_clip == nullptr) copy->closing_transition = get_closing_transition()->copy(copy, nullptr); + } copy->recalculateMaxLength(); diff --git a/project/clip.h b/project/clip.h index 99e896472..1e5d245a5 100644 --- a/project/clip.h +++ b/project/clip.h @@ -35,7 +35,7 @@ struct Clip { Clip(Sequence* s); ~Clip(); - Clip* copy(Sequence* s); + Clip* copy(Sequence* s, bool duplicate_transitions = true); void reset_audio(); void reset(); void refresh(); diff --git a/project/undo.cpp b/project/undo.cpp index f37e13793..d16b481c4 100644 --- a/project/undo.cpp +++ b/project/undo.cpp @@ -209,7 +209,7 @@ SetTimelineInOutCommand::SetTimelineInOutCommand(Sequence *s, bool enabled, long void SetTimelineInOutCommand::undo() { seq->using_workarea = old_enabled; - seq->enable_workarea = old_workarea_enabled; + seq->enable_workarea = old_workarea_enabled; seq->workarea_in = old_in; seq->workarea_out = old_out; @@ -226,11 +226,11 @@ void SetTimelineInOutCommand::undo() { void SetTimelineInOutCommand::redo() { old_enabled = seq->using_workarea; - old_workarea_enabled = seq->enable_workarea; + old_workarea_enabled = seq->enable_workarea; old_in = seq->workarea_in; old_out = seq->workarea_out; - if (!seq->using_workarea) seq->enable_workarea = true; + if (!seq->using_workarea) seq->enable_workarea = true; seq->using_workarea = new_enabled; seq->workarea_in = new_in; seq->workarea_out = new_out; diff --git a/project/undo.h b/project/undo.h index aaae9a016..c4fbf7619 100644 --- a/project/undo.h +++ b/project/undo.h @@ -174,7 +174,7 @@ public: private: Sequence* seq; - bool old_workarea_enabled; + bool old_workarea_enabled; bool old_enabled; long old_in; diff --git a/ui/audiomonitor.cpp b/ui/audiomonitor.cpp index 45fa8d573..114e745b0 100644 --- a/ui/audiomonitor.cpp +++ b/ui/audiomonitor.cpp @@ -29,7 +29,7 @@ void AudioMonitor::set_value(const QVector &ivalues) { values = ivalues; update(); - QMetaObject::invokeMethod(&clear_timer, "start"); + QMetaObject::invokeMethod(&clear_timer, "start", Qt::QueuedConnection); } void AudioMonitor::clear() { diff --git a/ui/renderfunctions.cpp b/ui/renderfunctions.cpp index a950fde15..c881208c9 100644 --- a/ui/renderfunctions.cpp +++ b/ui/renderfunctions.cpp @@ -238,7 +238,7 @@ GLuint compose_sequence(Viewer* viewer, c->texture->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); c->texture->allocateStorage(get_gl_pix_fmt_from_av(c->pix_fmt), QOpenGLTexture::UInt8); } - get_clip_frame(c, playhead, texture_failed); + get_clip_frame(c, qMax(playhead, c->timeline_in), texture_failed); textureID = c->texture->textureId(); break; case MEDIA_TYPE_SEQUENCE: @@ -258,6 +258,7 @@ GLuint compose_sequence(Viewer* viewer, c->fbo = new QOpenGLFramebufferObject* [2]; c->fbo[0] = new QOpenGLFramebufferObject(video_width, video_height); c->fbo[1] = new QOpenGLFramebufferObject(video_width, video_height); + ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, current_fbo); } // clear fbos @@ -268,6 +269,7 @@ GLuint compose_sequence(Viewer* viewer, glClear(GL_COLOR_BUFFER_BIT); c->fbo[1]->release();*/ + bool fbo_switcher = false; glViewport(0, 0, video_width, video_height); @@ -351,20 +353,6 @@ GLuint compose_sequence(Viewer* viewer, } // EFFECT CODE END - /*if (!nests.isEmpty()) { - nests.last()->fbo[0]->bind(); - glViewport(0, 0, s->width, s->height); - } else if (rendering) { - glViewport(0, 0, s->width, s->height); - } else { - int widget_width = width(); - int widget_height = height(); - - widget_width *= QApplication::desktop()->devicePixelRatio(); - widget_height *= QApplication::desktop()->devicePixelRatio(); - - glViewport(0, 0, widget_width, widget_height); - }*/ if (!nests.isEmpty()) { nests.last()->fbo[0]->bind(); } @@ -377,6 +365,9 @@ GLuint compose_sequence(Viewer* viewer, glBegin(GL_QUADS); + GLint current_fbo = 0; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ¤t_fbo); + if (coords.grid_size <= 1) { float z = 0.0f; @@ -449,7 +440,7 @@ GLuint compose_sequence(Viewer* viewer, motion_blur_prog++;*/ } } else { - if (render_audio || (config.enable_audio_scrubbing && audio_scrub)) { + if (render_audio || (config.enable_audio_scrubbing && audio_scrub && seq->playhead > c->timeline_in)) { if (c->media != nullptr && c->media->get_type() == MEDIA_TYPE_SEQUENCE) { nests.append(c); compose_sequence(viewer, ctx, seq, nests, video, render_audio, gizmos, texture_failed, rendering);