Tag Parser  6.4.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
overallmp4.cpp
Go to the documentation of this file.
1 #include "./helper.h"
2 #include "./overall.h"
3 
4 #include "../abstracttrack.h"
5 #include "../mp4/mp4ids.h"
6 #include "../mp4/mp4tag.h"
7 #include "../mp4/mp4container.h"
8 
9 namespace Mp4TestFlags {
11 {
12  ForceRewring = 0x1,
13  KeepTagPos = 0x2,
17  ForceTagPos = 0x8,
18 };
19 }
20 
24 void OverallTests::checkMp4Testfile1()
25 {
26  CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Mp4);
27  const auto tracks = m_fileInfo.tracks();
28  CPPUNIT_ASSERT(tracks.size() == 1);
29  for(const auto &track : tracks) {
30  switch(track->id()) {
31  case 1:
32  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
33  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
34  CPPUNIT_ASSERT_EQUAL(2012, track->creationTime().year());
35  CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
36  CPPUNIT_ASSERT_EQUAL(static_cast<byte>(Mpeg4ChannelConfigs::FrontLeftFrontRight), track->channelConfig());
37  break;
38  default:
39  CPPUNIT_FAIL("unknown track ID");
40  }
41  }
42  const auto tags = m_fileInfo.tags();
43  switch(m_tagStatus) {
45  CPPUNIT_ASSERT(tags.size() == 1);
46  CPPUNIT_ASSERT(tags.front()->value(KnownField::Title).toString() == "Danse Macabre, Op.40");
47  CPPUNIT_ASSERT(tags.front()->value(KnownField::Artist).toString() == "Saint-SaĆ«ns");
48  CPPUNIT_ASSERT(tags.front()->value(KnownField::Genre).toString() == "Classical");
49  CPPUNIT_ASSERT(tags.front()->value(KnownField::Encoder).toString() == "qaac 1.32, CoreAudioToolbox 7.9.7.3, AAC-LC Encoder, TVBR q63, Quality 96");
50  CPPUNIT_ASSERT(tags.front()->value(KnownField::TrackPosition).toPositionInSet().position() == 10);
51  break;
53  checkMp4TestMetaData();
54  break;
55  case TagStatus::Removed:
56  CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
57  }
58 }
59 
63 void OverallTests::checkMp4Testfile2()
64 {
65  CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Mp4);
66  const auto tracks = m_fileInfo.tracks();
67  CPPUNIT_ASSERT_EQUAL(5_st, tracks.size());
68  for(const auto &track : tracks) {
69  switch(track->id()) {
70  case 1:
71  CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
72  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
73  CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(SubFormats::AvcHighProfile), track->format().sub);
74  CPPUNIT_ASSERT_EQUAL(4.0, track->version());
75  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
76  CPPUNIT_ASSERT(track->pixelSize() == Size(1920, 750));
77  break;
78  case 2:
79  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
80  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
81  CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(SubFormats::AacMpeg4LowComplexityProfile), track->format().sub);
82  CPPUNIT_ASSERT(!(track->format().extension & ExtensionFormats::SpectralBandReplication));
83  CPPUNIT_ASSERT(!(track->format().extension & ExtensionFormats::ParametricStereo));
84  CPPUNIT_ASSERT_EQUAL("eng"s, track->language());
85  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
86  CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
87  CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(Mpeg4ChannelConfigs::FrontLeftFrontRight), track->channelConfig());
88  break;
89  case 3:
90  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
91  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Ac3, track->format().general);
92  CPPUNIT_ASSERT_EQUAL("eng"s, track->language());
93  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
94  break;
95  case 4:
96  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
97  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general);
98  CPPUNIT_ASSERT_EQUAL("eng"s, track->language());
99  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
100  break;
101  case 6:
102  CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
103  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general);
104  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
105  break;
106  default:
107  CPPUNIT_FAIL("unknown track ID");
108  }
109  }
110  const auto tags = m_fileInfo.tags();
111  switch(m_tagStatus) {
112  case TagStatus::Original:
113  CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
114  break;
116  checkMp4TestMetaData();
117  break;
118  case TagStatus::Removed:
119  CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
120  }
121 }
122 
126 void OverallTests::checkMp4Testfile3()
127 {
128  CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Mp4);
129  CPPUNIT_ASSERT(m_fileInfo.container() && m_fileInfo.container()->documentType() == "dash");
130  const auto tracks = m_fileInfo.tracks();
131  CPPUNIT_ASSERT(tracks.size() == 1);
132  for(const auto &track : tracks) {
133  switch(track->id()) {
134  case 1:
135  CPPUNIT_ASSERT(track->mediaType() == MediaType::Video);
136  CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Avc);
137  CPPUNIT_ASSERT(track->format().sub == SubFormats::AvcMainProfile);
138  CPPUNIT_ASSERT(track->version() == 3.1);
139  CPPUNIT_ASSERT(track->creationTime().year() == 2014);
140  CPPUNIT_ASSERT(track->pixelSize() == Size(854, 480));
141  CPPUNIT_ASSERT(!strcmp(track->chromaFormat(), "YUV 4:2:0"));
142  break;
143  default:
144  CPPUNIT_FAIL("unknown track ID");
145  }
146  }
147  const auto tags = m_fileInfo.tags();
148  switch(m_tagStatus) {
149  case TagStatus::Original:
150  CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
151  break;
153  checkMp4TestMetaData();
154  break;
155  case TagStatus::Removed:
156  CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
157  }
158 }
159 
163 void OverallTests::checkMp4Testfile4()
164 {
165  CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Mp4);
166  CPPUNIT_ASSERT(m_fileInfo.container() && m_fileInfo.container()->documentType() == "M4A ");
167  const auto tracks = m_fileInfo.tracks();
168  CPPUNIT_ASSERT(tracks.size() == 1);
169  for(const auto &track : tracks) {
170  switch(track->id()) {
171  case 1:
172  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
173  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Alac, track->format().general);
174  CPPUNIT_ASSERT(track->creationTime().year() == 2008);
175  CPPUNIT_ASSERT(track->channelCount() == 2);
176  CPPUNIT_ASSERT(track->bitsPerSample() == 16);
177  break;
178  default:
179  CPPUNIT_FAIL("unknown track ID");
180  }
181  }
182  const auto tags = m_fileInfo.tags();
183  switch(m_tagStatus) {
184  case TagStatus::Original:
185  CPPUNIT_ASSERT(tags.size() == 1);
186  CPPUNIT_ASSERT(tags.front()->value(KnownField::Title).toString() == "Sad Song");
187  CPPUNIT_ASSERT(tags.front()->value(KnownField::Artist).toString() == "Oasis");
188  CPPUNIT_ASSERT(tags.front()->value(KnownField::Album).toString() == "Don't Go Away (Apple Lossless)");
189  CPPUNIT_ASSERT(tags.front()->value(KnownField::Genre).toString() == "Alternative & Punk");
190  CPPUNIT_ASSERT(tags.front()->value(KnownField::Encoder).toString() == "iTunes v7.5.0.20");
191  CPPUNIT_ASSERT(tags.front()->value(KnownField::Year).toString() == "1998");
192  CPPUNIT_ASSERT(tags.front()->value(KnownField::Comment).isEmpty());
193  CPPUNIT_ASSERT(tags.front()->value(KnownField::Cover).dataSize() == 0x58f3);
194  CPPUNIT_ASSERT(BE::toUInt64(tags.front()->value(KnownField::Cover).dataPointer()) == 0xFFD8FFE000104A46);
195  CPPUNIT_ASSERT(tags.front()->value(KnownField::TrackPosition).toPositionInSet() == PositionInSet(3, 4));
196  CPPUNIT_ASSERT(tags.front()->value(KnownField::DiskPosition).toPositionInSet() == PositionInSet(1, 1));
197  break;
199  checkMp4TestMetaData();
200  break;
201  case TagStatus::Removed:
202  CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
203  }
204 }
205 
209 void OverallTests::checkMp4Testfile5()
210 {
211  CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Mp4);
212  CPPUNIT_ASSERT(m_fileInfo.container() && m_fileInfo.container()->documentType() == "mp42");
213  const auto tracks = m_fileInfo.tracks();
214  CPPUNIT_ASSERT(tracks.size() == 1);
215  for(const auto &track : tracks) {
216  switch(track->id()) {
217  case 1:
218  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
219  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
220  CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(SubFormats::AacMpeg4LowComplexityProfile), track->format().sub);
221  CPPUNIT_ASSERT(track->format().extension & ExtensionFormats::SpectralBandReplication);
222  CPPUNIT_ASSERT(track->format().extension & ExtensionFormats::ParametricStereo);
223  CPPUNIT_ASSERT(track->creationTime().year() == 2014);
224  CPPUNIT_ASSERT(track->channelCount() == 2);
225  CPPUNIT_ASSERT(track->channelConfig() == Mpeg4ChannelConfigs::FrontCenter);
226  CPPUNIT_ASSERT(track->extensionChannelConfig() == Mpeg4ChannelConfigs::FrontLeftFrontRight);
227  CPPUNIT_ASSERT(track->samplingFrequency() == 24000);
228  CPPUNIT_ASSERT(track->extensionSamplingFrequency() == 48000);
229  CPPUNIT_ASSERT(track->bitsPerSample() == 16);
230  break;
231  default:
232  CPPUNIT_FAIL("unknown track ID");
233  }
234  }
235  const auto tags = m_fileInfo.tags();
236  switch(m_tagStatus) {
237  case TagStatus::Original:
238  CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
239  break;
241  checkMp4TestMetaData();
242  break;
243  case TagStatus::Removed:
244  CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
245  }
246 }
247 
251 void OverallTests::checkMp4Testfile6()
252 {
253  CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Mp4);
254  const auto tracks = m_fileInfo.tracks();
255  if(m_mode & Mp4TestFlags::RemoveTagOrTrack) {
256  CPPUNIT_ASSERT_EQUAL(4_st, tracks.size());
257  } else {
258  CPPUNIT_ASSERT_EQUAL(6_st, tracks.size());
259  }
260  bool track2Present = false, track5Present = false;
261  for(const auto &track : tracks) {
262  switch(track->id()) {
263  case 1:
264  CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
265  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general);
266  CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(SubFormats::AvcHighProfile), track->format().sub);
267  CPPUNIT_ASSERT_EQUAL(4.0, track->version());
268  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
269  CPPUNIT_ASSERT(track->pixelSize() == Size(1920, 750));
270  break;
271  case 2:
272  CPPUNIT_ASSERT(track2Present = !track2Present);
273  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
274  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
275  CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(SubFormats::AacMpeg4LowComplexityProfile), track->format().sub);
276  CPPUNIT_ASSERT(!(track->format().extension & ExtensionFormats::SpectralBandReplication));
277  CPPUNIT_ASSERT(!(track->format().extension & ExtensionFormats::ParametricStereo));
278  CPPUNIT_ASSERT_EQUAL("ger"s, track->language());
279  CPPUNIT_ASSERT_EQUAL("test"s, track->name());
280  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
281  CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
282  CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(Mpeg4ChannelConfigs::FrontLeftFrontRight), track->channelConfig());
283  break;
284  case 3:
285  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
286  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Ac3, track->format().general);
287  CPPUNIT_ASSERT_EQUAL("eng"s, track->language());
288  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
289  break;
290  case 4:
291  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
292  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general);
293  CPPUNIT_ASSERT_EQUAL("eng"s, track->language());
294  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
295  break;
296  case 5:
297  CPPUNIT_ASSERT(track5Present = !track5Present);
298  CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
299  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general);
300  CPPUNIT_ASSERT_EQUAL(2012, track->creationTime().year());
301  CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
302  CPPUNIT_ASSERT_EQUAL(static_cast<byte>(Mpeg4ChannelConfigs::FrontLeftFrontRight), track->channelConfig());
303  CPPUNIT_ASSERT_EQUAL("new track"s, track->name());
304  break;
305  case 6:
306  CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType());
307  CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general);
308  CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year());
309  break;
310  default:
311  CPPUNIT_FAIL("unknown track ID");
312  }
313  }
314  if(m_mode & Mp4TestFlags::RemoveTagOrTrack) {
315  CPPUNIT_ASSERT(!track2Present);
316  CPPUNIT_ASSERT(!track5Present);
317  } else {
318  CPPUNIT_ASSERT(track2Present);
319  CPPUNIT_ASSERT(track5Present);
320  }
321 
322  CPPUNIT_ASSERT_EQUAL(0_st, m_fileInfo.tags().size());
323 }
324 
328 void OverallTests::checkMp4TestMetaData()
329 {
330  // check whether a tag is assigned
331  const auto tags = m_fileInfo.tags();
332  Mp4Tag *tag = m_fileInfo.mp4Tag();
333  CPPUNIT_ASSERT(tags.size() == 1);
334  CPPUNIT_ASSERT(tag != nullptr);
335 
336  // check test meta data
337  CPPUNIT_ASSERT_EQUAL(m_testTitle, tag->value(KnownField::Title));
338  CPPUNIT_ASSERT_EQUAL(m_testComment.toString(), tag->value(KnownField::Comment).toString()); // loss of description is ok
339  CPPUNIT_ASSERT_EQUAL(m_testAlbum, tag->value(KnownField::Album));
340  CPPUNIT_ASSERT_EQUAL(m_preservedMetaData.front(), tag->value(KnownField::Artist));
341  CPPUNIT_ASSERT_EQUAL(m_testPosition, tag->value(KnownField::TrackPosition));
342  CPPUNIT_ASSERT_EQUAL(m_testPosition, tag->value(KnownField::DiskPosition));
343 
344  // TODO: check more fields
345  m_preservedMetaData.pop();
346 }
347 
351 void OverallTests::checkMp4Constraints()
352 {
353  using namespace Mp4TestFlags;
354 
355  CPPUNIT_ASSERT(m_fileInfo.container());
356  if(m_mode & PaddingConstraints) {
357  if(m_mode & ForceRewring) {
358  CPPUNIT_ASSERT_EQUAL(4096_st, m_fileInfo.paddingSize());
359  } else {
360  CPPUNIT_ASSERT(m_fileInfo.paddingSize() >= 1024);
361  CPPUNIT_ASSERT(m_fileInfo.paddingSize() <= (4096 + 1024));
362  }
363  if(!(m_mode & RemoveTagOrTrack) && (m_fileInfo.container()->documentType() != "dash") && ((m_mode & ForceRewring) || (m_mode & ForceTagPos))) {
364  const ElementPosition currentTagPos = m_fileInfo.container()->determineTagPosition();
365  if(currentTagPos == ElementPosition::Keep) {
366  CPPUNIT_ASSERT_EQUAL(m_expectedTagPos, m_fileInfo.container()->determineIndexPosition());
367  }
368  }
369  }
370 }
371 
375 void OverallTests::setMp4TestMetaData()
376 {
377  // ensure a tag exists
378  Tag *tag = m_fileInfo.container()->createTag();
379 
380  // assign test meta data
381  tag->setValue(KnownField::Title, m_testTitle);
382  tag->setValue(KnownField::Comment, m_testComment);
383  tag->setValue(KnownField::Album, m_testAlbum);
384  m_preservedMetaData.push(tag->value(KnownField::Artist));
385  tag->setValue(KnownField::TrackPosition, m_testPosition);
386  tag->setValue(KnownField::DiskPosition, m_testPosition);
387  // TODO: set more fields
388 }
389 
397 void OverallTests::alterMp4Tracks()
398 {
399  m_additionalFileInfo.setPath(TestUtilities::testFilePath("mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"));
400  m_additionalFileInfo.reopen(true);
401  m_additionalFileInfo.parseContainerFormat();
402  m_additionalFileInfo.parseTracks();
403  CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_additionalFileInfo.containerFormat());
404  CPPUNIT_ASSERT_EQUAL(ContainerFormat::Mp4, m_fileInfo.containerFormat());
405  const auto &tracks = m_additionalFileInfo.tracks();
406  CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
407  CPPUNIT_ASSERT_EQUAL(TrackType::Mp4Track, tracks[0]->type());
408  auto *track = static_cast<Mp4Track *>(tracks[0]);
409  CPPUNIT_ASSERT(static_cast<Mp4Container *>(m_additionalFileInfo.container())->removeTrack(track));
410  CPPUNIT_ASSERT_EQUAL(0_st, m_additionalFileInfo.trackCount());
411  track->setName("new track");
412  auto *container = static_cast<Mp4Container *>(m_fileInfo.container());
413  CPPUNIT_ASSERT_EQUAL(5_st, container->trackCount());
414  container->addTrack(track);
415  CPPUNIT_ASSERT_EQUAL(6_st, container->trackCount());
416  auto &secondTrack = container->tracks()[1];
417  secondTrack->setLanguage("ger");
418  secondTrack->setName("test");
419 }
420 
425 {
426  cerr << endl << "MP4 parser" << endl;
427  m_fileInfo.setForceFullParse(false);
428  m_tagStatus = TagStatus::Original;
429  parseFile(TestUtilities::testFilePath("mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"), &OverallTests::checkMp4Testfile1);
430  parseFile(TestUtilities::testFilePath("mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), &OverallTests::checkMp4Testfile2);
431  parseFile(TestUtilities::testFilePath("mtx-test-data/mp4/dash/dragon-age-inquisition-H1LkM6IVlm4-video.mp4"), &OverallTests::checkMp4Testfile3);
432  parseFile(TestUtilities::testFilePath("mtx-test-data/alac/othertest-itunes.m4a"), &OverallTests::checkMp4Testfile4);
433  parseFile(TestUtilities::testFilePath("mtx-test-data/aac/he-aacv2-ps.m4a"), &OverallTests::checkMp4Testfile5);
434 }
435 
436 #ifdef PLATFORM_UNIX
437 
441 void OverallTests::testMp4Making()
442 {
443  // full parse is required to determine padding
444  m_fileInfo.setForceFullParse(true);
445 
446  // do the test under different conditions
447  for(m_mode = 0; m_mode != 0x20; ++m_mode) {
448  using namespace Mp4TestFlags;
449 
450  // setup test conditions
451 
452  m_fileInfo.setForceRewrite(m_mode & ForceRewring);
453  if(m_mode & KeepTagPos) {
454  m_fileInfo.setTagPosition(ElementPosition::Keep);
455  } else {
456  m_fileInfo.setTagPosition(m_mode & TagsBeforeData ? ElementPosition::BeforeData : ElementPosition::AfterData);
457  }
458  m_fileInfo.setIndexPosition(m_fileInfo.tagPosition());
459  m_fileInfo.setPreferredPadding(m_mode & PaddingConstraints ? 4096 : 0);
460  m_fileInfo.setMinPadding(m_mode & PaddingConstraints ? 1024 : 0);
461  m_fileInfo.setMaxPadding(m_mode & PaddingConstraints ? (4096 + 1024) : static_cast<size_t>(-1));
462  m_fileInfo.setForceTagPosition(m_mode & ForceTagPos);
463  m_fileInfo.setForceIndexPosition(m_mode & ForceTagPos);
464 
465  // print test conditions
466  list<string> testConditions;
467  if(m_mode & ForceRewring) {
468  testConditions.emplace_back("forcing rewrite");
469  }
470  if(m_mode & KeepTagPos) {
471  if(m_mode & RemoveTagOrTrack) {
472  testConditions.emplace_back("removing tag");
473  } else {
474  testConditions.emplace_back("keeping tag position");
475  }
476  } else if(m_mode & TagsBeforeData) {
477  testConditions.emplace_back("tags before data");
478  } else {
479  testConditions.emplace_back("tags after data");
480  }
481  if(m_mode & PaddingConstraints) {
482  testConditions.emplace_back("padding constraints");
483  }
484  if(m_mode & ForceTagPos) {
485  testConditions.emplace_back("forcing tag position");
486  }
487  cerr << endl << "MP4 maker - testmode " << m_mode << ": " << joinStrings(testConditions, ", ") << endl;
488 
489  // do actual tests
490  // -> either remove tags or set test meta data
492  void (OverallTests::*modifyRoutine)(void) = (m_mode & RemoveTagOrTrack) ? &OverallTests::removeAllTags : &OverallTests::setMp4TestMetaData;
493  makeFile(TestUtilities::workingCopyPath("mtx-test-data/mp4/10-DanseMacabreOp.40.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile1);
494  makeFile(TestUtilities::workingCopyPath("mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile2);
495  makeFile(TestUtilities::workingCopyPath("mtx-test-data/mp4/dash/dragon-age-inquisition-H1LkM6IVlm4-video.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile3);
496  makeFile(TestUtilities::workingCopyPath("mtx-test-data/alac/othertest-itunes.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile4);
497  makeFile(TestUtilities::workingCopyPath("mtx-test-data/aac/he-aacv2-ps.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile5);
498  // -> add/remove tracks
499  modifyRoutine = (m_mode & RemoveTagOrTrack) ? &OverallTests::removeSecondTrack : &OverallTests::alterMp4Tracks;
500  m_fileInfo.setTagPosition(ElementPosition::Keep);
501  makeFile(TestUtilities::workingCopyPath("mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile6);
502  }
503 }
504 #endif
The Size class defines the size of a two-dimensional object using integer point precision.
Definition: size.h:16
Implementation of Media::AbstractTrack for the MP4 container.
Definition: mp4track.h:119
bool addTrack(TrackType *track)
Adds the specified track to the container.
Implementation of GenericContainer<MediaFileInfo, Mp4Tag, Mp4Track, Mp4Atom>.
Definition: mp4container.h:19
The PositionInSet class describes the position of an element in a set which consists of a certain num...
Definition: positioninset.h:20
Implementation of Media::Tag for the MP4 container.
Definition: mp4tag.h:90
The OverallTests class tests reading and writing tags and parsing technical information for all suppo...
Definition: overall.h:44
The Tag class is used to store, read and write tag information.
Definition: tag.h:98
const TagValue & value(KnownField value) const
Returns the value of the specified field.
Definition: mp4tag.cpp:58
void setName(const std::string &name)
Sets the name.
void testMp4Parsing()
Tests the MP4 parser via MediaFileInfo.
Definition: overallmp4.cpp:424
virtual bool setValue(KnownField field, const TagValue &value)=0
Assigns the given value to the specified field.
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.
Definition: tagvalue.h:320
virtual const TagValue & value(KnownField field) const =0
Returns the value of the specified field.