4 #include "../abstracttrack.h" 5 #include "../mp4/mp4container.h" 6 #include "../mp4/mp4ids.h" 7 #include "../mp4/mp4tag.h" 23 void OverallTests::checkMp4Testfile1()
26 const auto tracks = m_fileInfo.
tracks();
27 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
28 for (
const auto &track : tracks) {
29 switch (track->id()) {
33 CPPUNIT_ASSERT_EQUAL(2012, track->creationTime().year());
34 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
38 CPPUNIT_FAIL(
"unknown track ID");
41 const auto tags = m_fileInfo.
tags();
42 switch (m_tagStatus) {
44 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
45 CPPUNIT_ASSERT_EQUAL(
"Danse Macabre, Op.40"s, tags.front()->value(
KnownField::Title).toString());
46 CPPUNIT_ASSERT_EQUAL(
"Saint-Saƫns"s, tags.front()->value(
KnownField::Artist).toString());
47 CPPUNIT_ASSERT_EQUAL(
"Classical"s, tags.front()->value(
KnownField::Genre).toString());
49 "qaac 1.32, CoreAudioToolbox 7.9.7.3, AAC-LC Encoder, TVBR q63, Quality 96"s, tags.front()->value(
KnownField::Encoder).toString());
53 checkMp4TestMetaData();
56 CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
58 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
64 void OverallTests::checkMp4Testfile2()
67 const auto tracks = m_fileInfo.
tracks();
68 CPPUNIT_ASSERT_EQUAL(5_st, tracks.size());
69 for (
const auto &track : tracks) {
70 switch (track->id()) {
75 CPPUNIT_ASSERT_EQUAL(4.0, track->version());
76 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
77 CPPUNIT_ASSERT(track->pixelSize() ==
Size(1920, 750));
85 CPPUNIT_ASSERT_EQUAL(
"eng"s, track->language());
86 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
87 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
93 CPPUNIT_ASSERT_EQUAL(
"eng"s, track->language());
94 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
98 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general);
99 CPPUNIT_ASSERT_EQUAL(
"eng"s, track->language());
100 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
103 CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
104 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general);
105 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
108 CPPUNIT_FAIL(
"unknown track ID");
111 const auto tags = m_fileInfo.
tags();
112 switch (m_tagStatus) {
114 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
117 checkMp4TestMetaData();
120 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
122 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
128 void OverallTests::checkMp4Testfile3()
131 CPPUNIT_ASSERT(m_fileInfo.
container() !=
nullptr);
133 const auto tracks = m_fileInfo.
tracks();
134 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
135 for (
const auto &track : tracks) {
136 switch (track->id()) {
141 CPPUNIT_ASSERT_EQUAL(3.1, track->version());
142 CPPUNIT_ASSERT_EQUAL(2014, track->creationTime().year());
143 CPPUNIT_ASSERT_EQUAL(
Size(854, 480), track->pixelSize());
144 CPPUNIT_ASSERT_EQUAL(
"YUV 4:2:0"s,
string(track->chromaFormat()));
147 CPPUNIT_FAIL(
"unknown track ID");
150 const auto tags = m_fileInfo.
tags();
151 switch (m_tagStatus) {
153 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
156 checkMp4TestMetaData();
159 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
162 for (
const auto &msg : m_diag) {
163 if (msg.level() != DiagLevel::Warning) {
167 CPPUNIT_FAIL(
"No warnings expected when putting tags before data.");
169 CPPUNIT_ASSERT_EQUAL(
"Sorry, but putting index/tags at the end is not possible when dealing with DASH files."s, msg.message());
172 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Warning);
178 void OverallTests::checkMp4Testfile4()
181 CPPUNIT_ASSERT(m_fileInfo.
container() !=
nullptr);
183 const auto tracks = m_fileInfo.
tracks();
184 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
185 for (
const auto &track : tracks) {
186 switch (track->id()) {
190 CPPUNIT_ASSERT_EQUAL(2008, track->creationTime().year());
191 CPPUNIT_ASSERT_EQUAL(static_cast<uint16>(2), track->channelCount());
192 CPPUNIT_ASSERT_EQUAL(static_cast<uint16>(16), track->bitsPerSample());
195 CPPUNIT_FAIL(
"unknown track ID");
198 const auto tags = m_fileInfo.
tags();
199 switch (m_tagStatus) {
201 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
202 CPPUNIT_ASSERT_EQUAL(
"Sad Song"s, tags.front()->value(
KnownField::Title).toString());
204 CPPUNIT_ASSERT_EQUAL(
"Don't Go Away (Apple Lossless)"s, tags.front()->value(
KnownField::Album).toString());
205 CPPUNIT_ASSERT_EQUAL(
"Alternative & Punk"s, tags.front()->value(
KnownField::Genre).toString());
206 CPPUNIT_ASSERT_EQUAL(
"iTunes v7.5.0.20"s, tags.front()->value(
KnownField::Encoder).toString());
207 CPPUNIT_ASSERT_EQUAL(
"1998"s, tags.front()->value(
KnownField::Year).toString());
209 CPPUNIT_ASSERT_EQUAL(0x58f3_st, tags.front()->value(
KnownField::Cover).dataSize());
210 CPPUNIT_ASSERT_EQUAL(0xFFD8FFE000104A46ul, BE::toUInt64(tags.front()->value(
KnownField::Cover).dataPointer()));
215 checkMp4TestMetaData();
218 CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
220 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
226 void OverallTests::checkMp4Testfile5()
229 CPPUNIT_ASSERT(m_fileInfo.
container() !=
nullptr);
231 const auto tracks = m_fileInfo.
tracks();
232 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
233 for (
const auto &track : tracks) {
234 switch (track->id()) {
241 CPPUNIT_ASSERT_EQUAL(2014, track->creationTime().year());
242 CPPUNIT_ASSERT_EQUAL(static_cast<uint16>(2), track->channelCount());
245 CPPUNIT_ASSERT_EQUAL(24000u, track->samplingFrequency());
246 CPPUNIT_ASSERT_EQUAL(48000u, track->extensionSamplingFrequency());
247 CPPUNIT_ASSERT_EQUAL(static_cast<uint16>(16), track->bitsPerSample());
250 CPPUNIT_FAIL(
"unknown track ID");
253 const auto tags = m_fileInfo.
tags();
254 switch (m_tagStatus) {
256 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
259 checkMp4TestMetaData();
262 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
264 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
270 void OverallTests::checkMp4Testfile6()
273 const auto tracks = m_fileInfo.
tracks();
275 CPPUNIT_ASSERT_EQUAL(4_st, tracks.size());
277 CPPUNIT_ASSERT_EQUAL(6_st, tracks.size());
279 bool track2Present =
false, track5Present =
false;
280 for (
const auto &track : tracks) {
281 switch (track->id()) {
286 CPPUNIT_ASSERT_EQUAL(4.0, track->version());
287 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
288 CPPUNIT_ASSERT_EQUAL(
Size(1920, 750), track->pixelSize());
291 CPPUNIT_ASSERT(track2Present = !track2Present);
297 CPPUNIT_ASSERT_EQUAL(
"ger"s, track->language());
298 CPPUNIT_ASSERT_EQUAL(
"test"s, track->name());
299 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
300 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
306 CPPUNIT_ASSERT_EQUAL(
"eng"s, track->language());
307 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
311 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general);
312 CPPUNIT_ASSERT_EQUAL(
"eng"s, track->language());
313 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
316 CPPUNIT_ASSERT(track5Present = !track5Present);
319 CPPUNIT_ASSERT_EQUAL(2012, track->creationTime().year());
320 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
322 CPPUNIT_ASSERT_EQUAL(
"new track"s, track->name());
325 CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
326 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general);
327 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
330 CPPUNIT_FAIL(
"unknown track ID");
334 CPPUNIT_ASSERT(!track2Present);
335 CPPUNIT_ASSERT(!track5Present);
337 CPPUNIT_ASSERT(track2Present);
338 CPPUNIT_ASSERT(track5Present);
341 CPPUNIT_ASSERT_EQUAL(0_st, m_fileInfo.
tags().size());
342 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
348 void OverallTests::checkMp4TestMetaData()
351 const auto tags = m_fileInfo.
tags();
353 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
354 CPPUNIT_ASSERT(tag !=
nullptr);
365 m_preservedMetaData.pop();
371 void OverallTests::checkMp4Constraints()
375 CPPUNIT_ASSERT(m_fileInfo.container());
378 CPPUNIT_ASSERT_EQUAL(4096_st, m_fileInfo.paddingSize());
380 CPPUNIT_ASSERT(m_fileInfo.paddingSize() >= 1024);
381 CPPUNIT_ASSERT(m_fileInfo.paddingSize() <= (4096 + 1024));
383 if (!(m_mode &
RemoveTagOrTrack) && (m_fileInfo.container()->documentType() !=
"dash")
385 const ElementPosition currentTagPos = m_fileInfo.container()->determineTagPosition(m_diag);
386 if (currentTagPos == ElementPosition::Keep) {
387 CPPUNIT_ASSERT_EQUAL(m_expectedTagPos, m_fileInfo.container()->determineIndexPosition(m_diag));
396 void OverallTests::setMp4TestMetaData()
418 void OverallTests::alterMp4Tracks()
420 m_additionalFileInfo.
setPath(TestUtilities::testFilePath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"));
421 m_additionalFileInfo.
reopen(
true);
426 const auto &tracks = m_additionalFileInfo.
tracks();
427 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
428 CPPUNIT_ASSERT_EQUAL(TrackType::Mp4Track, tracks[0]->type());
429 auto *track =
static_cast<Mp4Track *
>(tracks[0]);
430 CPPUNIT_ASSERT(static_cast<Mp4Container *>(m_additionalFileInfo.
container())->removeTrack(track));
431 CPPUNIT_ASSERT_EQUAL(0_st, m_additionalFileInfo.
trackCount());
434 CPPUNIT_ASSERT_EQUAL(5_st, container->trackCount());
436 CPPUNIT_ASSERT_EQUAL(6_st, container->trackCount());
437 auto &secondTrack = container->tracks()[1];
438 secondTrack->setLanguage(
"ger");
439 secondTrack->setName(
"test");
447 cerr << endl <<
"MP4 parser" << endl;
450 parseFile(TestUtilities::testFilePath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"), &OverallTests::checkMp4Testfile1);
451 parseFile(TestUtilities::testFilePath(
"mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), &OverallTests::checkMp4Testfile2);
452 parseFile(TestUtilities::testFilePath(
"mtx-test-data/mp4/dash/dragon-age-inquisition-H1LkM6IVlm4-video.mp4"), &OverallTests::checkMp4Testfile3);
453 parseFile(TestUtilities::testFilePath(
"mtx-test-data/alac/othertest-itunes.m4a"), &OverallTests::checkMp4Testfile4);
454 parseFile(TestUtilities::testFilePath(
"mtx-test-data/aac/he-aacv2-ps.m4a"), &OverallTests::checkMp4Testfile5);
462 void OverallTests::testMp4Making()
468 for (m_mode = 0; m_mode != 0x20; ++m_mode) {
475 m_fileInfo.setTagPosition(ElementPosition::Keep);
477 m_fileInfo.setTagPosition(m_mode &
TagsBeforeData ? ElementPosition::BeforeData : ElementPosition::AfterData);
479 m_fileInfo.setIndexPosition(m_fileInfo.tagPosition());
482 m_fileInfo.setMaxPadding(m_mode &
PaddingConstraints ? (4096 + 1024) : numeric_limits<size_t>::max());
483 m_fileInfo.setForceTagPosition(m_mode &
ForceTagPos);
484 m_fileInfo.setForceIndexPosition(m_mode &
ForceTagPos);
487 list<string> testConditions;
489 testConditions.emplace_back(
"forcing rewrite");
493 testConditions.emplace_back(
"removing tag");
495 testConditions.emplace_back(
"keeping tag position");
498 testConditions.emplace_back(
"tags before data");
500 testConditions.emplace_back(
"tags after data");
503 testConditions.emplace_back(
"padding constraints");
506 testConditions.emplace_back(
"forcing tag position");
508 cerr << endl <<
"MP4 maker - testmode " << m_mode <<
": " << joinStrings(testConditions,
", ") << endl;
513 void (
OverallTests::*modifyRoutine)(void) = (m_mode &
RemoveTagOrTrack) ? &OverallTests::removeAllTags : &OverallTests::setMp4TestMetaData;
514 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile1);
515 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile2);
516 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/mp4/dash/dragon-age-inquisition-H1LkM6IVlm4-video.mp4"), modifyRoutine,
517 &OverallTests::checkMp4Testfile3);
518 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/alac/othertest-itunes.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile4);
519 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/aac/he-aacv2-ps.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile5);
521 modifyRoutine = (m_mode &
RemoveTagOrTrack) ? &OverallTests::removeSecondTrack : &OverallTests::alterMp4Tracks;
522 m_fileInfo.setTagPosition(ElementPosition::Keep);
523 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile6);
void setPath(const std::string &path)
Sets the current file.
const std::string & documentType() const
Returns a string that describes the document type if available; otherwise returns an empty string...
bool addTrack(TrackType *track)
Adds the specified track to the container.
virtual bool setValue(KnownField field, const TagValue &value)=0
Assigns the given value to the specified field.
virtual Tag * createTag(const TagTarget &target=TagTarget())
Creates and returns a tag for the specified target.
The Size class defines the size of a two-dimensional object using integer point precision.
The OverallTests class tests reading and writing tags and parsing technical information for all suppo...
void reopen(bool readonly=false)
Opens a std::fstream for the current file.
void setName(const std::string &name)
Sets the name.
void testMp4Parsing()
Tests the MP4 parser via MediaFileInfo.
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
virtual const TagValue & value(KnownField field) const =0
Returns the value of the specified field.
const TagValue & value(KnownField value) const override
Returns the value of the specified field.