From 7fe8dbc77a40a2f4c9538e6c8cf83405e56fe7e8 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Thu, 22 Jul 2021 01:09:06 -0700 Subject: [PATCH 1/4] timeline: fixed double remove on transitions Fixes #1655 --- app/widget/timelinewidget/timelinewidget.cpp | 5 +++-- app/widget/timelinewidget/timelinewidget.h | 2 +- app/widget/timelinewidget/tool/pointer.cpp | 2 +- app/widget/timelinewidget/undo/timelineundogeneral.cpp | 2 +- app/widget/timelinewidget/undo/timelineundogeneral.h | 5 ++++- 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/widget/timelinewidget/timelinewidget.cpp b/app/widget/timelinewidget/timelinewidget.cpp index 3a0742f45..1d3fbea4a 100644 --- a/app/widget/timelinewidget/timelinewidget.cpp +++ b/app/widget/timelinewidget/timelinewidget.cpp @@ -447,7 +447,8 @@ void TimelineWidget::SplitAtPlayhead() void TimelineWidget::ReplaceBlocksWithGaps(const QVector &blocks, bool remove_from_graph, - MultiUndoCommand *command) + MultiUndoCommand *command, + bool handle_transitions) { foreach (Block* b, blocks) { if (dynamic_cast(b)) { @@ -458,7 +459,7 @@ void TimelineWidget::ReplaceBlocksWithGaps(const QVector &blocks, Track* original_track = b->track(); - command->add_child(new TrackReplaceBlockWithGapCommand(original_track, b)); + command->add_child(new TrackReplaceBlockWithGapCommand(original_track, b, handle_transitions)); if (remove_from_graph) { command->add_child(new NodeRemoveWithExclusiveDependenciesAndDisconnect(b)); diff --git a/app/widget/timelinewidget/timelinewidget.h b/app/widget/timelinewidget/timelinewidget.h index 23853d90f..502243266 100644 --- a/app/widget/timelinewidget/timelinewidget.h +++ b/app/widget/timelinewidget/timelinewidget.h @@ -112,7 +112,7 @@ public: void RestoreSplitterState(const QByteArray& state); - static void ReplaceBlocksWithGaps(const QVector &blocks, bool remove_from_graph, MultiUndoCommand *command); + static void ReplaceBlocksWithGaps(const QVector &blocks, bool remove_from_graph, MultiUndoCommand *command, bool handle_transitions = true); /** * @brief Retrieve the QGraphicsItem at a particular scene position diff --git a/app/widget/timelinewidget/tool/pointer.cpp b/app/widget/timelinewidget/tool/pointer.cpp index dade2c454..14cc30169 100644 --- a/app/widget/timelinewidget/tool/pointer.cpp +++ b/app/widget/timelinewidget/tool/pointer.cpp @@ -591,7 +591,7 @@ void PointerTool::FinishDrag(TimelineViewMouseEvent *event) blocks_to_delete[i] = blocks_moving.at(i).block; } - parent()->ReplaceBlocksWithGaps(blocks_to_delete, false, command); + parent()->ReplaceBlocksWithGaps(blocks_to_delete, false, command, false); } if (inserting) { diff --git a/app/widget/timelinewidget/undo/timelineundogeneral.cpp b/app/widget/timelinewidget/undo/timelineundogeneral.cpp index e9b2cda64..a44099fa6 100644 --- a/app/widget/timelinewidget/undo/timelineundogeneral.cpp +++ b/app/widget/timelinewidget/undo/timelineundogeneral.cpp @@ -441,7 +441,7 @@ void TrackListInsertGaps::undo() void TrackReplaceBlockWithGapCommand::redo() { // Determine if this block is connected to any transitions that should also be removed by this operation - if (transition_remove_commands_.isEmpty()) { + if (handle_transitions_ && transition_remove_commands_.isEmpty()) { CreateRemoveTransitionCommandIfNecessary(false); CreateRemoveTransitionCommandIfNecessary(true); } diff --git a/app/widget/timelinewidget/undo/timelineundogeneral.h b/app/widget/timelinewidget/undo/timelineundogeneral.h index b47587ff5..fe07ed764 100644 --- a/app/widget/timelinewidget/undo/timelineundogeneral.h +++ b/app/widget/timelinewidget/undo/timelineundogeneral.h @@ -196,12 +196,13 @@ private: class TrackReplaceBlockWithGapCommand : public UndoCommand { public: - TrackReplaceBlockWithGapCommand(Track* track, Block* block) : + TrackReplaceBlockWithGapCommand(Track* track, Block* block, bool handle_transitions = true) : track_(track), block_(block), existing_gap_(nullptr), existing_merged_gap_(nullptr), our_gap_(nullptr), + handle_transitions_(handle_transitions), position_command_(nullptr) { } @@ -232,6 +233,8 @@ private: bool existing_gap_precedes_; GapBlock* our_gap_; + bool handle_transitions_; + NodeSetPositionAsChildCommand* position_command_; QObject memory_manager_; From 72b11add9cfee056efc78b211567dfe99c5b980d Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 23 Jul 2021 06:44:45 -0700 Subject: [PATCH 2/4] viewer: don't use in/out on loop unless play in/out was selected Fixes #1302 --- app/widget/viewer/viewer.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/app/widget/viewer/viewer.cpp b/app/widget/viewer/viewer.cpp index 736450acf..bcfa27815 100644 --- a/app/widget/viewer/viewer.cpp +++ b/app/widget/viewer/viewer.cpp @@ -1156,21 +1156,18 @@ void ViewerWidget::PlaybackTimerUpdate() int64_t min_time, max_time; - { - if ((play_in_to_out_only_ || Config::Current()["Loop"].toBool()) - && GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) { + if (play_in_to_out_only_ && GetConnectedNode()->GetTimelinePoints()->workarea()->enabled()) { - // If "play in to out" is enabled or we're looping AND we have a workarea, only play the workarea - min_time = Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->in(), timebase()); - max_time = Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->out(), timebase()); + // If "play in to out" is enabled or we're looping AND we have a workarea, only play the workarea + min_time = Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->in(), timebase()); + max_time = Timecode::time_to_timestamp(GetConnectedNode()->GetTimelinePoints()->workarea()->out(), timebase()); - } else { + } else { - // Otherwise set the bounds to the range of the sequence - min_time = 0; - max_time = Timecode::time_to_timestamp(GetConnectedNode()->GetLength(), timebase()); + // Otherwise set the bounds to the range of the sequence + min_time = 0; + max_time = Timecode::time_to_timestamp(GetConnectedNode()->GetLength(), timebase()); - } } if ((playback_speed_ < 0 && current_time <= min_time) From 179e8d9014c23e518ef736d3d21837e6e07a1d08 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 23 Jul 2021 15:47:25 -0700 Subject: [PATCH 3/4] audio: added null check Fixes common crash. --- app/render/audioplaybackcache.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/render/audioplaybackcache.cpp b/app/render/audioplaybackcache.cpp index 0f9a1183a..ed507581b 100644 --- a/app/render/audioplaybackcache.cpp +++ b/app/render/audioplaybackcache.cpp @@ -71,7 +71,7 @@ void AudioPlaybackCache::WritePCM(const TimeRange &range, const TimeRangeList &v TimeRangeList ranges_we_validated; // Calculate buffer size per channel - qint64 buffer_size_per_channel = samples->sample_count() * params_.bytes_per_sample_per_channel(); + qint64 buffer_size_per_channel = samples ? samples->sample_count() * params_.bytes_per_sample_per_channel() : 0; // Write each valid range to the segments foreach (const TimeRange& r, valid_ranges) { @@ -103,9 +103,6 @@ void AudioPlaybackCache::WritePCM(const TimeRange &range, const TimeRangeList &v // Determine how many bytes need to be written qint64 total_write_length = params_.time_to_bytes_per_channel(this_write_out_point - this_write_in_point); - // Retrieve data buffer - const char *a = reinterpret_cast(samples->data(i)); - // Determine how many bytes we actually have in the source buffer qint64 possible_write_length = qMin(qMax(qint64(0), buffer_size_per_channel - src_offset), total_write_length); @@ -114,7 +111,9 @@ void AudioPlaybackCache::WritePCM(const TimeRange &range, const TimeRangeList &v // If we have source bytes to write, write them here if (possible_write_length > 0) { - seg_file.write(a + src_offset, possible_write_length); + // Assume `samples` is valid if we're here, or else `buffer_size_per_channel` and + // therefore `possible_write_length` will be 0. + seg_file.write(reinterpret_cast(samples->data(i)) + src_offset, possible_write_length); } if (possible_write_length < total_write_length) { From 9e183779f353855bcb05178f1595d2473dcd9075 Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Fri, 23 Jul 2021 15:50:25 -0700 Subject: [PATCH 4/4] timeline: null check on setting beam cursor Fixes crash --- app/widget/timelinewidget/view/timelineview.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/widget/timelinewidget/view/timelineview.cpp b/app/widget/timelinewidget/view/timelineview.cpp index b1a3c364b..e07c981f6 100644 --- a/app/widget/timelinewidget/view/timelineview.cpp +++ b/app/widget/timelinewidget/view/timelineview.cpp @@ -589,6 +589,10 @@ void TimelineView::ConnectTrackList(TrackList *list) void TimelineView::SetBeamCursor(const TimelineCoordinate &coord) { + if (!connected_track_list_) { + return; + } + bool update_required = coord.GetTrack().type() == connected_track_list_->type() || cursor_coord_.GetTrack().type() == connected_track_list_->type();