Skip to content

Fix copy/paste transition causes bad audio - #1880

Open
bmatherly wants to merge 1 commit into
masterfrom
transition_paste
Open

Fix copy/paste transition causes bad audio#1880
bmatherly wants to merge 1 commit into
masterfrom
transition_paste

Conversation

@bmatherly

Copy link
Copy Markdown
Member

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates multi-clip paste operations in TimelineDock to better preserve transitions when copying/pasting a track/tractor, addressing a reported issue where pasted transitions could cause incorrect audio.

Changes:

  • Detect transition “mix” clips in pasted MLT playlists and skip inserting them as normal clips.
  • Recreate skipped transitions via AddTransitionByTrimOutCommand after inserting adjacent clips.
  • Adjust inserted clip in/out points and insertion positions to account for skipped transition entries.
Comments suppressed due to low confidence (3)

src/docks/timelinedock.cpp:4538

  • A transition is added whenever pendingTransitionDuration > 0, even if the transition tractor's right-side clip could not be resolved (pendingTransitionRightIn < 0 / pendingTransitionRightClip invalid) or does not match the current clip. In those cases this can add a transition between the wrong pair of clips. Gate the transition creation on successfully matching the current clip to the transition's right clip, but still reset the pending-transition state either way.
                            if (pendingTransitionDuration > 0) {
                                const int rightClipIndex = clipIndexAtPosition(trackIndex,
                                                                               overwritePosition);
                                const int leftClipIndex = rightClipIndex - 1;
                                if (leftClipIndex >= 0 && rightClipIndex >= 0

src/docks/timelinedock.cpp:4532

  • This code now overwrites clips at overwritePosition (= position + info.start - skippedTransitionDuration), but the group-restore pass later in this function still looks up overwritten clips using position + clipInfo.start. When transitions are skipped (skippedTransitionDuration > 0), those lookups can resolve to the wrong clip (or blank), causing copied group membership to be restored incorrectly for pastes that include transitions.
                            const int overwritePosition = position + info.start
                                                          - skippedTransitionDuration;
                            MAIN.undoStack()->push(new Timeline::OverwriteCommand(m_model,
                                                                                  trackIndex,
                                                                                  overwritePosition,
                                                                                  MLT.XML(&clip),
                                                                                  false));

src/docks/timelinedock.cpp:4303

  • A transition is added whenever pendingTransitionDuration > 0, even if the transition tractor's right-side clip could not be resolved (pendingTransitionRightIn < 0 / pendingTransitionRightClip invalid) or does not match the current clip. In those cases this can add a transition between the wrong pair of clips. Gate the transition creation on successfully matching the current clip to the transition's right clip, but still reset the pending-transition state either way.
                            if (pendingTransitionDuration > 0) {
                                const int rightClipIndex = clipIndexAtPosition(trackIndex,
                                                                               insertPosition);
                                const int leftClipIndex = rightClipIndex - 1;
                                if (leftClipIndex >= 0 && rightClipIndex >= 0

Comment on lines +2703 to +2724
if (pendingTransitionDuration > 0) {
const int rightClipIndex = clipCount(trackIndex) - 1;
const int leftClipIndex = rightClipIndex - 1;
if (leftClipIndex >= 0 && rightClipIndex >= 0
&& !isBlank(trackIndex, leftClipIndex)
&& !isBlank(trackIndex, rightClipIndex)
&& !isTransition(trackIndex, leftClipIndex)
&& !isTransition(trackIndex, rightClipIndex)
&& m_model.addTransitionByTrimOutValid(
trackIndex, leftClipIndex, -pendingTransitionDuration)) {
MAIN.undoStack()->push(
new Timeline::AddTransitionByTrimOutCommand(
m_model,
trackIndex,
leftClipIndex,
-pendingTransitionDuration,
0));
}
pendingTransitionDuration = 0;
pendingTransitionRightIn = -1;
pendingTransitionRightClip = Mlt::Producer();
}
Comment on lines +4288 to 4296
const int insertPosition = position + info.start
- skippedTransitionDuration;
bool lastClip = mltTrackIndex == tractor.count() - 1
&& mltClipIndex == playlist.count() - 1;
MAIN.undoStack()->push(new Timeline::InsertCommand(m_model,
m_markersModel,
trackIndex,
position + info.start,
insertPosition,
MLT.XML(&clip),
@ddennedy

Copy link
Copy Markdown
Member

sheez, these methods are huge. Is there an opportunity to make a reusable method in the added code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants