1 #include "catch.hpp" 2 #include "doc/docundostack.hpp" 3 #include "test_utils.hpp" 4 5 #include <QString> 6 #include <cmath> 7 #include <iostream> 8 #include <tuple> 9 #include <unordered_set> 10 11 #include "definitions.h" 12 #define private public 13 #define protected public 14 #include "core.h" 15 16 using namespace fakeit; 17 Mlt::Profile profile_mix; 18 19 TEST_CASE("Simple Mix", "[SameTrackMix]") 20 { 21 // Create timeline 22 auto binModel = pCore->projectItemModel(); 23 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 24 std::shared_ptr<MarkerListModel> guideModel = std::make_shared<MarkerListModel>(undoStack); 25 26 // Here we do some trickery to enable testing. 27 // We mock the project class so that the undoStack function returns our undoStack 28 29 Mock<ProjectManager> pmMock; 30 When(Method(pmMock, undoStack)).AlwaysReturn(undoStack); 31 When(Method(pmMock, cacheDir)).AlwaysReturn(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))); 32 33 ProjectManager &mocked = pmMock.get(); 34 pCore->m_projectManager = &mocked; 35 36 // We also mock timeline object to spy few functions and mock others 37 TimelineItemModel tim(&profile_mix, undoStack); 38 Mock<TimelineItemModel> timMock(tim); __anonb3283b290102(...) 39 auto timeline = std::shared_ptr<TimelineItemModel>(&timMock.get(), [](...) {}); 40 TimelineItemModel::finishConstruct(timeline, guideModel); 41 42 // Create a request 43 int tid1 = TrackModel::construct(timeline, -1, -1, QString(), true); 44 int tid3 = TrackModel::construct(timeline, -1, -1, QString(), true); 45 int tid2 = TrackModel::construct(timeline); 46 int tid4 = TrackModel::construct(timeline); 47 48 // Create clip with audio 49 QString binId = createProducerWithSound(profile_mix, binModel, 100); 50 51 // Create video clip 52 QString binId2 = createProducer(profile_mix, "red", binModel, 50, false); 53 // Setup insert stream data 54 QMap <int, QString>audioInfo; 55 audioInfo.insert(1,QStringLiteral("stream1")); 56 timeline->m_binAudioTargets = audioInfo; 57 58 // Create AV clip 1 59 int cid1; 60 int cid2; 61 int cid3; 62 int cid4; 63 REQUIRE(timeline->requestClipInsertion(binId, tid2, 100, cid1)); 64 REQUIRE(timeline->requestItemResize(cid1, 10, true, true)); 65 66 // Create AV clip 2 67 REQUIRE(timeline->requestClipInsertion(binId, tid2, 110, cid2)); 68 REQUIRE(timeline->requestItemResize(cid2, 10, true, true)); 69 REQUIRE(timeline->requestClipMove(cid2, tid2, 110)); 70 71 // Create color clip 1 72 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 500, cid3)); 73 REQUIRE(timeline->requestItemResize(cid3, 20, true, true)); 74 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 520, cid4)); 75 REQUIRE(timeline->requestItemResize(cid4, 20, true, true)); 76 int mixDuration = pCore->getDurationFromString(KdenliveSettings::mix_duration()); 77 __anonb3283b290202() 78 auto state0 = [&]() { 79 REQUIRE(timeline->getClipsCount() == 6); 80 REQUIRE(timeline->getClipPlaytime(cid1) == 10); 81 REQUIRE(timeline->getClipPosition(cid1) == 100); 82 REQUIRE(timeline->getClipPlaytime(cid2) == 10); 83 REQUIRE(timeline->getClipPosition(cid2) == 110); 84 REQUIRE(timeline->getClipPosition(cid3) == 500); 85 REQUIRE(timeline->getClipPlaytime(cid3) == 20); 86 REQUIRE(timeline->getClipPosition(cid4) == 520); 87 REQUIRE(timeline->getClipPlaytime(cid4) == 20); 88 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 89 REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0); 90 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 91 }; 92 __anonb3283b290302() 93 auto state1 = [&]() { 94 REQUIRE(timeline->getClipsCount() == 6); 95 REQUIRE(timeline->getClipPlaytime(cid1) > 10); 96 REQUIRE(timeline->getClipPosition(cid1) == 100); 97 REQUIRE(timeline->getClipPlaytime(cid2) > 10); 98 REQUIRE(timeline->getClipPosition(cid2) < 110); 99 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 100 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 101 }; 102 __anonb3283b290402() 103 auto state3 = [&, mixDuration]() { 104 REQUIRE(timeline->getClipsCount() == 6); 105 REQUIRE(timeline->getClipPlaytime(cid1) > 30); 106 REQUIRE(timeline->getClipPosition(cid1) == 100); 107 REQUIRE(timeline->getClipPlaytime(cid2) > 30); 108 REQUIRE(timeline->getClipPosition(cid2) < 130); 109 REQUIRE(timeline->m_allClips[cid2]->getMixDuration() == mixDuration); 110 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 111 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 112 }; 113 __anonb3283b290502() 114 auto state2 = [&]() { 115 REQUIRE(timeline->getClipsCount() == 6); 116 REQUIRE(timeline->getClipPlaytime(cid3) > 20); 117 REQUIRE(timeline->getClipPosition(cid3) == 500); 118 REQUIRE(timeline->getClipPlaytime(cid4) > 20); 119 REQUIRE(timeline->getClipPosition(cid4) < 520); 120 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 121 REQUIRE(timeline->getTrackById_const(tid1)->mixCount() == 0); 122 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 123 }; 124 125 SECTION("Create and delete mix on color clips") 126 { 127 state0(); 128 REQUIRE(timeline->mixClip(cid4)); 129 state2(); 130 undoStack->undo(); 131 state0(); 132 undoStack->redo(); 133 state2(); 134 undoStack->undo(); 135 state0(); 136 } 137 138 SECTION("Create mix on color clips and move main (right side) clip") 139 { 140 // CID 3 length=20, pos=500, CID4 length=20, pos=520 141 // Default mix duration = 25 frames (12 before / 13 after) 142 state0(); 143 REQUIRE(timeline->mixClip(cid4)); 144 state2(); 145 146 // Move right clip to the left, should fail 147 REQUIRE(timeline->requestClipMove(cid4, tid2, 506) == false); 148 149 // Move clip inside mix zone, should delete the mix 150 REQUIRE(timeline->requestClipMove(cid4, tid2, 509)); 151 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 152 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 153 undoStack->undo(); 154 state2(); 155 // Move clip outside mix zone, should delete the mix and move it back to playlist 0 156 REQUIRE(timeline->requestClipMove(cid4, tid2, 600)); 157 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 158 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 159 undoStack->undo(); 160 state2(); 161 // Move clip to another track, should delete mix 162 REQUIRE(timeline->requestClipMove(cid4, tid4, 600)); 163 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 164 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 165 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 166 undoStack->undo(); 167 state2(); 168 undoStack->undo(); 169 state0(); 170 } 171 172 SECTION("Create mix on color clip and move left side clip") 173 { 174 state0(); 175 REQUIRE(timeline->mixClip(cid4)); 176 state2(); 177 178 // Move left clip to the right, should silently fail 179 REQUIRE(timeline->requestClipMove(cid3, tid2, 502, true, true, false) == false); 180 REQUIRE(timeline->getClipPosition(cid3) == 500); 181 182 // Move clip inside mix zone, should delete the mix 183 REQUIRE(timeline->requestClipMove(cid3, tid2, 499)); 184 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 185 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 186 undoStack->undo(); 187 state2(); 188 // Move clip outside mix zone, should delete the mix 189 REQUIRE(timeline->requestClipMove(cid3, tid2, 450)); 190 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 191 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 192 undoStack->undo(); 193 state2(); 194 // Move clip to another track, should delete mix 195 REQUIRE(timeline->requestClipMove(cid3, tid4, 600)); 196 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 197 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 198 undoStack->undo(); 199 state2(); 200 undoStack->undo(); 201 state0(); 202 } 203 204 SECTION("Create mix on color clips and move some to another track") 205 { 206 state0(); 207 // insert third color clip 208 int cid5; 209 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 540, cid5)); 210 REQUIRE(timeline->requestItemResize(cid5, 20, true, true)); 211 REQUIRE(timeline->getClipPosition(cid5) == 540); 212 213 // CID 3 length=20, pos=500, CID4 length=20, pos=520, CID% length=20, pos=540 214 // Default mix duration = 25 frames (12 before / 13 after) 215 216 REQUIRE(timeline->mixClip(cid4)); 217 REQUIRE(timeline->mixClip(cid5)); 218 REQUIRE(timeline->getClipPosition(cid5) < 540); 219 undoStack->undo(); 220 REQUIRE(timeline->getClipPosition(cid5) == 540); 221 undoStack->redo(); 222 REQUIRE(timeline->getClipPosition(cid5) < 540); 223 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 224 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 225 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 226 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 227 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 228 229 // Move middle clip to another track, should delete the mixes 230 REQUIRE(timeline->requestClipMove(cid4, tid4, 500)); 231 REQUIRE(timeline->getClipPosition(cid5) == 540); 232 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 233 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 234 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 235 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 236 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 237 238 // Undo track move 239 undoStack->undo(); 240 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 241 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 242 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 243 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 244 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 245 246 // Undo mixes 247 undoStack->undo(); 248 undoStack->undo(); 249 // undo 3rd clip resize & insert 250 undoStack->undo(); 251 undoStack->undo(); 252 state0(); 253 } 254 255 SECTION("Create mix on color clips and group move") 256 { 257 state0(); 258 REQUIRE(timeline->mixClip(cid4)); 259 state2(); 260 // Move clip inside mix zone, should resize the mix 261 auto g1 = std::unordered_set<int>({cid3, cid4}); 262 REQUIRE(timeline->requestClipsGroup(g1)); 263 // Move clip to another track, should delete mix 264 REQUIRE(timeline->requestClipMove(cid4, tid4, 600)); 265 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 266 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 1); 267 undoStack->undo(); 268 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 269 REQUIRE(timeline->getTrackById_const(tid4)->mixCount() == 0); 270 state2(); 271 // Move on same track 272 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 273 REQUIRE(timeline->requestClipMove(cid4, tid3, 800)); 274 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 275 undoStack->undo(); 276 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 277 state2(); 278 // Undo group 279 undoStack->undo(); 280 // Undo mix 281 undoStack->undo(); 282 state0(); 283 } 284 285 SECTION("Create and delete mix on AV clips") 286 { 287 state0(); 288 REQUIRE(timeline->requestItemResize(cid2, 30, true, true) == 30); 289 REQUIRE(timeline->requestItemResize(cid2, 10, false, true) == 10); 290 REQUIRE(timeline->requestClipMove(cid2, tid2, 110)); 291 REQUIRE(timeline->mixClip(cid2)); 292 state1(); 293 undoStack->undo(); 294 state0(); 295 undoStack->redo(); 296 state1(); 297 undoStack->undo(); 298 state0(); 299 } 300 301 SECTION("Create mix and move AV clips") 302 { 303 // CID 1 length=10, pos=100, CID2 length=10, pos=110 304 // Default mix duration = 25 frames (12 before / 13 after) 305 // Resize CID2 so that it has some space to expand left 306 REQUIRE(timeline->requestItemResize(cid2, 30, true, true) == 30); 307 REQUIRE(timeline->requestItemResize(cid2, 10, false, true) == 10); 308 REQUIRE(timeline->requestClipMove(cid2, tid2, 110)); 309 // Resize clip, should resize the mix 310 state0(); 311 REQUIRE(timeline->mixClip(cid2)); 312 state1(); 313 // Resize right clip, should resize the mix 314 REQUIRE(timeline->requestItemResize(cid2, 15, false, true) == 15); 315 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 316 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 317 undoStack->undo(); 318 state1(); 319 // Resize left clip, should resize the mix 320 REQUIRE(timeline->requestItemResize(cid1, 20, true, true) == 20); 321 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 322 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 323 undoStack->undo(); 324 state1(); 325 // Move clip outside mix zone, should delete the mix 326 REQUIRE(timeline->requestClipMove(cid2, tid2, 200)); 327 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 0); 328 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 329 undoStack->undo(); 330 state1(); 331 // Undo mix 332 undoStack->undo(); 333 state0(); 334 } 335 336 SECTION("Create mix on color clip and resize") 337 { 338 state0(); 339 // CID 3 length=20, pos=500, CID4 length=20, pos=520 340 // Default mix duration = 25 frames (12 before / 13 after) 341 REQUIRE(timeline->mixClip(cid4)); 342 state2(); 343 // Resize left clip, should resize the mix 344 REQUIRE(timeline->requestItemResize(cid3, 24, true, true) == 24); 345 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 346 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 347 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 348 undoStack->undo(); 349 state2(); 350 // Resize left clip outside mix zone, should delete the mix 351 REQUIRE(timeline->requestItemResize(cid3, 4, true, true) == 20); 352 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 353 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 354 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 355 undoStack->undo(); 356 state2(); 357 // Resize right clip, should resize the mix 358 REQUIRE(timeline->requestItemResize(cid4, 16, false, true) == 16); 359 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 360 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 361 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 362 undoStack->undo(); 363 state2(); 364 // Resize right clip outside mix zone, should delete the mix 365 REQUIRE(timeline->requestItemResize(cid4, 4, false, true) == 4); 366 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 367 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 368 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 0); 369 undoStack->undo(); 370 state2(); 371 // Resize right clip before left clip, should limit the resize to left clip position 372 REQUIRE(timeline->requestItemResize(cid4, 50, false, true) == 40); 373 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 374 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 375 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 376 undoStack->undo(); 377 state2(); 378 // Resize left clip past right clip, should limit the resize to left clip position 379 REQUIRE(timeline->requestItemResize(cid3, 100, true, true) == 40); 380 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 381 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 382 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 383 undoStack->undo(); 384 state2(); 385 386 undoStack->undo(); 387 state0(); 388 } 389 390 SECTION("Create mix on AV clips and resize") 391 { 392 state0(); 393 // CID 1 length=10, pos=100, CID2 length=10, pos=110 394 REQUIRE(timeline->m_allClips[cid1]->getPlaytime() == 10); 395 REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == 10); 396 // Resize clip in to have some space for mix 397 REQUIRE(timeline->requestItemResize(cid2, 90, true, true) == 90); 398 REQUIRE(timeline->requestItemResize(cid2, 30, false, true) == 30); 399 REQUIRE(timeline->requestClipMove(cid2, tid2, 130)); 400 REQUIRE(timeline->requestItemResize(cid1, 30, true, true) == 30); 401 402 REQUIRE(timeline->mixClip(cid2)); 403 state3(); 404 // CID 1 length=30, pos=100, CID2 length=30, pos=130 405 // Default mix duration = 25 frames (12 before / 13 after) 406 // Resize left clip, should resize the mix 407 REQUIRE(timeline->requestItemResize(cid1, 35, true, true) == 35); 408 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 409 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 410 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 411 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 412 undoStack->undo(); 413 state3(); 414 // Resize left clip outside mix zone, should delete the mix 415 REQUIRE(timeline->requestItemResize(cid1, 10, true, true) == 30); 416 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 417 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 0); 418 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 419 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 0); 420 undoStack->undo(); 421 state3(); 422 // Resize right clip, should resize the mix 423 REQUIRE(timeline->requestItemResize(cid2, 25, false, true) == 25); 424 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 425 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 426 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 427 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 428 undoStack->undo(); 429 state3(); 430 // Resize right clip outside mix zone, should delete the mix 431 REQUIRE(timeline->requestItemResize(cid2, 4, false, true) == 4); 432 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 0); 433 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 0); 434 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 435 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 0); 436 undoStack->undo(); 437 state3(); 438 // Resize right clip before left clip, should limit to left clip position 439 REQUIRE(timeline->requestItemResize(cid2, 80, false, true) == 60); 440 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 441 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 442 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 443 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 444 undoStack->undo(); 445 state3(); 446 // Resize left clip after right clip, should limit to right clip duration 447 REQUIRE(timeline->requestItemResize(cid1, 80, true, true) == 60); 448 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 449 REQUIRE(timeline->getTrackById_const(tid3)->mixCount() == 1); 450 REQUIRE(timeline->m_allClips[cid1]->getSubPlaylistIndex() == 0); 451 REQUIRE(timeline->m_allClips[cid2]->getSubPlaylistIndex() == 1); 452 undoStack->undo(); 453 state3(); 454 undoStack->undo(); 455 undoStack->undo(); 456 undoStack->undo(); 457 undoStack->undo(); 458 undoStack->undo(); 459 state0(); 460 } 461 462 SECTION("Test chained mixes on color clips") 463 { 464 // Add 2 more color clips 465 int cid5; 466 int cid6; 467 int cid7; 468 state0(); 469 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 540, cid5)); 470 REQUIRE(timeline->requestItemResize(cid5, 20, true, true)); 471 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 560, cid6)); 472 REQUIRE(timeline->requestItemResize(cid6, 40, true, true)); 473 REQUIRE(timeline->requestClipInsertion(binId2, tid2, 600, cid7)); 474 REQUIRE(timeline->requestItemResize(cid7, 20, true, true)); 475 476 // Cid3 pos=500, duration=20 477 // Cid4 pos=520, duration=20 478 // Cid5 pos=540, duration=20 479 // Cid6 pos=560, duration=40 480 // Cid7 pos=600, duration=20 481 482 // Mix 3 and 4 483 REQUIRE(timeline->mixClip(cid4)); 484 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 485 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 486 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 487 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 488 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 489 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 490 491 // Mix 6 and 7 492 REQUIRE(timeline->mixClip(cid7)); 493 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 494 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 495 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 496 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 497 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 1); 498 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 499 500 // Mix 5 and 6 501 REQUIRE(timeline->mixClip(cid6)); 502 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 503 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 504 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 505 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 1); 506 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 507 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 3); 508 509 // Undo mix 5 and 6 510 undoStack->undo(); 511 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 512 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 513 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 514 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 515 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 1); 516 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 2); 517 518 // Undo mix 6 and 7 519 undoStack->undo(); 520 REQUIRE(timeline->m_allClips[cid3]->getSubPlaylistIndex() == 0); 521 REQUIRE(timeline->m_allClips[cid4]->getSubPlaylistIndex() == 1); 522 REQUIRE(timeline->m_allClips[cid5]->getSubPlaylistIndex() == 0); 523 REQUIRE(timeline->m_allClips[cid6]->getSubPlaylistIndex() == 0); 524 REQUIRE(timeline->m_allClips[cid7]->getSubPlaylistIndex() == 0); 525 REQUIRE(timeline->getTrackById_const(tid2)->mixCount() == 1); 526 527 // Undo mix 3 and 4 528 undoStack->undo(); 529 530 // Undo insert/resize ops 531 undoStack->undo(); 532 undoStack->undo(); 533 undoStack->undo(); 534 undoStack->undo(); 535 undoStack->undo(); 536 undoStack->undo(); 537 538 state0(); 539 } 540 binModel->clean(); 541 pCore->m_projectManager = nullptr; 542 } 543