4#include "../abstracttrack.h"
5#include "../mp4/mp4container.h"
6#include "../mp4/mp4ids.h"
7#include "../mp4/mp4tag.h"
25void OverallTests::checkMp4Testfile1()
27 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.
containerFormat());
28 const auto tracks = m_fileInfo.
tracks();
29 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
30 for (
const auto &track : tracks) {
31 switch (track->id()) {
33 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
34 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
35 CPPUNIT_ASSERT_EQUAL(2012, track->creationTime().year());
36 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
40 CPPUNIT_FAIL(
"unknown track ID");
43 const auto tags = m_fileInfo.
tags();
44 switch (m_tagStatus) {
46 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
47 CPPUNIT_ASSERT_EQUAL(
"Danse Macabre, Op.40"s, tags.front()->value(KnownField::Title).toString());
48 CPPUNIT_ASSERT_EQUAL(
"Saint-Saƫns"s, tags.front()->value(KnownField::Artist).toString());
49 CPPUNIT_ASSERT_EQUAL(
"Classical"s, tags.front()->value(KnownField::Genre).toString());
51 "qaac 1.32, CoreAudioToolbox 7.9.7.3, AAC-LC Encoder, TVBR q63, Quality 96"s, tags.front()->value(KnownField::Encoder).toString());
52 CPPUNIT_ASSERT_EQUAL(10, tags.front()->value(KnownField::TrackPosition).toPositionInSet().position());
55 checkMp4TestMetaData();
58 CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
60 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
66void OverallTests::checkMp4Testfile2()
68 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.
containerFormat());
69 const auto tracks = m_fileInfo.
tracks();
70 CPPUNIT_ASSERT_EQUAL(5_st, tracks.size());
71 for (
const auto &track : tracks) {
72 switch (track->id()) {
74 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
75 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
77 CPPUNIT_ASSERT_EQUAL(4.0, track->version());
78 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
79 CPPUNIT_ASSERT(track->pixelSize() ==
Size(1920, 750));
82 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
83 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
87 CPPUNIT_ASSERT_EQUAL(
Locale(
"eng"sv, LocaleFormat::ISO_639_2_T), track->locale());
88 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
89 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
93 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
94 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Ac3, track->format().general);
95 CPPUNIT_ASSERT_EQUAL(
Locale(
"eng"sv, LocaleFormat::ISO_639_2_T), track->locale());
96 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
99 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
100 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general);
101 CPPUNIT_ASSERT_EQUAL(
Locale(
"eng"sv, LocaleFormat::ISO_639_2_T), track->locale());
102 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
105 CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
106 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general);
107 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
110 CPPUNIT_FAIL(
"unknown track ID");
113 const auto tags = m_fileInfo.
tags();
114 switch (m_tagStatus) {
116 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
119 checkMp4TestMetaData();
122 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
124 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
130void OverallTests::checkMp4Testfile3()
132 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.
containerFormat());
133 CPPUNIT_ASSERT(m_fileInfo.
container() !=
nullptr);
135 const auto tracks = m_fileInfo.
tracks();
136 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
137 for (
const auto &track : tracks) {
138 switch (track->id()) {
140 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
141 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
143 CPPUNIT_ASSERT_EQUAL(3.1, track->version());
144 CPPUNIT_ASSERT_EQUAL(2014, track->creationTime().year());
145 CPPUNIT_ASSERT_EQUAL(
Size(854, 480), track->pixelSize());
146 CPPUNIT_ASSERT_EQUAL(
"YUV 4:2:0"s,
string(track->chromaFormat()));
149 CPPUNIT_FAIL(
"unknown track ID");
152 const auto tags = m_fileInfo.
tags();
153 switch (m_tagStatus) {
155 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
158 checkMp4TestMetaData();
161 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
164 for (
const auto &msg : m_diag) {
165 if (msg.level() != DiagLevel::Warning) {
169 CPPUNIT_FAIL(
"No warnings expected when putting tags before data.");
171 CPPUNIT_ASSERT_EQUAL(
"Sorry, but putting index/tags at the end is not possible when dealing with DASH files."s, msg.message());
174 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Warning);
180void OverallTests::checkMp4Testfile4()
182 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.
containerFormat());
183 CPPUNIT_ASSERT(m_fileInfo.
container() !=
nullptr);
185 const auto tracks = m_fileInfo.
tracks();
186 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
187 for (
const auto &track : tracks) {
188 switch (track->id()) {
190 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
191 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Alac, track->format().general);
192 CPPUNIT_ASSERT_EQUAL(2008, track->creationTime().year());
193 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2), track->channelCount());
194 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(16), track->bitsPerSample());
197 CPPUNIT_FAIL(
"unknown track ID");
200 const auto tags = m_fileInfo.
tags();
201 switch (m_tagStatus) {
203 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
204 CPPUNIT_ASSERT_EQUAL(
"Sad Song"s, tags.front()->value(KnownField::Title).toString());
205 CPPUNIT_ASSERT_EQUAL(
"Oasis"s, tags.front()->value(KnownField::Artist).toString());
206 CPPUNIT_ASSERT_EQUAL(
"Don't Go Away (Apple Lossless)"s, tags.front()->value(KnownField::Album).toString());
207 CPPUNIT_ASSERT_EQUAL(
"Alternative & Punk"s, tags.front()->value(KnownField::Genre).toString());
208 CPPUNIT_ASSERT_EQUAL(
"iTunes v7.5.0.20"s, tags.front()->value(KnownField::Encoder).toString());
209 CPPUNIT_ASSERT_EQUAL(
"1998"s, tags.front()->value(KnownField::RecordDate).toString());
210 CPPUNIT_ASSERT(tags.front()->value(KnownField::Comment).isEmpty());
211 CPPUNIT_ASSERT_EQUAL(0x58f3_st, tags.front()->value(KnownField::Cover).dataSize());
212 CPPUNIT_ASSERT_EQUAL(0xFFD8FFE000104A46ul, BE::toInt<std::uint64_t>(tags.front()->value(KnownField::Cover).dataPointer()));
213 CPPUNIT_ASSERT_EQUAL(
PositionInSet(3, 4), tags.front()->value(KnownField::TrackPosition).toPositionInSet());
214 CPPUNIT_ASSERT_EQUAL(
PositionInSet(1, 1), tags.front()->value(KnownField::DiskPosition).toPositionInSet());
217 checkMp4TestMetaData();
220 CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
222 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
228void OverallTests::checkMp4Testfile5()
230 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.
containerFormat());
231 CPPUNIT_ASSERT(m_fileInfo.
container() !=
nullptr);
233 const auto tracks = m_fileInfo.
tracks();
234 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
235 for (
const auto &track : tracks) {
236 switch (track->id()) {
238 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
239 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
243 CPPUNIT_ASSERT_EQUAL(2014, track->creationTime().year());
244 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2), track->channelCount());
247 CPPUNIT_ASSERT_EQUAL(24000u, track->samplingFrequency());
248 CPPUNIT_ASSERT_EQUAL(48000u, track->extensionSamplingFrequency());
249 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(16), track->bitsPerSample());
252 CPPUNIT_FAIL(
"unknown track ID");
255 const auto tags = m_fileInfo.
tags();
256 switch (m_tagStatus) {
258 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
261 checkMp4TestMetaData();
264 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
266 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
272void OverallTests::checkMp4Testfile6()
274 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.
containerFormat());
275 const auto tracks = m_fileInfo.
tracks();
277 CPPUNIT_ASSERT_EQUAL(4_st, tracks.size());
279 CPPUNIT_ASSERT_EQUAL(6_st, tracks.size());
281 bool track2Present =
false, track5Present =
false;
282 for (
const auto &track : tracks) {
283 switch (track->id()) {
285 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
286 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
288 CPPUNIT_ASSERT_EQUAL(4.0, track->version());
289 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
290 CPPUNIT_ASSERT_EQUAL(
Size(1920, 750), track->pixelSize());
293 CPPUNIT_ASSERT(track2Present = !track2Present);
294 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
295 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
299 CPPUNIT_ASSERT_EQUAL(
Locale(
"ger"sv, LocaleFormat::ISO_639_2_T), track->locale());
300 CPPUNIT_ASSERT_EQUAL(
"test"s, track->name());
301 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
302 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
306 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
307 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Ac3, track->format().general);
308 CPPUNIT_ASSERT_EQUAL(
Locale(
"eng"sv, LocaleFormat::ISO_639_2_T), track->locale());
309 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
312 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
313 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general);
314 CPPUNIT_ASSERT_EQUAL(
Locale(
"eng"sv, LocaleFormat::ISO_639_2_T), track->locale());
315 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
318 CPPUNIT_ASSERT(track5Present = !track5Present);
319 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
320 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
321 CPPUNIT_ASSERT_EQUAL(2012, track->creationTime().year());
322 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
324 CPPUNIT_ASSERT_EQUAL(
"new track"s, track->name());
327 CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
328 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general);
329 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
332 CPPUNIT_FAIL(
"unknown track ID");
336 CPPUNIT_ASSERT(!track2Present);
337 CPPUNIT_ASSERT(!track5Present);
339 CPPUNIT_ASSERT(track2Present);
340 CPPUNIT_ASSERT(track5Present);
343 CPPUNIT_ASSERT_EQUAL(0_st, m_fileInfo.
tags().size());
344 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
350void OverallTests::checkMp4Testfile7()
352 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.
containerFormat());
353 CPPUNIT_ASSERT(m_fileInfo.
container() !=
nullptr);
355 const auto tracks = m_fileInfo.
tracks();
356 CPPUNIT_ASSERT_EQUAL(3_st, tracks.size());
357 for (
const auto &track : tracks) {
358 switch (track->id()) {
360 CPPUNIT_ASSERT_EQUAL(
"VideoHandle"s, track->name());
361 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
362 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
364 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned char>(0), track->format().extension);
365 CPPUNIT_ASSERT_EQUAL(4.0, track->version());
366 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(0), track->channelCount());
367 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint8_t
>(0), track->channelConfig());
368 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint8_t
>(0), track->extensionChannelConfig());
369 CPPUNIT_ASSERT_EQUAL(0u, track->samplingFrequency());
370 CPPUNIT_ASSERT_EQUAL(0u, track->extensionSamplingFrequency());
371 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(24), track->depth());
372 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(51), track->sampleCount());
373 CPPUNIT_ASSERT_EQUAL(1920u, track->pixelSize().width());
374 CPPUNIT_ASSERT_EQUAL(1080u, track->pixelSize().height());
375 CPPUNIT_ASSERT_EQUAL(72u, track->resolution().width());
376 CPPUNIT_ASSERT_EQUAL(72u, track->resolution().height());
377 CPPUNIT_ASSERT_EQUAL(DateTime::fromDateAndTime(2018, 7, 8, 20, 3, 52), track->creationTime());
378 CPPUNIT_ASSERT_EQUAL(DateTime::fromDateAndTime(2018, 7, 8, 20, 3, 52), track->modificationTime());
379 CPPUNIT_ASSERT_EQUAL(
"YUV 4:2:0"s,
string(track->chromaFormat()));
380 CPPUNIT_ASSERT_EQUAL(1, track->duration().seconds());
383 CPPUNIT_ASSERT_EQUAL(
"SoundHandle"s, track->name());
384 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
385 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
387 CPPUNIT_ASSERT_EQUAL(
static_cast<unsigned char>(0), track->format().extension);
388 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2), track->channelCount());
390 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint8_t
>(0), track->extensionChannelConfig());
391 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
392 CPPUNIT_ASSERT_EQUAL(0u, track->extensionSamplingFrequency());
393 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(16), track->bitsPerSample());
394 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(76), track->sampleCount());
395 CPPUNIT_ASSERT_EQUAL(DateTime::fromDateAndTime(2018, 7, 8, 20, 3, 52), track->creationTime());
396 CPPUNIT_ASSERT_EQUAL(DateTime::fromDateAndTime(2018, 7, 8, 20, 3, 52), track->modificationTime());
397 CPPUNIT_ASSERT_EQUAL(1, track->duration().seconds());
398 CPPUNIT_ASSERT_EQUAL(256.0, track->bitrate());
401 CPPUNIT_ASSERT_EQUAL(
"MetaHandler"s, track->name());
402 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Unknown, track->format().general);
403 CPPUNIT_ASSERT_EQUAL(
"urim"s, track->formatId());
406 CPPUNIT_FAIL(
"unknown track ID");
409 const auto tags = m_fileInfo.
tags();
410 switch (m_tagStatus) {
412 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
415 checkMp4TestMetaData();
418 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
420 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
426void OverallTests::checkMp4TestMetaData()
429 const auto tags = m_fileInfo.
tags();
431 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
432 CPPUNIT_ASSERT(tag !=
nullptr);
435 CPPUNIT_ASSERT_EQUAL(m_testTitle, tag->
value(KnownField::Title));
437 CPPUNIT_ASSERT_EQUAL(m_testAlbum, tag->
value(KnownField::Album));
438 CPPUNIT_ASSERT_EQUAL(m_preservedMetaData.front(), tag->
value(KnownField::Artist));
439 CPPUNIT_ASSERT_EQUAL(m_testPosition, tag->
value(KnownField::TrackPosition));
440 CPPUNIT_ASSERT_EQUAL(m_testPosition, tag->
value(KnownField::DiskPosition));
443 m_preservedMetaData.pop();
449void OverallTests::checkMp4Constraints()
454 if (m_mode & PaddingConstraints) {
455 if (m_mode & ForceRewring) {
456 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint64_t
>(4096), m_fileInfo.
paddingSize());
459 CPPUNIT_ASSERT(m_fileInfo.
paddingSize() <= (4096 + 1024));
462 && ((m_mode & ForceRewring) || (m_mode & ForceTagPos))) {
464 if (currentTagPos == ElementPosition::Keep) {
474void OverallTests::setMp4TestMetaData()
480 tag->
setValue(KnownField::Title, m_testTitle);
481 tag->
setValue(KnownField::Comment, m_testComment);
482 tag->
setValue(KnownField::Album, m_testAlbum);
483 m_preservedMetaData.push(tag->
value(KnownField::Artist));
484 tag->
setValue(KnownField::TrackPosition, m_testPosition);
485 tag->
setValue(KnownField::DiskPosition, m_testPosition);
496void OverallTests::alterMp4Tracks()
498 m_additionalFileInfo.
setPath(testFilePath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"));
499 m_additionalFileInfo.
reopen(
true);
501 m_additionalFileInfo.
parseTracks(m_diag, m_progress);
502 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_additionalFileInfo.
containerFormat());
503 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.
containerFormat());
504 const auto &tracks = m_additionalFileInfo.
tracks();
505 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
506 CPPUNIT_ASSERT_EQUAL(TrackType::Mp4Track, tracks[0]->type());
507 auto *track =
static_cast<Mp4Track *
>(tracks[0]);
509 CPPUNIT_ASSERT_EQUAL(0_st, m_additionalFileInfo.
trackCount());
510 track->setName(
"new track");
512 CPPUNIT_ASSERT_EQUAL(5_st, container->trackCount());
513 container->addTrack(track);
514 CPPUNIT_ASSERT_EQUAL(6_st, container->trackCount());
515 auto &secondTrack = container->tracks()[1];
516 secondTrack->setLocale(
Locale(
"ger"sv, LocaleFormat::ISO_639_2_T));
517 secondTrack->setName(
"test");
525 cerr << endl <<
"MP4 parser" << endl;
528 parseFile(testFilePath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"), &OverallTests::checkMp4Testfile1);
529 parseFile(testFilePath(
"mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), &OverallTests::checkMp4Testfile2);
530 parseFile(testFilePath(
"mtx-test-data/mp4/dash/dragon-age-inquisition-H1LkM6IVlm4-video.mp4"), &OverallTests::checkMp4Testfile3);
531 parseFile(testFilePath(
"mtx-test-data/alac/othertest-itunes.m4a"), &OverallTests::checkMp4Testfile4);
532 parseFile(testFilePath(
"mtx-test-data/aac/he-aacv2-ps.m4a"), &OverallTests::checkMp4Testfile5);
533 parseFile(testFilePath(
"mp4/android-8.1-camera-recoding.mp4"), &OverallTests::checkMp4Testfile7);
546 for (m_mode = 0; m_mode != 0x20; ++m_mode) {
552 if (m_mode & KeepTagPos) {
555 m_fileInfo.
setTagPosition(m_mode & TagsBeforeData ? ElementPosition::BeforeData : ElementPosition::AfterData);
559 m_fileInfo.
setMinPadding(m_mode & PaddingConstraints ? 1024 : 0);
560 m_fileInfo.
setMaxPadding(m_mode & PaddingConstraints ? (4096 + 1024) : numeric_limits<size_t>::max());
565 list<string> testConditions;
566 if (m_mode & ForceRewring) {
567 testConditions.emplace_back(
"forcing rewrite");
569 if (m_mode & KeepTagPos) {
570 if (m_mode & RemoveTagOrTrack) {
571 testConditions.emplace_back(
"removing tag");
573 testConditions.emplace_back(
"keeping tag position");
575 }
else if (m_mode & TagsBeforeData) {
576 testConditions.emplace_back(
"tags before data");
578 testConditions.emplace_back(
"tags after data");
580 if (m_mode & PaddingConstraints) {
581 testConditions.emplace_back(
"padding constraints");
583 if (m_mode & ForceTagPos) {
584 testConditions.emplace_back(
"forcing tag position");
586 cerr << endl <<
"MP4 maker - testmode " << m_mode <<
": " << joinStrings(testConditions,
", ") << endl;
591 void (
OverallTests::*modifyRoutine)(
void) = (m_mode & RemoveTagOrTrack) ? &OverallTests::removeAllTags : &OverallTests::setMp4TestMetaData;
592 makeFile(workingCopyPath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile1);
593 makeFile(workingCopyPath(
"mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile2);
595 workingCopyPath(
"mtx-test-data/mp4/dash/dragon-age-inquisition-H1LkM6IVlm4-video.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile3);
596 makeFile(workingCopyPath(
"mtx-test-data/alac/othertest-itunes.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile4);
597 makeFile(workingCopyPath(
"mtx-test-data/aac/he-aacv2-ps.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile5);
598 makeFile(workingCopyPath(
"mp4/android-8.1-camera-recoding.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile7);
600 modifyRoutine = (m_mode & RemoveTagOrTrack) ? &OverallTests::removeSecondTrack : &OverallTests::alterMp4Tracks;
602 makeFile(workingCopyPath(
"mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile6);
The OverallTests class tests reading and writing tags and parsing technical information for all suppo...
void testMp4Making()
Tests the MP4 maker via MediaFileInfo.
void testMp4Parsing()
Tests the MP4 parser via MediaFileInfo.
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.
const std::string & documentType() const
Returns a string that describes the document type if available; otherwise returns an empty string.
virtual Tag * createTag(const TagTarget &target=TagTarget())
Creates and returns a tag for the specified target.
void reopen(bool readOnly=false)
Opens a std::fstream for the current file.
void setPath(std::string_view path)
Sets the current file.
DiagLevel level() const
Returns the worst diag level present in the container.
bool removeTrack(AbstractTrack *track) override
Removes the specified track to the container.
Implementation of GenericContainer<MediaFileInfo, Mp4Tag, Mp4Track, Mp4Atom>.
Implementation of TagParser::Tag for the MP4 container.
const TagValue & value(KnownField value) const override
Returns the value of the specified field.
Implementation of TagParser::AbstractTrack for the MP4 container.
The PositionInSet class describes the position of an element in a set which consists of a certain num...
The Size class defines the size of a two-dimensional object using integer point precision.
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.
virtual const TagValue & value(KnownField field) const =0
Returns the value of the specified field.
The Locale struct specifies a language and/or a country using one or more LocaleDetail objects.