corrected nanosecond unit change -> milliseconds

taglib/mp4/mp4chapterlist.h
• start​Time doc comment: 100​-nanosecond units → milliseconds

taglib/mp4/mp4chapterlist.cpp
• render​Chpl​Data: from​Long​Long(ch​.start​Time) → from​Long​Long(ch​.start​Time * 10000​LL)
• parse​Chpl​Data: ch​.start​Time = start​Time → ch​.start​Time = start​Time100ns / 10000​LL

taglib/mp4/mp4qtchapterlist.cpp
• read: current​Time * 10000000​.0 / timescale → current​Time * 1000​.0 / timescale
• build​Stts lambda: time100ns * timescale / 10000000​.0 → time​Ms * timescale / 1000​.0

tests/test_mp4.cpp
• All start​Time assignments and assertions divided by 10,000 (e.g. 300000000​LL → 30000​LL)
This commit is contained in:
Ryan Francesconi
2026-04-15 09:29:52 -07:00
parent c5ea13bb34
commit ba2441b378
4 changed files with 36 additions and 36 deletions

View File

@@ -149,8 +149,8 @@ namespace
if(i++ >= count)
break;
// Start time: 8 bytes big-endian
data.append(ByteVector::fromLongLong(ch.startTime));
// Start time: 8 bytes big-endian, on-disk format is 100-nanosecond units
data.append(ByteVector::fromLongLong(ch.startTime * 10000LL));
// Title: 1-byte length + UTF-8 bytes (max 255 bytes)
ByteVector titleBytes = ch.title.data(String::UTF8);
@@ -188,7 +188,7 @@ namespace
unsigned int count = static_cast<unsigned char>(data[pos++]);
for(unsigned int i = 0; i < count && pos + 9 <= data.size(); ++i) {
long long startTime = data.toLongLong(pos);
long long startTime100ns = data.toLongLong(pos);
pos += 8;
unsigned int titleLen = static_cast<unsigned char>(data[pos++]);
@@ -200,7 +200,7 @@ namespace
}
MP4::Chapter ch;
ch.startTime = startTime;
ch.startTime = startTime100ns / 10000LL;
ch.title = title;
chapters.append(ch);
}

View File

@@ -37,7 +37,7 @@ namespace TagLib {
* A single Nero-style chapter marker.
*/
struct TAGLIB_EXPORT Chapter {
long long startTime; //!< Start time in 100-nanosecond units
long long startTime; //!< Start time in milliseconds
String title;
};

View File

@@ -446,9 +446,9 @@ namespace
return ByteVector();
// Convert 100-ns units to timescale units
auto toTimescale = [timescale](long long time100ns) -> unsigned int {
auto toTimescale = [timescale](long long timeMs) -> unsigned int {
return static_cast<unsigned int>(
static_cast<double>(time100ns) * static_cast<double>(timescale) / 10000000.0 + 0.5);
static_cast<double>(timeMs) * static_cast<double>(timescale) / 1000.0 + 0.5);
};
unsigned int totalDuration = static_cast<unsigned int>(
@@ -992,12 +992,12 @@ MP4::MP4QTChapterList::read(MP4::File *file)
String title = readTextSample(file, offsets[sampleIndex], sampleSize);
long long startTime100ns = static_cast<long long>(
static_cast<double>(currentTime) * 10000000.0 /
long long startTimeMs = static_cast<long long>(
static_cast<double>(currentTime) * 1000.0 /
static_cast<double>(trackInfo.timescale) + 0.5);
Chapter ch;
ch.startTime = startTime100ns;
ch.startTime = startTimeMs;
ch.title = title;
chapters.append(ch);

View File

@@ -908,12 +908,12 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 300000000LL; // 30 seconds in 100ns units
ch2.startTime = 30000LL; // 30 seconds in ms
ch2.title = "Main Content";
chapters.append(ch2);
MP4::Chapter ch3;
ch3.startTime = 600000000LL; // 60 seconds
ch3.startTime = 60000LL; // 60 seconds in ms
ch3.title = "Conclusion";
chapters.append(ch3);
@@ -926,9 +926,9 @@ public:
CPPUNIT_ASSERT_EQUAL(3U, chapters.size());
CPPUNIT_ASSERT_EQUAL(0LL, chapters[0].startTime);
CPPUNIT_ASSERT_EQUAL(String("Introduction"), chapters[0].title);
CPPUNIT_ASSERT_EQUAL(300000000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(30000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(String("Main Content"), chapters[1].title);
CPPUNIT_ASSERT_EQUAL(600000000LL, chapters[2].startTime);
CPPUNIT_ASSERT_EQUAL(60000LL, chapters[2].startTime);
CPPUNIT_ASSERT_EQUAL(String("Conclusion"), chapters[2].title);
}
@@ -1009,7 +1009,7 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 100000000LL; // 10 seconds
ch2.startTime = 10000LL; // 10 seconds in ms
ch2.title = "Verse";
chapters.append(ch2);
@@ -1065,12 +1065,12 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 150000000LL; // 15 seconds
ch2.startTime = 15000LL; // 15 seconds in ms
ch2.title = "Verse";
chapters.append(ch2);
MP4::Chapter ch3;
ch3.startTime = 300000000LL; // 30 seconds
ch3.startTime = 30000LL; // 30 seconds in ms
ch3.title = "Outro";
chapters.append(ch3);
@@ -1083,9 +1083,9 @@ public:
CPPUNIT_ASSERT_EQUAL(3U, chapters.size());
CPPUNIT_ASSERT_EQUAL(0LL, chapters[0].startTime);
CPPUNIT_ASSERT_EQUAL(String("Intro"), chapters[0].title);
CPPUNIT_ASSERT_EQUAL(150000000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(15000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(String("Verse"), chapters[1].title);
CPPUNIT_ASSERT_EQUAL(300000000LL, chapters[2].startTime);
CPPUNIT_ASSERT_EQUAL(30000LL, chapters[2].startTime);
CPPUNIT_ASSERT_EQUAL(String("Outro"), chapters[2].title);
}
}
@@ -1104,7 +1104,7 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 100000000LL; // 10 seconds
ch2.startTime = 10000LL; // 10 seconds in ms
ch2.title = "Chapter 2";
chapters.append(ch2);
@@ -1153,7 +1153,7 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 100000000LL; // 10 seconds
ch2.startTime = 10000LL; // 10 seconds in ms
ch2.title = "Verse";
chapters.append(ch2);
@@ -1203,7 +1203,7 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 50000000LL; // 5 seconds
ch2.startTime = 5000LL; // 5 seconds in ms
ch2.title = "Old2";
chapters.append(ch2);
@@ -1225,12 +1225,12 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 100000000LL; // 10 seconds
ch2.startTime = 10000LL; // 10 seconds in ms
ch2.title = "New2";
chapters.append(ch2);
MP4::Chapter ch3;
ch3.startTime = 200000000LL; // 20 seconds
ch3.startTime = 20000LL; // 20 seconds in ms
ch3.title = "New3";
chapters.append(ch3);
@@ -1261,7 +1261,7 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 15000000LL; // 1.5 seconds in 100ns units
ch2.startTime = 1500LL; // 1.5 seconds in ms
ch2.title = "Precise";
chapters.append(ch2);
@@ -1273,7 +1273,7 @@ public:
MP4::ChapterList chapters = MP4::MP4QTChapterList::read(filename.c_str());
CPPUNIT_ASSERT_EQUAL(2U, chapters.size());
CPPUNIT_ASSERT_EQUAL(0LL, chapters[0].startTime);
CPPUNIT_ASSERT_EQUAL(15000000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(1500LL, chapters[1].startTime);
}
}
@@ -1286,17 +1286,17 @@ public:
{
MP4::ChapterList chapters;
MP4::Chapter ch1;
ch1.startTime = 100000000LL; // 10 seconds
ch1.startTime = 10000LL; // 10 seconds in ms
ch1.title = "One";
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 200000000LL; // 20 seconds
ch2.startTime = 20000LL; // 20 seconds in ms
ch2.title = "Two";
chapters.append(ch2);
MP4::Chapter ch3;
ch3.startTime = 300000000LL; // 30 seconds
ch3.startTime = 30000LL; // 30 seconds in ms
ch3.title = "Three";
chapters.append(ch3);
@@ -1307,9 +1307,9 @@ public:
{
MP4::ChapterList chapters = MP4::MP4QTChapterList::read(filename.c_str());
CPPUNIT_ASSERT_EQUAL(3U, chapters.size());
CPPUNIT_ASSERT_EQUAL(100000000LL, chapters[0].startTime);
CPPUNIT_ASSERT_EQUAL(200000000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(300000000LL, chapters[2].startTime);
CPPUNIT_ASSERT_EQUAL(10000LL, chapters[0].startTime);
CPPUNIT_ASSERT_EQUAL(20000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(30000LL, chapters[2].startTime);
CPPUNIT_ASSERT_EQUAL(String("One"), chapters[0].title);
CPPUNIT_ASSERT_EQUAL(String("Two"), chapters[1].title);
CPPUNIT_ASSERT_EQUAL(String("Three"), chapters[2].title);
@@ -1332,7 +1332,7 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 200000000LL; // 20 seconds
ch2.startTime = 20000LL; // 20 seconds in ms
ch2.title = "Beta";
chapters.append(ch2);
@@ -1348,7 +1348,7 @@ public:
CPPUNIT_ASSERT_EQUAL(2U, chapters.size());
CPPUNIT_ASSERT_EQUAL(0LL, chapters[0].startTime);
CPPUNIT_ASSERT_EQUAL(String("Alpha"), chapters[0].title);
CPPUNIT_ASSERT_EQUAL(200000000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(20000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(String("Beta"), chapters[1].title);
}
@@ -1384,7 +1384,7 @@ public:
chapters.append(ch1);
MP4::Chapter ch2;
ch2.startTime = 200000000LL; // 20 seconds
ch2.startTime = 20000LL; // 20 seconds in ms
ch2.title = "Beta";
chapters.append(ch2);
@@ -1400,7 +1400,7 @@ public:
CPPUNIT_ASSERT_EQUAL(2U, chapters.size());
CPPUNIT_ASSERT_EQUAL(0LL, chapters[0].startTime);
CPPUNIT_ASSERT_EQUAL(String("Alpha"), chapters[0].title);
CPPUNIT_ASSERT_EQUAL(200000000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(20000LL, chapters[1].startTime);
CPPUNIT_ASSERT_EQUAL(String("Beta"), chapters[1].title);
}