mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:57:35 +00:00
LibVideo: Make Matroska Block and Cluster timestamps absolute
This commit is contained in:
parent
5c2cede2c9
commit
9040194d54
4 changed files with 15 additions and 16 deletions
|
@ -12,6 +12,7 @@
|
|||
#include <AK/NonnullOwnPtrVector.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Utf8View.h>
|
||||
#include <LibVideo/Color/CodingIndependentCodePoints.h>
|
||||
|
||||
|
@ -152,8 +153,8 @@ public:
|
|||
|
||||
u64 track_number() const { return m_track_number; }
|
||||
void set_track_number(u64 track_number) { m_track_number = track_number; }
|
||||
i16 timestamp() const { return m_timestamp; }
|
||||
void set_timestamp(i16 timestamp) { m_timestamp = timestamp; }
|
||||
Time timestamp() const { return m_timestamp; }
|
||||
void set_timestamp(Time timestamp) { m_timestamp = timestamp; }
|
||||
bool only_keyframes() const { return m_only_keyframes; }
|
||||
void set_only_keyframes(bool only_keyframes) { m_only_keyframes = only_keyframes; }
|
||||
bool invisible() const { return m_invisible; }
|
||||
|
@ -170,7 +171,7 @@ public:
|
|||
|
||||
private:
|
||||
u64 m_track_number { 0 };
|
||||
i16 m_timestamp { 0 };
|
||||
Time m_timestamp { Time::zero() };
|
||||
bool m_only_keyframes { false };
|
||||
bool m_invisible { false };
|
||||
Lacing m_lacing { None };
|
||||
|
@ -180,11 +181,11 @@ private:
|
|||
|
||||
class Cluster {
|
||||
public:
|
||||
u64 timestamp() const { return m_timestamp; }
|
||||
void set_timestamp(u64 timestamp) { m_timestamp = timestamp; }
|
||||
Time timestamp() const { return m_timestamp; }
|
||||
void set_timestamp(Time timestamp) { m_timestamp = timestamp; }
|
||||
|
||||
private:
|
||||
u64 m_timestamp;
|
||||
Time m_timestamp { Time::zero() };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -72,10 +72,8 @@ DecoderErrorOr<NonnullOwnPtr<Sample>> MatroskaDemuxer::get_next_sample_for_track
|
|||
status.block = TRY(status.iterator.next_block());
|
||||
status.frame_index = 0;
|
||||
}
|
||||
auto const& cluster = status.iterator.current_cluster();
|
||||
Time timestamp = Time::from_nanoseconds((cluster.timestamp() + status.block->timestamp()) * TRY(m_reader.segment_information()).timestamp_scale());
|
||||
auto cicp = TRY(m_reader.track_for_track_number(track.identifier())).video_track()->color_format.to_cicp();
|
||||
return make<VideoSample>(status.block->frame(status.frame_index++), cicp, timestamp);
|
||||
return make<VideoSample>(status.block->frame(status.frame_index++), cicp, status.block->timestamp());
|
||||
}
|
||||
|
||||
DecoderErrorOr<Time> MatroskaDemuxer::duration()
|
||||
|
|
|
@ -487,7 +487,7 @@ constexpr size_t get_element_id_size(u32 element_id)
|
|||
return sizeof(element_id) - (count_leading_zeroes(element_id) / 8);
|
||||
}
|
||||
|
||||
static DecoderErrorOr<Cluster> parse_cluster(Streamer& streamer)
|
||||
static DecoderErrorOr<Cluster> parse_cluster(Streamer& streamer, u64 timestamp_scale)
|
||||
{
|
||||
Optional<u64> timestamp;
|
||||
size_t first_element_position = 0;
|
||||
|
@ -516,11 +516,11 @@ static DecoderErrorOr<Cluster> parse_cluster(Streamer& streamer)
|
|||
TRY_READ(streamer.seek_to_position(first_element_position));
|
||||
|
||||
Cluster cluster;
|
||||
cluster.set_timestamp(timestamp.release_value());
|
||||
cluster.set_timestamp(Time::from_nanoseconds(timestamp.release_value() * timestamp_scale));
|
||||
return cluster;
|
||||
}
|
||||
|
||||
static DecoderErrorOr<Block> parse_simple_block(Streamer& streamer)
|
||||
static DecoderErrorOr<Block> parse_simple_block(Streamer& streamer, Time cluster_timestamp, u64 timestamp_scale)
|
||||
{
|
||||
Block block;
|
||||
|
||||
|
@ -529,7 +529,7 @@ static DecoderErrorOr<Block> parse_simple_block(Streamer& streamer)
|
|||
auto position_before_track_number = streamer.position();
|
||||
block.set_track_number(TRY_READ(streamer.read_variable_size_integer()));
|
||||
|
||||
block.set_timestamp(TRY_READ(streamer.read_i16()));
|
||||
block.set_timestamp(cluster_timestamp + Time::from_nanoseconds(TRY_READ(streamer.read_i16()) * timestamp_scale));
|
||||
|
||||
auto flags = TRY_READ(streamer.read_octet());
|
||||
block.set_only_keyframes((flags & (1u << 7u)) != 0);
|
||||
|
@ -627,10 +627,10 @@ DecoderErrorOr<Block> SampleIterator::next_block()
|
|||
|
||||
if (element_id == CLUSTER_ELEMENT_ID) {
|
||||
dbgln_if(MATROSKA_DEBUG, " Iterator is parsing new cluster.");
|
||||
m_current_cluster = TRY(parse_cluster(streamer));
|
||||
m_current_cluster = TRY(parse_cluster(streamer, m_timestamp_scale));
|
||||
} else if (element_id == SIMPLE_BLOCK_ID) {
|
||||
dbgln_if(MATROSKA_TRACE_DEBUG, " Iterator is parsing new block.");
|
||||
auto candidate_block = TRY(parse_simple_block(streamer));
|
||||
auto candidate_block = TRY(parse_simple_block(streamer, m_current_cluster->timestamp(), m_timestamp_scale));
|
||||
if (candidate_block.track_number() == m_track_id)
|
||||
block = move(candidate_block);
|
||||
} else {
|
||||
|
|
|
@ -56,7 +56,7 @@ ErrorOr<int> serenity_main(Main::Arguments)
|
|||
return block_result.release_error();
|
||||
}
|
||||
auto block = block_result.release_value();
|
||||
outln("\t\tBlock at timestamp {}:", iterator.current_cluster().timestamp() + block.timestamp());
|
||||
outln("\t\tBlock at timestamp {}ms:", block.timestamp().to_milliseconds());
|
||||
outln("\t\t\tContains {} frames", block.frame_count());
|
||||
outln("\t\t\tLacing is {}", static_cast<u8>(block.lacing()));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue