File indexing completed on 2024-05-12 08:55:36

0001 /*
0002     SPDX-FileCopyrightText: 2022 Jean-Baptiste Mardelle <jb@kdenlive.org>
0003     SPDX-FileCopyrightText: 2022 Eric Jiang
0004     SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 #include "catch.hpp"
0007 #include "test_utils.hpp"
0008 // test specific headers
0009 #include <QString>
0010 #include <cmath>
0011 #include <iostream>
0012 #include <tuple>
0013 #include <unordered_set>
0014 
0015 #include <chrono>
0016 #include <thread>
0017 
0018 #include "bin/binplaylist.hpp"
0019 #include "definitions.h"
0020 #include "doc/kdenlivedoc.h"
0021 #include "timeline2/model/builders/meltBuilder.hpp"
0022 #include "timeline2/view/previewmanager.h"
0023 #include "xml/xml.hpp"
0024 
0025 TEST_CASE("Timeline preview insert-remove", "[TimelinePreview]")
0026 {
0027     // Create timeline
0028     auto binModel = pCore->projectItemModel();
0029     std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr);
0030     // Ensure we use a progressive project profile
0031     pCore->setCurrentProfile("atsc_1080p_25");
0032 
0033     // Create document
0034     KdenliveDoc document(undoStack);
0035     Mock<KdenliveDoc> docMock(document);
0036     KdenliveDoc &mockedDoc = docMock.get();
0037 
0038     // We mock the project class so that the undoStack function returns our undoStack, and our mocked document
0039     Mock<ProjectManager> pmMock;
0040     When(Method(pmMock, undoStack)).AlwaysReturn(undoStack);
0041     When(Method(pmMock, cacheDir)).AlwaysReturn(QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)));
0042     When(Method(pmMock, current)).AlwaysReturn(&mockedDoc);
0043     ProjectManager &mocked = pmMock.get();
0044     pCore->m_projectManager = &mocked;
0045     mocked.m_project = &mockedDoc;
0046     QDateTime documentDate = QDateTime::currentDateTime();
0047     mocked.updateTimeline(false, QString(), QString(), documentDate, 0);
0048     auto timeline = mockedDoc.getTimeline(mockedDoc.uuid());
0049     mocked.m_activeTimelineModel = timeline;
0050 
0051     mocked.testSetActiveDocument(&mockedDoc, timeline);
0052 
0053     QString documentId = QString::number(QDateTime::currentMSecsSinceEpoch());
0054     mockedDoc.setDocumentProperty(QStringLiteral("documentid"), documentId);
0055     mockedDoc.setDocumentProperty(QStringLiteral("previewextension"), QStringLiteral("avi"));
0056     mockedDoc.setDocumentProperty(QStringLiteral("previewparameters"), QStringLiteral("vcodec=mjpeg progressive=1 qscale=10"));
0057 
0058     // Create base tmp folder
0059     bool ok = false;
0060     QDir dir = mockedDoc.getCacheDir(CacheBase, &ok);
0061     dir.mkpath(QStringLiteral("."));
0062     dir.mkdir(QLatin1String("preview"));
0063 
0064     int tid3 = timeline->getTrackIndexFromPosition(2);
0065     QString binId = createProducer(pCore->getProjectProfile(), "red", binModel);
0066 
0067     // Initialize timeline preview
0068     timeline->initializePreviewManager();
0069     timeline->buildPreviewTrack();
0070     REQUIRE(dir.exists(QLatin1String("preview")));
0071     dir.cd(QLatin1String("preview"));
0072     // Trigger a timeline preview
0073     timeline->previewManager()->addPreviewRange({0, 50}, true);
0074     timeline->previewManager()->startPreviewRender();
0075 
0076     // Wait until the preview rendering is over
0077     while (timeline->previewManager()->isRunning()) {
0078         std::this_thread::sleep_for(std::chrono::milliseconds(2000));
0079         qDebug() << ":::: WAITING FOR PROGRESS...";
0080         qApp->processEvents();
0081     }
0082     QFileInfoList list = dir.entryInfoList(QDir::Files, QDir::Time);
0083     for (auto &file : list) {
0084         qDebug() << "::: FOUND FILE: " << dir.absoluteFilePath(file.fileName());
0085     }
0086     if (list.size() != 3) {
0087         QProcess p;
0088         const QString ffpath = QStandardPaths::findExecutable(QStringLiteral("melt"));
0089         p.start(ffpath, {QStringLiteral("-query"), QStringLiteral("formats")});
0090         p.waitForFinished();
0091         qDebug() << "::: MLT CODEC FORMATS :::\nMLT EXE: " << ffpath << "\nFORMATS:\n"
0092                  << p.readAllStandardOutput() << "\n----------\n"
0093                  << p.readAllStandardError();
0094     }
0095     // This should create 3 output chunks
0096     REQUIRE(list.size() == 3);
0097 
0098     // Create and insert clip
0099     int cid1 = -1;
0100     // Setup insert stream data
0101     QMap<int, QString> audioInfo;
0102     audioInfo.insert(1, QStringLiteral("stream1"));
0103     timeline->m_binAudioTargets = audioInfo;
0104     REQUIRE(timeline->requestClipInsertion(binId, tid3, 50, cid1, true, true, false));
0105     REQUIRE(timeline->getClipsCount() == 1);
0106     timeline->previewManager()->invalidatePreviews();
0107     list = dir.entryInfoList(QDir::Files, QDir::Time);
0108     for (auto &file : list) {
0109         qDebug() << "::: FOUND FILE AFTER: " << file.fileName();
0110     }
0111     // 2 chunks should remain
0112     REQUIRE(list.size() == 2);
0113     timeline->resetPreviewManager();
0114     // Ensure preview project folder is deleted on close
0115     REQUIRE(dir.exists() == false);
0116     binModel->clean();
0117     pCore->m_projectManager = nullptr;
0118 }