Set Matroska track meta-data when element not present
This commit is contained in:
parent
9b0d74b6ad
commit
6741e9ca0f
|
@ -151,15 +151,19 @@ bool FieldMapBasedTag<FieldType, Compare>::setValues(const typename FieldType::i
|
||||||
{
|
{
|
||||||
auto valuesIterator = values.cbegin();
|
auto valuesIterator = values.cbegin();
|
||||||
auto range = m_fields.equal_range(id);
|
auto range = m_fields.equal_range(id);
|
||||||
|
// iterate through all specified and all existing values
|
||||||
for(; valuesIterator != values.cend() && range.first != range.second; ++valuesIterator) {
|
for(; valuesIterator != values.cend() && range.first != range.second; ++valuesIterator) {
|
||||||
|
// replace existing value with non-empty specified value
|
||||||
if(!valuesIterator->isEmpty()) {
|
if(!valuesIterator->isEmpty()) {
|
||||||
range.first->second.setValue(*valuesIterator);
|
range.first->second.setValue(*valuesIterator);
|
||||||
++range.first;
|
++range.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// add remaining specified values (there are more specified values than existing ones)
|
||||||
for(; valuesIterator != values.cend(); ++valuesIterator) {
|
for(; valuesIterator != values.cend(); ++valuesIterator) {
|
||||||
m_fields.insert(std::make_pair(id, FieldType(id, *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) {
|
for(; range.first != range.second; ++range.first) {
|
||||||
range.first->second.setValue(TagValue());
|
range.first->second.setValue(TagValue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,28 +474,30 @@ MatroskaTrackHeaderMaker::MatroskaTrackHeaderMaker(const MatroskaTrack &track) :
|
||||||
m_track(track),
|
m_track(track),
|
||||||
m_dataSize(0)
|
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()) {
|
for(EbmlElement *trackInfoElement = m_track.m_trackElement->firstChild(); trackInfoElement; trackInfoElement = trackInfoElement->nextSibling()) {
|
||||||
switch(trackInfoElement->id()) {
|
switch(trackInfoElement->id()) {
|
||||||
case MatroskaIds::TrackNumber:
|
case MatroskaIds::TrackNumber:
|
||||||
m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.trackNumber());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackUID:
|
case MatroskaIds::TrackUID:
|
||||||
m_dataSize += 2 + 1 + EbmlElement::calculateUIntegerLength(m_track.id());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackName:
|
case MatroskaIds::TrackName:
|
||||||
m_dataSize += 2 + EbmlElement::calculateSizeDenotationLength(m_track.name().size()) + m_track.name().size();
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackLanguage:
|
case MatroskaIds::TrackLanguage:
|
||||||
m_dataSize += 3 + EbmlElement::calculateSizeDenotationLength(m_track.language().size()) + m_track.language().size();
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackFlagEnabled:
|
case MatroskaIds::TrackFlagEnabled:
|
||||||
m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.isEnabled());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackFlagDefault:
|
case MatroskaIds::TrackFlagDefault:
|
||||||
m_dataSize += 1 + 1 + EbmlElement::calculateUIntegerLength(m_track.isDefault());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackFlagForced:
|
case MatroskaIds::TrackFlagForced:
|
||||||
m_dataSize += 2 + 1 + EbmlElement::calculateUIntegerLength(m_track.isForced());
|
// skip recognized elements
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
trackInfoElement->makeBuffer();
|
trackInfoElement->makeBuffer();
|
||||||
|
@ -521,29 +523,30 @@ void MatroskaTrackHeaderMaker::make(ostream &stream) const
|
||||||
EbmlElement::makeSizeDenotation(m_dataSize, buffer + 2);
|
EbmlElement::makeSizeDenotation(m_dataSize, buffer + 2);
|
||||||
stream.write(buffer, 2 + m_sizeDenotationLength);
|
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()) {
|
for(EbmlElement *trackInfoElement = m_track.m_trackElement->firstChild(); trackInfoElement; trackInfoElement = trackInfoElement->nextSibling()) {
|
||||||
switch(trackInfoElement->id()) {
|
switch(trackInfoElement->id()) {
|
||||||
case MatroskaIds::TrackNumber:
|
case MatroskaIds::TrackNumber:
|
||||||
EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackNumber, m_track.trackNumber());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackUID:
|
case MatroskaIds::TrackUID:
|
||||||
EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackUID, m_track.id());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackName:
|
case MatroskaIds::TrackName:
|
||||||
EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackName, m_track.name());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackLanguage:
|
case MatroskaIds::TrackLanguage:
|
||||||
EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackLanguage, m_track.language());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackFlagEnabled:
|
case MatroskaIds::TrackFlagEnabled:
|
||||||
EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagEnabled, m_track.isEnabled());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackFlagDefault:
|
case MatroskaIds::TrackFlagDefault:
|
||||||
EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagDefault, m_track.isDefault());
|
|
||||||
break;
|
|
||||||
case MatroskaIds::TrackFlagForced:
|
case MatroskaIds::TrackFlagForced:
|
||||||
EbmlElement::makeSimpleElement(stream, MatroskaIds::TrackFlagForced, m_track.isForced());
|
// skip recognized elements
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
trackInfoElement->copyBuffer(stream);
|
trackInfoElement->copyBuffer(stream);
|
||||||
|
|
|
@ -37,13 +37,13 @@ void OverallTests::checkMkvTestfile1()
|
||||||
for(const auto &track : tracks) {
|
for(const auto &track : tracks) {
|
||||||
switch(track->id()) {
|
switch(track->id()) {
|
||||||
case 2422994868:
|
case 2422994868:
|
||||||
CPPUNIT_ASSERT(track->mediaType() == MediaType::Video);
|
CPPUNIT_ASSERT_EQUAL(MediaType::Video, track->mediaType());
|
||||||
CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::MicrosoftMpeg4);
|
CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::MicrosoftMpeg4, track->format().general);
|
||||||
break;
|
break;
|
||||||
case 3653291187:
|
case 3653291187:
|
||||||
CPPUNIT_ASSERT(track->mediaType() == MediaType::Audio);
|
CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
|
||||||
CPPUNIT_ASSERT(track->format() == GeneralMediaFormat::Mpeg1Audio);
|
CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Mpeg1Audio, track->format().general);
|
||||||
CPPUNIT_ASSERT(track->samplingFrequency() == 48000);
|
CPPUNIT_ASSERT_EQUAL(48000u, track->samplingFrequency());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CPPUNIT_FAIL("unknown track ID");
|
CPPUNIT_FAIL("unknown track ID");
|
||||||
|
@ -171,10 +171,17 @@ void OverallTests::checkMkvTestfile4()
|
||||||
case TagStatus::Original:
|
case TagStatus::Original:
|
||||||
case TagStatus::Removed:
|
case TagStatus::Removed:
|
||||||
CPPUNIT_ASSERT_EQUAL("und"s, track->language());
|
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;
|
break;
|
||||||
case TagStatus::TestMetaDataPresent:
|
case TagStatus::TestMetaDataPresent:
|
||||||
// not implemented yet, so currently still undefined instead of German
|
|
||||||
CPPUNIT_ASSERT_EQUAL("ger"s, track->language());
|
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;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -538,10 +545,14 @@ void OverallTests::setMkvTestMetaData()
|
||||||
if(fileName == "test4.mkv") {
|
if(fileName == "test4.mkv") {
|
||||||
// test4.mkv has no tag, so one must be created first
|
// test4.mkv has no tag, so one must be created first
|
||||||
container->createTag(TagTarget(50));
|
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);
|
MatroskaTrack *track = container->trackById(3171450505);
|
||||||
CPPUNIT_ASSERT(track);
|
CPPUNIT_ASSERT(track);
|
||||||
track->setLanguage("ger");
|
track->setLanguage("ger");
|
||||||
|
track->setName("the name");
|
||||||
|
track->setDefault(true);
|
||||||
|
track->setEnabled(true);
|
||||||
|
track->setForced(true);
|
||||||
} else if(fileName == "handbrake-chapters-2.mkv") {
|
} else if(fileName == "handbrake-chapters-2.mkv") {
|
||||||
// remove 2nd tag
|
// remove 2nd tag
|
||||||
m_fileInfo.removeTag(m_fileInfo.tags().at(1));
|
m_fileInfo.removeTag(m_fileInfo.tags().at(1));
|
||||||
|
|
Loading…
Reference in New Issue