diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | core/metadata.cpp | 15 |
2 files changed, 14 insertions, 3 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ba284890..7d9a66a64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ - +- media: read timestamp from mvhd atom of QuickTime/MP4 style videos --- * Always add new entries at the very top of this file above other existing entries and this note. * Use this layout for new entries: `[Area]: [Details about the change] [reference thread / issue]` diff --git a/core/metadata.cpp b/core/metadata.cpp index e7cc0a08b..81371ba3f 100644 --- a/core/metadata.cpp +++ b/core/metadata.cpp @@ -184,6 +184,18 @@ static bool parseMP4(QFile &f, metadata *metadata) // Recurse into "moov", "trak", "mdia" and "udta" atoms atom_stack.push_back(atom_size); continue; + } else if (!memcmp(type, "mvhd", 4) && atom_size >= 100 && atom_size < 4096) { + std::vector<char> data(atom_size); + if (f.read(&data[0], atom_size) != static_cast<int>(atom_size)) + break; + + timestamp_t timestamp = getBE<uint32_t>(&data[4]); + + // Timestamp is given as seconds since midnight 1904/1/1. To be convertible to the UNIX epoch + // it must be larger than 2082844800. + // Note that we only set timestamp if not already set, because we give priority to XMP data. + if (!metadata->timestamp && timestamp >= 2082844800) + metadata->timestamp = timestamp - 2082844800; } else if (!memcmp(type, "mdhd", 4) && atom_size >= 24 && atom_size < 4096) { // Parse "mdhd" (media header). // Sanity check: size between 24 and 4096 @@ -235,9 +247,8 @@ static bool parseMP4(QFile &f, metadata *metadata) break; static const char xmp_uid[17] = "\xBE\x7A\xCF\xCB\x97\xA9\x42\xE8\x9C\x71\x99\x94\x91\xE3\xAF\xAC"; - if (!memcmp(&d[0], xmp_uid, 16)) { + if (!memcmp(&d[0], xmp_uid, 16)) parseXMP(&d[16], atom_size - 16, metadata); - } } else { // Jump over unknown atom if (!f.seek(f.pos() + atom_size)) // TODO: switch to QFile::skip() |