mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 07:47:37 +00:00
LibVideo: Parse Matroska from ReadonlyBytes and keep the start position
Keeping the entire Matroska stream available is a prerequisite to being able to stream from it and seek to cue points.
This commit is contained in:
parent
2dfd236dcd
commit
be9de58932
3 changed files with 21 additions and 23 deletions
|
@ -15,7 +15,7 @@ DecoderErrorOr<NonnullOwnPtr<MatroskaDemuxer>> MatroskaDemuxer::from_file(String
|
||||||
|
|
||||||
DecoderErrorOr<NonnullOwnPtr<MatroskaDemuxer>> MatroskaDemuxer::from_data(ReadonlyBytes data)
|
DecoderErrorOr<NonnullOwnPtr<MatroskaDemuxer>> MatroskaDemuxer::from_data(ReadonlyBytes data)
|
||||||
{
|
{
|
||||||
return make<MatroskaDemuxer>(TRY(Reader::parse_matroska_from_data(data.data(), data.size())));
|
return make<MatroskaDemuxer>(TRY(Reader::parse_matroska_from_data(data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<Track> MatroskaDemuxer::get_tracks_for_type(TrackType type)
|
Vector<Track> MatroskaDemuxer::get_tracks_for_type(TrackType type)
|
||||||
|
|
|
@ -58,12 +58,12 @@ constexpr u32 TIMESTAMP_ID = 0xE7;
|
||||||
DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> Reader::parse_matroska_from_file(StringView path)
|
DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> Reader::parse_matroska_from_file(StringView path)
|
||||||
{
|
{
|
||||||
auto mapped_file = DECODER_TRY(DecoderErrorCategory::IO, Core::MappedFile::map(path));
|
auto mapped_file = DECODER_TRY(DecoderErrorCategory::IO, Core::MappedFile::map(path));
|
||||||
return parse_matroska_from_data((u8*)mapped_file->data(), mapped_file->size());
|
return parse_matroska_from_data(mapped_file->bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> Reader::parse_matroska_from_data(u8 const* data, size_t size)
|
DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> Reader::parse_matroska_from_data(ReadonlyBytes data)
|
||||||
{
|
{
|
||||||
Reader reader(data, size);
|
Reader reader(data);
|
||||||
return reader.parse();
|
return reader.parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,9 +426,10 @@ ErrorOr<u8> Reader::Streamer::read_octet()
|
||||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Ran out of stream data");
|
dbgln_if(MATROSKA_TRACE_DEBUG, "Ran out of stream data");
|
||||||
return Error::from_string_literal("Stream is out of data");
|
return Error::from_string_literal("Stream is out of data");
|
||||||
}
|
}
|
||||||
m_size_remaining--;
|
u8 byte = *data();
|
||||||
m_octets_read.last()++;
|
m_octets_read.last()++;
|
||||||
return *(m_data_ptr++);
|
m_position++;
|
||||||
|
return byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<i16> Reader::Streamer::read_i16()
|
ErrorOr<i16> Reader::Streamer::read_i16()
|
||||||
|
@ -438,7 +439,7 @@ ErrorOr<i16> Reader::Streamer::read_i16()
|
||||||
|
|
||||||
ErrorOr<u64> Reader::Streamer::read_variable_size_integer(bool mask_length)
|
ErrorOr<u64> Reader::Streamer::read_variable_size_integer(bool mask_length)
|
||||||
{
|
{
|
||||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Reading from offset {:p}", m_data_ptr);
|
dbgln_if(MATROSKA_TRACE_DEBUG, "Reading from offset {:p}", data());
|
||||||
auto length_descriptor = TRY(read_octet());
|
auto length_descriptor = TRY(read_octet());
|
||||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Reading VINT, first byte is {:#02x}", length_descriptor);
|
dbgln_if(MATROSKA_TRACE_DEBUG, "Reading VINT, first byte is {:#02x}", length_descriptor);
|
||||||
if (length_descriptor == 0)
|
if (length_descriptor == 0)
|
||||||
|
@ -495,9 +496,8 @@ ErrorOr<void> Reader::Streamer::drop_octets(size_t num_octets)
|
||||||
{
|
{
|
||||||
if (remaining() < num_octets)
|
if (remaining() < num_octets)
|
||||||
return Error::from_string_literal("Tried to drop octets past the end of the stream");
|
return Error::from_string_literal("Tried to drop octets past the end of the stream");
|
||||||
m_size_remaining -= num_octets;
|
m_position += num_octets;
|
||||||
m_octets_read.last() += num_octets;
|
m_octets_read.last() += num_octets;
|
||||||
m_data_ptr += num_octets;
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,28 +20,27 @@ namespace Video::Matroska {
|
||||||
|
|
||||||
class Reader {
|
class Reader {
|
||||||
public:
|
public:
|
||||||
Reader(u8 const* data, size_t size)
|
Reader(ReadonlyBytes data)
|
||||||
: m_streamer(data, size)
|
: m_streamer(data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> parse_matroska_from_file(StringView path);
|
static DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> parse_matroska_from_file(StringView path);
|
||||||
static DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> parse_matroska_from_data(u8 const*, size_t);
|
static DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> parse_matroska_from_data(ReadonlyBytes data);
|
||||||
|
|
||||||
DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> parse();
|
DecoderErrorOr<NonnullOwnPtr<MatroskaDocument>> parse();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Streamer {
|
class Streamer {
|
||||||
public:
|
public:
|
||||||
Streamer(u8 const* data, size_t size)
|
Streamer(ReadonlyBytes data)
|
||||||
: m_data_ptr(data)
|
: m_data(data)
|
||||||
, m_size_remaining(size)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 const* data() { return m_data_ptr; }
|
u8 const* data() { return m_data.data() + m_position; }
|
||||||
|
|
||||||
char const* data_as_chars() { return reinterpret_cast<char const*>(m_data_ptr); }
|
char const* data_as_chars() { return reinterpret_cast<char const*>(data()); }
|
||||||
|
|
||||||
size_t octets_read() { return m_octets_read.last(); }
|
size_t octets_read() { return m_octets_read.last(); }
|
||||||
|
|
||||||
|
@ -70,15 +69,14 @@ private:
|
||||||
|
|
||||||
ErrorOr<void> drop_octets(size_t num_octets);
|
ErrorOr<void> drop_octets(size_t num_octets);
|
||||||
|
|
||||||
bool at_end() const { return m_size_remaining == 0; }
|
bool at_end() const { return remaining() == 0; }
|
||||||
bool has_octet() const { return m_size_remaining >= 1; }
|
bool has_octet() const { return remaining() >= 1; }
|
||||||
|
|
||||||
size_t remaining() const { return m_size_remaining; }
|
size_t remaining() const { return m_data.size() - m_position; }
|
||||||
void set_remaining(size_t remaining) { m_size_remaining = remaining; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
u8 const* m_data_ptr { nullptr };
|
ReadonlyBytes m_data;
|
||||||
size_t m_size_remaining { 0 };
|
size_t m_position { 0 };
|
||||||
Vector<size_t> m_octets_read { 0 };
|
Vector<size_t> m_octets_read { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue