mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:57:45 +00:00
LibVideo/PlaybackManager: Don't crash when demuxer seek throws an error
`seek_demuxer_to_most_recent_keyframe()` wasn't correctly returning in cases where an error was thrown by the demuxer. To avoid this, the function now returns the error, and the playback state handler must act on it instead, allowing it to exit the seeking state early.
This commit is contained in:
parent
b94c132dd1
commit
1789905d4a
2 changed files with 10 additions and 7 deletions
|
@ -189,12 +189,9 @@ void PlaybackManager::seek_to_timestamp(Duration target_timestamp, SeekMode seek
|
||||||
TRY_OR_FATAL_ERROR(m_playback_handler->seek(target_timestamp, seek_mode));
|
TRY_OR_FATAL_ERROR(m_playback_handler->seek(target_timestamp, seek_mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Duration> PlaybackManager::seek_demuxer_to_most_recent_keyframe(Duration timestamp, Optional<Duration> earliest_available_sample)
|
DecoderErrorOr<Optional<Duration>> PlaybackManager::seek_demuxer_to_most_recent_keyframe(Duration timestamp, Optional<Duration> earliest_available_sample)
|
||||||
{
|
{
|
||||||
auto result = m_demuxer->seek_to_most_recent_keyframe(m_selected_video_track, timestamp, move(earliest_available_sample));
|
return m_demuxer->seek_to_most_recent_keyframe(m_selected_video_track, timestamp, move(earliest_available_sample));
|
||||||
if (result.is_error())
|
|
||||||
dispatch_decoder_error(result.release_error());
|
|
||||||
return result.release_value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<FrameQueueItem> PlaybackManager::dequeue_one_frame()
|
Optional<FrameQueueItem> PlaybackManager::dequeue_one_frame()
|
||||||
|
@ -597,7 +594,13 @@ private:
|
||||||
|
|
||||||
{
|
{
|
||||||
Threading::MutexLocker demuxer_locker(manager().m_demuxer_mutex);
|
Threading::MutexLocker demuxer_locker(manager().m_demuxer_mutex);
|
||||||
auto keyframe_timestamp = manager().seek_demuxer_to_most_recent_keyframe(m_target_timestamp, earliest_available_sample);
|
|
||||||
|
auto demuxer_seek_result = manager().seek_demuxer_to_most_recent_keyframe(m_target_timestamp, earliest_available_sample);
|
||||||
|
if (demuxer_seek_result.is_error()) {
|
||||||
|
manager().dispatch_decoder_error(demuxer_seek_result.release_error());
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto keyframe_timestamp = demuxer_seek_result.release_value();
|
||||||
|
|
||||||
#if PLAYBACK_MANAGER_DEBUG
|
#if PLAYBACK_MANAGER_DEBUG
|
||||||
auto seek_mode_name = m_seek_mode == SeekMode::Accurate ? "Accurate"sv : "Fast"sv;
|
auto seek_mode_name = m_seek_mode == SeekMode::Accurate ? "Accurate"sv : "Fast"sv;
|
||||||
|
|
|
@ -158,7 +158,7 @@ private:
|
||||||
|
|
||||||
void timer_callback();
|
void timer_callback();
|
||||||
// This must be called with m_demuxer_mutex locked!
|
// This must be called with m_demuxer_mutex locked!
|
||||||
Optional<Duration> seek_demuxer_to_most_recent_keyframe(Duration timestamp, Optional<Duration> earliest_available_sample = OptionalNone());
|
DecoderErrorOr<Optional<Duration>> seek_demuxer_to_most_recent_keyframe(Duration timestamp, Optional<Duration> earliest_available_sample = OptionalNone());
|
||||||
|
|
||||||
Optional<FrameQueueItem> dequeue_one_frame();
|
Optional<FrameQueueItem> dequeue_one_frame();
|
||||||
void set_state_update_timer(int delay_ms);
|
void set_state_update_timer(int delay_ms);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue