1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 11:37:44 +00:00

LibVideo: Extract video metadata for public-facing video track data

This copies the video data from the Matroska document into the Track
structure that outside users have access to. Because Track can actually
represent other media types, this is set up such that the Track can hold
metadata for those other types when they are needed.

This is needed for LibWeb's HTMLMediaElement implementation.
This commit is contained in:
Timothy Flynn 2023-04-04 13:18:35 -04:00 committed by Linus Groh
parent 952808eaaa
commit c978beb18b
2 changed files with 44 additions and 1 deletions

View file

@ -38,9 +38,21 @@ DecoderErrorOr<Vector<Track>> MatroskaDemuxer::get_tracks_for_type(TrackType typ
Vector<Track> tracks; Vector<Track> tracks;
TRY(m_reader.for_each_track_of_type(matroska_track_type, [&](TrackEntry const& track_entry) -> DecoderErrorOr<IterationDecision> { TRY(m_reader.for_each_track_of_type(matroska_track_type, [&](TrackEntry const& track_entry) -> DecoderErrorOr<IterationDecision> {
VERIFY(track_entry.track_type() == matroska_track_type); VERIFY(track_entry.track_type() == matroska_track_type);
DECODER_TRY_ALLOC(tracks.try_append(Track(type, track_entry.track_number()))); Track track(type, track_entry.track_number());
switch (type) {
case TrackType::Video:
if (auto video_track = track_entry.video_track(); video_track.has_value())
track.set_video_data({ TRY(duration()), video_track->pixel_width, video_track->pixel_height });
break;
default:
break;
}
DECODER_TRY_ALLOC(tracks.try_append(track));
return IterationDecision::Continue; return IterationDecision::Continue;
})); }));
return tracks; return tracks;
} }

View file

@ -7,8 +7,10 @@
#pragma once #pragma once
#include <AK/HashFunctions.h> #include <AK/HashFunctions.h>
#include <AK/Time.h>
#include <AK/Traits.h> #include <AK/Traits.h>
#include <AK/Types.h> #include <AK/Types.h>
#include <AK/Variant.h>
namespace Video { namespace Video {
@ -19,20 +21,47 @@ enum class TrackType : u32 {
}; };
struct Track { struct Track {
struct VideoData {
Time duration {};
u64 pixel_width { 0 };
u64 pixel_height { 0 };
};
public: public:
Track(TrackType type, size_t identifier) Track(TrackType type, size_t identifier)
: m_type(type) : m_type(type)
, m_identifier(identifier) , m_identifier(identifier)
{ {
switch (m_type) {
case TrackType::Video:
m_track_data = VideoData {};
break;
default:
m_track_data = Empty {};
break;
}
} }
TrackType type() { return m_type; } TrackType type() { return m_type; }
size_t identifier() const { return m_identifier; } size_t identifier() const { return m_identifier; }
void set_video_data(VideoData data)
{
VERIFY(m_type == TrackType::Video);
m_track_data = data;
}
VideoData const& video_data() const
{
VERIFY(m_type == TrackType::Video);
return m_track_data.get<VideoData>();
}
bool operator==(Track const& other) const bool operator==(Track const& other) const
{ {
return m_type == other.m_type && m_identifier == other.m_identifier; return m_type == other.m_type && m_identifier == other.m_identifier;
} }
unsigned hash() const unsigned hash() const
{ {
return pair_int_hash(to_underlying(m_type), m_identifier); return pair_int_hash(to_underlying(m_type), m_identifier);
@ -41,6 +70,8 @@ public:
private: private:
TrackType m_type; TrackType m_type;
size_t m_identifier; size_t m_identifier;
Variant<Empty, VideoData> m_track_data;
}; };
} }