1#include <c++utilities/chrono/format.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>
37void OverallTests::checkMkvTestfile1()
39 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
40 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromMinutes(1.0) + TimeSpan::fromSeconds(27.0) + TimeSpan::fromMilliseconds(336.0), 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()) {
46 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
47 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::MicrosoftMpeg4, track->format().general);
48 CPPUNIT_ASSERT(track->isEnabled());
49 CPPUNIT_ASSERT(!track->isForced());
50 CPPUNIT_ASSERT(track->isDefault());
53 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
54 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Mpeg1Audio, track->format().general);
55 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
56 CPPUNIT_ASSERT(track->isEnabled());
57 CPPUNIT_ASSERT(!track->isForced());
58 CPPUNIT_ASSERT(track->isDefault());
61 CPPUNIT_FAIL(
"unknown track ID");
64 const auto tags = m_fileInfo.
tags();
65 switch (m_tagStatus) {
67 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
68 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 1"s, tags.front()->value(KnownField::Title).toString());
69 CPPUNIT_ASSERT_EQUAL(
TagValue(), tags.front()->value(KnownField::Artist));
71 "Matroska Validation File1, basic MPEG4.2 and MP3 with only SimpleBlock"s, tags.front()->value(KnownField::Comment).toString());
72 CPPUNIT_ASSERT_EQUAL(
"2010"s, tags.front()->value(KnownField::ReleaseDate).toString());
75 checkMkvTestMetaData();
78 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
80 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
86void OverallTests::checkMkvTestfile2()
88 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
89 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(47.0) + TimeSpan::fromMilliseconds(509.0), m_fileInfo.
duration());
90 const auto tracks = m_fileInfo.
tracks();
91 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
92 for (
const auto &track : tracks) {
93 switch (track->id()) {
95 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
96 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
97 CPPUNIT_ASSERT_EQUAL(
Size(1354, 576), track->displaySize());
98 CPPUNIT_ASSERT(track->isEnabled());
99 CPPUNIT_ASSERT(!track->isForced());
100 CPPUNIT_ASSERT(track->isDefault());
103 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
104 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
105 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
106 CPPUNIT_ASSERT(track->isEnabled());
107 CPPUNIT_ASSERT(!track->isForced());
108 CPPUNIT_ASSERT(track->isDefault());
111 CPPUNIT_FAIL(
"unknown track ID");
114 const auto tags = m_fileInfo.
tags();
115 switch (m_tagStatus) {
117 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
118 CPPUNIT_ASSERT_EQUAL(
"Elephant Dream - test 2"s, tags.front()->value(KnownField::Title).toString());
119 CPPUNIT_ASSERT_EQUAL(
TagValue(), tags.front()->value(KnownField::Artist));
120 CPPUNIT_ASSERT_EQUAL(
"Matroska Validation File 2, 100,000 timecode scale, odd aspect ratio, and CRC-32. Codecs are AVC and AAC"s,
121 tags.front()->value(KnownField::Comment).toString());
124 checkMkvTestMetaData();
127 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
129 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
135void OverallTests::checkMkvTestfile3()
137 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
138 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(49.0) + TimeSpan::fromMilliseconds(64.0), m_fileInfo.
duration());
139 const auto tracks = m_fileInfo.
tracks();
140 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
141 for (
const auto &track : tracks) {
142 switch (track->id()) {
144 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
145 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
146 CPPUNIT_ASSERT_EQUAL(
Size(1024, 576), track->displaySize());
147 CPPUNIT_ASSERT(track->isEnabled());
148 CPPUNIT_ASSERT(!track->isForced());
149 CPPUNIT_ASSERT(track->isDefault());
152 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
153 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Mpeg1Audio, track->format().general);
154 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
155 CPPUNIT_ASSERT(track->isEnabled());
156 CPPUNIT_ASSERT(!track->isForced());
157 CPPUNIT_ASSERT(track->isDefault());
160 CPPUNIT_FAIL(
"unknown track ID");
163 const auto tags = m_fileInfo.
tags();
164 switch (m_tagStatus) {
166 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
167 CPPUNIT_ASSERT_EQUAL(
"Elephant Dream - test 3"s, tags.front()->value(KnownField::Title).toString());
168 CPPUNIT_ASSERT_EQUAL(
TagValue(), tags.front()->value(KnownField::Artist));
169 CPPUNIT_ASSERT_EQUAL(
"Matroska Validation File 3, header stripping on the video track and no SimpleBlock"s,
170 tags.front()->value(KnownField::Comment).toString());
173 checkMkvTestMetaData();
176 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
178 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
185void OverallTests::checkMkvTestfile4()
187 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
190 const auto tracks = m_fileInfo.
tracks();
191 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
192 for (
const auto &track : tracks) {
193 switch (track->id()) {
195 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
196 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Theora, track->format().general);
197 CPPUNIT_ASSERT_EQUAL(
Size(1280, 720), track->displaySize());
200 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
201 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Vorbis, track->format().general);
202 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
203 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2u), track->channelCount());
204 switch (m_tagStatus) {
207 CPPUNIT_ASSERT_EQUAL(
Locale(
"und"sv, LocaleFormat::ISO_639_2_B), track->locale());
208 CPPUNIT_ASSERT_EQUAL(
string(), track->name());
209 CPPUNIT_ASSERT(track->isEnabled());
210 CPPUNIT_ASSERT(!track->isForced());
211 CPPUNIT_ASSERT(track->isDefault());
214 CPPUNIT_ASSERT_EQUAL(
Locale(
"ger"sv, LocaleFormat::ISO_639_2_B), track->locale());
215 CPPUNIT_ASSERT_EQUAL(
"the name"s, track->name());
216 CPPUNIT_ASSERT(track->isEnabled());
217 CPPUNIT_ASSERT(track->isForced());
218 CPPUNIT_ASSERT(!track->isDefault());
223 CPPUNIT_FAIL(
"unknown track ID");
226 const auto tags = m_fileInfo.
tags();
227 switch (m_tagStatus) {
230 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
233 checkMkvTestMetaData();
238 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Critical);
244void OverallTests::checkMkvTestfile5()
246 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
247 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(46.0) + TimeSpan::fromMilliseconds(665.0), m_fileInfo.
duration());
248 const auto tracks = m_fileInfo.
tracks();
249 CPPUNIT_ASSERT_EQUAL(11_st, tracks.size());
250 for (
const auto &track : tracks) {
251 switch (track->id()) {
253 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
254 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
255 CPPUNIT_ASSERT_EQUAL(
Size(1024, 576), track->displaySize());
256 CPPUNIT_ASSERT_EQUAL(
true, track->isDefault());
257 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
258 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
261 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
262 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
263 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
265 CPPUNIT_ASSERT_EQUAL(
true, track->isDefault());
266 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
267 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
270 CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
271 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TextSubtitle, track->format().general);
272 CPPUNIT_ASSERT_EQUAL(
Locale(
"ger"sv, LocaleFormat::ISO_639_2_B), track->locale());
277 const auto tags = m_fileInfo.
tags();
278 switch (m_tagStatus) {
280 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
281 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 8"s, tags.front()->value(KnownField::Title).toString());
282 CPPUNIT_ASSERT_EQUAL(
TagValue(), tags.front()->value(KnownField::Artist));
283 CPPUNIT_ASSERT_EQUAL(
"Matroska Validation File 8, secondary audio commentary track, misc subtitle tracks"s,
284 tags.front()->value(KnownField::Comment).toString());
287 checkMkvTestMetaData();
290 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
292 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
298void OverallTests::checkMkvTestfile6()
300 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
301 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromMinutes(1.0) + TimeSpan::fromSeconds(27.0) + TimeSpan::fromMilliseconds(336.0), m_fileInfo.
duration());
302 const auto tracks = m_fileInfo.
tracks();
303 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
304 for (
const auto &track : tracks) {
305 switch (track->id()) {
307 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
308 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::MicrosoftMpeg4, track->format().general);
309 CPPUNIT_ASSERT_EQUAL(
Size(854, 480), track->displaySize());
310 CPPUNIT_ASSERT_EQUAL(
false, track->isDefault());
311 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
312 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
315 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
316 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Mpeg1Audio, track->format().general);
317 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
318 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint8_t
>(MpegChannelMode::Stereo), track->channelConfig());
319 CPPUNIT_ASSERT_EQUAL(
false, track->isDefault());
320 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
321 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
324 CPPUNIT_FAIL(
"unknown track ID");
327 const auto tags = m_fileInfo.
tags();
328 switch (m_tagStatus) {
330 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
331 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 6"s, tags.front()->value(KnownField::Title).toString());
332 CPPUNIT_ASSERT_EQUAL(
TagValue(), tags.front()->value(KnownField::Artist));
333 CPPUNIT_ASSERT_EQUAL(
"Matroska Validation File 6, random length to code the size of Clusters and Blocks, no Cues for seeking"s,
334 tags.front()->value(KnownField::Comment).toString());
337 checkMkvTestMetaData();
340 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
342 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
348void OverallTests::checkMkvTestfile7()
350 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
351 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(37.0) + TimeSpan::fromMilliseconds(43.0), m_fileInfo.
duration());
352 const auto tracks = m_fileInfo.
tracks();
353 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
354 for (
const auto &track : tracks) {
355 switch (track->id()) {
357 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
358 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
359 CPPUNIT_ASSERT_EQUAL(
Size(1024, 576), track->displaySize());
360 CPPUNIT_ASSERT_EQUAL(
"YUV 4:2:0"s,
string(track->chromaFormat()));
361 CPPUNIT_ASSERT_EQUAL(
false, track->isDefault());
362 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
363 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
366 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
367 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
368 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
370 CPPUNIT_ASSERT_EQUAL(
false, track->isDefault());
371 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
372 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
375 CPPUNIT_FAIL(
"unknown track ID");
378 const auto tags = m_fileInfo.
tags();
379 switch (m_tagStatus) {
381 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
382 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 7"s, tags.front()->value(KnownField::Title).toString());
383 CPPUNIT_ASSERT_EQUAL(
TagValue(), tags.front()->value(KnownField::Artist));
384 CPPUNIT_ASSERT_EQUAL(
385 "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,
386 tags.front()->value(KnownField::Comment).toString());
389 checkMkvTestMetaData();
392 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
395 for (
const auto &msg : m_diag) {
396 if (msg.level() != DiagLevel::Warning) {
399 CPPUNIT_ASSERT(startsWith(msg.context(),
"parsing header of EBML element 0xEA \"cue codec state\" at"));
400 CPPUNIT_ASSERT_EQUAL(
"Data of EBML element seems to be truncated; unable to parse siblings of that element."s, msg.message());
402 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Warning);
408void OverallTests::checkMkvTestfile8()
410 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
411 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(47.0) + TimeSpan::fromMilliseconds(341.0), m_fileInfo.
duration());
412 const auto tracks = m_fileInfo.
tracks();
413 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
414 for (
const auto &track : tracks) {
415 switch (track->id()) {
417 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
418 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
419 CPPUNIT_ASSERT_EQUAL(
Size(1024, 576), track->displaySize());
420 CPPUNIT_ASSERT_EQUAL(
"YUV 4:2:0"s,
string(track->chromaFormat()));
421 CPPUNIT_ASSERT_EQUAL(
false, track->isDefault());
422 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
423 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
426 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
427 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
428 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
430 CPPUNIT_ASSERT_EQUAL(
false, track->isDefault());
431 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
432 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
435 CPPUNIT_FAIL(
"unknown track ID");
438 const auto tags = m_fileInfo.
tags();
439 switch (m_tagStatus) {
441 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
442 CPPUNIT_ASSERT_EQUAL(
"Big Buck Bunny - test 8"s, tags.front()->value(KnownField::Title).toString());
443 CPPUNIT_ASSERT_EQUAL(
TagValue(), tags.front()->value(KnownField::Artist));
444 CPPUNIT_ASSERT_EQUAL(
445 "Matroska Validation File 8, audio missing between timecodes 6.019s and 6.360s"s, tags.front()->value(KnownField::Comment).toString());
448 checkMkvTestMetaData();
451 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
453 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
459void OverallTests::checkMkvTestfileHandbrakeChapters()
461 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
462 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(27.0) + TimeSpan::fromMilliseconds(569.0), m_fileInfo.
duration());
463 const auto tracks = m_fileInfo.
tracks();
464 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
465 for (
const auto &track : tracks) {
466 switch (track->id()) {
468 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
469 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
470 CPPUNIT_ASSERT_EQUAL(4.0, track->version());
471 CPPUNIT_ASSERT_EQUAL(
Size(1280, 544), track->pixelSize());
472 CPPUNIT_ASSERT_EQUAL(
Size(1280, 544), track->displaySize());
473 CPPUNIT_ASSERT_EQUAL(23u, track->fps());
474 CPPUNIT_ASSERT_EQUAL(
true, track->isDefault());
475 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
476 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
479 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
480 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
481 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
483 CPPUNIT_ASSERT_EQUAL(
true, track->isDefault());
484 CPPUNIT_ASSERT_EQUAL(
true, track->isEnabled());
485 CPPUNIT_ASSERT_EQUAL(
false, track->isForced());
488 CPPUNIT_FAIL(argsToString(
"unknown track ID ", track->id()));
491 const auto chapters = m_fileInfo.
chapters();
492 CPPUNIT_ASSERT_EQUAL(2_st, chapters.size());
493 for (
const auto &chapter : chapters) {
494 switch (chapter->id()) {
496 CPPUNIT_ASSERT_EQUAL(
"Kapitel 01"s,
static_cast<const string &
>(chapter->names().at(0)));
497 CPPUNIT_ASSERT_EQUAL(
static_cast<std::int64_t
>(0), chapter->startTime().totalTicks());
498 CPPUNIT_ASSERT_EQUAL(15, chapter->endTime().seconds());
501 CPPUNIT_ASSERT_EQUAL(
"Kapitel 02"s,
static_cast<const string &
>(chapter->names().at(0)));
502 CPPUNIT_ASSERT_EQUAL(15, chapter->startTime().seconds());
503 CPPUNIT_ASSERT_EQUAL(27, chapter->endTime().seconds());
506 CPPUNIT_FAIL(argsToString(
"unknown chapter ID ", chapter->id()));
509 const auto tags = m_fileInfo.
tags();
510 switch (m_tagStatus) {
512 CPPUNIT_ASSERT_EQUAL(2_st, tags.size());
513 CPPUNIT_ASSERT(tags[0]->target().isEmpty());
514 CPPUNIT_ASSERT_EQUAL(
""s,
static_cast<MatroskaTag *
>(tags[0])->value(
"CREATION_TIME").toString());
515 CPPUNIT_ASSERT_EQUAL(
"Lavf55.12.0"s, tags[0]->value(KnownField::Encoder).toString());
516 CPPUNIT_ASSERT_EQUAL(
static_cast<TagTarget::IdType>(2), tags[1]->target().tracks().at(0));
517 CPPUNIT_ASSERT_EQUAL(
"eng"s, tags[1]->value(KnownField::Language).toString());
520 checkMkvTestMetaData();
523 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
525 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
531void OverallTests::checkMkvTestfileNestedTags()
533 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
534 const auto tags = m_fileInfo.
tags();
535 bool generalTagFound =
false;
536 switch (m_tagStatus) {
539 CPPUNIT_ASSERT_EQUAL(5_st, tags.size());
540 for (
const Tag *tag : tags) {
541 CPPUNIT_ASSERT(tag->type() == TagType::MatroskaTag);
542 const auto *mkvTag =
static_cast<const MatroskaTag *
>(tag);
543 const auto &target = mkvTag->
target();
544 if (target.level() == 50 && target.tracks().empty()) {
545 generalTagFound =
true;
546 CPPUNIT_ASSERT_EQUAL(
"Vanilla Sky"s, tag->value(KnownField::Title).toString());
547 const auto &fields = mkvTag->fields();
548 const auto &artistField = fields.find(mkvTag->fieldId(KnownField::Artist));
549 CPPUNIT_ASSERT(artistField != fields.end());
550 CPPUNIT_ASSERT_EQUAL(
"Test artist"s, artistField->second.value().toString());
551 const auto &nestedFields = artistField->second.nestedFields();
552 CPPUNIT_ASSERT_EQUAL(1_st, nestedFields.size());
553 CPPUNIT_ASSERT_EQUAL(
"ADDRESS"s, nestedFields[0].idToString());
554 CPPUNIT_ASSERT_EQUAL(
"Test address"s, nestedFields[0].value().toString());
557 CPPUNIT_ASSERT(generalTagFound);
560 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
565 for (
const auto &msg : m_diag) {
566 if (msg.level() != DiagLevel::Warning) {
569 CPPUNIT_ASSERT(startsWith(msg.message(),
"\"SimpleTag\"-element contains unknown element 0x44B4 at"));
571 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Warning);
577void OverallTests::checkMkvTestMetaData()
580 const auto tags = m_fileInfo.
tags();
581 const auto tracks = m_fileInfo.
tracks();
582 CPPUNIT_ASSERT_EQUAL(2_st, tags.size());
583 CPPUNIT_ASSERT_EQUAL(m_testTitle.
toString(), tags.front()->value(KnownField::Title).toString());
584 CPPUNIT_ASSERT(tags.front()->value(KnownField::Artist).isEmpty());
585 CPPUNIT_ASSERT_EQUAL(m_testComment.
toString(), tags.front()->value(KnownField::Comment).toString());
586 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(30), tags[1]->target().level());
587 CPPUNIT_ASSERT_EQUAL(tracks.at(0)->id(), tags[1]->target().tracks().at(0));
588 CPPUNIT_ASSERT_EQUAL(m_testAlbum.
toString(), tags[1]->value(KnownField::Album).toString());
589 CPPUNIT_ASSERT_EQUAL(m_testPartNumber.
toInteger(), tags[1]->value(KnownField::PartNumber).toInteger());
590 CPPUNIT_ASSERT_EQUAL(m_testTotalParts.
toInteger(), tags[1]->value(KnownField::TotalParts).toInteger());
594 CPPUNIT_ASSERT_EQUAL(1_st, attachments.size());
595 CPPUNIT_ASSERT_EQUAL(
"image/png"s, attachments[0]->mimeType());
596 CPPUNIT_ASSERT_EQUAL(
"cover.jpg"s, attachments[0]->name());
598 CPPUNIT_ASSERT(attachmentData !=
nullptr);
599 if (m_testCover.empty()) {
600 m_testCover = readFile(testFilePath(
"matroska_wave1/logo3_256x256.png"), 20000);
602 CPPUNIT_ASSERT_EQUAL(m_testCover.size(),
static_cast<size_t>(attachmentData->
size()));
603 istream &attachmentSteam = attachmentData->
stream();
604 attachmentSteam.seekg(
static_cast<std::streamoff
>(attachmentData->
startOffset()), std::ios_base::beg);
605 for (
char expectedChar : m_testCover) {
606 CPPUNIT_ASSERT_EQUAL(expectedChar,
static_cast<char>(attachmentSteam.get()));
613void OverallTests::checkMkvConstraints()
618 if (m_mode & PaddingConstraints) {
619 if (m_mode & ForceRewring) {
620 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(4096), m_fileInfo.
paddingSize());
623 CPPUNIT_ASSERT(m_fileInfo.
paddingSize() <= (4096 + 1024));
625 if (!(m_mode & RemoveTag) && (m_expectedTagPos != ElementPosition::Keep) && ((m_mode & ForceRewring) || (m_mode & ForceTagPos))) {
628 if ((m_expectedIndexPos != ElementPosition::Keep) && ((m_mode & ForceRewring) || (m_mode & ForceIndexPos))) {
637void OverallTests::setMkvTestMetaData()
639 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Matroska, m_fileInfo.
containerFormat());
643 const string fileName(m_fileInfo.
fileName());
644 if (fileName ==
"test4.mkv") {
649 CPPUNIT_ASSERT(track);
655 }
else if (fileName ==
"handbrake-chapters-2.mkv") {
659 Tag *firstTag = m_fileInfo.
tags().at(0);
660 firstTag->
setValue(KnownField::Title, m_testTitle);
661 firstTag->
setValue(KnownField::Comment, m_testComment);
664 trackIds.emplace_back(m_fileInfo.
tracks().at(0)->id());
665 Tag *newTag = container->createTag(
TagTarget(30, trackIds));
666 CPPUNIT_ASSERT_MESSAGE(
"create tag", newTag);
667 newTag->
setValue(KnownField::Album, m_testAlbum);
668 newTag->
setValue(KnownField::PartNumber, m_testPartNumber);
669 newTag->
setValue(KnownField::TotalParts, m_testTotalParts);
672 CPPUNIT_ASSERT_MESSAGE(
"create attachment", attachment);
673 attachment->
setFile(testFilePath(
"matroska_wave1/logo3_256x256.png"), m_diag, m_progress);
675 attachment->
setName(
"cover.jpg");
683 cerr << endl <<
"Matroska parser" << endl;
686 parseFile(testFilePath(
"matroska_wave1/test1.mkv"), &OverallTests::checkMkvTestfile1);
687 parseFile(testFilePath(
"matroska_wave1/test2.mkv"), &OverallTests::checkMkvTestfile2);
688 parseFile(testFilePath(
"matroska_wave1/test3.mkv"), &OverallTests::checkMkvTestfile3);
689 parseFile(testFilePath(
"matroska_wave1/test4.mkv"), &OverallTests::checkMkvTestfile4);
690 parseFile(testFilePath(
"matroska_wave1/test5.mkv"), &OverallTests::checkMkvTestfile5);
691 parseFile(testFilePath(
"matroska_wave1/test6.mkv"), &OverallTests::checkMkvTestfile6);
692 parseFile(testFilePath(
"matroska_wave1/test7.mkv"), &OverallTests::checkMkvTestfile7);
693 parseFile(testFilePath(
"matroska_wave1/test8.mkv"), &OverallTests::checkMkvTestfile8);
694 parseFile(testFilePath(
"mtx-test-data/mkv/handbrake-chapters-2.mkv"), &OverallTests::checkMkvTestfileHandbrakeChapters);
695 parseFile(testFilePath(
"mkv/nested-tags.mkv"), &OverallTests::checkMkvTestfileNestedTags);
711 for (m_mode = 0; m_mode != 0x100; ++m_mode) {
716 if (m_mode & KeepTagPos) {
719 m_fileInfo.
setTagPosition(m_mode & TagsBeforeData ? ElementPosition::BeforeData : ElementPosition::AfterData);
721 if (m_mode & KeepIndexPos) {
722 if (m_mode & IndexBeforeData) {
727 m_fileInfo.
setIndexPosition(m_mode & IndexBeforeData ? ElementPosition::BeforeData : ElementPosition::AfterData);
730 m_fileInfo.
setMinPadding(m_mode & PaddingConstraints ? 1024 : 0);
731 m_fileInfo.
setMaxPadding(m_mode & PaddingConstraints ? (4096 + 1024) : numeric_limits<size_t>::max());
736 list<string> testConditions;
737 if (m_mode & ForceRewring) {
738 testConditions.emplace_back(
"forcing rewrite");
740 if (m_mode & KeepTagPos) {
741 if (m_mode & RemoveTag) {
742 testConditions.emplace_back(
"removing tag");
744 testConditions.emplace_back(
"keeping tag position");
746 }
else if (m_mode & TagsBeforeData) {
747 testConditions.emplace_back(
"tags before data");
749 testConditions.emplace_back(
"tags after data");
751 if (m_mode & KeepIndexPos) {
752 testConditions.emplace_back(
"keeping index position");
753 }
else if (m_mode & IndexBeforeData) {
754 testConditions.emplace_back(
"index before data");
756 testConditions.emplace_back(
"index after data");
758 if (m_mode & PaddingConstraints) {
759 testConditions.emplace_back(
"padding constraints");
761 if (m_mode & ForceTagPos) {
762 testConditions.emplace_back(
"forcing tag position");
764 if (m_mode & ForceIndexPos) {
765 testConditions.emplace_back(
"forcing index position");
767 cerr << endl <<
"Matroska maker - testmode " << m_mode <<
": " << joinStrings(testConditions,
", ") << endl;
771 void (
OverallTests::*modifyRoutine)(void) = (m_mode & RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setMkvTestMetaData;
772 makeFile(workingCopyPath(
"matroska_wave1/test1.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile1);
773 makeFile(workingCopyPath(
"matroska_wave1/test2.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile2);
774 makeFile(workingCopyPath(
"matroska_wave1/test3.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile3);
775 makeFile(workingCopyPath(
"matroska_wave1/test4.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile4);
776 makeFile(workingCopyPath(
"matroska_wave1/test5.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile5);
777 makeFile(workingCopyPath(
"matroska_wave1/test6.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile6);
778 makeFile(workingCopyPath(
"matroska_wave1/test7.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile7);
779 makeFile(workingCopyPath(
"matroska_wave1/test8.mkv"), modifyRoutine, &OverallTests::checkMkvTestfile8);
780 makeFile(workingCopyPath(
"mtx-test-data/mkv/handbrake-chapters-2.mkv"), modifyRoutine, &OverallTests::checkMkvTestfileHandbrakeChapters);
790 cerr << endl <<
"Matroska maker - rewrite file with nested tags" << endl;
795 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.
virtual ElementPosition determineTagPosition(Diagnostics &diag) const
Determines the position of the tags inside the file.
virtual ElementPosition determineIndexPosition(Diagnostics &diag) const
Determines the position of the index.
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.
static std::string fileName(std::string_view path, bool cutExtension=false)
Returns the file name of the given file.
DiagLevel level() const
Returns the worst diag level present in the container.
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.
std::int32_t toInteger() const
Converts the value of the current TagValue object to its equivalent integer representation.
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
The Tag class is used to store, read and write tag information.
virtual bool setValue(KnownField field, const TagValue &value)=0
Assigns the given value to the specified field.
const TagTarget & target() const
The Locale struct specifies a language and/or a country using one or more LocaleDetail objects.