mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 11:27:35 +00:00
LibVideo: Reorganize demuxer file hierarchy and rename Matroska files
As new demuxers are added, this will get quite full of files, so it'll be good to have a separate folder for these. To avoid too many chained namespaces, the Containers subdirectory is not also a namespace, but the Matroska folder is for the sake of separating the multiple classes for parsed information entering the Video namespace.
This commit is contained in:
parent
edec6bdc32
commit
9cf7e8c5aa
13 changed files with 56 additions and 58 deletions
175
Userland/Libraries/LibVideo/Containers/Matroska/Reader.h
Normal file
175
Userland/Libraries/LibVideo/Containers/Matroska/Reader.h
Normal file
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Document.h"
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/IntegralMath.h>
|
||||
#include <AK/NonnullOwnPtrVector.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
|
||||
namespace Video::Matroska {
|
||||
|
||||
class Reader {
|
||||
public:
|
||||
Reader(u8 const* data, size_t size)
|
||||
: m_streamer(data, size)
|
||||
{
|
||||
}
|
||||
|
||||
static OwnPtr<MatroskaDocument> parse_matroska_from_file(StringView path);
|
||||
static OwnPtr<MatroskaDocument> parse_matroska_from_data(u8 const*, size_t);
|
||||
|
||||
OwnPtr<MatroskaDocument> parse();
|
||||
|
||||
private:
|
||||
class Streamer {
|
||||
public:
|
||||
Streamer(u8 const* data, size_t size)
|
||||
: m_data_ptr(data)
|
||||
, m_size_remaining(size)
|
||||
{
|
||||
}
|
||||
|
||||
u8 const* data() { return m_data_ptr; }
|
||||
|
||||
char const* data_as_chars() { return reinterpret_cast<char const*>(m_data_ptr); }
|
||||
|
||||
u8 read_octet()
|
||||
{
|
||||
VERIFY(m_size_remaining >= 1);
|
||||
m_size_remaining--;
|
||||
m_octets_read.last()++;
|
||||
return *(m_data_ptr++);
|
||||
}
|
||||
|
||||
i16 read_i16()
|
||||
{
|
||||
return (read_octet() << 8) | read_octet();
|
||||
}
|
||||
|
||||
size_t octets_read() { return m_octets_read.last(); }
|
||||
|
||||
void push_octets_read() { m_octets_read.append(0); }
|
||||
|
||||
void pop_octets_read()
|
||||
{
|
||||
auto popped = m_octets_read.take_last();
|
||||
if (!m_octets_read.is_empty())
|
||||
m_octets_read.last() += popped;
|
||||
}
|
||||
|
||||
Optional<u64> read_variable_size_integer(bool mask_length = true)
|
||||
{
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Reading from offset {:p}", m_data_ptr);
|
||||
if (!has_octet()) {
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Ran out of stream data");
|
||||
return {};
|
||||
}
|
||||
auto length_descriptor = read_octet();
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Reading VINT, first byte is {:#02x}", length_descriptor);
|
||||
if (length_descriptor == 0)
|
||||
return {};
|
||||
size_t length = 0;
|
||||
while (length < 8) {
|
||||
if (length_descriptor & (1u << (8 - length)))
|
||||
break;
|
||||
length++;
|
||||
}
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Reading VINT of total length {}", length);
|
||||
if (length > 8)
|
||||
return {};
|
||||
|
||||
u64 result;
|
||||
if (mask_length)
|
||||
result = length_descriptor & ~(1u << (8 - length));
|
||||
else
|
||||
result = length_descriptor;
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Beginning of VINT is {:#02x}", result);
|
||||
for (size_t i = 1; i < length; i++) {
|
||||
if (!has_octet()) {
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Ran out of stream data");
|
||||
return {};
|
||||
}
|
||||
u8 next_octet = read_octet();
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, "Read octet of {:#02x}", next_octet);
|
||||
result = (result << 8u) | next_octet;
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, "New result is {:#010x}", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Optional<i64> read_variable_sized_signed_integer()
|
||||
{
|
||||
auto length_descriptor = read_octet();
|
||||
if (length_descriptor == 0)
|
||||
return {};
|
||||
size_t length = 0;
|
||||
while (length < 8) {
|
||||
if (length_descriptor & (1u << (8 - length)))
|
||||
break;
|
||||
length++;
|
||||
}
|
||||
if (length > 8)
|
||||
return {};
|
||||
|
||||
i64 result = length_descriptor & ~(1u << (8 - length));
|
||||
for (size_t i = 1; i < length; i++) {
|
||||
if (!has_octet()) {
|
||||
return {};
|
||||
}
|
||||
u8 next_octet = read_octet();
|
||||
result = (result << 8u) | next_octet;
|
||||
}
|
||||
result -= AK::exp2<i64>(length * 7 - 1) - 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
void drop_octets(size_t num_octets)
|
||||
{
|
||||
VERIFY(m_size_remaining >= num_octets);
|
||||
m_size_remaining -= num_octets;
|
||||
m_octets_read.last() += num_octets;
|
||||
m_data_ptr += num_octets;
|
||||
}
|
||||
|
||||
bool at_end() const { return !m_size_remaining; }
|
||||
bool has_octet() const { return m_size_remaining >= 1; }
|
||||
|
||||
size_t remaining() const { return m_size_remaining; }
|
||||
void set_remaining(size_t remaining) { m_size_remaining = remaining; }
|
||||
|
||||
private:
|
||||
u8 const* m_data_ptr { nullptr };
|
||||
size_t m_size_remaining { 0 };
|
||||
Vector<size_t> m_octets_read { 0 };
|
||||
};
|
||||
|
||||
bool parse_master_element(StringView element_name, Function<bool(u64 element_id)> element_consumer);
|
||||
Optional<EBMLHeader> parse_ebml_header();
|
||||
|
||||
bool parse_segment_elements(MatroskaDocument&);
|
||||
OwnPtr<SegmentInformation> parse_information();
|
||||
|
||||
bool parse_tracks(MatroskaDocument&);
|
||||
OwnPtr<TrackEntry> parse_track_entry();
|
||||
Optional<TrackEntry::VideoTrack> parse_video_track_information();
|
||||
Optional<TrackEntry::ColorFormat> parse_video_color_information();
|
||||
Optional<TrackEntry::AudioTrack> parse_audio_track_information();
|
||||
OwnPtr<Cluster> parse_cluster();
|
||||
OwnPtr<Block> parse_simple_block();
|
||||
|
||||
Optional<String> read_string_element();
|
||||
Optional<u64> read_u64_element();
|
||||
Optional<double> read_float_element();
|
||||
bool read_unknown_element();
|
||||
|
||||
Streamer m_streamer;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue