mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-29 08:11:13 +00:00
LibMedia/Matroska: Handle negative timestamp offsets correctly
The timestamp offset of a block was being converted from i16 to u64, so negative values would overflow and cause timestamps that fall before the cluster's timestamp from being close to the minimum representable i64. The math is also now done using saturating operations to prevent any other similar issues from occurring.
This commit is contained in:
parent
bbd8a218a5
commit
ef99e701b7
Notes:
sideshowbarker
2024-07-17 01:23:08 +09:00
Author: https://github.com/Zaggy1024 Commit: https://github.com/LadybirdBrowser/ladybird/commit/ef99e701b7 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/230 Reviewed-by: https://github.com/ADKaster
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/Function.h>
|
||||
#include <AK/Math.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Time.h>
|
||||
#include <AK/Utf8View.h>
|
||||
|
@ -616,11 +617,13 @@ static DecoderErrorOr<Block> parse_simple_block(Streamer& streamer, Duration clu
|
|||
// of that track. To get the timestamp in nanoseconds of the first frame in a Block or
|
||||
// SimpleBlock, the formula becomes:
|
||||
// `( ( Cluster\Timestamp + ( block timestamp * TrackTimestampScale ) ) * TimestampScale ) - CodecDelay`
|
||||
Duration timestamp_offset = Duration::from_nanoseconds(static_cast<i64>(static_cast<double>(TRY_READ(streamer.read_i16()) * segment_timestamp_scale) * track.timestamp_scale()));
|
||||
timestamp_offset -= Duration::from_nanoseconds(static_cast<i64>(track.codec_delay()));
|
||||
auto raw_timestamp_offset = TRY_READ(streamer.read_i16());
|
||||
Checked<i64> timestamp_offset_ns = AK::clamp_to<i64>(static_cast<double>(raw_timestamp_offset * AK::clamp_to<i64>(segment_timestamp_scale)) * track.timestamp_scale());
|
||||
timestamp_offset_ns.saturating_sub(AK::clamp_to<i64>(track.codec_delay()));
|
||||
// This is only mentioned in the elements specification under TrackOffset.
|
||||
// https://www.matroska.org/technical/elements.html
|
||||
timestamp_offset += Duration::from_nanoseconds(static_cast<i64>(track.timestamp_offset()));
|
||||
timestamp_offset_ns.saturating_add(AK::clamp_to<i64>(track.timestamp_offset()));
|
||||
Duration timestamp_offset = Duration::from_nanoseconds(timestamp_offset_ns.value());
|
||||
block.set_timestamp(cluster_timestamp + timestamp_offset);
|
||||
|
||||
auto flags = TRY_READ(streamer.read_octet());
|
||||
|
|
Loading…
Reference in a new issue