File indexing completed on 2024-04-14 04:47:49
0001 /* 0002 SPDX-FileCopyrightText: 2020-2022 Jean-Baptiste Mardelle <jb@kdenlive.org> 0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 #include "catch.hpp" 0006 #include "test_utils.hpp" 0007 // test specific headers 0008 #include "doc/docundostack.hpp" 0009 #include "doc/kdenlivedoc.h" 0010 #include <QString> 0011 #include <cmath> 0012 #include <iostream> 0013 #include <tuple> 0014 #include <unordered_set> 0015 0016 #include "core.h" 0017 #include "definitions.h" 0018 0019 using namespace fakeit; 0020 0021 TEST_CASE("Simple Mix", "[SameTrackMix]") 0022 { 0023 // Ensure our core profile is correct 0024 REQUIRE(pCore->timecode().fps() == 25.); 0025 REQUIRE(pCore->getDurationFromString(KdenliveSettings::mix_duration()) == 25); 0026 0027 // Create timeline 0028 auto binModel = pCore->projectItemModel(); 0029 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0030 // Here we do some trickery to enable testing. 0031 // We mock the project class so that the undoStack function returns our undoStack 0032 KdenliveDoc document(undoStack); 0033 0034 pCore->projectManager()->m_project = &document; 0035 QDateTime documentDate = QDateTime::currentDateTime(); 0036 pCore->projectManager()->updateTimeline(false, QString(), QString(), documentDate, 0); 0037 auto timeline = document.getTimeline(document.uuid()); 0038 pCore->projectManager()->testSetActiveDocument(&document, timeline); 0039 0040 // Create a request 0041 int tid1 = timeline->getTrackIndexFromPosition(0); 0042 int tid3 = timeline->getTrackIndexFromPosition(1); 0043 int tid2 = timeline->getTrackIndexFromPosition(2); 0044 int tid4 = timeline->getTrackIndexFromPosition(3); 0045 0046 // Create clip with audio 0047 QString binId = createProducerWithSound(pCore->getProjectProfile(), binModel, 100); 0048 0049 // Create video clip 0050 QString binId2 = createProducer(pCore->getProjectProfile(), "red", binModel, 50, false); 0051 // Setup insert stream data 0052 QMap<int, QString> audioInfo; 0053 audioInfo.insert(1, QStringLiteral("stream1")); 0054 timeline->m_binAudioTargets = audioInfo; 0055 0056 // Create AV clip 1 0057 int cid1; 0058 int cid2; 0059 int cid3; 0060 int cid4; 0061 int cid5; 0062 int audio1; 0063 int audio2; 0064 int audio5; 0065 REQUIRE(timeline->requestClipInsertion(binId, tid2, 100, cid1)); 0066 REQUIRE(timeline->requestItemResize(cid1, 10, true, true)); 0067 audio1 = timeline->getClipSplitPartner(cid1); 0068 0069 // Create AV clip 2 0070 REQUIRE(timeline->requestClipInsertion(binId, tid2, 110, cid2)); 0071 REQUIRE(timeline->requestItemResize(cid2, 10, true, true)); 0072 REQUIRE(timeline->requestClipMove(cid2, tid2, 110)); 0073 audio2 = timeline->getClipSplitPartner(cid2); 0074 0075 // Create color clip 1 0076 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 500, cid3)); 0077 REQUIRE(timeline->requestItemResize(cid3, 20, true, true)); 0078 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 520, cid4)); 0079 REQUIRE(timeline->requestItemResize(cid4, 20, true, true)); 0080 int mixDuration = pCore->getDurationFromString(KdenliveSettings::mix_duration()); 0081 0082 auto state0 = [&]() { 0083 REQUIRE(timeline->getClipsCount() == 6); 0084 REQUIRE(timeline->getClipPlaytime(cid1) == 10); 0085 REQUIRE(timeline->getClipPosition(cid1) == 100); 0086 REQUIRE(timeline->getClipPlaytime(cid2) == 10); 0087 REQUIRE(timeline->getClipPosition(cid2) == 110); 0088 REQUIRE(timeline->getClipPosition(cid3) == 500); 0089 REQUIRE(timeline->getClipPlaytime(cid3) == 20); 0090 REQUIRE(timeline->getClipPosition(cid4) == 520); 0091 REQUIRE(timeline->getClipPlaytime(cid4) == 20); 0092 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0093 REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0); 0094 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0095 }; 0096 0097 auto state0b = [&]() { 0098 REQUIRE(timeline->getClipsCount() == 8); 0099 REQUIRE(timeline->getClipPlaytime(cid1) == 10); 0100 REQUIRE(timeline->getClipPosition(cid1) == 100); 0101 REQUIRE(timeline->getClipPlaytime(cid2) == 10); 0102 REQUIRE(timeline->getClipPosition(cid2) == 110); 0103 REQUIRE(timeline->getClipPlaytime(cid5) == 10); 0104 REQUIRE(timeline->getClipPosition(cid5) == 120); 0105 REQUIRE(timeline->getClipPosition(cid3) == 500); 0106 REQUIRE(timeline->getClipPlaytime(cid3) == 20); 0107 REQUIRE(timeline->getClipPosition(cid4) == 520); 0108 REQUIRE(timeline->getClipPlaytime(cid4) == 20); 0109 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0110 REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0); 0111 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0112 }; 0113 0114 auto state1 = [&]() { 0115 REQUIRE(timeline->getClipsCount() == 6); 0116 REQUIRE(timeline->getClipPlaytime(cid1) > 10); 0117 REQUIRE(timeline->getClipPosition(cid1) == 100); 0118 REQUIRE(timeline->getClipPlaytime(cid2) > 10); 0119 REQUIRE(timeline->getClipPosition(cid2) < 110); 0120 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0121 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0122 }; 0123 0124 auto state1b = [&]() { 0125 REQUIRE(timeline->getClipsCount() == 8); 0126 REQUIRE(timeline->getClipPlaytime(cid1) > 10); 0127 REQUIRE(timeline->getClipPosition(cid1) == 100); 0128 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 0129 REQUIRE(timeline->m_allClips[audio1]->getSubPlaylistIndex() == 0); 0130 REQUIRE(timeline->getClipPlaytime(cid2) > 10); 0131 REQUIRE(timeline->getClipPosition(cid2) < 110); 0132 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 0133 REQUIRE(timeline->m_allClips[audio2]->getSubPlaylistIndex() == 1); 0134 REQUIRE(timeline->getClipPlaytime(cid5) == 10); 0135 REQUIRE(timeline->getClipPosition(cid5) == 120); 0136 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0137 REQUIRE(timeline->m_allClips[audio5]->getSubPlaylistIndex() == 0); 0138 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0139 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0140 }; 0141 0142 auto state3 = [&, mixDuration]() { 0143 REQUIRE(timeline->getClipsCount() == 6); 0144 REQUIRE(timeline->getClipPlaytime(cid1) > 30); 0145 REQUIRE(timeline->getClipPosition(cid1) == 100); 0146 REQUIRE(timeline->getClipPlaytime(cid2) > 30); 0147 REQUIRE(timeline->getClipPosition(cid2) < 130); 0148 REQUIRE(timeline->m_allClips[cid2]->getMixDuration() == mixDuration); 0149 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0150 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0151 }; 0152 0153 auto state2 = [&]() { 0154 REQUIRE(timeline->getClipsCount() == 6); 0155 REQUIRE(timeline->getClipPlaytime(cid3) == 32); 0156 REQUIRE(timeline->getClipPosition(cid3) == 500); 0157 REQUIRE(timeline->getClipPlaytime(cid4) == 33); 0158 REQUIRE(timeline->getClipPosition(cid4) == 507); 0159 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0160 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0161 REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0); 0162 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0163 }; 0164 0165 SECTION("Create and delete mix on color clips") 0166 { 0167 state0(); 0168 REQUIRE(timeline->mixClip(cid4)); 0169 state2(); 0170 undoStack->undo(); 0171 state0(); 0172 undoStack->redo(); 0173 state2(); 0174 undoStack->undo(); 0175 state0(); 0176 } 0177 0178 SECTION("Create mix on color clips and move main (right side) clip") 0179 { 0180 // CID 3 length=20, pos=500, CID4 length=20, pos=520 0181 // Default mix duration = 25 frames (12 before / 13 after) 0182 state0(); 0183 REQUIRE(timeline->mixClip(cid4)); 0184 state2(); 0185 0186 // Move right clip to the left, should fail 0187 REQUIRE(timeline->requestClipMove(cid4, tid2, 506) == false); 0188 0189 // Move clip inside mix zone, should delete the mix 0190 REQUIRE(timeline->requestClipMove(cid4, tid2, 509)); 0191 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0192 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0193 undoStack->undo(); 0194 state2(); 0195 // Move clip outside mix zone, should delete the mix and move it back to playlist 0 0196 REQUIRE(timeline->requestClipMove(cid4, tid2, 600)); 0197 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0198 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0199 undoStack->undo(); 0200 state2(); 0201 // Move clip to another track, should delete mix 0202 REQUIRE(timeline->requestClipMove(cid4, tid4, 600)); 0203 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0204 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0205 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 0206 undoStack->undo(); 0207 state2(); 0208 undoStack->undo(); 0209 state0(); 0210 } 0211 0212 SECTION("Create mix on color clip and move left side clip") 0213 { 0214 state0(); 0215 REQUIRE(timeline->mixClip(cid4)); 0216 state2(); 0217 0218 // Move left clip to the right, should silently fail 0219 REQUIRE(timeline->requestClipMove(cid3, tid2, 502, true, true, false) == false); 0220 REQUIRE(timeline->getClipPosition(cid3) == 500); 0221 0222 // Move clip inside mix zone, should delete the mix 0223 REQUIRE(timeline->requestClipMove(cid3, tid2, 499)); 0224 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0225 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0226 undoStack->undo(); 0227 state2(); 0228 // Move clip outside mix zone, should delete the mix 0229 REQUIRE(timeline->requestClipMove(cid3, tid2, 450)); 0230 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0231 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0232 undoStack->undo(); 0233 state2(); 0234 // Move clip to another track, should delete mix 0235 REQUIRE(timeline->requestClipMove(cid3, tid4, 600)); 0236 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0237 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 0238 undoStack->undo(); 0239 state2(); 0240 undoStack->undo(); 0241 state0(); 0242 } 0243 0244 SECTION("Create mix on color clips and move some to another track") 0245 { 0246 state0(); 0247 // insert third color clip 0248 cid5 = -1; 0249 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 540, cid5)); 0250 REQUIRE(timeline->requestItemResize(cid5, 20, true, true)); 0251 REQUIRE(timeline->getClipPosition(cid5) == 540); 0252 audio5 = timeline->getClipSplitPartner(cid5); 0253 0254 // CID 3 length=20, pos=500, CID4 length=20, pos=520, CID5 length=20, pos=540 0255 // Default mix duration = 25 frames (12 before / 13 after) 0256 0257 REQUIRE(timeline->mixClip(cid3)); 0258 REQUIRE(timeline->mixClip(cid4)); 0259 REQUIRE(timeline->getClipPosition(cid5) < 540); 0260 undoStack->undo(); 0261 REQUIRE(timeline->getClipPosition(cid5) == 540); 0262 undoStack->redo(); 0263 REQUIRE(timeline->getClipPosition(cid5) < 540); 0264 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0265 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0266 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0267 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 0268 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 0269 0270 // Move middle clip to another track, should delete the mixes 0271 REQUIRE(timeline->requestClipMove(cid4, tid4, 500)); 0272 REQUIRE(timeline->getClipPosition(cid5) == 540); 0273 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0274 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0275 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0276 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 0277 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0278 0279 // Undo track move 0280 undoStack->undo(); 0281 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0282 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0283 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0284 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 0285 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 0286 0287 // Undo mixes 0288 undoStack->undo(); 0289 undoStack->undo(); 0290 // undo 3rd clip resize & insert 0291 undoStack->undo(); 0292 undoStack->undo(); 0293 state0(); 0294 } 0295 0296 SECTION("Create mix on color clips and group move") 0297 { 0298 state0(); 0299 REQUIRE(timeline->mixClip(cid4)); 0300 state2(); 0301 // Move clip inside mix zone, should resize the mix 0302 auto g1 = std::unordered_set<int>({cid3, cid4}); 0303 REQUIRE(timeline->requestClipsGroup(g1)); 0304 // Move clip to another track, should delete mix 0305 REQUIRE(timeline->requestClipMove(cid4, tid4, 600)); 0306 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0307 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 1); 0308 undoStack->undo(); 0309 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0310 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 0311 state2(); 0312 // Move on same track 0313 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0314 REQUIRE(timeline->requestClipMove(cid4, tid3, 800)); 0315 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0316 undoStack->undo(); 0317 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0318 state2(); 0319 // Undo group 0320 undoStack->undo(); 0321 // Undo mix 0322 undoStack->undo(); 0323 state0(); 0324 } 0325 0326 SECTION("Create and delete mix on AV clips") 0327 { 0328 state0(); 0329 // Clips are cid1 at 100, cid2 at 110 0330 REQUIRE(timeline->requestItemResize(cid2, 30, true, true) == 30); 0331 REQUIRE(timeline->requestItemResize(cid2, 10, false, true) == 10); 0332 REQUIRE(timeline->requestClipMove(cid2, tid2, 110)); 0333 REQUIRE(timeline->mixClip(cid1)); 0334 state1(); 0335 undoStack->undo(); 0336 state0(); 0337 undoStack->redo(); 0338 state1(); 0339 undoStack->undo(); 0340 state0(); 0341 } 0342 0343 SECTION("Create mix and move AV clips") 0344 { 0345 // CID 1 length=10, pos=100, CID2 length=10, pos=110 0346 // Default mix duration = 25 frames (12 before / 13 after) 0347 // Resize CID2 so that it has some space to expand left 0348 REQUIRE(timeline->requestItemResize(cid2, 30, true, true) == 30); 0349 REQUIRE(timeline->requestItemResize(cid2, 10, false, true) == 10); 0350 REQUIRE(timeline->requestClipMove(cid2, tid2, 110)); 0351 // Resize clip, should resize the mix 0352 state0(); 0353 REQUIRE(timeline->mixClip(cid2)); 0354 state1(); 0355 // Resize right clip, should resize the mix 0356 REQUIRE(timeline->requestItemResize(cid2, 15, false, true) == 15); 0357 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0358 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0359 undoStack->undo(); 0360 state1(); 0361 // Resize left clip, should resize the mix 0362 REQUIRE(timeline->requestItemResize(cid1, 20, true, true) == 20); 0363 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0364 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0365 undoStack->undo(); 0366 state1(); 0367 // Move clip outside mix zone, should delete the mix 0368 REQUIRE(timeline->requestClipMove(cid2, tid2, 200)); 0369 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 0); 0370 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0371 undoStack->undo(); 0372 state1(); 0373 // Undo mix 0374 undoStack->undo(); 0375 state0(); 0376 } 0377 0378 SECTION("Create chained mixes on AV clips") 0379 { 0380 // CID 1 length=10, pos=100, CID2 length=10, pos=110 0381 // Default mix duration = 25 frames (12 before / 13 after) 0382 // Resize CID2 so that it has some space to expand left 0383 REQUIRE(timeline->requestItemResize(cid2, 30, true, true) == 30); 0384 REQUIRE(timeline->requestItemResize(cid2, 10, false, true) == 10); 0385 REQUIRE(timeline->requestClipMove(cid2, tid2, 110)); 0386 state0(); 0387 0388 // Create a third AV clip and make some space 0389 cid5 = -1; 0390 REQUIRE(timeline->requestClipInsertion(binId, tid2, 120, cid5)); 0391 REQUIRE(timeline->requestItemResize(cid5, 30, true, true) == 30); 0392 REQUIRE(timeline->requestItemResize(cid5, 10, false, true) == 10); 0393 REQUIRE(timeline->requestClipMove(cid5, tid2, 120)); 0394 audio5 = timeline->getClipSplitPartner(cid5); 0395 0396 state0b(); 0397 0398 // CID 1 length=10, pos=100, CID2 length=20, pos=130, CID5 length=20, pos=130 0399 0400 // Create mix between cid1 and cid2 0401 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 0); 0402 REQUIRE(timeline->mixClip(cid1)); 0403 state1b(); 0404 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid2) == false); 0405 REQUIRE(timeline->getTrackById_const(tid3)->mixIsReversed(audio2) == false); 0406 0407 // Create mix between cid2 and cid5 0408 REQUIRE(timeline->mixClip(cid2)); 0409 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid2) == false); 0410 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == true); 0411 REQUIRE(timeline->getTrackById_const(tid3)->mixIsReversed(audio2) == false); 0412 REQUIRE(timeline->getTrackById_const(tid3)->mixIsReversed(audio5) == true); 0413 // Undo cid5 mix 0414 undoStack->undo(); 0415 0416 state1b(); 0417 // Undo cid2 mix 0418 undoStack->undo(); 0419 // Undo cid5 0420 undoStack->undo(); 0421 undoStack->undo(); 0422 undoStack->undo(); 0423 undoStack->undo(); 0424 0425 state0(); 0426 } 0427 0428 SECTION("Create mix on color clip and resize") 0429 { 0430 state0(); 0431 // CID 3 length=20, pos=500, CID4 length=20, pos=520 0432 // Default mix duration = 25 frames (12 before / 13 after) 0433 REQUIRE(timeline->mixClip(cid3)); 0434 state2(); 0435 // Resize left clip, should resize the mix 0436 REQUIRE(timeline->requestItemResize(cid3, 24, true, true) == 24); 0437 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0438 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0439 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0440 undoStack->undo(); 0441 state2(); 0442 // Resize left clip outside mix zone, should delete the mix 0443 REQUIRE(timeline->requestItemResize(cid3, 4, true, true) == 20); 0444 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0445 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0446 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0447 undoStack->undo(); 0448 state2(); 0449 // Resize right clip, should resize the mix 0450 REQUIRE(timeline->requestItemResize(cid4, 16, false, true) == 16); 0451 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0452 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0453 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0454 undoStack->undo(); 0455 state2(); 0456 // Resize right clip outside mix zone, should delete the mix 0457 REQUIRE(timeline->requestItemResize(cid4, 4, false, true) == 20); 0458 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0459 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0460 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0461 undoStack->undo(); 0462 state2(); 0463 // Resize right clip before left clip, should limit the resize to left clip position 0464 REQUIRE(timeline->requestItemResize(cid4, 50, false, true) == 40); 0465 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0466 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0467 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0468 undoStack->undo(); 0469 state2(); 0470 // Resize left clip past right clip, should limit the resize to left clip position 0471 REQUIRE(timeline->requestItemResize(cid3, 100, true, true) == 40); 0472 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0473 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0474 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0475 undoStack->undo(); 0476 state2(); 0477 0478 // Before mix: CID 3 length=20, pos=500, CID4 length=20, pos=520 0479 // Default mix duration = 25 frames (12 before / 13 after) 0480 0481 // Resize left clip before right clip start, then right clip outside left clip, should delete the mix 0482 REQUIRE(timeline->requestItemResize(cid3, 20, true, true) == 20); 0483 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0484 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0485 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0486 REQUIRE(timeline->requestItemResize(cid4, 20, false, true) == 20); 0487 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0488 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0489 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0490 undoStack->undo(); 0491 undoStack->undo(); 0492 state2(); 0493 0494 // Resize right clip after left clip end, then left clip outside right clip, should delete the mix 0495 REQUIRE(timeline->requestItemResize(cid4, 20, false, true) == 20); 0496 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0497 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0498 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0499 REQUIRE(timeline->requestItemResize(cid3, 20, true, true) == 20); 0500 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0501 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0502 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0503 undoStack->undo(); 0504 undoStack->undo(); 0505 state2(); 0506 0507 undoStack->undo(); 0508 state0(); 0509 } 0510 0511 SECTION("Create mix on AV clips and resize") 0512 { 0513 state0(); 0514 // CID 1 length=10, pos=100, CID2 length=10, pos=110 0515 REQUIRE(timeline->m_allClips[cid1]->getPlaytime() == 10); 0516 REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == 10); 0517 // Resize clip in to have some space for mix 0518 REQUIRE(timeline->requestItemResize(cid2, 90, true, true) == 90); 0519 REQUIRE(timeline->requestItemResize(cid2, 30, false, true) == 30); 0520 REQUIRE(timeline->requestClipMove(cid2, tid2, 130)); 0521 REQUIRE(timeline->requestItemResize(cid1, 30, true, true) == 30); 0522 0523 REQUIRE(timeline->mixClip(cid1)); 0524 state3(); 0525 // CID 1 length=30, pos=100, CID2 length=30, pos=130 0526 // Default mix duration = 25 frames (12 before / 13 after) 0527 // Resize left clip, should resize the mix 0528 REQUIRE(timeline->requestItemResize(cid1, 35, true, true) == 35); 0529 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0530 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0531 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 0532 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 0533 undoStack->undo(); 0534 state3(); 0535 // Resize left clip outside mix zone, should delete the mix 0536 REQUIRE(timeline->requestItemResize(cid1, 10, true, true) == 30); 0537 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0538 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 0); 0539 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 0540 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 0); 0541 undoStack->undo(); 0542 state3(); 0543 // Resize right clip, should resize the mix 0544 REQUIRE(timeline->requestItemResize(cid2, 25, false, true) == 25); 0545 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0546 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0547 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 0548 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 0549 undoStack->undo(); 0550 state3(); 0551 // Resize right clip outside mix zone, should delete the mix 0552 REQUIRE(timeline->requestItemResize(cid2, 4, false, true) == 30); 0553 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0554 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 0); 0555 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 0556 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 0); 0557 undoStack->undo(); 0558 state3(); 0559 // Resize right clip before left clip, should limit to left clip position 0560 REQUIRE(timeline->requestItemResize(cid2, 80, false, true) == 60); 0561 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0562 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0563 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 0564 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 0565 undoStack->undo(); 0566 state3(); 0567 // Resize left clip after right clip, should limit to right clip duration 0568 REQUIRE(timeline->requestItemResize(cid1, 80, true, true) == 60); 0569 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0570 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 0571 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 0572 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 0573 undoStack->undo(); 0574 state3(); 0575 undoStack->undo(); 0576 undoStack->undo(); 0577 undoStack->undo(); 0578 undoStack->undo(); 0579 undoStack->undo(); 0580 state0(); 0581 } 0582 0583 SECTION("Test chained mixes on color clips") 0584 { 0585 // Add 2 more color clips 0586 cid5 = -1; 0587 int cid6; 0588 int cid7; 0589 state0(); 0590 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 540, cid5)); 0591 REQUIRE(timeline->requestItemResize(cid5, 20, true, true)); 0592 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 560, cid6)); 0593 REQUIRE(timeline->requestItemResize(cid6, 40, true, true)); 0594 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 600, cid7)); 0595 REQUIRE(timeline->requestItemResize(cid7, 20, true, true)); 0596 audio5 = timeline->getClipSplitPartner(cid5); 0597 0598 // Cid3 pos=500, duration=20 0599 // Cid4 pos=520, duration=20 0600 // Cid5 pos=540, duration=20 0601 // Cid6 pos=560, duration=40 0602 // Cid7 pos=600, duration=20 0603 0604 // Mix 3 and 4 0605 REQUIRE(timeline->mixClip(cid3)); 0606 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0607 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0608 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0609 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0610 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0611 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0612 0613 // Mix 6 and 7 0614 REQUIRE(timeline->mixClip(cid6)); 0615 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0616 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0617 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0618 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0619 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 1); 0620 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 0621 0622 // Mix 5 and 6 0623 REQUIRE(timeline->mixClip(cid5)); 0624 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0625 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0626 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0627 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 1); 0628 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0629 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 3); 0630 0631 // Undo mix 5 and 6 0632 undoStack->undo(); 0633 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0634 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0635 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0636 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0637 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 1); 0638 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 0639 0640 // Undo mix 6 and 7 0641 undoStack->undo(); 0642 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0643 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0644 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0645 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0646 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0647 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0648 0649 // Undo mix 3 and 4 0650 undoStack->undo(); 0651 0652 // Undo insert/resize ops 0653 undoStack->undo(); 0654 undoStack->undo(); 0655 undoStack->undo(); 0656 undoStack->undo(); 0657 undoStack->undo(); 0658 undoStack->undo(); 0659 0660 state0(); 0661 } 0662 0663 SECTION("Test chained mixes and check mix direction") 0664 { 0665 // Add 3 more color clips 0666 cid5 = -1; 0667 int cid6; 0668 int cid7; 0669 state0(); 0670 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 540, cid5)); 0671 REQUIRE(timeline->requestItemResize(cid5, 20, true, true)); 0672 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 560, cid6)); 0673 REQUIRE(timeline->requestItemResize(cid6, 40, true, true)); 0674 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 600, cid7)); 0675 REQUIRE(timeline->requestItemResize(cid7, 20, true, true)); 0676 0677 // Cid3 pos=500, duration=20 0678 // Cid4 pos=520, duration=20 0679 // Cid5 pos=540, duration=20 0680 // Cid6 pos=560, duration=40 0681 // Cid7 pos=600, duration=20 0682 0683 auto mix0 = [&]() { 0684 REQUIRE(timeline->getClipsCount() == 9); 0685 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0686 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0687 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 1); 0688 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0689 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0690 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0691 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == false); 0692 }; 0693 0694 auto mix1 = [&]() { 0695 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0696 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0697 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 1); 0698 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0699 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0700 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 0701 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == false); 0702 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid6) == true); 0703 }; 0704 0705 auto mix2 = [&]() { 0706 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0707 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0708 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 1); 0709 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0710 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 1); 0711 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 3); 0712 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == false); 0713 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid6) == true); 0714 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid7) == false); 0715 }; 0716 0717 auto mix3 = [&]() { 0718 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0719 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0720 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0721 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 1); 0722 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0723 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 4); 0724 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid4) == false); 0725 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == true); 0726 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid6) == false); 0727 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid7) == true); 0728 }; 0729 0730 // Mix 4 and 5 0731 REQUIRE(timeline->mixClip(cid4)); 0732 mix0(); 0733 0734 // Mix 5 and 6 0735 REQUIRE(timeline->mixClip(cid5)); 0736 mix1(); 0737 0738 // Mix 6 and 7 0739 REQUIRE(timeline->mixClip(cid6)); 0740 mix2(); 0741 0742 // Mix 3 and 4, this will revert all subsequent mixes 0743 REQUIRE(timeline->mixClip(cid3)); 0744 mix3(); 0745 0746 // Undo mix 3 and 4 0747 undoStack->undo(); 0748 mix2(); 0749 0750 // Now switch mixes to Slide type 0751 timeline->switchComposition(cid7, QString("slide")); 0752 timeline->switchComposition(cid6, QString("slide")); 0753 timeline->switchComposition(cid5, QString("slide")); 0754 mix2(); 0755 0756 // Mix 3 and 4, this will revert all subsequent mixes 0757 REQUIRE(timeline->mixClip(cid3)); 0758 mix3(); 0759 0760 // Undo mix 3 and 4 0761 undoStack->undo(); 0762 mix2(); 0763 0764 // Now switch mixes to Wipe type 0765 timeline->switchComposition(cid7, QString("wipe")); 0766 timeline->switchComposition(cid6, QString("wipe")); 0767 timeline->switchComposition(cid5, QString("wipe")); 0768 mix2(); 0769 0770 // Mix 3 and 4, this will revert all subsequent mixes 0771 REQUIRE(timeline->mixClip(cid3)); 0772 mix3(); 0773 0774 // Undo mix 3 and 4 0775 undoStack->undo(); 0776 mix2(); 0777 0778 // Undo Wipe mix switch on cid5 0779 undoStack->undo(); 0780 // Undo mix switch on cid6 0781 undoStack->undo(); 0782 // Undo mix switch on cid7 0783 undoStack->undo(); 0784 mix2(); 0785 0786 // Undo Slide mix switch on cid5 0787 undoStack->undo(); 0788 // Undo mix switch on cid6 0789 undoStack->undo(); 0790 // Undo mix switch on cid7 0791 undoStack->undo(); 0792 mix2(); 0793 0794 // Undo mix 6 and 7 0795 undoStack->undo(); 0796 mix1(); 0797 // Undo mix 5 and 6 0798 undoStack->undo(); 0799 mix0(); 0800 // Undo mix 4 and 5 0801 undoStack->undo(); 0802 0803 // Undo insert/resize ops 0804 undoStack->undo(); 0805 undoStack->undo(); 0806 undoStack->undo(); 0807 undoStack->undo(); 0808 undoStack->undo(); 0809 undoStack->undo(); 0810 0811 state0(); 0812 } 0813 0814 SECTION("Test mixes track move and direction") 0815 { 0816 // Add 3 more av clips 0817 cid5 = -1; 0818 int cid6; 0819 int cid7; 0820 state0(); 0821 REQUIRE(timeline->requestClipInsertion(binId, tid2, 540, cid5)); 0822 REQUIRE(timeline->requestItemResize(cid5, 20, true, true)); 0823 REQUIRE(timeline->requestClipInsertion(binId, tid2, 560, cid6)); 0824 REQUIRE(timeline->requestItemResize(cid6, 40, true, true)); 0825 REQUIRE(timeline->requestClipInsertion(binId, tid2, 600, cid7)); 0826 REQUIRE(timeline->requestItemResize(cid7, 20, true, true)); 0827 audio5 = timeline->getClipSplitPartner(cid5); 0828 0829 // Cid3 pos=500, duration=20 0830 // Cid4 pos=520, duration=20 0831 // Cid5 pos=540, duration=20 0832 // Cid6 pos=560, duration=40 0833 // Cid7 pos=600, duration=20 0834 0835 auto mix0 = [&]() { 0836 REQUIRE(timeline->getClipsCount() == 12); 0837 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0838 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0839 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 1); 0840 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0841 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0842 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0843 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == false); 0844 }; 0845 0846 auto mix1 = [&]() { 0847 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0848 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0849 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 1); 0850 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0851 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0852 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 0853 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == false); 0854 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid6) == true); 0855 }; 0856 0857 auto mix2 = [&]() { 0858 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0859 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 0860 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 1); 0861 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0862 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 1); 0863 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 3); 0864 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == false); 0865 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid6) == true); 0866 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid7) == false); 0867 }; 0868 0869 auto mix3 = [&]() { 0870 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0871 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0872 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0873 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 1); 0874 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0875 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 4); 0876 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid4) == false); 0877 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid5) == true); 0878 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid6) == false); 0879 REQUIRE(timeline->getTrackById_const(tid2)->mixIsReversed(cid7) == true); 0880 }; 0881 0882 auto mix3b = [&]() { 0883 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0884 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0885 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0886 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 1); 0887 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 0888 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 0889 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 4); 0890 REQUIRE(timeline->getTrackById_const(tid4)->mixIsReversed(cid4) == false); 0891 REQUIRE(timeline->getTrackById_const(tid4)->mixIsReversed(cid5) == true); 0892 REQUIRE(timeline->getTrackById_const(tid4)->mixIsReversed(cid6) == false); 0893 REQUIRE(timeline->getTrackById_const(tid4)->mixIsReversed(cid7) == true); 0894 }; 0895 0896 // Mix 4 and 5 0897 REQUIRE(timeline->mixClip(cid4)); 0898 mix0(); 0899 0900 // Mix 5 and 6 0901 REQUIRE(timeline->mixClip(cid5)); 0902 mix1(); 0903 0904 // Mix 6 and 7 0905 REQUIRE(timeline->mixClip(cid6)); 0906 mix2(); 0907 0908 // Mix 3 and 4, this will revert all subsequent mixes 0909 REQUIRE(timeline->mixClip(cid3)); 0910 mix3(); 0911 0912 // Move everything to another track 0913 auto g1 = std::unordered_set<int>({cid3, cid4, cid5, cid6, cid7}); 0914 REQUIRE(timeline->requestClipsGroup(g1)); 0915 0916 REQUIRE(timeline->requestClipMove(cid3, tid4, 600)); 0917 // Now clips 3, 4, 5, 6 and 7 will be on top video track. Check mixes have the correct direction 0918 mix3b(); 0919 // Undo track move 0920 undoStack->undo(); 0921 mix3(); 0922 // Redo track move 0923 undoStack->redo(); 0924 mix3b(); 0925 undoStack->undo(); 0926 undoStack->undo(); 0927 undoStack->undo(); 0928 undoStack->undo(); 0929 undoStack->undo(); 0930 undoStack->undo(); 0931 0932 // Undo insert/resize ops 0933 undoStack->undo(); 0934 undoStack->undo(); 0935 undoStack->undo(); 0936 undoStack->undo(); 0937 undoStack->undo(); 0938 undoStack->undo(); 0939 0940 state0(); 0941 } 0942 SECTION("Test chained mixes and cuts") 0943 { 0944 // Add 2 more color clips 0945 cid5 = -1; 0946 int cid6; 0947 state0(); 0948 REQUIRE(timeline->requestItemResize(cid4, 80, true, true)); 0949 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 600, cid5)); 0950 REQUIRE(timeline->requestItemResize(cid5, 80, true, true)); 0951 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 680, cid6)); 0952 REQUIRE(timeline->requestItemResize(cid6, 80, true, true)); 0953 audio5 = timeline->getClipSplitPartner(cid5); 0954 0955 // Cid3 pos=500, duration=20 0956 // Cid4 pos=520, duration=80 0957 // Cid5 pos=600, duration=80 0958 // Cid6 pos=680, duration=80 0959 0960 // Mix 3 and 4 0961 REQUIRE(timeline->mixClip(cid3)); 0962 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0963 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0964 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0965 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0966 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 0967 0968 // Mix 4 and 5 0969 REQUIRE(timeline->mixClip(cid4)); 0970 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0971 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0972 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0973 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 0974 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 0975 0976 // Mix 5 and 6 0977 REQUIRE(timeline->mixClip(cid5)); 0978 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0979 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 0980 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 0981 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 1); 0982 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 3); 0983 0984 // Now try to cut mixes and check they are in the correct subplaylist 0985 0986 // Cut a clip with mix start only 0987 REQUIRE(TimelineFunctions::requestClipCut(timeline, cid3, 505)); 0988 // Get newly created cut clip 0989 int clone = timeline->getClipByPosition(tid2, 506, 0); 0990 // Ensure each clip is on the correct playlist 0991 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 1); 0992 REQUIRE(timeline->m_allClips[clone]->getSubPlaylistIndex() == 0); 0993 // Undo cid3 cut 0994 undoStack->undo(); 0995 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 0996 undoStack->redo(); 0997 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 1); 0998 undoStack->undo(); 0999 1000 // Cut a clip with mix at start and end 1001 REQUIRE(TimelineFunctions::requestClipCut(timeline, cid4, 540)); 1002 // Get newly created cut clip 1003 clone = timeline->getClipByPosition(tid2, 540, 1); 1004 // Ensure each clip is on the correct playlist 1005 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 1006 REQUIRE(timeline->m_allClips[clone]->getSubPlaylistIndex() == 1); 1007 // Undo cid3 cut 1008 undoStack->undo(); 1009 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 1010 undoStack->redo(); 1011 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 1012 REQUIRE(timeline->m_allClips[clone]->getSubPlaylistIndex() == 1); 1013 undoStack->undo(); 1014 1015 // Cut a clip with mix at end 1016 REQUIRE(TimelineFunctions::requestClipCut(timeline, cid6, 710)); 1017 // Get newly created cut clip 1018 clone = timeline->getClipByPosition(tid2, 710, 0); 1019 // Ensure each clip is on the correct playlist 1020 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 1021 REQUIRE(timeline->m_allClips[clone]->getSubPlaylistIndex() == 0); 1022 undoStack->undo(); 1023 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 1024 undoStack->redo(); 1025 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 1026 REQUIRE(timeline->m_allClips[clone]->getSubPlaylistIndex() == 0); 1027 undoStack->undo(); 1028 1029 // Undo mix 5 and 6 1030 undoStack->undo(); 1031 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 1032 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 1033 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 1034 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 1035 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 1036 1037 // Undo mix 4 and 5 1038 undoStack->undo(); 1039 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 1040 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 1041 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 1042 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 1043 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 1044 1045 // Undo mix 3 and 4 1046 undoStack->undo(); 1047 1048 // Undo insert/resize ops 1049 undoStack->undo(); 1050 undoStack->undo(); 1051 undoStack->undo(); 1052 undoStack->undo(); 1053 undoStack->undo(); 1054 state0(); 1055 } 1056 timeline.reset(); 1057 pCore->projectManager()->closeCurrentDocument(false, false); 1058 }