LibMedia: Return whether a demuxer seek moved the stream position

We no longer need to return a timestamp from the seek function, which
makes it much easier to implement backend-agnostically.
This commit is contained in:
Zaggy1024 2025-10-09 15:56:31 -05:00 committed by Jelle Raaijmakers
parent 27ed536540
commit b1c9a872bc
6 changed files with 15 additions and 10 deletions

View File

@ -169,12 +169,12 @@ DecoderErrorOr<ReadonlyBytes> MatroskaDemuxer::get_codec_initialization_data_for
return TRY(m_reader.track_for_track_number(track.identifier()))->codec_private_data();
}
DecoderErrorOr<Optional<AK::Duration>> MatroskaDemuxer::seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions options)
DecoderErrorOr<DemuxerSeekResult> MatroskaDemuxer::seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions options)
{
// Removing the track status will cause us to start from the beginning.
if (timestamp.is_zero()) {
m_track_statuses.remove(track);
return timestamp;
return DemuxerSeekResult::MovedPosition;
}
auto& track_status = *TRY(get_track_status(track));
@ -187,11 +187,11 @@ DecoderErrorOr<Optional<AK::Duration>> MatroskaDemuxer::seek_to_most_recent_keyf
bool skip_seek = seeked_iterator.last_timestamp().value() <= last_sample.value() && last_sample.value() <= timestamp;
dbgln_if(MATROSKA_DEBUG, "The last available sample at {}ms is {}closer to target timestamp {}ms than the keyframe at {}ms, {}", last_sample->to_milliseconds(), skip_seek ? ""sv : "not "sv, timestamp.to_milliseconds(), seeked_iterator.last_timestamp()->to_milliseconds(), skip_seek ? "skipping seek"sv : "seeking"sv);
if (skip_seek)
return OptionalNone();
return DemuxerSeekResult::KeptCurrentPosition;
}
track_status.iterator = move(seeked_iterator);
return track_status.iterator.last_timestamp();
return DemuxerSeekResult::MovedPosition;
}
DecoderErrorOr<CodedFrame> MatroskaDemuxer::get_next_sample_for_track(Track const& track)

View File

@ -30,7 +30,7 @@ public:
DecoderErrorOr<Vector<Track>> get_tracks_for_type(TrackType type) override;
DecoderErrorOr<Optional<Track>> get_preferred_track_for_type(TrackType type) override;
DecoderErrorOr<Optional<AK::Duration>> seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions) override;
DecoderErrorOr<DemuxerSeekResult> seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions) override;
DecoderErrorOr<AK::Duration> duration_of_track(Track const& track) override;
DecoderErrorOr<AK::Duration> total_duration() override;

View File

@ -25,6 +25,11 @@ enum class DemuxerSeekOptions : u8 {
AK_ENUM_BITWISE_OPERATORS(DemuxerSeekOptions);
enum class DemuxerSeekResult : u8 {
MovedPosition,
KeptCurrentPosition,
};
class Demuxer : public AtomicRefCounted<Demuxer> {
public:
virtual ~Demuxer() = default;
@ -43,7 +48,7 @@ public:
// Returns the timestamp of the keyframe that was seeked to.
// The value is `Optional` to allow the demuxer to decide not to seek so that it can keep its position
// in the case that the timestamp is closer to the current time than the nearest keyframe.
virtual DecoderErrorOr<Optional<AK::Duration>> seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions = DemuxerSeekOptions::None) = 0;
virtual DecoderErrorOr<DemuxerSeekResult> seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions = DemuxerSeekOptions::None) = 0;
virtual DecoderErrorOr<AK::Duration> duration_of_track(Track const&) = 0;
virtual DecoderErrorOr<AK::Duration> total_duration() = 0;

View File

@ -141,7 +141,7 @@ DecoderErrorOr<Optional<Track>> FFmpegDemuxer::get_preferred_track_for_type(Trac
return get_track_for_stream_index(best_stream_index);
}
DecoderErrorOr<Optional<AK::Duration>> FFmpegDemuxer::seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions)
DecoderErrorOr<DemuxerSeekResult> FFmpegDemuxer::seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions)
{
VERIFY(track.identifier() < m_format_context->nb_streams);
auto* stream = m_format_context->streams[track.identifier()];
@ -152,7 +152,7 @@ DecoderErrorOr<Optional<AK::Duration>> FFmpegDemuxer::seek_to_most_recent_keyfra
if (av_seek_frame(m_format_context, stream->index, sample_timestamp, AVSEEK_FLAG_BACKWARD) < 0)
return DecoderError::format(DecoderErrorCategory::Unknown, "Failed to seek");
return timestamp;
return DemuxerSeekResult::MovedPosition;
}
DecoderErrorOr<CodecID> FFmpegDemuxer::get_codec_id_for_track(Track const& track)

View File

@ -29,7 +29,7 @@ public:
virtual DecoderErrorOr<Vector<Track>> get_tracks_for_type(TrackType type) override;
virtual DecoderErrorOr<Optional<Track>> get_preferred_track_for_type(TrackType type) override;
virtual DecoderErrorOr<Optional<AK::Duration>> seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions) override;
virtual DecoderErrorOr<DemuxerSeekResult> seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions) override;
virtual DecoderErrorOr<AK::Duration> duration_of_track(Track const&) override;
virtual DecoderErrorOr<AK::Duration> total_duration() override;

View File

@ -62,7 +62,7 @@ public:
});
}
virtual DecoderErrorOr<Optional<AK::Duration>> seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions seek_options = DemuxerSeekOptions::None) override
virtual DecoderErrorOr<DemuxerSeekResult> seek_to_most_recent_keyframe(Track const& track, AK::Duration timestamp, DemuxerSeekOptions seek_options = DemuxerSeekOptions::None) override
{
return m_demuxer.with_locked([&](auto& demuxer) {
return demuxer->seek_to_most_recent_keyframe(track, timestamp, seek_options);