Set Matroska track meta-data when element not present

This commit is contained in:
Martchus 2017-06-14 22:46:33 +02:00
parent 9b0d74b6ad
commit 6741e9ca0f
3 changed files with 52 additions and 34 deletions

View File

@ -151,15 +151,19 @@ bool FieldMapBasedTag<FieldType, Compare>::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());
}

View File

@ -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);

View File

@ -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));