/src/serenity/Userland/Libraries/LibMedia/Containers/Matroska/Reader.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com> |
3 | | * Copyright (c) 2022, Gregory Bertilson <Zaggy1024@gmail.com> |
4 | | * |
5 | | * SPDX-License-Identifier: BSD-2-Clause |
6 | | */ |
7 | | |
8 | | #pragma once |
9 | | |
10 | | #include <AK/IntegralMath.h> |
11 | | #include <AK/Optional.h> |
12 | | #include <AK/OwnPtr.h> |
13 | | #include <LibCore/MappedFile.h> |
14 | | #include <LibMedia/DecoderError.h> |
15 | | |
16 | | #include "Document.h" |
17 | | |
18 | | namespace Media::Matroska { |
19 | | |
20 | | class SampleIterator; |
21 | | class Streamer; |
22 | | |
23 | | class Reader { |
24 | | public: |
25 | | typedef Function<DecoderErrorOr<IterationDecision>(TrackEntry const&)> TrackEntryCallback; |
26 | | |
27 | | static DecoderErrorOr<Reader> from_file(StringView path); |
28 | | static DecoderErrorOr<Reader> from_mapped_file(NonnullOwnPtr<Core::MappedFile> mapped_file); |
29 | | |
30 | | static DecoderErrorOr<Reader> from_data(ReadonlyBytes data); |
31 | | |
32 | 0 | EBMLHeader const& header() const { return m_header.value(); } |
33 | | |
34 | | DecoderErrorOr<SegmentInformation> segment_information(); |
35 | | |
36 | | DecoderErrorOr<void> for_each_track(TrackEntryCallback); |
37 | | DecoderErrorOr<void> for_each_track_of_type(TrackEntry::TrackType, TrackEntryCallback); |
38 | | DecoderErrorOr<NonnullRefPtr<TrackEntry>> track_for_track_number(u64); |
39 | | DecoderErrorOr<size_t> track_count(); |
40 | | |
41 | | DecoderErrorOr<SampleIterator> create_sample_iterator(u64 track_number); |
42 | | DecoderErrorOr<SampleIterator> seek_to_random_access_point(SampleIterator, Duration); |
43 | | DecoderErrorOr<Optional<Vector<CuePoint> const&>> cue_points_for_track(u64 track_number); |
44 | | DecoderErrorOr<bool> has_cues_for_track(u64 track_number); |
45 | | |
46 | | private: |
47 | | Reader(ReadonlyBytes data) |
48 | 5.57k | : m_data(data) |
49 | 5.57k | { |
50 | 5.57k | } |
51 | | |
52 | | DecoderErrorOr<void> parse_initial_data(); |
53 | | |
54 | | DecoderErrorOr<Optional<size_t>> find_first_top_level_element_with_id([[maybe_unused]] StringView element_name, u32 element_id); |
55 | | |
56 | | DecoderErrorOr<void> ensure_tracks_are_parsed(); |
57 | | DecoderErrorOr<void> parse_tracks(Streamer&); |
58 | | |
59 | | DecoderErrorOr<void> parse_cues(Streamer&); |
60 | | DecoderErrorOr<void> ensure_cues_are_parsed(); |
61 | | DecoderErrorOr<void> seek_to_cue_for_timestamp(SampleIterator&, Duration const&); |
62 | | |
63 | | RefPtr<Core::SharedMappedFile> m_mapped_file; |
64 | | ReadonlyBytes m_data; |
65 | | |
66 | | Optional<EBMLHeader> m_header; |
67 | | |
68 | | size_t m_segment_contents_position { 0 }; |
69 | | size_t m_segment_contents_size { 0 }; |
70 | | |
71 | | HashMap<u32, size_t> m_seek_entries; |
72 | | size_t m_last_top_level_element_position { 0 }; |
73 | | |
74 | | Optional<SegmentInformation> m_segment_information; |
75 | | |
76 | | OrderedHashMap<u64, NonnullRefPtr<TrackEntry>> m_tracks; |
77 | | |
78 | | // The vectors must be sorted by timestamp at all times. |
79 | | HashMap<u64, Vector<CuePoint>> m_cues; |
80 | | bool m_cues_have_been_parsed { false }; |
81 | | }; |
82 | | |
83 | | class SampleIterator { |
84 | | public: |
85 | | DecoderErrorOr<Block> next_block(); |
86 | 0 | Cluster const& current_cluster() const { return *m_current_cluster; } |
87 | 0 | Optional<Duration> const& last_timestamp() const { return m_last_timestamp; } |
88 | 0 | TrackEntry const& track() const { return *m_track; } |
89 | | |
90 | | private: |
91 | | friend class Reader; |
92 | | |
93 | | SampleIterator(RefPtr<Core::SharedMappedFile> file, ReadonlyBytes data, TrackEntry& track, u64 timestamp_scale, size_t position) |
94 | 0 | : m_file(move(file)) |
95 | 0 | , m_data(data) |
96 | 0 | , m_track(track) |
97 | 0 | , m_segment_timestamp_scale(timestamp_scale) |
98 | 0 | , m_position(position) |
99 | 0 | { |
100 | 0 | } |
101 | | |
102 | | DecoderErrorOr<void> seek_to_cue_point(CuePoint const& cue_point); |
103 | | |
104 | | RefPtr<Core::SharedMappedFile> m_file; |
105 | | ReadonlyBytes m_data; |
106 | | NonnullRefPtr<TrackEntry> m_track; |
107 | | u64 m_segment_timestamp_scale { 0 }; |
108 | | |
109 | | // Must always point to an element ID or the end of the stream. |
110 | | size_t m_position { 0 }; |
111 | | |
112 | | Optional<Duration> m_last_timestamp; |
113 | | |
114 | | Optional<Cluster> m_current_cluster; |
115 | | }; |
116 | | |
117 | | class Streamer { |
118 | | public: |
119 | | Streamer(ReadonlyBytes data) |
120 | 15.8k | : m_data(data) |
121 | 15.8k | { |
122 | 15.8k | } |
123 | | |
124 | 11.1M | u8 const* data() { return m_data.data() + m_position; } |
125 | | |
126 | 11.7k | char const* data_as_chars() { return reinterpret_cast<char const*>(data()); } |
127 | | |
128 | 1.44M | size_t octets_read() { return m_octets_read.last(); } |
129 | | |
130 | 52.0k | void push_octets_read() { m_octets_read.append(0); } |
131 | | |
132 | | void pop_octets_read() |
133 | 43.9k | { |
134 | 43.9k | auto popped = m_octets_read.take_last(); |
135 | 43.9k | if (!m_octets_read.is_empty()) |
136 | 43.9k | m_octets_read.last() += popped; |
137 | 43.9k | } |
138 | | |
139 | | ErrorOr<u8> read_octet(); |
140 | | |
141 | | ErrorOr<i16> read_i16(); |
142 | | |
143 | | ErrorOr<u64> read_variable_size_integer(bool mask_length = true); |
144 | | ErrorOr<i64> read_variable_size_signed_integer(); |
145 | | |
146 | | ErrorOr<u64> read_u64(); |
147 | | ErrorOr<double> read_float(); |
148 | | |
149 | | ErrorOr<ByteString> read_string(); |
150 | | |
151 | | ErrorOr<void> read_unknown_element(); |
152 | | |
153 | | ErrorOr<ReadonlyBytes> read_raw_octets(size_t num_octets); |
154 | | |
155 | 11.3M | size_t position() const { return m_position; } |
156 | 11.1M | size_t remaining() const { return m_data.size() - position(); } |
157 | | |
158 | 0 | bool at_end() const { return remaining() == 0; } |
159 | 10.8M | bool has_octet() const { return remaining() >= 1; } |
160 | | |
161 | | ErrorOr<void> seek_to_position(size_t position); |
162 | | |
163 | | private: |
164 | | ReadonlyBytes m_data; |
165 | | size_t m_position { 0 }; |
166 | | Vector<size_t> m_octets_read { 0 }; |
167 | | }; |
168 | | |
169 | | } |