Skip to content

Commit e72080b

Browse files
Zaggy1024gmta
authored andcommitted
LibMedia: Adjust Matroska seeking based on SeekPreRoll
This is important for seeking Opus tracks, as Opus needs to decode a certain amount of input data before its output converges. Without this, audio after a seek can sound muffled briefly.
1 parent 31c751e commit e72080b

File tree

2 files changed

+10
-0
lines changed

2 files changed

+10
-0
lines changed

Libraries/LibMedia/Containers/Matroska/Document.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ class TrackEntry : public RefCounted<TrackEntry> {
135135
void set_timestamp_scale(double timestamp_scale) { m_timestamp_scale = timestamp_scale; }
136136
u64 codec_delay() const { return m_codec_delay; }
137137
void set_codec_delay(u64 codec_delay) { m_codec_delay = codec_delay; }
138+
u64 seek_pre_roll() const { return m_seek_pre_roll; }
139+
void set_seek_pre_roll(u64 seek_pre_roll) { m_seek_pre_roll = seek_pre_roll; }
138140
u64 timestamp_offset() const { return m_timestamp_offset; }
139141
void set_timestamp_offset(u64 timestamp_offset) { m_timestamp_offset = timestamp_offset; }
140142
Optional<VideoTrack> video_track() const { return m_video_track; }
@@ -153,6 +155,7 @@ class TrackEntry : public RefCounted<TrackEntry> {
153155
FixedArray<u8> m_codec_private_data;
154156
double m_timestamp_scale { 1 };
155157
u64 m_codec_delay { 0 };
158+
u64 m_seek_pre_roll { 0 };
156159
u64 m_timestamp_offset { 0 };
157160
Optional<VideoTrack> m_video_track;
158161
Optional<AudioTrack> m_audio_track;

Libraries/LibMedia/Containers/Matroska/Reader.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ constexpr u32 TRACK_LANGUAGE_BCP_47_ID = 0x22B59D;
5757
constexpr u32 TRACK_CODEC_ID = 0x86;
5858
constexpr u32 TRACK_CODEC_PRIVATE_ID = 0x63A2;
5959
constexpr u32 TRACK_CODEC_DELAY_ID = 0x56AA;
60+
constexpr u32 TRACK_SEEK_PRE_ROLL_ID = 0x56BB;
6061
constexpr u32 TRACK_TIMESTAMP_SCALE_ID = 0x23314F;
6162
constexpr u32 TRACK_OFFSET_ID = 0x537F;
6263
constexpr u32 TRACK_VIDEO_ID = 0xE0;
@@ -512,6 +513,10 @@ static DecoderErrorOr<NonnullRefPtr<TrackEntry>> parse_track_entry(Streamer& str
512513
track_entry->set_codec_delay(TRY_READ(streamer.read_u64()));
513514
dbgln_if(MATROSKA_TRACE_DEBUG, "Read Track's CodecDelay attribute: {}", track_entry->codec_delay());
514515
break;
516+
case TRACK_SEEK_PRE_ROLL_ID:
517+
track_entry->set_seek_pre_roll(TRY_READ(streamer.read_u64()));
518+
dbgln_if(MATROSKA_TRACE_DEBUG, "Read Track's SeekPreRoll attribute: {}", track_entry->seek_pre_roll());
519+
break;
515520
case TRACK_TIMESTAMP_SCALE_ID:
516521
track_entry->set_timestamp_scale(TRY_READ(streamer.read_float()));
517522
dbgln_if(MATROSKA_TRACE_DEBUG, "Read Track's TrackTimestampScale attribute: {}", track_entry->timestamp_scale());
@@ -1090,6 +1095,8 @@ DecoderErrorOr<bool> Reader::has_cues_for_track(u64 track_number)
10901095

10911096
DecoderErrorOr<SampleIterator> Reader::seek_to_random_access_point(SampleIterator iterator, AK::Duration timestamp)
10921097
{
1098+
timestamp -= AK::Duration::from_nanoseconds(AK::clamp_to<i64>(iterator.m_track->seek_pre_roll()));
1099+
10931100
if (TRY(has_cues_for_track(iterator.m_track->track_number()))) {
10941101
TRY(seek_to_cue_for_timestamp(iterator, timestamp));
10951102
VERIFY(iterator.last_timestamp().has_value());

0 commit comments

Comments
 (0)