This shouldn't actually be necessary, since the sample iterator will resume from where it hit the error last anyway. Now that the decoded data producers don't clear their queues when the demuxer doesn't move, this works just fine for EOF. This could easily be triggered by scrubbing aborting reads to restart seeks, which would force us to decode from a prior keyframe instead of continuing to decode from where the last seek left off if it's faster.
39 lines
1.7 KiB
C++
39 lines
1.7 KiB
C++
/*
|
|
* Copyright (c) 2026, Gregory Bertilson <gregory@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibCore/File.h>
|
|
#include <LibMedia/Containers/Matroska/MatroskaDemuxer.h>
|
|
#include <LibTest/TestCase.h>
|
|
|
|
TEST_CASE(seek_past_eos)
|
|
{
|
|
auto file = MUST(Core::File::open("./vfr.mkv"sv, Core::File::OpenMode::Read));
|
|
auto stream = Media::IncrementallyPopulatedStream::create_from_buffer(MUST(file->read_until_eof()));
|
|
auto demuxer = MUST(Media::Matroska::MatroskaDemuxer::from_stream(stream));
|
|
|
|
auto optional_track = MUST(demuxer->get_preferred_track_for_type(Media::TrackType::Video));
|
|
EXPECT(optional_track.has_value());
|
|
auto track = optional_track.release_value();
|
|
MUST(demuxer->create_context_for_track(track));
|
|
|
|
AK::Duration last_timestamp;
|
|
while (true) {
|
|
auto sample_result = demuxer->get_next_sample_for_track(track);
|
|
if (sample_result.is_error()) {
|
|
EXPECT_EQ(sample_result.error().category(), Media::DecoderErrorCategory::EndOfStream);
|
|
break;
|
|
}
|
|
last_timestamp = sample_result.release_value().timestamp();
|
|
}
|
|
EXPECT_EQ(last_timestamp, AK::Duration::from_milliseconds(30126));
|
|
|
|
auto seek_time = AK::Duration::from_milliseconds(31000);
|
|
auto seek_result = MUST(demuxer->seek_to_most_recent_keyframe(track, seek_time, Media::DemuxerSeekOptions::None));
|
|
EXPECT_EQ(seek_result, Media::DemuxerSeekResult::KeptCurrentPosition);
|
|
auto sample_result_after_seek = demuxer->get_next_sample_for_track(track);
|
|
EXPECT(sample_result_after_seek.is_error());
|
|
EXPECT_EQ(sample_result_after_seek.error().category(), Media::DecoderErrorCategory::EndOfStream);
|
|
}
|