Matroska: read the segment title without audio properties (#1409)

Matroska::Tag::title() falls back to \Segment\Info\Title when a file has
no TITLE simple tag. That title was only extracted inside read()'s
readProperties branch, because Info is also where the audio properties
come from, so opening a file with readAudioProperties = false left the
tag with an empty title:

  FileRef(path, true ).tag()->title();  // "handbrake"
  FileRef(path, false).tag()->title();  // ""

Reading tags without audio properties is the documented fast path for
scanning a library, so this silently emptied the title for exactly the
callers who opted into it, and it made tag content depend on an
audio-properties flag in a way no other format does.

Store the segment title on the file itself, read regardless of
readProperties, and use it from both read() and tag(). The Info element
is already resident by then, so no additional I/O is involved and
audioProperties() still returns null when properties were not requested.
This commit is contained in:
Ryan Francesconi
2026-08-13 06:28:38 +02:00
committed by GitHub
parent e37ee8498f
commit b2e27c3a45
6 changed files with 55 additions and 11 deletions
+19
View File
@@ -185,6 +185,7 @@ class TestMatroska : public CppUnit::TestFixture
CPPUNIT_TEST(testFastReadStyleLargeSegment);
CPPUNIT_TEST(testAttachedFileDataReadOnDemand);
CPPUNIT_TEST(testSaveUnrequestedAttachedFileData);
CPPUNIT_TEST(testSegmentTitleWithoutAudioProperties);
CPPUNIT_TEST_SUITE_END();
public:
@@ -1908,6 +1909,24 @@ public:
}
}
void testSegmentTitleWithoutAudioProperties()
{
// optimized.mkv keeps its title in \Segment\Info\Title and has no TITLE
// simple tag, so Tag::title() falls back to the segment title. That fallback
// must not depend on whether the audio properties were read.
for(const bool readProperties : {true, false}) {
Matroska::File f(TEST_FILE_PATH_C("optimized.mkv"), readProperties);
CPPUNIT_ASSERT(f.isValid());
CPPUNIT_ASSERT_EQUAL(readProperties, f.audioProperties() != nullptr);
CPPUNIT_ASSERT_EQUAL(String("handbrake"), f.tag()->title());
}
// A file without a segment title still reports an empty title.
Matroska::File noTitle(TEST_FILE_PATH_C("no-tags.mka"), false);
CPPUNIT_ASSERT(noTitle.isValid());
CPPUNIT_ASSERT_EQUAL(String(""), noTitle.tag()->title());
}
void testUnknownSizeSegment()
{
ScopedFileCopy copy("no-tags", ".mka");