Commit eff592e4 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Fix mix corruption when moving a clip with start and end mixes to another track, add test

parent b1ab1979
......@@ -932,13 +932,26 @@ bool TimelineModel::mixClip(int idToMove, const QString &mixId, int delta)
// Make sure we have enough space in clip to resize
int maxLengthLeft = m_allClips[previousClip]->getMaxDuration();
int maxLengthRight = m_allClips[s]->getMaxDuration();
leftMax = maxLengthLeft > -1 ? (maxLengthLeft - 1 - m_allClips[previousClip]->getOut()) : -1;
rightMax = maxLengthRight > -1 ? (m_allClips[s]->getIn()) : -1;
// leftMax is the maximum frames we have to expand first clip on the right
leftMax = maxLengthLeft > -1 ? (maxLengthLeft - 1 - m_allClips[previousClip]->getOut()) : m_allClips[s]->getPlaytime();
// rightMax is the maximum frames we have to expand second clip on the left
rightMax = maxLengthRight > -1 ? (m_allClips[s]->getIn()) : m_allClips[previousClip]->getPlaytime();
if (getTrackById_const(selectedTrack)->hasStartMix(previousClip)) {
int spaceBeforeMix = m_allClips[s]->getPosition() - (m_allClips[previousClip]->getPosition() + m_allClips[previousClip]->getMixDuration());
rightMax = rightMax == -1 ? spaceBeforeMix : qMin(rightMax, spaceBeforeMix);
}
if (getTrackById_const(selectedTrack)->hasEndMix(s)) {
MixInfo mixData = getTrackById_const(selectedTrack)->getMixInfo(s).second;
if (mixData.secondClipId > -1) {
int spaceAfterMix = m_allClips[s]->getPlaytime() - m_allClips[mixData.secondClipId]->getMixDuration();
leftMax = leftMax == -1 ? spaceAfterMix : qMin(leftMax, spaceAfterMix);
}
}
if (leftMax > -1 && rightMax > -1 && (leftMax + rightMax < 3)) {
noSpaceInClip = 1;
continue;
}
// Mix at start of selected clip
// Create Mix at start of selected clip
clipsToMix.first = previousClip;
clipsToMix.second = s;
idToMove = s;
......@@ -948,8 +961,21 @@ bool TimelineModel::mixClip(int idToMove, const QString &mixId, int delta)
// Make sure we have enough space in clip to resize
int maxLengthLeft = m_allClips[s]->getMaxDuration();
int maxLengthRight = m_allClips[nextClip]->getMaxDuration();
leftMax = maxLengthLeft > -1 ? (maxLengthLeft - 1 - m_allClips[s]->getOut()) : -1;
rightMax = maxLengthRight > -1 ? (m_allClips[nextClip]->getIn()) : -1;
// leftMax is the maximum frames we have to expand first clip on the right
leftMax = maxLengthLeft > -1 ? (maxLengthLeft - 1 - m_allClips[s]->getOut()) : m_allClips[nextClip]->getPlaytime();
// rightMax is the maximum frames we have to expand second clip on the left
rightMax = maxLengthRight > -1 ? (m_allClips[nextClip]->getIn()) : m_allClips[s]->getPlaytime();
if (getTrackById_const(selectedTrack)->hasStartMix(s)) {
int spaceBeforeMix = m_allClips[nextClip]->getPosition() - (m_allClips[s]->getPosition() + m_allClips[s]->getMixDuration());
rightMax = rightMax == -1 ? spaceBeforeMix : qMin(rightMax, spaceBeforeMix);
}
if (getTrackById_const(selectedTrack)->hasEndMix(nextClip)) {
MixInfo mixData = getTrackById_const(selectedTrack)->getMixInfo(nextClip).second;
if (mixData.secondClipId > -1) {
int spaceAfterMix = m_allClips[nextClip]->getPlaytime() - m_allClips[mixData.secondClipId]->getMixDuration();
leftMax = leftMax == -1 ? spaceAfterMix : qMin(leftMax, spaceAfterMix);
}
}
if (leftMax > -1 && rightMax > -1 && (leftMax + rightMax < 3)) {
noSpaceInClip = 2;
continue;
......@@ -993,7 +1019,7 @@ bool TimelineModel::mixClip(int idToMove, const QString &mixId, int delta)
} else {
if (rightMax > -1) {
mixDurations.second = qMin(mixDuration - mixDuration / 2, rightMax);
mixDurations.first= mixDuration - mixDurations.first;
mixDurations.first = mixDuration - mixDurations.second;
} else {
mixDurations.first = mixDuration / 2;
mixDurations.second = mixDuration - mixDurations.first;
......@@ -2523,7 +2549,6 @@ bool TimelineModel::requestGroupMove(int itemId, int groupId, int delta_track, i
subPlaylist = m_allClips[item.first]->getSubPlaylistIndex();
}
if (!getTrackById_const(current_track_id)->isAvailable(moveStart, moveEnd - moveStart, subPlaylist)) {
qDebug()<<"===== REQUESTING GRP MOVE ABORT 5, POSITION: "<<moveStart<<" - "<<(moveEnd - moveStart)<<" ON PLAYL: "<<subPlaylist<<" FOR CLIP: "<<item.first;
int newStart = getTrackById_const(current_track_id)->getBlankEnd(current_in + playtime, subPlaylist);
if (newStart == current_in + playtime) {
// No move possible, abort
......
......@@ -1628,19 +1628,24 @@ bool TrackModel::requestRemoveMix(std::pair<int, int> clipIds, Fun &undo, Fun &r
int secondInPos;
int mixPosition;
int src_track = 0;
bool clipHasEndMix = false;
int first_src_track = 0;
bool secondClipHasEndMix = false;
bool firstClipHasStartMix = false;
QList <int> allowedMixes = {clipIds.first};
if (auto ptr = m_parent.lock()) {
// The clip that will be moved to playlist 1
std::shared_ptr<ClipModel> firstClip(ptr->getClipPtr(clipIds.first));
std::shared_ptr<ClipModel> secondClip(ptr->getClipPtr(clipIds.second));
mixDuration = secondClip->getMixDuration();
mixCutPos = secondClip->getMixCutPosition();
mixPosition = secondClip->getPosition();
firstInPos = firstClip->getPosition();
secondInPos = mixPosition + mixDuration - mixCutPos;
firstInPos = ptr->getClipPtr(clipIds.first)->getPosition();
endPos = mixPosition + secondClip->getPlaytime();
clipHasEndMix = hasEndMix(clipIds.second);
secondClipHasEndMix = hasEndMix(clipIds.second);
firstClipHasStartMix = hasStartMix(clipIds.first);
src_track = secondClip->getSubPlaylistIndex();
first_src_track = firstClip->getSubPlaylistIndex();
} else {
return false;
}
......@@ -1663,10 +1668,18 @@ bool TrackModel::requestRemoveMix(std::pair<int, int> clipIds, Fun &undo, Fun &r
QString assetId = m_sameCompositions[clipIds.second]->getAssetId();
QVector<QPair<QString, QVariant>> params = m_sameCompositions[clipIds.second]->getAllParameters();
bool switchSecondTrack = false;
if (src_track == 1 && !clipHasEndMix && !closing) {
bool switchFirstTrack = false;
if (src_track == 1 && !secondClipHasEndMix && !closing) {
switchSecondTrack = true;
}
Fun replay = [this, clipIds, secondInPos, switchSecondTrack]() {
if (first_src_track == 1 && !firstClipHasStartMix && !closing) {
switchFirstTrack = true;
}
Fun replay = [this, clipIds, firstInPos, secondInPos, switchFirstTrack, switchSecondTrack]() {
if (switchFirstTrack) {
// Revert clip to playlist 0 since it has no mix
switchPlaylist(clipIds.first, firstInPos, 1, 0);
}
if (switchSecondTrack) {
// Revert clip to playlist 0 since it has no mix
switchPlaylist(clipIds.second, secondInPos, 1, 0);
......@@ -1690,8 +1703,12 @@ bool TrackModel::requestRemoveMix(std::pair<int, int> clipIds, Fun &undo, Fun &r
return true;
};
replay();
Fun reverse = [this, clipIds, assetId, params, mixDuration, mixPosition, mixCutPos, secondInPos, switchSecondTrack]() {
Fun reverse = [this, clipIds, assetId, params, mixDuration, mixPosition, mixCutPos, firstInPos, secondInPos, switchFirstTrack, switchSecondTrack]() {
// First restore correct playlist
if (switchFirstTrack) {
// Revert clip to playlist 1
switchPlaylist(clipIds.first, firstInPos, 0, 1);
}
if (switchSecondTrack) {
// Revert clip to playlist 1
switchPlaylist(clipIds.second, secondInPos, 0, 1);
......
......@@ -200,6 +200,57 @@ TEST_CASE("Simple Mix", "[SameTrackMix]")
undoStack->undo();
state0();
}
SECTION("Create mix on color clips and move some to another track")
{
state0();
// insert third color clip
int cid5;
REQUIRE(timeline->requestClipInsertion(binId2, tid2, 540, cid5));
REQUIRE(timeline->requestItemResize(cid5, 20, true, true));
REQUIRE(timeline->getClipPosition(cid5) == 540);
// CID 3 length=20, pos=500, CID4 length=20, pos=520, CID% length=20, pos=540
// Default mix duration = 25 frames (12 before / 13 after)
REQUIRE(timeline->mixClip(cid4));
REQUIRE(timeline->mixClip(cid5));
REQUIRE(timeline->getClipPosition(cid5) < 540);
undoStack->undo();
REQUIRE(timeline->getClipPosition(cid5) == 540);
undoStack->redo();
REQUIRE(timeline->getClipPosition(cid5) < 540);
REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0);
REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1);
REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0);
REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2);
// Move middle clip to another track, should delete the mixes
REQUIRE(timeline->requestClipMove(cid4, tid4, 500));
REQUIRE(timeline->getClipPosition(cid5) == 540);
REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0);
REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0);
REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0);
REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0);
// Undo track move
undoStack->undo();
REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0);
REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1);
REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0);
REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0);
REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2);
// Undo mixes
undoStack->undo();
undoStack->undo();
// undo 3rd clip resize & insert
undoStack->undo();
undoStack->undo();
state0();
}
SECTION("Create mix on color clips and group move")
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment