MP4: Reuse parsed atoms when lazily reading chapters (#1460)

neroChapters() and qtChapters() parsed the whole atom tree again on first
use, although the file already holds it from opening. They now use the
parsed atoms, and parse them again after a save or strip, which can move
atoms.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
MSOB7Y
2026-10-17 07:32:51 +02:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 649607f1fc
commit 96970251ce
7 changed files with 90 additions and 7 deletions
+32
View File
@@ -179,6 +179,7 @@ class TestMP4 : public CppUnit::TestFixture
CPPUNIT_TEST(testNeroAndQTChaptersAreIndependent);
CPPUNIT_TEST(testNeroChaptersAloneWhenNoQT);
CPPUNIT_TEST(testLazyReadingAndWritingChapters);
CPPUNIT_TEST(testReadingChaptersAfterSave);
CPPUNIT_TEST_SUITE_END();
public:
@@ -1992,6 +1993,37 @@ public:
}
}
void testReadingChaptersAfterSave()
{
ScopedFileCopy copy("has-tags", ".m4a");
string filename = copy.fileName();
{
MP4::File f(filename.c_str());
f.setNeroChapters(MP4::ChapterList{
MP4::Chapter("Nero 1", 0),
MP4::Chapter("Nero 2", 10000LL)
});
CPPUNIT_ASSERT(f.save());
}
// Writing QT chapters moves atoms, chapters first read afterwards must
// not use the atoms parsed when the file was opened.
{
MP4::File f(filename.c_str());
f.setQtChapters(MP4::ChapterList{
MP4::Chapter("QT 1", 0),
MP4::Chapter("QT 2", 20000LL)
});
CPPUNIT_ASSERT(f.save());
const MP4::ChapterList nero = f.neroChapters();
CPPUNIT_ASSERT_EQUAL(2U, nero.size());
CPPUNIT_ASSERT_EQUAL(String("Nero 2"), nero[1].title());
CPPUNIT_ASSERT_EQUAL(10000LL, nero[1].startTime());
}
}
};
CPPUNIT_TEST_SUITE_REGISTRATION(TestMP4);