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(tracks.size() == 1);
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()
132 const auto tracks = m_fileInfo.
tracks();
133 CPPUNIT_ASSERT(tracks.size() == 1);
134 for (
const auto &track : tracks) {
135 switch (track->id()) {
140 CPPUNIT_ASSERT(track->version() == 3.1);
141 CPPUNIT_ASSERT(track->creationTime().year() == 2014);
142 CPPUNIT_ASSERT(track->pixelSize() ==
Size(854, 480));
143 CPPUNIT_ASSERT(!strcmp(track->chromaFormat(),
"YUV 4:2:0"));
146 CPPUNIT_FAIL(
"unknown track ID");
149 const auto tags = m_fileInfo.
tags();
150 switch (m_tagStatus) {
152 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
155 checkMp4TestMetaData();
158 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
161 for (
const auto &msg : m_diag) {
162 if (msg.level() != DiagLevel::Warning) {
166 CPPUNIT_FAIL(
"No warnings expected when putting tags before data.");
168 CPPUNIT_ASSERT_EQUAL(
"Sorry, but putting index/tags at the end is not possible when dealing with DASH files."s, msg.message());
171 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Warning);
177 void OverallTests::checkMp4Testfile4()
181 const auto tracks = m_fileInfo.
tracks();
182 CPPUNIT_ASSERT(tracks.size() == 1);
183 for (
const auto &track : tracks) {
184 switch (track->id()) {
188 CPPUNIT_ASSERT(track->creationTime().year() == 2008);
189 CPPUNIT_ASSERT(track->channelCount() == 2);
190 CPPUNIT_ASSERT(track->bitsPerSample() == 16);
193 CPPUNIT_FAIL(
"unknown track ID");
196 const auto tags = m_fileInfo.
tags();
197 switch (m_tagStatus) {
199 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
202 CPPUNIT_ASSERT(tags.front()->value(
KnownField::Album).toString() ==
"Don't Go Away (Apple Lossless)");
203 CPPUNIT_ASSERT(tags.front()->value(
KnownField::Genre).toString() ==
"Alternative & Punk");
208 CPPUNIT_ASSERT(BE::toUInt64(tags.front()->value(
KnownField::Cover).dataPointer()) == 0xFFD8FFE000104A46);
213 checkMp4TestMetaData();
216 CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
218 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
224 void OverallTests::checkMp4Testfile5()
228 const auto tracks = m_fileInfo.
tracks();
229 CPPUNIT_ASSERT(tracks.size() == 1);
230 for (
const auto &track : tracks) {
231 switch (track->id()) {
238 CPPUNIT_ASSERT(track->creationTime().year() == 2014);
239 CPPUNIT_ASSERT(track->channelCount() == 2);
242 CPPUNIT_ASSERT(track->samplingFrequency() == 24000);
243 CPPUNIT_ASSERT(track->extensionSamplingFrequency() == 48000);
244 CPPUNIT_ASSERT(track->bitsPerSample() == 16);
247 CPPUNIT_FAIL(
"unknown track ID");
250 const auto tags = m_fileInfo.
tags();
251 switch (m_tagStatus) {
253 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
256 checkMp4TestMetaData();
259 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
261 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
267 void OverallTests::checkMp4Testfile6()
270 const auto tracks = m_fileInfo.
tracks();
272 CPPUNIT_ASSERT_EQUAL(4_st, tracks.size());
274 CPPUNIT_ASSERT_EQUAL(6_st, tracks.size());
276 bool track2Present =
false, track5Present =
false;
277 for (
const auto &track : tracks) {
278 switch (track->id()) {
283 CPPUNIT_ASSERT_EQUAL(4.0, track->version());
284 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
285 CPPUNIT_ASSERT(track->pixelSize() ==
Size(1920, 750));
288 CPPUNIT_ASSERT(track2Present = !track2Present);
294 CPPUNIT_ASSERT_EQUAL(
"ger"s, track->language());
295 CPPUNIT_ASSERT_EQUAL(
"test"s, track->name());
296 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
297 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
303 CPPUNIT_ASSERT_EQUAL(
"eng"s, track->language());
304 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
308 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general);
309 CPPUNIT_ASSERT_EQUAL(
"eng"s, track->language());
310 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
313 CPPUNIT_ASSERT(track5Present = !track5Present);
316 CPPUNIT_ASSERT_EQUAL(2012, track->creationTime().year());
317 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
319 CPPUNIT_ASSERT_EQUAL(
"new track"s, track->name());
322 CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
323 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general);
324 CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
327 CPPUNIT_FAIL(
"unknown track ID");
331 CPPUNIT_ASSERT(!track2Present);
332 CPPUNIT_ASSERT(!track5Present);
334 CPPUNIT_ASSERT(track2Present);
335 CPPUNIT_ASSERT(track5Present);
338 CPPUNIT_ASSERT_EQUAL(0_st, m_fileInfo.
tags().size());
339 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
345 void OverallTests::checkMp4TestMetaData()
348 const auto tags = m_fileInfo.
tags();
350 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
351 CPPUNIT_ASSERT(tag !=
nullptr);
362 m_preservedMetaData.pop();
368 void OverallTests::checkMp4Constraints()
372 CPPUNIT_ASSERT(m_fileInfo.container());
375 CPPUNIT_ASSERT_EQUAL(4096_st, m_fileInfo.paddingSize());
377 CPPUNIT_ASSERT(m_fileInfo.paddingSize() >= 1024);
378 CPPUNIT_ASSERT(m_fileInfo.paddingSize() <= (4096 + 1024));
380 if (!(m_mode &
RemoveTagOrTrack) && (m_fileInfo.container()->documentType() !=
"dash")
382 const ElementPosition currentTagPos = m_fileInfo.container()->determineTagPosition(m_diag);
383 if (currentTagPos == ElementPosition::Keep) {
384 CPPUNIT_ASSERT_EQUAL(m_expectedTagPos, m_fileInfo.container()->determineIndexPosition(m_diag));
393 void OverallTests::setMp4TestMetaData()
415 void OverallTests::alterMp4Tracks()
417 m_additionalFileInfo.
setPath(TestUtilities::testFilePath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"));
418 m_additionalFileInfo.
reopen(
true);
423 const auto &tracks = m_additionalFileInfo.
tracks();
424 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
425 CPPUNIT_ASSERT_EQUAL(TrackType::Mp4Track, tracks[0]->type());
426 auto *track =
static_cast<Mp4Track *
>(tracks[0]);
427 CPPUNIT_ASSERT(static_cast<Mp4Container *>(m_additionalFileInfo.
container())->removeTrack(track));
428 CPPUNIT_ASSERT_EQUAL(0_st, m_additionalFileInfo.
trackCount());
431 CPPUNIT_ASSERT_EQUAL(5_st, container->trackCount());
433 CPPUNIT_ASSERT_EQUAL(6_st, container->trackCount());
434 auto &secondTrack = container->tracks()[1];
435 secondTrack->setLanguage(
"ger");
436 secondTrack->setName(
"test");
444 cerr << endl <<
"MP4 parser" << endl;
447 parseFile(TestUtilities::testFilePath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"), &OverallTests::checkMp4Testfile1);
448 parseFile(TestUtilities::testFilePath(
"mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), &OverallTests::checkMp4Testfile2);
449 parseFile(TestUtilities::testFilePath(
"mtx-test-data/mp4/dash/dragon-age-inquisition-H1LkM6IVlm4-video.mp4"), &OverallTests::checkMp4Testfile3);
450 parseFile(TestUtilities::testFilePath(
"mtx-test-data/alac/othertest-itunes.m4a"), &OverallTests::checkMp4Testfile4);
451 parseFile(TestUtilities::testFilePath(
"mtx-test-data/aac/he-aacv2-ps.m4a"), &OverallTests::checkMp4Testfile5);
459 void OverallTests::testMp4Making()
465 for (m_mode = 0; m_mode != 0x20; ++m_mode) {
472 m_fileInfo.setTagPosition(ElementPosition::Keep);
474 m_fileInfo.setTagPosition(m_mode &
TagsBeforeData ? ElementPosition::BeforeData : ElementPosition::AfterData);
476 m_fileInfo.setIndexPosition(m_fileInfo.tagPosition());
479 m_fileInfo.setMaxPadding(m_mode &
PaddingConstraints ? (4096 + 1024) : numeric_limits<size_t>::max());
480 m_fileInfo.setForceTagPosition(m_mode &
ForceTagPos);
481 m_fileInfo.setForceIndexPosition(m_mode &
ForceTagPos);
484 list<string> testConditions;
486 testConditions.emplace_back(
"forcing rewrite");
490 testConditions.emplace_back(
"removing tag");
492 testConditions.emplace_back(
"keeping tag position");
495 testConditions.emplace_back(
"tags before data");
497 testConditions.emplace_back(
"tags after data");
500 testConditions.emplace_back(
"padding constraints");
503 testConditions.emplace_back(
"forcing tag position");
505 cerr << endl <<
"MP4 maker - testmode " << m_mode <<
": " << joinStrings(testConditions,
", ") << endl;
510 void (
OverallTests::*modifyRoutine)(void) = (m_mode &
RemoveTagOrTrack) ? &OverallTests::removeAllTags : &OverallTests::setMp4TestMetaData;
511 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile1);
512 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile2);
513 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/mp4/dash/dragon-age-inquisition-H1LkM6IVlm4-video.mp4"), modifyRoutine,
514 &OverallTests::checkMp4Testfile3);
515 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/alac/othertest-itunes.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile4);
516 makeFile(TestUtilities::workingCopyPath(
"mtx-test-data/aac/he-aacv2-ps.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile5);
518 modifyRoutine = (m_mode &
RemoveTagOrTrack) ? &OverallTests::removeSecondTrack : &OverallTests::alterMp4Tracks;
519 m_fileInfo.setTagPosition(ElementPosition::Keep);
520 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.