diff --git a/CMakeLists.txt b/CMakeLists.txt index 3248a52..061ca8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -169,8 +169,8 @@ set(META_APP_AUTHOR "Martchus") set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}") set(META_APP_DESCRIPTION "C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags") set(META_VERSION_MAJOR 6) -set(META_VERSION_MINOR 3) -set(META_VERSION_PATCH 1) +set(META_VERSION_MINOR 4) +set(META_VERSION_PATCH 0) set(META_PUBLIC_SHARED_LIB_DEPENDS c++utilities) set(META_PUBLIC_STATIC_LIB_DEPENDS c++utilities_static) set(META_PRIVATE_COMPILE_DEFINITIONS LEGACY_API) diff --git a/abstracttrack.h b/abstracttrack.h index 24054f0..8e6647d 100644 --- a/abstracttrack.h +++ b/abstracttrack.h @@ -66,12 +66,14 @@ public: uint64 id() const; void setId(uint64 id); const std::string name() const; + void setName(const std::string &name); const ChronoUtilities::TimeSpan &duration() const; double bitrate() const; double maxBitrate() const; const ChronoUtilities::DateTime &creationTime() const; const ChronoUtilities::DateTime &modificationTime() const; const std::string &language() const; + void setLanguage(const std::string &language); uint32 samplingFrequency() const; uint32 extensionSamplingFrequency() const; uint16 bitsPerSample() const; @@ -86,6 +88,7 @@ public: const Size &displaySize() const; const Size &resolution() const; const std::string &compressorName() const; + void setCompressorName(const std::string &compressorName); uint16 depth() const; uint32 fps() const; const char *chromaFormat() const; @@ -93,8 +96,11 @@ public: bool isInterlaced() const; uint32 timeScale() const; bool isEnabled() const; + void setEnabled(bool enabled); bool isDefault() const; + void setDefault(bool isDefault); bool isForced() const; + void setForced(bool forced); bool hasLacing() const; bool isEncrypted() const; uint32 colorSpace() const; @@ -341,6 +347,15 @@ inline const std::string AbstractTrack::name() const return m_name; } +/*! + * \brief Sets the name. + * \remarks Whether the new value is applied when saving changes depends on the implementation. + */ +inline void AbstractTrack::setName(const std::string &name) +{ + m_name = name; +} + /*! * \brief Returns the duration if known; otherwise returns a TimeSpan of zero ticks. */ @@ -391,6 +406,15 @@ inline const std::string &AbstractTrack::language() const return m_language; } +/*! + * \brief Sets the language of the track. + * \remarks Whether the new value is applied when saving changes depends on the implementation. + */ +inline void AbstractTrack::setLanguage(const std::string &language) +{ + m_language = language; +} + /*! * \brief Returns the number of samples per second if known; otherwise returns 0. */ @@ -493,6 +517,15 @@ inline const std::string &AbstractTrack::compressorName() const return m_compressorName; } +/*! + * \brief Returns the compressor name if known; otherwise returns an empty string. + * \remarks Whether the new value is applied when saving changes depends on the implementation. + */ +inline void AbstractTrack::setCompressorName(const std::string &compressorName) +{ + m_compressorName = compressorName; +} + /*! * \brief Returns the bit depth if known; otherwise returns 0. */ @@ -557,6 +590,15 @@ inline bool AbstractTrack::isEnabled() const return m_enabled; } +/*! + * \brief Sets whether the track is enabled. + * \remarks Whether the new value is applied when saving changes depends on the implementation. + */ +inline void AbstractTrack::setEnabled(bool enabled) +{ + m_enabled = enabled; +} + /*! * \brief Returns true if the track is denoted as default; otherwise returns false. */ @@ -565,6 +607,15 @@ inline bool AbstractTrack::isDefault() const return m_default; } +/*! + * \brief Sets whether the track is a default track. + * \remarks Whether the new value is applied when saving changes depends on the implementation. + */ +inline void AbstractTrack::setDefault(bool isDefault) +{ + m_default = isDefault; +} + /*! * \brief Returns true if the track is denoted as forced; otherwise returns false. */ @@ -573,6 +624,15 @@ inline bool AbstractTrack::isForced() const return m_forced; } +/*! + * \brief Sets whether the track is forced. + * \remarks Whether the new value is applied when saving changes depends on the implementation. + */ +inline void AbstractTrack::setForced(bool forced) +{ + m_forced = forced; +} + /*! * \brief Returns true if the track has lacing; otherwise returns false. */ diff --git a/tests/overall.h b/tests/overall.h index d986f86..692799b 100644 --- a/tests/overall.h +++ b/tests/overall.h @@ -106,7 +106,7 @@ private: void removeAllTags(); void noop(); void createMkvWithNestedTags(); - void addMp4Track(); + void alterMp4Tracks(); void removeSecondTrack(); public: diff --git a/tests/overallflac.cpp b/tests/overallflac.cpp index 458ba9f..4265f71 100644 --- a/tests/overallflac.cpp +++ b/tests/overallflac.cpp @@ -41,7 +41,7 @@ void OverallTests::checkFlacTestfile1() checkOggTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -71,7 +71,7 @@ void OverallTests::checkFlacTestfile2() checkOggTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } diff --git a/tests/overallmkv.cpp b/tests/overallmkv.cpp index 35be04d..d03775d 100644 --- a/tests/overallmkv.cpp +++ b/tests/overallmkv.cpp @@ -62,7 +62,7 @@ void OverallTests::checkMkvTestfile1() checkMkvTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -102,7 +102,7 @@ void OverallTests::checkMkvTestfile2() checkMkvTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -142,7 +142,7 @@ void OverallTests::checkMkvTestfile3() checkMkvTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -176,7 +176,7 @@ void OverallTests::checkMkvTestfile4() switch(m_tagStatus) { case TagStatus::Original: case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); break; case TagStatus::TestMetaDataPresent: checkMkvTestMetaData(); @@ -226,7 +226,7 @@ void OverallTests::checkMkvTestfile5() checkMkvTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -267,7 +267,7 @@ void OverallTests::checkMkvTestfile6() checkMkvTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -309,7 +309,7 @@ void OverallTests::checkMkvTestfile7() checkMkvTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -351,7 +351,7 @@ void OverallTests::checkMkvTestfile8() checkMkvTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -415,7 +415,7 @@ void OverallTests::checkMkvTestfileHandbrakeChapters() checkMkvTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -451,7 +451,7 @@ void OverallTests::checkMkvTestfileNestedTags() CPPUNIT_ASSERT(generalTagFound); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tags.size()); } } diff --git a/tests/overallmp3.cpp b/tests/overallmp3.cpp index 54567ae..8f94aec 100644 --- a/tests/overallmp3.cpp +++ b/tests/overallmp3.cpp @@ -77,7 +77,7 @@ void OverallTests::checkMp3Testfile1() checkMp3TestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } diff --git a/tests/overallmp4.cpp b/tests/overallmp4.cpp index a783b74..94489e4 100644 --- a/tests/overallmp4.cpp +++ b/tests/overallmp4.cpp @@ -53,7 +53,7 @@ void OverallTests::checkMp4Testfile1() checkMp4TestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -68,11 +68,11 @@ void OverallTests::checkMp4Testfile2() for(const auto &track : tracks) { switch(track->id()) { case 1: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Video); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Avc); - CPPUNIT_ASSERT(track->format().sub == SubFormats::AvcHighProfile); + CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general); + CPPUNIT_ASSERT_EQUAL(static_cast(SubFormats::AvcHighProfile), track->format().sub); CPPUNIT_ASSERT_EQUAL(4.0, track->version()); - CPPUNIT_ASSERT(track->creationTime().year() == 2013); + CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); CPPUNIT_ASSERT(track->pixelSize() == Size(1920, 750)); break; case 2: @@ -87,21 +87,21 @@ void OverallTests::checkMp4Testfile2() CPPUNIT_ASSERT_EQUAL(static_cast(Mpeg4ChannelConfigs::FrontLeftFrontRight), track->channelConfig()); break; case 3: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Audio); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Ac3); + CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Ac3, track->format().general); CPPUNIT_ASSERT_EQUAL("eng"s, track->language()); - CPPUNIT_ASSERT(track->creationTime().year() == 2013); + CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); break; case 4: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Audio); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::DtsHd); + CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general); CPPUNIT_ASSERT_EQUAL("eng"s, track->language()); - CPPUNIT_ASSERT(track->creationTime().year() == 2013); + CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); break; case 6: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Text); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::TimedText); - CPPUNIT_ASSERT(track->creationTime().year() == 2013); + CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general); + CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); break; default: CPPUNIT_FAIL("unknown track ID"); @@ -147,13 +147,13 @@ void OverallTests::checkMp4Testfile3() const auto tags = m_fileInfo.tags(); switch(m_tagStatus) { case TagStatus::Original: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); break; case TagStatus::TestMetaDataPresent: checkMp4TestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -169,8 +169,8 @@ void OverallTests::checkMp4Testfile4() for(const auto &track : tracks) { switch(track->id()) { case 1: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Audio); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Alac); + CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Alac, track->format().general); CPPUNIT_ASSERT(track->creationTime().year() == 2008); CPPUNIT_ASSERT(track->channelCount() == 2); CPPUNIT_ASSERT(track->bitsPerSample() == 16); @@ -199,7 +199,7 @@ void OverallTests::checkMp4Testfile4() checkMp4TestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -215,9 +215,9 @@ void OverallTests::checkMp4Testfile5() for(const auto &track : tracks) { switch(track->id()) { case 1: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Audio); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Aac); - CPPUNIT_ASSERT(track->format().sub == SubFormats::AacMpeg4LowComplexityProfile); + CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Aac, track->format().general); + CPPUNIT_ASSERT_EQUAL(static_cast(SubFormats::AacMpeg4LowComplexityProfile), track->format().sub); CPPUNIT_ASSERT(track->format().extension & ExtensionFormats::SpectralBandReplication); CPPUNIT_ASSERT(track->format().extension & ExtensionFormats::ParametricStereo); CPPUNIT_ASSERT(track->creationTime().year() == 2014); @@ -235,13 +235,13 @@ void OverallTests::checkMp4Testfile5() const auto tags = m_fileInfo.tags(); switch(m_tagStatus) { case TagStatus::Original: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); break; case TagStatus::TestMetaDataPresent: checkMp4TestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -253,19 +253,19 @@ void OverallTests::checkMp4Testfile6() CPPUNIT_ASSERT(m_fileInfo.containerFormat() == ContainerFormat::Mp4); const auto tracks = m_fileInfo.tracks(); if(m_mode & Mp4TestFlags::RemoveTagOrTrack) { - CPPUNIT_ASSERT(tracks.size() == 4); + CPPUNIT_ASSERT_EQUAL(4_st, tracks.size()); } else { - CPPUNIT_ASSERT(tracks.size() == 6); + CPPUNIT_ASSERT_EQUAL(6_st, tracks.size()); } bool track2Present = false, track5Present = false; for(const auto &track : tracks) { switch(track->id()) { case 1: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Video); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Avc); - CPPUNIT_ASSERT(track->format().sub == SubFormats::AvcHighProfile); - CPPUNIT_ASSERT(track->version() == 4); - CPPUNIT_ASSERT(track->creationTime().year() == 2013); + CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Avc, track->format().general); + CPPUNIT_ASSERT_EQUAL(static_cast(SubFormats::AvcHighProfile), track->format().sub); + CPPUNIT_ASSERT_EQUAL(4.0, track->version()); + CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); CPPUNIT_ASSERT(track->pixelSize() == Size(1920, 750)); break; case 2: @@ -275,22 +275,23 @@ void OverallTests::checkMp4Testfile6() CPPUNIT_ASSERT_EQUAL(static_cast(SubFormats::AacMpeg4LowComplexityProfile), track->format().sub); CPPUNIT_ASSERT(!(track->format().extension & ExtensionFormats::SpectralBandReplication)); CPPUNIT_ASSERT(!(track->format().extension & ExtensionFormats::ParametricStereo)); - CPPUNIT_ASSERT_EQUAL("eng"s, track->language()); + CPPUNIT_ASSERT_EQUAL("ger"s, track->language()); + CPPUNIT_ASSERT_EQUAL("test"s, track->name()); CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency()); CPPUNIT_ASSERT_EQUAL(static_cast(Mpeg4ChannelConfigs::FrontLeftFrontRight), track->channelConfig()); break; case 3: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Audio); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Ac3); - CPPUNIT_ASSERT(track->language() == "eng"); - CPPUNIT_ASSERT(track->creationTime().year() == 2013); + CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Ac3, track->format().general); + CPPUNIT_ASSERT_EQUAL("eng"s, track->language()); + CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); break; case 4: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Audio); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::DtsHd); - CPPUNIT_ASSERT(track->language() == "eng"); - CPPUNIT_ASSERT(track->creationTime().year() == 2013); + CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::DtsHd, track->format().general); + CPPUNIT_ASSERT_EQUAL("eng"s, track->language()); + CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); break; case 5: CPPUNIT_ASSERT(track5Present = !track5Present); @@ -299,11 +300,12 @@ void OverallTests::checkMp4Testfile6() CPPUNIT_ASSERT_EQUAL(2012, track->creationTime().year()); CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency()); CPPUNIT_ASSERT_EQUAL(static_cast(Mpeg4ChannelConfigs::FrontLeftFrontRight), track->channelConfig()); + CPPUNIT_ASSERT_EQUAL("new track"s, track->name()); break; case 6: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Text); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::TimedText); - CPPUNIT_ASSERT(track->creationTime().year() == 2013); + CPPUNIT_ASSERT_EQUAL(MediaType::Text, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::TimedText, track->format().general); + CPPUNIT_ASSERT_EQUAL(2013, track->creationTime().year()); break; default: CPPUNIT_FAIL("unknown track ID"); @@ -317,7 +319,7 @@ void OverallTests::checkMp4Testfile6() CPPUNIT_ASSERT(track5Present); } - CPPUNIT_ASSERT(m_fileInfo.tags().size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, m_fileInfo.tags().size()); } /*! @@ -386,9 +388,13 @@ void OverallTests::setMp4TestMetaData() } /*! - * \brief Adds all tracks from mtx-test-data/mp4/10-DanseMacabreOp.40.m4a to the file to be tested. + * \brief Alters the tracks of the file to be testd. + * + * - Adds track from mtx-test-data/mp4/10-DanseMacabreOp.40.m4a + * - Sets the language of the 2nd track to German + * - Sets the name of the 2nd track to "test". */ -void OverallTests::addMp4Track() +void OverallTests::alterMp4Tracks() { m_additionalFileInfo.setPath(TestUtilities::testFilePath("mtx-test-data/mp4/10-DanseMacabreOp.40.m4a")); m_additionalFileInfo.reopen(true); @@ -401,7 +407,15 @@ void OverallTests::addMp4Track() CPPUNIT_ASSERT_EQUAL(TrackType::Mp4Track, tracks[0]->type()); auto *track = static_cast(tracks[0]); CPPUNIT_ASSERT(static_cast(m_additionalFileInfo.container())->removeTrack(track)); - static_cast(m_fileInfo.container())->addTrack(track); + CPPUNIT_ASSERT_EQUAL(0_st, m_additionalFileInfo.trackCount()); + track->setName("new track"); + auto *container = static_cast(m_fileInfo.container()); + CPPUNIT_ASSERT_EQUAL(5_st, container->trackCount()); + container->addTrack(track); + CPPUNIT_ASSERT_EQUAL(6_st, container->trackCount()); + auto &secondTrack = container->tracks()[1]; + secondTrack->setLanguage("ger"); + secondTrack->setName("test"); } /*! @@ -482,7 +496,7 @@ void OverallTests::testMp4Making() makeFile(TestUtilities::workingCopyPath("mtx-test-data/alac/othertest-itunes.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile4); makeFile(TestUtilities::workingCopyPath("mtx-test-data/aac/he-aacv2-ps.m4a"), modifyRoutine, &OverallTests::checkMp4Testfile5); // -> add/remove tracks - modifyRoutine = (m_mode & RemoveTagOrTrack) ? &OverallTests::removeSecondTrack : &OverallTests::addMp4Track; + modifyRoutine = (m_mode & RemoveTagOrTrack) ? &OverallTests::removeSecondTrack : &OverallTests::alterMp4Tracks; m_fileInfo.setTagPosition(ElementPosition::Keep); makeFile(TestUtilities::workingCopyPath("mtx-test-data/mp4/1080p-DTS-HD-7.1.mp4"), modifyRoutine, &OverallTests::checkMp4Testfile6); } diff --git a/tests/overallogg.cpp b/tests/overallogg.cpp index c804202..3df7f2d 100644 --- a/tests/overallogg.cpp +++ b/tests/overallogg.cpp @@ -42,7 +42,7 @@ void OverallTests::checkOggTestfile1() checkOggTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } } @@ -77,7 +77,7 @@ void OverallTests::checkOggTestfile2() checkOggTestMetaData(); break; case TagStatus::Removed: - CPPUNIT_ASSERT(tags.size() == 0); + CPPUNIT_ASSERT_EQUAL(0_st, tracks.size()); } }