From 6741e9ca0fe05076d79c538dec9bae92575fb34c Mon Sep 17 00:00:00 2001 From: Martchus Date: Wed, 14 Jun 2017 22:46:33 +0200 Subject: [PATCH] Set Matroska track meta-data when element not present --- fieldbasedtag.h | 4 +++ matroska/matroskatrack.cpp | 57 ++++++++++++++++++++------------------ tests/overallmkv.cpp | 25 ++++++++++++----- 3 files changed, 52 insertions(+), 34 deletions(-) diff --git a/fieldbasedtag.h b/fieldbasedtag.h index ef97091..6fe6da1 100644 --- a/fieldbasedtag.h +++ b/fieldbasedtag.h @@ -151,15 +151,19 @@ bool FieldMapBasedTag::setValues(const typename FieldType::i { auto valuesIterator = values.cbegin(); auto range = m_fields.equal_range(id); + // iterate through all specified and all existing values for(; valuesIterator != values.cend() && range.first != range.second; ++valuesIterator) { + // replace existing value with non-empty specified value if(!valuesIterator->isEmpty()) { range.first->second.setValue(*valuesIterator); ++range.first; } } + // add remaining specified values (there are more specified values than existing ones) for(; valuesIterator != values.cend(); ++valuesIterator) { m_fields.insert(std::make_pair(id, FieldType(id, *valuesIterator))); } + // remove remaining existing values (there are more existing values than specified ones) for(; range.first != range.second; ++range.first) { range.first->second.setValue(TagValue()); } diff --git a/matroska/matroskatrack.cpp b/matroska/matroskatrack.cpp index d39b201..f1c13f4 100644 --- a/matroska/matroskatrack.cpp +++ b/matroska/matroskatrack.cpp @@ -474,28 +474,30 @@ MatroskaTrackHeaderMaker::MatroskaTrackHeaderMaker(const MatroskaTrack &track) : m_track(track), m_dataSize(0) { + // calculate size for recognized elements + m_dataSize += 2 + 1 + EbmlElement::calculateUIntegerLength(m_track.id()); + m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.trackNumber()); + m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.isEnabled()); + m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.isDefault()); + m_dataSize += 2 + 1 + EbmlElement::calculateUIntegerLength(m_track.isForced()); + if(!m_track.name().empty()) { + m_dataSize += 2 + EbmlElement::calculateSizeDenotationLength(m_track.name().size()) + m_track.name().size(); + } + if(!m_track.language().empty()) { + m_dataSize += 3 + EbmlElement::calculateSizeDenotationLength(m_track.language().size()) + m_track.language().size(); + } + + // calculate size for other elements for(EbmlElement *trackInfoElement = m_track.m_trackElement->firstChild(); trackInfoElement; trackInfoElement = trackInfoElement->nextSibling()) { switch(trackInfoElement->id()) { case MatroskaIds::TrackNumber: - m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.trackNumber()); - break; case MatroskaIds::TrackUID: - m_dataSize += 2 + 1 + EbmlElement::calculateUIntegerLength(m_track.id()); - break; case MatroskaIds::TrackName: - m_dataSize += 2 + EbmlElement::calculateSizeDenotationLength(m_track.name().size()) + m_track.name().size(); - break; case MatroskaIds::TrackLanguage: - m_dataSize += 3 + EbmlElement::calculateSizeDenotationLength(m_track.language().size()) + m_track.language().size(); - break; case MatroskaIds::TrackFlagEnabled: - m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.isEnabled()); - break; case MatroskaIds::TrackFlagDefault: - m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.isDefault()); - break; case MatroskaIds::TrackFlagForced: - m_dataSize += 2 + 1 + EbmlElement::calculateUIntegerLength(m_track.isForced()); + // skip recognized elements break; default: trackInfoElement->makeBuffer(); @@ -521,29 +523,30 @@ void MatroskaTrackHeaderMaker::make(ostream &stream) const EbmlElement::makeSizeDenotation(m_dataSize, buffer + 2); stream.write(buffer, 2 + m_sizeDenotationLength); - // make child elements + // make recognized elements + EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackUID, m_track.id()); + EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackNumber, m_track.trackNumber()); + EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagEnabled, m_track.isEnabled()); + EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagDefault, m_track.isDefault()); + EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagForced, m_track.isForced()); + if(!m_track.name().empty()) { + EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackName, m_track.name()); + } + if(!m_track.language().empty()) { + EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackLanguage, m_track.language()); + } + + // make other elements for(EbmlElement *trackInfoElement = m_track.m_trackElement->firstChild(); trackInfoElement; trackInfoElement = trackInfoElement->nextSibling()) { switch(trackInfoElement->id()) { case MatroskaIds::TrackNumber: - EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackNumber, m_track.trackNumber()); - break; case MatroskaIds::TrackUID: - EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackUID, m_track.id()); - break; case MatroskaIds::TrackName: - EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackName, m_track.name()); - break; case MatroskaIds::TrackLanguage: - EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackLanguage, m_track.language()); - break; case MatroskaIds::TrackFlagEnabled: - EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagEnabled, m_track.isEnabled()); - break; case MatroskaIds::TrackFlagDefault: - EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagDefault, m_track.isDefault()); - break; case MatroskaIds::TrackFlagForced: - EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagForced, m_track.isForced()); + // skip recognized elements break; default: trackInfoElement->copyBuffer(stream); diff --git a/tests/overallmkv.cpp b/tests/overallmkv.cpp index c1c2697..dfcb8d5 100644 --- a/tests/overallmkv.cpp +++ b/tests/overallmkv.cpp @@ -37,13 +37,13 @@ void OverallTests::checkMkvTestfile1() for(const auto &track : tracks) { switch(track->id()) { case 2422994868: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Video); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::MicrosoftMpeg4); + CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::MicrosoftMpeg4, track->format().general); break; case 3653291187: - CPPUNIT_ASSERT(track->mediaType() == MediaType::Audio); - CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Mpeg1Audio); - CPPUNIT_ASSERT(track->samplingFrequency() == 48000); + CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType()); + CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Mpeg1Audio, track->format().general); + CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency()); break; default: CPPUNIT_FAIL("unknown track ID"); @@ -171,10 +171,17 @@ void OverallTests::checkMkvTestfile4() case TagStatus::Original: case TagStatus::Removed: CPPUNIT_ASSERT_EQUAL("und"s, track->language()); + CPPUNIT_ASSERT_EQUAL(string(), track->name()); + CPPUNIT_ASSERT(track->isEnabled()); + CPPUNIT_ASSERT(!track->isForced()); + CPPUNIT_ASSERT(!track->isDefault()); break; case TagStatus::TestMetaDataPresent: - // not implemented yet, so currently still undefined instead of German CPPUNIT_ASSERT_EQUAL("ger"s, track->language()); + CPPUNIT_ASSERT_EQUAL("the name"s, track->name()); + CPPUNIT_ASSERT(track->isEnabled()); + CPPUNIT_ASSERT(track->isForced()); + CPPUNIT_ASSERT(track->isDefault()); break; } break; @@ -538,10 +545,14 @@ void OverallTests::setMkvTestMetaData() if(fileName == "test4.mkv") { // test4.mkv has no tag, so one must be created first container->createTag(TagTarget(50)); - // also change language of track "3171450505" to German + // also change language, name, forced and default of track "3171450505" to German MatroskaTrack *track = container->trackById(3171450505); CPPUNIT_ASSERT(track); track->setLanguage("ger"); + track->setName("the name"); + track->setDefault(true); + track->setEnabled(true); + track->setForced(true); } else if(fileName == "handbrake-chapters-2.mkv") { // remove 2nd tag m_fileInfo.removeTag(m_fileInfo.tags().at(1));