1 #include <c++utilities/chrono/format.h>
5 #include "../abstracttrack.h"
6 #include "../matroska/matroskacontainer.h"
7 #include "../mp4/mp4ids.h"
8 #include "../mpegaudio/mpegaudioframe.h"
10 #include <c++utilities/chrono/timespan.h>
11 #include <c++utilities/conversion/binaryconversion.h>
12 #include <c++utilities/conversion/stringconversion.h>
13 #include <c++utilities/io/misc.h>
37 void OverallTests::checkMkvTestfile1()
39 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
40 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromMinutes(1) + TimeSpan::fromSeconds(27) + TimeSpan::fromMilliseconds(336), m_fileInfo.duration());
41 const auto tracks = m_fileInfo.tracks();
42 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
43 for (
const auto &track : tracks) {
44 switch (track->id()) {
47 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::MicrosoftMpeg4, track->format().general);
52 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
55 CPPUNIT_FAIL(
"unknown track ID");
58 const auto tags = m_fileInfo.tags();
59 switch (m_tagStatus) {
61 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
62 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 1"s, tags.front()->value(
KnownField::Title).toString());
65 "Matroska Validation File1, basic MPEG4.2 and MP3 with only SimpleBlock"s, tags.front()->value(
KnownField::Comment).toString());
66 CPPUNIT_ASSERT_EQUAL(
"2010"s, tags.front()->value(KnownField::ReleaseDate).toString());
69 checkMkvTestMetaData();
72 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
74 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
80 void OverallTests::checkMkvTestfile2()
82 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
83 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(47) + TimeSpan::fromMilliseconds(509), m_fileInfo.duration());
84 const auto tracks = m_fileInfo.tracks();
85 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
86 for (
const auto &track : tracks) {
87 switch (track->id()) {
91 CPPUNIT_ASSERT_EQUAL(
Size(1354, 576), track->displaySize());
96 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
99 CPPUNIT_FAIL(
"unknown track ID");
102 const auto tags = m_fileInfo.tags();
103 switch (m_tagStatus) {
105 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
106 CPPUNIT_ASSERT_EQUAL(
"Elephant Dream - test 2"s, tags.front()->value(
KnownField::Title).toString());
108 CPPUNIT_ASSERT_EQUAL(
"Matroska Validation File 2, 100,000 timecode scale, odd aspect ratio, and CRC-32. Codecs are AVC and AAC"s,
112 checkMkvTestMetaData();
115 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
117 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
123 void OverallTests::checkMkvTestfile3()
125 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
126 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(49) + TimeSpan::fromMilliseconds(64), m_fileInfo.duration());
127 const auto tracks = m_fileInfo.tracks();
128 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
129 for (
const auto &track : tracks) {
130 switch (track->id()) {
134 CPPUNIT_ASSERT_EQUAL(
Size(1024, 576), track->displaySize());
139 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
142 CPPUNIT_FAIL(
"unknown track ID");
145 const auto tags = m_fileInfo.tags();
146 switch (m_tagStatus) {
148 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
149 CPPUNIT_ASSERT_EQUAL(
"Elephant Dream - test 3"s, tags.front()->value(
KnownField::Title).toString());
151 CPPUNIT_ASSERT_EQUAL(
"Matroska Validation File 3, header stripping on the video track and no SimpleBlock"s,
155 checkMkvTestMetaData();
158 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
160 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
167 void OverallTests::checkMkvTestfile4()
169 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
170 CPPUNIT_ASSERT_EQUAL(
TimeSpan(), m_fileInfo.duration());
172 const auto tracks = m_fileInfo.tracks();
173 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
174 for (
const auto &track : tracks) {
175 switch (track->id()) {
178 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Theora, track->format().general);
179 CPPUNIT_ASSERT_EQUAL(
Size(1280, 720), track->displaySize());
183 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Vorbis, track->format().general);
184 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
185 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2u), track->channelCount());
186 switch (m_tagStatus) {
189 CPPUNIT_ASSERT_EQUAL(
Locale(
"und"sv, LocaleFormat::ISO_639_2_B), track->locale());
190 CPPUNIT_ASSERT_EQUAL(
string(), track->name());
191 CPPUNIT_ASSERT(track->isEnabled());
192 CPPUNIT_ASSERT(!track->isForced());
193 CPPUNIT_ASSERT(!track->isDefault());
196 CPPUNIT_ASSERT_EQUAL(
Locale(
"ger"sv, LocaleFormat::ISO_639_2_B), track->locale());
197 CPPUNIT_ASSERT_EQUAL(
"the name"s, track->name());
198 CPPUNIT_ASSERT(track->isEnabled());
199 CPPUNIT_ASSERT(track->isForced());
200 CPPUNIT_ASSERT(track->isDefault());
205 CPPUNIT_FAIL(
"unknown track ID");
208 const auto tags = m_fileInfo.tags();
209 switch (m_tagStatus) {
212 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
215 checkMkvTestMetaData();
220 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Critical);
226 void OverallTests::checkMkvTestfile5()
228 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
229 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(46) + TimeSpan::fromMilliseconds(665), m_fileInfo.duration());
230 const auto tracks = m_fileInfo.tracks();
231 CPPUNIT_ASSERT_EQUAL(11_st, tracks.size());
232 for (
const auto &track : tracks) {
233 switch (track->id()) {
237 CPPUNIT_ASSERT_EQUAL(
Size(1024, 576), track->displaySize());
242 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
246 CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
248 CPPUNIT_ASSERT_EQUAL(
Locale(
"ger"sv, LocaleFormat::ISO_639_2_B), track->locale());
253 const auto tags = m_fileInfo.tags();
254 switch (m_tagStatus) {
256 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
257 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 8"s, tags.front()->value(
KnownField::Title).toString());
259 CPPUNIT_ASSERT_EQUAL(
"Matroska Validation File 8, secondary audio commentary track, misc subtitle tracks"s,
263 checkMkvTestMetaData();
266 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
268 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
274 void OverallTests::checkMkvTestfile6()
276 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
277 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromMinutes(1) + TimeSpan::fromSeconds(27) + TimeSpan::fromMilliseconds(336), m_fileInfo.duration());
278 const auto tracks = m_fileInfo.tracks();
279 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
280 for (
const auto &track : tracks) {
281 switch (track->id()) {
284 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::MicrosoftMpeg4, track->format().general);
285 CPPUNIT_ASSERT_EQUAL(
Size(854, 480), track->displaySize());
290 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
291 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint8_t
>(MpegChannelMode::Stereo), track->channelConfig());
294 CPPUNIT_FAIL(
"unknown track ID");
297 const auto tags = m_fileInfo.tags();
298 switch (m_tagStatus) {
300 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
301 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 6"s, tags.front()->value(
KnownField::Title).toString());
303 CPPUNIT_ASSERT_EQUAL(
"Matroska Validation File 6, random length to code the size of Clusters and Blocks, no Cues for seeking"s,
307 checkMkvTestMetaData();
310 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
312 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
318 void OverallTests::checkMkvTestfile7()
320 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
321 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(37) + TimeSpan::fromMilliseconds(43), m_fileInfo.duration());
322 const auto tracks = m_fileInfo.tracks();
323 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
324 for (
const auto &track : tracks) {
325 switch (track->id()) {
329 CPPUNIT_ASSERT_EQUAL(
Size(1024, 576), track->displaySize());
330 CPPUNIT_ASSERT_EQUAL(
"YUV 4:2:0"s,
string(track->chromaFormat()));
335 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
339 CPPUNIT_FAIL(
"unknown track ID");
342 const auto tags = m_fileInfo.tags();
343 switch (m_tagStatus) {
345 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
346 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 7"s, tags.front()->value(
KnownField::Title).toString());
348 CPPUNIT_ASSERT_EQUAL(
349 "Matroska Validation File 7, junk elements are present at the beggining or end of clusters, the parser should skip it. There is also a damaged element at 451418"s,
353 checkMkvTestMetaData();
356 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
359 for (
const auto &msg : m_diag) {
360 if (msg.level() != DiagLevel::Warning) {
363 CPPUNIT_ASSERT(startsWith(msg.context(),
"parsing header of EBML element 0xEA \"cue codec state\" at"));
364 CPPUNIT_ASSERT_EQUAL(
"Data of EBML element seems to be truncated; unable to parse siblings of that element."s, msg.message());
366 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Warning);
372 void OverallTests::checkMkvTestfile8()
374 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
375 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(47) + TimeSpan::fromMilliseconds(341), m_fileInfo.duration());
376 const auto tracks = m_fileInfo.tracks();
377 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
378 for (
const auto &track : tracks) {
379 switch (track->id()) {
383 CPPUNIT_ASSERT_EQUAL(
Size(1024, 576), track->displaySize());
384 CPPUNIT_ASSERT_EQUAL(
"YUV 4:2:0"s,
string(track->chromaFormat()));
389 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
393 CPPUNIT_FAIL(
"unknown track ID");
396 const auto tags = m_fileInfo.tags();
397 switch (m_tagStatus) {
399 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
400 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 8"s, tags.front()->value(
KnownField::Title).toString());
402 CPPUNIT_ASSERT_EQUAL(
403 "Matroska Validation File 8, audio missing between timecodes 6.019s and 6.360s"s, tags.front()->value(
KnownField::Comment).toString());
406 checkMkvTestMetaData();
409 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
411 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
417 void OverallTests::checkMkvTestfileHandbrakeChapters()
419 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
420 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(27) + TimeSpan::fromMilliseconds(569), m_fileInfo.duration());
421 const auto tracks = m_fileInfo.tracks();
422 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
423 for (
const auto &track : tracks) {
424 switch (track->id()) {
428 CPPUNIT_ASSERT_EQUAL(4.0, track->version());
429 CPPUNIT_ASSERT_EQUAL(
Size(1280, 544), track->pixelSize());
430 CPPUNIT_ASSERT_EQUAL(
Size(1280, 544), track->displaySize());
431 CPPUNIT_ASSERT_EQUAL(23u, track->fps());
436 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
440 CPPUNIT_FAIL(argsToString(
"unknown track ID ", track->id()));
443 const auto chapters = m_fileInfo.chapters();
444 CPPUNIT_ASSERT_EQUAL(2_st, chapters.size());
445 for (
const auto &chapter : chapters) {
446 switch (chapter->id()) {
448 CPPUNIT_ASSERT_EQUAL(
"Kapitel 01"s,
static_cast<const string &
>(chapter->names().at(0)));
449 CPPUNIT_ASSERT_EQUAL(
static_cast<std::int64_t
>(0), chapter->startTime().totalTicks());
450 CPPUNIT_ASSERT_EQUAL(15, chapter->endTime().seconds());
453 CPPUNIT_ASSERT_EQUAL(
"Kapitel 02"s,
static_cast<const string &
>(chapter->names().at(0)));
454 CPPUNIT_ASSERT_EQUAL(15, chapter->startTime().seconds());
455 CPPUNIT_ASSERT_EQUAL(27, chapter->endTime().seconds());
458 CPPUNIT_FAIL(argsToString(
"unknown chapter ID ", chapter->id()));
461 const auto tags = m_fileInfo.tags();
462 switch (m_tagStatus) {
464 CPPUNIT_ASSERT_EQUAL(2_st, tags.size());
465 CPPUNIT_ASSERT(tags[0]->target().isEmpty());
466 CPPUNIT_ASSERT_EQUAL(
""s,
static_cast<MatroskaTag *
>(tags[0])->value(
"CREATION_TIME").toString());
468 CPPUNIT_ASSERT_EQUAL(
static_cast<TagTarget::IdType>(2), tags[1]->target().tracks().at(0));
469 CPPUNIT_ASSERT_EQUAL(
"eng"s, tags[1]->value(KnownField::Language).toString());
472 checkMkvTestMetaData();
475 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
477 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
483 void OverallTests::checkMkvTestfileNestedTags()
485 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
486 const auto tags = m_fileInfo.tags();
487 bool generalTagFound =
false;
488 switch (m_tagStatus) {
491 CPPUNIT_ASSERT_EQUAL(5_st, tags.size());
492 for (
const Tag *tag : tags) {
493 CPPUNIT_ASSERT(tag->type() == TagType::MatroskaTag);
494 const auto *mkvTag =
static_cast<const MatroskaTag *
>(tag);
495 const auto &target = mkvTag->
target();
496 if (target.level() == 50 && target.tracks().empty()) {
497 generalTagFound =
true;
499 const auto &fields = mkvTag->fields();
501 CPPUNIT_ASSERT(artistField != fields.end());
502 CPPUNIT_ASSERT_EQUAL(
"Test artist"s, artistField->second.value().toString());
503 const auto &nestedFields = artistField->second.nestedFields();
504 CPPUNIT_ASSERT_EQUAL(1_st, nestedFields.size());
505 CPPUNIT_ASSERT_EQUAL(
"ADDRESS"s, nestedFields[0].idToString());
506 CPPUNIT_ASSERT_EQUAL(
"Test address"s, nestedFields[0].value().toString());
509 CPPUNIT_ASSERT(generalTagFound);
512 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
517 for (
const auto &msg : m_diag) {
518 if (msg.level() != DiagLevel::Warning) {
521 CPPUNIT_ASSERT(startsWith(msg.message(),
"\"SimpleTag\"-element contains unknown element 0x44B4 at"));
523 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Warning);
529 void OverallTests::checkMkvTestMetaData()
532 const auto tags = m_fileInfo.tags();
533 const auto tracks = m_fileInfo.tracks();
534 CPPUNIT_ASSERT_EQUAL(2_st, tags.size());
535 CPPUNIT_ASSERT_EQUAL(m_testTitle.toString(), tags.front()->value(
KnownField::Title).toString());
537 CPPUNIT_ASSERT_EQUAL(m_testComment.toString(), tags.front()->value(
KnownField::Comment).toString());
538 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(30), tags[1]->target().level());
539 CPPUNIT_ASSERT_EQUAL(tracks.at(0)->id(), tags[1]->target().tracks().at(0));
540 CPPUNIT_ASSERT_EQUAL(m_testAlbum.toString(), tags[1]->value(
KnownField::Album).toString());
541 CPPUNIT_ASSERT_EQUAL(m_testPartNumber.toInteger(), tags[1]->value(KnownField::PartNumber).toInteger());
542 CPPUNIT_ASSERT_EQUAL(m_testTotalParts.toInteger(), tags[1]->value(KnownField::TotalParts).toInteger());
545 const auto attachments = m_fileInfo.attachments();
546 CPPUNIT_ASSERT_EQUAL(1_st, attachments.size());
547 CPPUNIT_ASSERT_EQUAL(
"image/png"s, attachments[0]->mimeType());
548 CPPUNIT_ASSERT_EQUAL(
"cover.jpg"s, attachments[0]->name());
550 CPPUNIT_ASSERT(attachmentData !=
nullptr);
551 if (m_testCover.empty()) {
552 m_testCover = readFile(testFilePath(
"matroska_wave1/logo3_256x256.png"), 20000);
554 CPPUNIT_ASSERT_EQUAL(m_testCover.size(),
static_cast<size_t>(attachmentData->
size()));
555 istream &attachmentSteam = attachmentData->
stream();
556 attachmentSteam.seekg(
static_cast<std::streamoff
>(attachmentData->
startOffset()), std::ios_base::beg);
557 for (
char expectedChar : m_testCover) {
558 CPPUNIT_ASSERT_EQUAL(expectedChar,
static_cast<char>(attachmentSteam.get()));
565 void OverallTests::checkMkvConstraints()
569 CPPUNIT_ASSERT(m_fileInfo.container());
572 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(4096), m_fileInfo.paddingSize());
574 CPPUNIT_ASSERT(m_fileInfo.paddingSize() >= 1024);
575 CPPUNIT_ASSERT(m_fileInfo.paddingSize() <= (4096 + 1024));
578 CPPUNIT_ASSERT_EQUAL(m_expectedTagPos, m_fileInfo.container()->determineTagPosition(m_diag));
581 CPPUNIT_ASSERT_EQUAL(m_expectedIndexPos, m_fileInfo.container()->determineIndexPosition(m_diag));
589 void OverallTests::setMkvTestMetaData()
591 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.containerFormat());
595 const string fileName(m_fileInfo.fileName());
596 if (fileName ==
"test4.mkv") {
601 CPPUNIT_ASSERT(track);
607 }
else if (fileName ==
"handbrake-chapters-2.mkv") {
609 m_fileInfo.removeTag(m_fileInfo.tags().at(1));
611 Tag *firstTag = m_fileInfo.tags().at(0);
616 trackIds.emplace_back(m_fileInfo.tracks().at(0)->id());
617 Tag *newTag = container->createTag(
TagTarget(30, trackIds));
618 CPPUNIT_ASSERT_MESSAGE(
"create tag", newTag);
620 newTag->
setValue(KnownField::PartNumber, m_testPartNumber);
621 newTag->
setValue(KnownField::TotalParts, m_testTotalParts);
624 CPPUNIT_ASSERT_MESSAGE(
"create attachment", attachment);
625 attachment->
setFile(testFilePath(
"matroska_wave1/logo3_256x256.png"), m_diag, m_progress);
627 attachment->
setName(
"cover.jpg");
635 cerr << endl <<
"Matroska parser" << endl;
636 m_fileInfo.setForceFullParse(
false);
638 parseFile(testFilePath(
"matroska_wave1/test1.mkv"), &OverallTests::checkMkvTestfile1);
639 parseFile(testFilePath(
"matroska_wave1/test2.mkv"), &OverallTests::checkMkvTestfile2);
640 parseFile(testFilePath(
"matroska_wave1/test3.mkv"), &OverallTests::checkMkvTestfile3);
641 parseFile(testFilePath(
"matroska_wave1/test4.mkv"), &OverallTests::checkMkvTestfile4);
642 parseFile(testFilePath(
"matroska_wave1/test5.mkv"), &OverallTests::checkMkvTestfile5);
643 parseFile(testFilePath(
"matroska_wave1/test6.mkv"), &OverallTests::checkMkvTestfile6);
644 parseFile(testFilePath(
"matroska_wave1/test7.mkv"), &OverallTests::checkMkvTestfile7);
645 parseFile(testFilePath(
"matroska_wave1/test8.mkv"), &OverallTests::checkMkvTestfile8);
646 parseFile(testFilePath(
"mtx-test-data/mkv/handbrake-chapters-2.mkv"), &OverallTests::checkMkvTestfileHandbrakeChapters);
647 parseFile(testFilePath(
"mkv/nested-tags.mkv"), &OverallTests::checkMkvTestfileNestedTags);
660 m_fileInfo.setForceFullParse(
true);
663 for (m_mode = 0; m_mode != 0x100; ++m_mode) {
669 m_fileInfo.setTagPosition(ElementPosition::Keep);
671 m_fileInfo.setTagPosition(m_mode &
TagsBeforeData ? ElementPosition::BeforeData : ElementPosition::AfterData);
677 m_fileInfo.setIndexPosition(ElementPosition::Keep);
679 m_fileInfo.setIndexPosition(m_mode &
IndexBeforeData ? ElementPosition::BeforeData : ElementPosition::AfterData);
683 m_fileInfo.setMaxPadding(m_mode &
PaddingConstraints ? (4096 + 1024) : numeric_limits<size_t>::max());
684 m_fileInfo.setForceTagPosition(m_mode &
ForceTagPos);
688 list<string> testConditions;
690 testConditions.emplace_back(
"forcing rewrite");
694 testConditions.emplace_back(
"removing tag");
696 testConditions.emplace_back(
"keeping tag position");
699 testConditions.emplace_back(
"tags before data");
701 testConditions.emplace_back(
"tags after data");
704 testConditions.emplace_back(
"keeping index position");
706 testConditions.emplace_back(
"index before data");
708 testConditions.emplace_back(
"index after data");
711 testConditions.emplace_back(
"padding constraints");
714 testConditions.emplace_back(
"forcing tag position");
717 testConditions.emplace_back(
"forcing index position");
719 cerr << endl <<
"Matroska maker - testmode " << m_mode <<
": " << joinStrings(testConditions,
", ") << endl;
723 void (
OverallTests::*modifyRoutine)(void) = (m_mode &
RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setMkvTestMetaData;
724 makeFile(workingCopyPath(
"matroska_wave1/test1.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile1);
725 makeFile(workingCopyPath(
"matroska_wave1/test2.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile2);
726 makeFile(workingCopyPath(
"matroska_wave1/test3.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile3);
727 makeFile(workingCopyPath(
"matroska_wave1/test4.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile4);
728 makeFile(workingCopyPath(
"matroska_wave1/test5.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile5);
729 makeFile(workingCopyPath(
"matroska_wave1/test6.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile6);
730 makeFile(workingCopyPath(
"matroska_wave1/test7.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile7);
731 makeFile(workingCopyPath(
"matroska_wave1/test8.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile8);
732 makeFile(workingCopyPath(
"mtx-test-data/mkv/handbrake-chapters-2.mkv"), modifyRoutine, &OverallTests::checkMkvTestfileHandbrakeChapters);
742 cerr << endl <<
"Matroska maker - rewrite file with nested tags" << endl;
743 m_fileInfo.setMinPadding(0);
744 m_fileInfo.setMaxPadding(0);
745 m_fileInfo.setTagPosition(ElementPosition::BeforeData);
746 m_fileInfo.setIndexPosition(ElementPosition::BeforeData);
747 makeFile(workingCopyPath(
"mkv/nested-tags.mkv"), &OverallTests::noop, &OverallTests::checkMkvTestfileNestedTags);
The OverallTests class tests reading and writing tags and parsing technical information for all suppo...
void testMkvMakingNestedTags()
Tests making a Matroska file with nested tags via MediaFileInfo.
void testMkvParsing()
Tests the Matroska parser via MediaFileInfo.
void testMkvMakingWithDifferentSettings()
Tests the Matroska maker via MediaFileInfo.
The AbstractAttachment class parses and stores attachment information.
void setFile(std::string_view path, Diagnostics &diag, AbortableProgressFeedback &progress)
Sets the data, name and MIME-type for the specified path.
void setName(std::string_view name)
Sets the (file) name of the attachment.
void setMimeType(std::string_view mimeType)
Sets the MIME-type of the attachment.
void setEnabled(bool enabled)
Sets whether the track is enabled.
void setDefault(bool isDefault)
Sets whether the track is a default track.
void setName(std::string_view name)
Sets the name.
void setForced(bool forced)
Sets whether the track is forced.
void setLocale(const Locale &locale)
Sets the locale of the track.
Implementation of GenericContainer<MediaFileInfo, MatroskaTag, MatroskaTrack, EbmlElement>.
Implementation of TagParser::Tag for the Matroska container.
Implementation of TagParser::AbstractTrack for the Matroska container.
The Size class defines the size of a two-dimensional object using integer point precision.
The StreamDataBlock class is a reference to a certain data block of a stream.
std::uint64_t startOffset() const
Returns the absolute start offset of the data block in the stream.
std::uint64_t size() const
Returns the size of the data block.
std::istream & stream() const
Returns the associated stream.
The TagTarget class specifies the target of a tag.
std::vector< IdType > IdContainerType
The TagValue class wraps values of different types.
The Tag class is used to store, read and write tag information.
const TagTarget & target() const
Returns the target of tag.
virtual bool setValue(KnownField field, const TagValue &value)=0
Assigns the given value to the specified field.
The Locale struct specifies a language and/or a country using one or more LocaleDetail objects.