File indexing completed on 2024-05-19 08:45:59
0001 /* 0002 SPDX-FileCopyrightText: 2022 Julius Künzel <jk.kdedev@smartlab.uber.space> 0003 SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 #include "test_utils.hpp" 0006 // test specific headers 0007 #include "doc/kdenlivedoc.h" 0008 #include "render/renderrequest.h" 0009 #include "renderpresets/renderpresetmodel.hpp" 0010 #include "renderpresets/renderpresetrepository.hpp" 0011 0012 TEST_CASE("Basic tests of the render preset model", "[RenderPresets]") 0013 { 0014 0015 RenderPresetRepository::m_acodecsList = QStringList(QStringLiteral("libvorbis")); 0016 RenderPresetRepository::m_vcodecsList = QStringList(QStringLiteral("libvpx")); 0017 RenderPresetRepository::m_supportedFormats = QStringList(QStringLiteral("mp4")); 0018 0019 SECTION("Test getters") 0020 { 0021 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("GettersTest"), QStringLiteral("Test"), QString(), QStringLiteral("mp4"), 0022 QString(), QString(), QString(), QString(), QString(), false)); 0023 CHECK(model->name() == QStringLiteral("GettersTest")); 0024 CHECK(model->groupName() == QStringLiteral("Test")); 0025 CHECK(model->extension() == QStringLiteral("mp4")); 0026 // we did not set the format parameter, test if it was automatically 0027 // set based on the extension 0028 CHECK(model->getParam("f") == QStringLiteral("mp4")); 0029 } 0030 0031 SECTION("Test parameter parsing") 0032 { 0033 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("ParamTest"), QStringLiteral("Test"), 0034 QStringLiteral("one=first two=second value three=third four=4"), QString(), QString(), 0035 QString(), QString(), QString(), QString(), false)); 0036 // test hasParam 0037 CHECK(model->hasParam("one")); 0038 CHECK(model->hasParam("two")); 0039 CHECK(model->hasParam("three")); 0040 CHECK(model->hasParam("four")); 0041 CHECK_FALSE(model->hasParam("fifth")); 0042 CHECK_FALSE(model->hasParam("first")); 0043 CHECK_FALSE(model->hasParam("second")); 0044 CHECK_FALSE(model->hasParam("value")); 0045 CHECK_FALSE(model->hasParam("third")); 0046 CHECK_FALSE(model->hasParam("4")); 0047 CHECK_FALSE(model->hasParam("e")); 0048 0049 // test getParam 0050 CHECK(model->getParam("one") == QStringLiteral("first")); 0051 CHECK(model->getParam("two") == QStringLiteral("second value")); 0052 CHECK(model->getParam("three") == QStringLiteral("third")); 0053 CHECK(model->getParam("four") == QStringLiteral("4")); 0054 0055 CHECK(model->params().toString().length() == QString("one=first two=second value three=third four=4").length()); 0056 CHECK(model->params().size() == 4); 0057 CHECK(model->params().contains("one")); 0058 CHECK(model->params().contains("two")); 0059 CHECK(model->params().contains("three")); 0060 CHECK(model->params().contains("four")); 0061 0062 // test removing a normal parameter in the middle 0063 CHECK(model->params({QStringLiteral("three")}).toString().length() == QString("one=first two=second value four=4").length()); 0064 CHECK(model->params({QStringLiteral("three")}).size() == 3); 0065 CHECK_FALSE(model->params({QStringLiteral("three")}).contains("three")); 0066 0067 // test removing a parameter at the first position 0068 CHECK(model->params({QStringLiteral("one")}).toString().length() == QString("two=second value three=third four=4").length()); 0069 CHECK(model->params({QStringLiteral("one")}).size() == 3); 0070 CHECK_FALSE(model->params({QStringLiteral("one")}).contains("one")); 0071 0072 // test removing a parameter at the last position 0073 CHECK(model->params({QStringLiteral("four")}).toString().length() == QString("one=first two=second value three=third").length()); 0074 CHECK(model->params({QStringLiteral("four")}).size() == 3); 0075 CHECK_FALSE(model->params({QStringLiteral("four")}).contains("four")); 0076 0077 // test removing a non-existing parameter 0078 CHECK(model->params({QStringLiteral("fifth")}).toString().length() == QString("one=first two=second value three=third four=4").length()); 0079 CHECK(model->params({QStringLiteral("fifth")}).size() == 4); 0080 CHECK_FALSE(model->params({QStringLiteral("fifth")}).contains("fifth")); 0081 0082 // test removing a handing a value should do nothing 0083 CHECK(model->params({QStringLiteral("first")}).toString().length() == QString("one=first two=second value three=third four=4").length()); 0084 CHECK(model->params({QStringLiteral("first")}).size() == 4); 0085 CHECK_FALSE(model->params({QStringLiteral("first")}).contains("first")); 0086 0087 // test removing multiple parameters 0088 CHECK(model->params({QStringLiteral("one"), QStringLiteral("three")}).toString().length() == QString("two=second value four=4").length()); 0089 CHECK(model->params({QStringLiteral("one"), QStringLiteral("three")}).size() == 2); 0090 CHECK_FALSE(model->params({QStringLiteral("one"), QStringLiteral("three")}).contains("one")); 0091 CHECK_FALSE(model->params({QStringLiteral("one"), QStringLiteral("three")}).contains("three")); 0092 0093 // test removing a parameter with space in value 0094 CHECK(model->params({QStringLiteral("two")}).toString().length() == QString("one=first three=third four=4").length()); 0095 CHECK(model->params({QStringLiteral("two")}).size() == 3); 0096 CHECK_FALSE(model->params({QStringLiteral("two")}).contains("two")); 0097 } 0098 0099 SECTION("Test profile with no parameters") 0100 { 0101 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("EmptyParamTest"), QStringLiteral("Test"), QString(), QString(), 0102 QString(), QString(), QString(), QString(), QString(), false)); 0103 0104 // check there are really no parameters 0105 CHECK(model->params().toString().length() == 0); 0106 CHECK(model->params().size() == 0); 0107 } 0108 0109 SECTION("Test unknown rate control") 0110 { 0111 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("UnknownRate"), QStringLiteral("Test"), QString(), QStringLiteral("mp4"), 0112 QString(), QString(), QString(), QString(), QString(), false)); 0113 CHECK(model->params().videoRateControl() == RenderPresetParams::RateControl::Unknown); 0114 } 0115 0116 /*SECTION("Test constant rate control") 0117 { 0118 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("Constant"), QStringLiteral("Test"), QStringLiteral(""), 0119 QStringLiteral("mp4"), QString(), QString(), QString(), QString(), QString(), false)); CHECK(model->videoRateControl() == 0120 RenderPresetModel::RateControl::Constant); 0121 } 0122 0123 SECTION("Test average rate control") 0124 { 0125 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("Constant"), QStringLiteral("Test"), QStringLiteral(""), 0126 QStringLiteral("mp4"), QString(), QString(), QString(), QString(), QString(), false)); CHECK(model->videoRateControl() == 0127 RenderPresetModel::RateControl::Average); 0128 } 0129 0130 SECTION("Test quality rate control") 0131 { 0132 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("Constant"), QStringLiteral("Test"), QStringLiteral(""), 0133 QStringLiteral("mp4"), QString(), QString(), QString(), QString(), QString(), false)); CHECK(model->videoRateControl() == 0134 RenderPresetModel::RateControl::Quality); 0135 }*/ 0136 0137 SECTION("Test error") 0138 { 0139 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("ErrorTest"), QStringLiteral("Test"), 0140 QStringLiteral("acodec=doesnotexist"), QStringLiteral("mp4"), QString(), QString(), 0141 QString(), QString(), QString(), false)); 0142 0143 // we have a unknown audio codec, the error message should not be empty 0144 CHECK_FALSE(model->error().isEmpty()); 0145 } 0146 0147 SECTION("Test replace placeholders") 0148 { 0149 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("ParamTest"), QStringLiteral("Test"), 0150 QStringLiteral("one=%hello two=this%isaphval value three=%isaph four=4"), QString(), 0151 QString(), QString(), QString(), QString(), QString(), false)); 0152 0153 RenderPresetParams params = model->params(); 0154 CHECK_FALSE(params.toString().contains(QStringLiteral("one=world"))); 0155 CHECK_FALSE(params.toString().contains(QStringLiteral("two=thismynewval value"))); 0156 CHECK_FALSE(params.toString().contains(QStringLiteral("three=mynew"))); 0157 0158 params.replacePlaceholder(QStringLiteral("%hello"), QStringLiteral("world")); 0159 CHECK(params.toString().contains(QStringLiteral("one=world"))); 0160 0161 params.replacePlaceholder(QStringLiteral("%isaph"), QStringLiteral("mynew")); 0162 CHECK(params.toString().contains(QStringLiteral("two=thismynewval value"))); 0163 CHECK(params.toString().contains(QStringLiteral("three=mynew"))); 0164 } 0165 0166 SECTION("Test alpha detection placeholders") 0167 { 0168 std::unique_ptr<RenderPresetModel> model(new RenderPresetModel(QStringLiteral("AlphaTest"), QStringLiteral("Test"), QStringLiteral(""), QString(), 0169 QString(), QString(), QString(), QString(), QString(), false)); 0170 CHECK_FALSE(model->params().hasAlpha()); 0171 0172 model.reset(new RenderPresetModel(QStringLiteral("AlphaTest"), QStringLiteral("Test"), QStringLiteral("pix_fmt=rgba"), QString(), QString(), QString(), 0173 QString(), QString(), QString(), false)); 0174 CHECK(model->params().hasAlpha()); 0175 } 0176 0177 SECTION("Test x265 param") 0178 { 0179 std::unique_ptr<RenderPresetModel> model( 0180 new RenderPresetModel(QStringLiteral("AlphaTest"), QStringLiteral("Test"), 0181 QStringLiteral("properties=x265-medium f=mp4 vcodec=libx265 crf=%quality acodec=aac ab=%audiobitrate+'k'"), QString(), 0182 QString(), QString(), QString(), QString(), QString(), false)); 0183 0184 RenderPresetParams params = model->params(); 0185 0186 // we did not calulate the x265 params yet, so we expect to not have them 0187 CHECK_FALSE(params.contains(QStringLiteral("x265-params"))); 0188 0189 params.refreshX265Params(); 0190 // now that we calculated them we expect them to exist 0191 CHECK(params.contains(QStringLiteral("x265-params"))); 0192 0193 params.insert(QStringLiteral("vcodec"), QStringLiteral("libx264")); 0194 params.refreshX265Params(); 0195 // for a non-x265 codec they should not be there 0196 CHECK_FALSE(params.contains(QStringLiteral("x265-params"))); 0197 0198 params.insert(QStringLiteral("vcodec"), QStringLiteral("libx265")); 0199 params.refreshX265Params(); 0200 // we set x265 codec again so the params should be back 0201 CHECK(params.contains(QStringLiteral("x265-params"))); 0202 } 0203 } 0204 0205 TEST_CASE("Tests of the render functions to use guides for sections", "[RenderRequestGuides]") 0206 { 0207 std::shared_ptr<DocUndoStack> undoStack = std::make_shared<DocUndoStack>(nullptr); 0208 std::shared_ptr<MarkerListModel> markerModel(new MarkerListModel(QString(), undoStack)); 0209 markerModel->loadCategories(KdenliveDoc::getDefaultGuideCategories()); 0210 0211 int guideCategory = 3; 0212 0213 // create some guides at different positions and in different categories 0214 markerModel->addMarker(GenTime(35, pCore->getCurrentFps()), QStringLiteral("test marker"), 1); 0215 markerModel->addMarker(GenTime(70, pCore->getCurrentFps()), QStringLiteral("test marker"), guideCategory); 0216 markerModel->addMarker(GenTime(25, pCore->getCurrentFps()), QStringLiteral("test marker"), guideCategory); 0217 0218 // set the bounding range 0219 int in = 0; 0220 int out = 100; 0221 0222 RenderRequest *r = new RenderRequest(); 0223 r->m_boundingIn = in; 0224 r->m_boundingOut = out; 0225 0226 std::vector<RenderRequest::RenderSection> sections; 0227 0228 SECTION("Single Guide") 0229 { 0230 // Category 1 contains only one guide and hence should have 2 sections 0231 r->setGuideParams(markerModel, true, 1); 0232 sections = r->getGuideSections(); 0233 CHECK(sections.size() == 2); 0234 } 0235 0236 SECTION("No markers at all") 0237 { 0238 // Category 0 has no guides and should return no sections at all 0239 r->setGuideParams(markerModel, true, 0); 0240 sections = r->getGuideSections(); 0241 CHECK(sections.size() == 0); 0242 } 0243 0244 SECTION("Multiple Guides") 0245 { 0246 r->setGuideParams(markerModel, true, guideCategory); 0247 sections = r->getGuideSections(); 0248 CHECK(sections.size() == 3); 0249 0250 // Add one more marker and check this leads to one more section 0251 markerModel->addMarker(GenTime(51, pCore->getCurrentFps()), QStringLiteral("test marker"), guideCategory); 0252 sections = r->getGuideSections(); 0253 CHECK(sections.size() == 4); 0254 0255 // The size should not change if we add a guide at the start, because there should always be a section from the start. 0256 // Our guide should only replace the automatically generated section which in our case should only affect the name. 0257 markerModel->addMarker(GenTime(0, pCore->getCurrentFps()), QStringLiteral("test marker"), guideCategory); 0258 sections = r->getGuideSections(); 0259 CHECK(sections.size() == 4); 0260 0261 // check in and out points 0262 CHECK(sections.at(0).in == in); 0263 CHECK(sections.at(0).out == 24); 0264 CHECK(sections.at(1).in == 25); 0265 CHECK(sections.at(1).out == 50); 0266 CHECK(sections.at(2).in == 51); 0267 CHECK(sections.at(2).out == 69); 0268 CHECK(sections.at(3).in == 70); 0269 CHECK(sections.at(3).out == out); 0270 0271 // check no section name appears twice, eventhough we have guides with the same name 0272 QStringList names; 0273 for (const auto §ion : sections) { 0274 names << section.name; 0275 } 0276 CHECK(names.removeDuplicates() == 0); 0277 0278 // change the bounding range 0279 in = 10; 0280 out = 60; 0281 r->m_boundingIn = in; 0282 r->m_boundingOut = out; 0283 0284 sections = r->getGuideSections(); 0285 CHECK(sections.size() == 3); 0286 0287 // check in and out points 0288 CHECK(sections.at(0).in == in); 0289 CHECK(sections.at(0).out == 24); 0290 CHECK(sections.at(1).in == 25); 0291 CHECK(sections.at(1).out == 50); 0292 CHECK(sections.at(2).in == 51); 0293 CHECK(sections.at(2).out == out); 0294 } 0295 }