4#include "../abstracttrack.h"
6#include "../vorbis/vorbiscomment.h"
8#include <c++utilities/io/misc.h>
17void OverallTests::checkOggTestfile1()
19 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Ogg, m_fileInfo.
containerFormat());
20 const auto tracks = m_fileInfo.
tracks();
21 CPPUNIT_ASSERT_EQUAL(2_st, tracks.size());
22 for (
const auto &track : tracks) {
23 switch (track->id()) {
25 CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
26 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Theora, track->format().general);
29 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
30 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Vorbis, track->format().general);
31 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2), track->channelCount());
32 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
33 CPPUNIT_ASSERT_EQUAL(4, track->duration().minutes());
36 CPPUNIT_FAIL(
"unknown track ID");
39 const auto tags = m_fileInfo.
tags();
40 switch (m_tagStatus) {
43 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
44 CPPUNIT_ASSERT_EQUAL(
"ffmpeg2theora 0.13"s, tags.front()->value(KnownField::Encoder).toString());
45 CPPUNIT_ASSERT_EQUAL(std::vector<std::uint64_t>{ 0x68a1ea7f }, tags.front()->target().tracks());
50 checkOggTestMetaData();
53 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
56 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
62void OverallTests::checkOggTestfile2()
64 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Ogg, m_fileInfo.
containerFormat());
65 const auto tracks = m_fileInfo.
tracks();
66 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
67 for (
const auto &track : tracks) {
68 switch (track->id()) {
70 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
71 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Opus, track->format().general);
72 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2), track->channelCount());
73 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
74 CPPUNIT_ASSERT_EQUAL(1, track->duration().minutes());
77 CPPUNIT_FAIL(
"unknown track ID");
80 const auto tags = m_fileInfo.
tags();
81 switch (m_tagStatus) {
84 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
85 CPPUNIT_ASSERT_EQUAL(
"opusenc from opus-tools 0.1.6"s, tags.front()->value(KnownField::Encoder).toString());
88 checkOggTestMetaData();
91 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
94 CPPUNIT_ASSERT(m_diag.
level() <= DiagLevel::Information);
100void OverallTests::checkOggTestfile3()
102 CPPUNIT_ASSERT_EQUAL(ContainerFormat::Ogg, m_fileInfo.
containerFormat());
103 const auto tracks = m_fileInfo.
tracks();
104 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
105 for (
const auto &track : tracks) {
106 switch (track->id()) {
108 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
109 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Opus, track->format().general);
110 CPPUNIT_ASSERT_EQUAL(
static_cast<std::uint16_t
>(2), track->channelCount());
111 CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
112 CPPUNIT_ASSERT_EQUAL(TimeSpan::fromSeconds(19.461), track->duration());
115 CPPUNIT_FAIL(
"unknown track ID");
118 const auto tags = m_fileInfo.
tags();
119 switch (m_tagStatus) {
122 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
123 CPPUNIT_ASSERT_EQUAL(
"Lavf58.76.100"s, tags.front()->value(KnownField::Encoder).toString());
124 CPPUNIT_ASSERT_EQUAL(
"eng"s, tags.front()->value(KnownField::Language).toString());
127 checkOggTestMetaDataCover();
130 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
134 CPPUNIT_ASSERT_MESSAGE(
"no warnings for non-broken file", m_diag.
level() <= DiagLevel::Information);
137 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"warning present", DiagLevel::Warning, m_diag.
level());
138 for (
const auto &msg : m_diag) {
139 if (msg.level() == DiagLevel::Warning) {
140 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"warning due to broken segment termination",
"3 bytes left in last segment."s, msg.message());
141 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"warning relates to Vorbis comment",
"parsing Vorbis comment"s, msg.context());
150void OverallTests::checkOggTestMetaData()
153 const auto tags = m_fileInfo.
tags();
155 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
156 CPPUNIT_ASSERT(tag !=
nullptr);
159 CPPUNIT_ASSERT_EQUAL(m_testTitle, tag->value(KnownField::Title));
160 CPPUNIT_ASSERT_EQUAL(m_testComment.
toString(), tag->value(KnownField::Comment).toString());
161 CPPUNIT_ASSERT_EQUAL(m_testAlbum, tag->value(KnownField::Album));
162 CPPUNIT_ASSERT_EQUAL(m_preservedMetaData.front(), tag->value(KnownField::Artist));
163 CPPUNIT_ASSERT_EQUAL(m_testPosition, tag->value(KnownField::TrackPosition));
164 CPPUNIT_ASSERT_EQUAL(m_testPosition, tag->value(KnownField::DiskPosition));
166 m_preservedMetaData.pop();
169void OverallTests::checkOggTestMetaDataCover()
172 const auto tags = m_fileInfo.
tags();
174 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
175 CPPUNIT_ASSERT(tag !=
nullptr);
177 const auto expectedCoverData = readFile(testFilePath(
"ogg/example-cover.png"));
178 CPPUNIT_ASSERT_EQUAL_MESSAGE(
"expected cover assigned", std::string_view(expectedCoverData), tag->value(KnownField::Cover).data());
181void OverallTests::setOggTestMetaData()
187 tag->
setValue(KnownField::Title, m_testTitle);
188 tag->setValue(KnownField::Comment, m_testComment);
189 tag->setValue(KnownField::Album, m_testAlbum);
190 m_preservedMetaData.push(tag->value(KnownField::Artist));
191 tag->setValue(KnownField::TrackPosition, m_testPosition);
192 tag->setValue(KnownField::DiskPosition, m_testPosition);
196void OverallTests::setOggTestMetaDataCover()
199 const auto cover = readFile(testFilePath(
"ogg/example-cover.png"));
200 tag->setValue(KnownField::Cover,
TagValue(
cover.data(),
cover.size(), TagDataType::Picture));
209 cerr << endl <<
"OGG parser" << endl;
212 parseFile(testFilePath(
"mtx-test-data/ogg/qt4dance_medium.ogg"), &OverallTests::checkOggTestfile1);
213 parseFile(testFilePath(
"mtx-test-data/opus/v-opus.ogg"), &OverallTests::checkOggTestfile2);
214 parseFile(testFilePath(
"ogg/noise-broken-segment-termination.opus"), &OverallTests::checkOggTestfile3);
229 for (m_mode = 0; m_mode != 0x2; ++m_mode) {
236 list<string> testConditions;
237 if (m_mode & RemoveTag) {
238 testConditions.emplace_back(
"removing tag");
240 testConditions.emplace_back(
"modifying tag");
242 cerr << endl <<
"OGG maker - testmode " << m_mode <<
": " << joinStrings(testConditions,
", ") << endl;
246 const auto modifyRoutine = (m_mode & RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setOggTestMetaData;
247 const auto modifyRoutineCover = (m_mode & RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setOggTestMetaDataCover;
248 makeFile(workingCopyPath(
"mtx-test-data/ogg/qt4dance_medium.ogg"), modifyRoutine, &OverallTests::checkOggTestfile1);
249 makeFile(workingCopyPath(
"mtx-test-data/opus/v-opus.ogg"), modifyRoutine, &OverallTests::checkOggTestfile2);
250 makeFile(workingCopyPath(
"ogg/noise-without-cover.opus"), modifyRoutineCover, &OverallTests::checkOggTestfile3);
void testOggParsing()
Tests the Ogg parser via MediaFileInfo.
void testOggMaking()
Tests the Ogg maker via MediaFileInfo.
DiagLevel level() const
Returns the worst diag level present in the container.
The TagValue class wraps values of different types.
std::string toString(TagTextEncoding encoding=TagTextEncoding::Unspecified) const
Converts the value of the current TagValue object to its equivalent std::string representation.