From 1789905d4ad6351fd9d584ecce09c02e14f49024 Mon Sep 17 00:00:00 2001 From: Zaggy1024 Date: Sat, 24 Jun 2023 04:57:27 -0500 Subject: [PATCH] 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. --- Userland/Libraries/LibVideo/PlaybackManager.cpp | 15 +++++++++------ Userland/Libraries/LibVideo/PlaybackManager.h | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Userland/Libraries/LibVideo/PlaybackManager.cpp b/Userland/Libraries/LibVideo/PlaybackManager.cpp index 38cd804b17..6189e21b41 100644 --- a/Userland/Libraries/LibVideo/PlaybackManager.cpp +++ b/Userland/Libraries/LibVideo/PlaybackManager.cpp @@ -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)); } -Optional PlaybackManager::seek_demuxer_to_most_recent_keyframe(Duration timestamp, Optional earliest_available_sample) +DecoderErrorOr> PlaybackManager::seek_demuxer_to_most_recent_keyframe(Duration timestamp, Optional earliest_available_sample) { - auto result = 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(); + return m_demuxer->seek_to_most_recent_keyframe(m_selected_video_track, timestamp, move(earliest_available_sample)); } Optional PlaybackManager::dequeue_one_frame() @@ -597,7 +594,13 @@ private: { 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 auto seek_mode_name = m_seek_mode == SeekMode::Accurate ? "Accurate"sv : "Fast"sv; diff --git a/Userland/Libraries/LibVideo/PlaybackManager.h b/Userland/Libraries/LibVideo/PlaybackManager.h index d5c82f4308..4a2665e243 100644 --- a/Userland/Libraries/LibVideo/PlaybackManager.h +++ b/Userland/Libraries/LibVideo/PlaybackManager.h @@ -158,7 +158,7 @@ private: void timer_callback(); // This must be called with m_demuxer_mutex locked! - Optional seek_demuxer_to_most_recent_keyframe(Duration timestamp, Optional earliest_available_sample = OptionalNone()); + DecoderErrorOr> seek_demuxer_to_most_recent_keyframe(Duration timestamp, Optional earliest_available_sample = OptionalNone()); Optional dequeue_one_frame(); void set_state_update_timer(int delay_ms);