diff options
author | Zaggy1024 <zaggy1024@gmail.com> | 2023-02-12 00:44:16 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-02-12 18:47:56 +0100 |
commit | 2a228e8a6eec2646c55d1c1dbfbf59459e16508d (patch) | |
tree | 897cf61ae18bfff03b21ac7ba5ae69807566a287 /Userland/Libraries/LibVideo/PlaybackManager.cpp | |
parent | e813b8fd197c60a299dbb96f9b46c18143f46148 (diff) | |
download | serenity-2a228e8a6eec2646c55d1c1dbfbf59459e16508d.zip |
LibVideo: Deduplicate logic for dispatching video frame queue items
Previously we had dispatch_decoder_error and on_decoder_error serving
the same function, with one not handling the end of stream properly.
There is also a new function to dispatch either an error or a frame to
the owner of this playback manager, so that PlaybackStateHandlers don't
have to duplicate this logic.
Diffstat (limited to 'Userland/Libraries/LibVideo/PlaybackManager.cpp')
-rw-r--r-- | Userland/Libraries/LibVideo/PlaybackManager.cpp | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/Userland/Libraries/LibVideo/PlaybackManager.cpp b/Userland/Libraries/LibVideo/PlaybackManager.cpp index 0024fd4a0f..522a6d2bd2 100644 --- a/Userland/Libraries/LibVideo/PlaybackManager.cpp +++ b/Userland/Libraries/LibVideo/PlaybackManager.cpp @@ -75,7 +75,7 @@ Time PlaybackManager::duration() { auto duration_result = m_demuxer->duration(); if (duration_result.is_error()) - on_decoder_error(duration_result.release_error()); + dispatch_decoder_error(duration_result.release_error()); return duration_result.release_value(); } @@ -89,7 +89,7 @@ void PlaybackManager::dispatch_fatal_error(Error error) m_event_handler.dispatch_event(event); } -void PlaybackManager::on_decoder_error(DecoderError error) +void PlaybackManager::dispatch_decoder_error(DecoderError error) { switch (error.category()) { case DecoderErrorCategory::EndOfStream: @@ -104,6 +104,23 @@ void PlaybackManager::on_decoder_error(DecoderError error) } } +void PlaybackManager::dispatch_new_frame(RefPtr<Gfx::Bitmap> frame) +{ + m_main_loop.post_event(m_event_handler, make<VideoFramePresentEvent>(frame)); +} + +bool PlaybackManager::dispatch_frame_queue_item(FrameQueueItem&& item) +{ + if (item.is_error()) { + dispatch_decoder_error(item.release_error()); + return true; + } + + dbgln_if(PLAYBACK_MANAGER_DEBUG, "Sent frame for presentation"); + dispatch_new_frame(item.bitmap()); + return false; +} + void PlaybackManager::timer_callback() { TRY_OR_FATAL_ERROR(m_playback_handler->on_timer_callback()); @@ -120,7 +137,7 @@ Optional<Time> PlaybackManager::seek_demuxer_to_most_recent_keyframe(Time timest // mutex so that seeking can't happen while that thread is getting a sample. auto result = m_demuxer->seek_to_most_recent_keyframe(m_selected_video_track, timestamp, move(earliest_available_sample)); if (result.is_error()) - on_decoder_error(result.release_error()); + dispatch_decoder_error(result.release_error()); return result.release_value(); } @@ -129,16 +146,6 @@ void PlaybackManager::restart_playback() seek_to_timestamp(Time::zero()); } -void PlaybackManager::dispatch_decoder_error(DecoderError error) -{ - m_main_loop.post_event(m_event_handler, make<DecoderErrorEvent>(error)); -} - -void PlaybackManager::dispatch_new_frame(RefPtr<Gfx::Bitmap> frame) -{ - m_main_loop.post_event(m_event_handler, make<VideoFramePresentEvent>(frame)); -} - void PlaybackManager::start_timer(int milliseconds) { m_present_timer->start(milliseconds); @@ -341,7 +348,7 @@ private: #endif if (future_frame_item.has_value()) { if (future_frame_item->is_error()) { - manager().on_decoder_error(future_frame_item.release_value().release_error()); + manager().dispatch_decoder_error(future_frame_item.release_value().release_error()); return {}; } manager().m_next_frame.emplace(future_frame_item.release_value()); @@ -355,15 +362,16 @@ private: auto now = Time::now_monotonic(); manager().m_last_present_in_media_time += now - m_last_present_in_real_time; m_last_present_in_real_time = now; - manager().dispatch_new_frame(manager().m_next_frame.value().bitmap()); - dbgln_if(PLAYBACK_MANAGER_DEBUG, "Sent frame for presentation"); + + if (manager().dispatch_frame_queue_item(manager().m_next_frame.release_value())) + return {}; } // Now that we've presented the current frame, we can throw whatever error is next in queue. // This way, we always display a frame before the stream ends, and should also show any frames // we already had when a real error occurs. if (future_frame_item->is_error()) { - manager().on_decoder_error(future_frame_item.release_value().release_error()); + manager().dispatch_decoder_error(future_frame_item.release_value().release_error()); return {}; } @@ -498,7 +506,7 @@ private: if (item.is_error()) { dbgln_if(PLAYBACK_MANAGER_DEBUG, "Encountered error while seeking: {}", item.error().description()); - manager().on_decoder_error(item.release_error()); + manager().dispatch_decoder_error(item.release_error()); return {}; } |