PlaybackManager.h 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Copyright (c) 2022, Gregory Bertilson <zaggy1024@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Atomic.h>
  8. #include <AK/Function.h>
  9. #include <AK/NonnullOwnPtr.h>
  10. #include <AK/Queue.h>
  11. #include <AK/Time.h>
  12. #include <LibCore/SharedCircularQueue.h>
  13. #include <LibGfx/Bitmap.h>
  14. #include <LibThreading/ConditionVariable.h>
  15. #include <LibThreading/Mutex.h>
  16. #include <LibThreading/Thread.h>
  17. #include <LibVideo/Containers/Demuxer.h>
  18. #include <LibVideo/Containers/Matroska/Document.h>
  19. #include "VideoDecoder.h"
  20. namespace Video {
  21. class FrameQueueItem {
  22. public:
  23. static constexpr Time no_timestamp = Time::min();
  24. enum class Type {
  25. Frame,
  26. Error,
  27. };
  28. static FrameQueueItem frame(RefPtr<Gfx::Bitmap> bitmap, Time timestamp)
  29. {
  30. return FrameQueueItem(move(bitmap), timestamp);
  31. }
  32. static FrameQueueItem error_marker(DecoderError&& error, Time timestamp)
  33. {
  34. return FrameQueueItem(move(error), timestamp);
  35. }
  36. bool is_frame() const { return m_data.has<RefPtr<Gfx::Bitmap>>(); }
  37. RefPtr<Gfx::Bitmap> bitmap() const { return m_data.get<RefPtr<Gfx::Bitmap>>(); }
  38. Time timestamp() const { return m_timestamp; }
  39. bool is_error() const { return m_data.has<DecoderError>(); }
  40. DecoderError const& error() const { return m_data.get<DecoderError>(); }
  41. DecoderError release_error()
  42. {
  43. auto error = move(m_data.get<DecoderError>());
  44. m_data.set(Empty());
  45. return error;
  46. }
  47. DeprecatedString debug_string() const
  48. {
  49. if (is_error())
  50. return DeprecatedString::formatted("{} at {}ms", error().string_literal(), timestamp().to_milliseconds());
  51. return DeprecatedString::formatted("frame at {}ms", timestamp().to_milliseconds());
  52. }
  53. private:
  54. FrameQueueItem(RefPtr<Gfx::Bitmap> bitmap, Time timestamp)
  55. : m_data(move(bitmap))
  56. , m_timestamp(timestamp)
  57. {
  58. VERIFY(m_timestamp != no_timestamp);
  59. }
  60. FrameQueueItem(DecoderError&& error, Time timestamp)
  61. : m_data(move(error))
  62. , m_timestamp(timestamp)
  63. {
  64. }
  65. Variant<Empty, RefPtr<Gfx::Bitmap>, DecoderError> m_data;
  66. Time m_timestamp;
  67. };
  68. static constexpr size_t FRAME_BUFFER_COUNT = 4;
  69. using VideoFrameQueue = Queue<FrameQueueItem, FRAME_BUFFER_COUNT>;
  70. enum class PlaybackState {
  71. Playing,
  72. Paused,
  73. Buffering,
  74. Seeking,
  75. Stopped,
  76. };
  77. class PlaybackManager {
  78. public:
  79. enum class SeekMode {
  80. Accurate,
  81. Fast,
  82. };
  83. static constexpr SeekMode DEFAULT_SEEK_MODE = SeekMode::Accurate;
  84. static DecoderErrorOr<NonnullOwnPtr<PlaybackManager>> from_file(StringView file);
  85. static DecoderErrorOr<NonnullOwnPtr<PlaybackManager>> from_data(ReadonlyBytes data);
  86. PlaybackManager(NonnullOwnPtr<Demuxer>& demuxer, Track video_track, NonnullOwnPtr<VideoDecoder>&& decoder);
  87. ~PlaybackManager();
  88. void resume_playback();
  89. void pause_playback();
  90. void restart_playback();
  91. void seek_to_timestamp(Time, SeekMode = DEFAULT_SEEK_MODE);
  92. bool is_playing() const
  93. {
  94. return m_playback_handler->is_playing();
  95. }
  96. PlaybackState get_state() const
  97. {
  98. return m_playback_handler->get_state();
  99. }
  100. u64 number_of_skipped_frames() const { return m_skipped_frames; }
  101. Time current_playback_time();
  102. Time duration();
  103. Function<void(RefPtr<Gfx::Bitmap>)> on_video_frame;
  104. Function<void()> on_playback_state_change;
  105. Function<void(DecoderError)> on_decoder_error;
  106. Function<void(Error)> on_fatal_playback_error;
  107. Track const& selected_video_track() const { return m_selected_video_track; }
  108. private:
  109. class PlaybackStateHandler;
  110. // Abstract class to allow resuming play/pause after the state is completed.
  111. class ResumingStateHandler;
  112. class PlayingStateHandler;
  113. class PausedStateHandler;
  114. class BufferingStateHandler;
  115. class SeekingStateHandler;
  116. class StoppedStateHandler;
  117. static DecoderErrorOr<NonnullOwnPtr<PlaybackManager>> create_with_demuxer(NonnullOwnPtr<Demuxer> demuxer);
  118. void start_timer(int milliseconds);
  119. void timer_callback();
  120. Optional<Time> seek_demuxer_to_most_recent_keyframe(Time timestamp, Optional<Time> earliest_available_sample = OptionalNone());
  121. bool decode_and_queue_one_sample();
  122. void on_decode_timer();
  123. void dispatch_decoder_error(DecoderError error);
  124. void dispatch_new_frame(RefPtr<Gfx::Bitmap> frame);
  125. // Returns whether we changed playback states. If so, any PlaybackStateHandler processing must cease.
  126. [[nodiscard]] bool dispatch_frame_queue_item(FrameQueueItem&&);
  127. void dispatch_state_change();
  128. void dispatch_fatal_error(Error);
  129. Time m_last_present_in_media_time = Time::zero();
  130. NonnullOwnPtr<Demuxer> m_demuxer;
  131. Track m_selected_video_track;
  132. NonnullOwnPtr<VideoDecoder> m_decoder;
  133. NonnullOwnPtr<VideoFrameQueue> m_frame_queue;
  134. RefPtr<Core::Timer> m_present_timer;
  135. unsigned m_decoding_buffer_time_ms = 16;
  136. RefPtr<Core::Timer> m_decode_timer;
  137. NonnullOwnPtr<PlaybackStateHandler> m_playback_handler;
  138. Optional<FrameQueueItem> m_next_frame;
  139. u64 m_skipped_frames { 0 };
  140. // This is a nested class to allow private access.
  141. class PlaybackStateHandler {
  142. public:
  143. PlaybackStateHandler(PlaybackManager& manager)
  144. : m_manager(manager)
  145. {
  146. }
  147. virtual ~PlaybackStateHandler() = default;
  148. virtual StringView name() = 0;
  149. virtual ErrorOr<void> on_enter() { return {}; }
  150. virtual ErrorOr<void> play() { return {}; };
  151. virtual bool is_playing() const = 0;
  152. virtual PlaybackState get_state() const = 0;
  153. virtual ErrorOr<void> pause() { return {}; };
  154. virtual ErrorOr<void> buffer() { return {}; };
  155. virtual ErrorOr<void> seek(Time target_timestamp, SeekMode);
  156. virtual ErrorOr<void> stop();
  157. virtual Time current_time() const;
  158. virtual ErrorOr<void> on_timer_callback() { return {}; };
  159. virtual ErrorOr<void> on_buffer_filled() { return {}; };
  160. protected:
  161. template<class T, class... Args>
  162. ErrorOr<void> replace_handler_and_delete_this(Args... args);
  163. PlaybackManager& manager() const;
  164. PlaybackManager& manager()
  165. {
  166. return const_cast<PlaybackManager&>(const_cast<PlaybackStateHandler const*>(this)->manager());
  167. }
  168. private:
  169. PlaybackManager& m_manager;
  170. #if PLAYBACK_MANAGER_DEBUG
  171. bool m_has_exited { false };
  172. #endif
  173. };
  174. };
  175. }