From 3a2f6c700d43e7a8f6668c5b5240f80edd7117eb Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Sat, 29 Oct 2022 17:01:01 -0500 Subject: [PATCH] LibVideo: Parse the duration of Matroska files --- .../Libraries/LibVideo/MatroskaDocument.h | 3 ++ .../Libraries/LibVideo/MatroskaReader.cpp | 30 +++++++++++++++++++ Userland/Libraries/LibVideo/MatroskaReader.h | 1 + 3 files changed, 34 insertions(+) diff --git a/Userland/Libraries/LibVideo/MatroskaDocument.h b/Userland/Libraries/LibVideo/MatroskaDocument.h index daa25378f91..ed416be1286 100644 --- a/Userland/Libraries/LibVideo/MatroskaDocument.h +++ b/Userland/Libraries/LibVideo/MatroskaDocument.h @@ -30,11 +30,14 @@ public: void set_muxing_app(String muxing_app) { m_muxing_app = move(muxing_app); } Utf8View writing_app() const { return Utf8View(m_writing_app); } void set_writing_app(String writing_app) { m_writing_app = move(writing_app); } + Optional duration() const { return m_duration; } + void set_duration(double duration) { m_duration.emplace(duration); } private: u64 m_timestamp_scale { 1'000'000 }; String m_muxing_app; String m_writing_app; + Optional m_duration; }; class TrackEntry { diff --git a/Userland/Libraries/LibVideo/MatroskaReader.cpp b/Userland/Libraries/LibVideo/MatroskaReader.cpp index 78e60228325..24036a4cee5 100644 --- a/Userland/Libraries/LibVideo/MatroskaReader.cpp +++ b/Userland/Libraries/LibVideo/MatroskaReader.cpp @@ -26,6 +26,7 @@ constexpr u32 CLUSTER_ELEMENT_ID = 0x1F43B675; constexpr u32 TIMESTAMP_SCALE_ID = 0x2AD7B1; constexpr u32 MUXING_APP_ID = 0x4D80; constexpr u32 WRITING_APP_ID = 0x5741; +constexpr u32 DURATION_ID = 0x4489; // Tracks constexpr u32 TRACK_ENTRY_ID = 0xAE; @@ -195,6 +196,11 @@ OwnPtr MatroskaReader::parse_information() CHECK_HAS_VALUE(writing_app); segment_information->set_writing_app(writing_app.value()); dbgln_if(MATROSKA_DEBUG, "Read WritingApp attribute: {}", writing_app.value()); + } else if (element_id == DURATION_ID) { + auto duration = read_float_element(); + CHECK_HAS_VALUE(duration); + segment_information->set_duration(duration.value()); + dbgln_if(MATROSKA_DEBUG, "Read Duration attribute: {}", duration.value()); } else { return read_unknown_element(); } @@ -516,6 +522,30 @@ Optional MatroskaReader::read_u64_element() return result; } +Optional MatroskaReader::read_float_element() +{ + auto length = m_streamer.read_variable_size_integer(); + if (!length.has_value() || m_streamer.remaining() < length.value()) + return {}; + if (length != 4u && length != 8u) + return {}; + + union { + u64 value; + float float_value; + double double_value; + } read_data; + read_data.value = 0; + for (size_t i = 0; i < length.value(); i++) { + if (!m_streamer.has_octet()) + return {}; + read_data.value = (read_data.value << 8u) + m_streamer.read_octet(); + } + if (length == 4u) + return read_data.float_value; + return read_data.double_value; +} + bool MatroskaReader::read_unknown_element() { auto element_length = m_streamer.read_variable_size_integer(); diff --git a/Userland/Libraries/LibVideo/MatroskaReader.h b/Userland/Libraries/LibVideo/MatroskaReader.h index 36c2a39165a..7dd140f26d3 100644 --- a/Userland/Libraries/LibVideo/MatroskaReader.h +++ b/Userland/Libraries/LibVideo/MatroskaReader.h @@ -166,6 +166,7 @@ private: Optional read_string_element(); Optional read_u64_element(); + Optional read_float_element(); bool read_unknown_element(); Streamer m_streamer;