Matroska: Read SamplingFrequency and Channels defaults when absent (#1358)

An Audio element without SamplingFrequency or Channels now reads their
defaults (RFC 9559: 8000 Hz, one channel) instead of 0, and the track
is no longer skipped when BitDepth is absent too. A track without an
Audio element is still skipped.
This commit is contained in:
Ryan Francesconi
2026-11-01 07:06:07 +01:00
committed by GitHub
parent 629b707fc5
commit d1bd220c26
2 changed files with 26 additions and 0 deletions
+4
View File
@@ -67,6 +67,10 @@ void EBML::MkTracks::parse(Matroska::Properties *properties) const
if(const Id trackEntryChildId = trackEntryChild->getId(); trackEntryChildId == Id::MkCodecID)
codecId = element_cast<Id::MkCodecID>(trackEntryChild)->getValue();
else if(trackEntryChildId == Id::MkAudio) {
// Their defaults (RFC 9559, 5.1.4.1.29), which a muxer may leave out
// when the value equals them (RFC 8794, 11.1.19).
samplingFrequency = 8000.0;
channels = 1;
const auto audio = element_cast<Id::MkAudio>(trackEntryChild);
for(const auto &audioChild : *audio) {
if(const Id audioChildId = audioChild->getId(); audioChildId == Id::MkSamplingFrequency)
+22
View File
@@ -219,6 +219,7 @@ class TestMatroska : public CppUnit::TestFixture
CPPUNIT_TEST(testPropertiesMka);
CPPUNIT_TEST(testPropertiesMkv);
CPPUNIT_TEST(testPropertiesWebm);
CPPUNIT_TEST(testPropertiesAudioDefaults);
CPPUNIT_TEST(testSimpleTagsAndAttachments);
CPPUNIT_TEST(testAddRemoveTagsAttachments);
CPPUNIT_TEST(testTagsWebm);
@@ -291,6 +292,27 @@ public:
CPPUNIT_ASSERT(!noProps.audioProperties());
}
void testPropertiesAudioDefaults()
{
// no-tags.mka's Audio element holds SamplingFrequency (44100) and Channels (2).
// Replaced by Void elements of the same size, they are absent, and their
// defaults apply.
ScopedFileCopy copy("no-tags", ".mka");
{
FileStream stream(copy.fileName().c_str());
const ByteVector audio("\xe1\x89\xb5\x84\x47\x2c\x44\x00\x9f\x81\x02", 11);
const offset_t offset = stream.readBlock(stream.length()).find(audio);
CPPUNIT_ASSERT(offset > 0);
stream.seek(offset + 2);
stream.writeBlock(ByteVector("\xec\x84\x00\x00\x00\x00\xec\x81\x00", 9));
}
Matroska::File f(copy.fileName().c_str());
CPPUNIT_ASSERT(f.audioProperties());
CPPUNIT_ASSERT_EQUAL(8000, f.audioProperties()->sampleRate());
CPPUNIT_ASSERT_EQUAL(1, f.audioProperties()->channels());
CPPUNIT_ASSERT_EQUAL(String("A_MPEG/L3"), f.audioProperties()->codecName());
}
void testSimpleTagsAndAttachments()
{
ScopedFileCopy copy("no-tags", ".mka");