PlaybackManager.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  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. class PlaybackTimer {
  71. public:
  72. virtual ~PlaybackTimer() = default;
  73. virtual void start() = 0;
  74. virtual void start(int interval_ms) = 0;
  75. };
  76. enum class PlaybackState {
  77. Playing,
  78. Paused,
  79. Buffering,
  80. Seeking,
  81. Stopped,
  82. };
  83. class PlaybackManager {
  84. public:
  85. enum class SeekMode {
  86. Accurate,
  87. Fast,
  88. };
  89. static constexpr SeekMode DEFAULT_SEEK_MODE = SeekMode::Accurate;
  90. using PlaybackTimerCreator = Function<ErrorOr<NonnullOwnPtr<PlaybackTimer>>(int, Function<void()>)>;
  91. static DecoderErrorOr<NonnullOwnPtr<PlaybackManager>> from_file(StringView file, PlaybackTimerCreator = nullptr);
  92. static DecoderErrorOr<NonnullOwnPtr<PlaybackManager>> from_data(ReadonlyBytes data, PlaybackTimerCreator = nullptr);
  93. PlaybackManager(NonnullOwnPtr<Demuxer>& demuxer, Track video_track, NonnullOwnPtr<VideoDecoder>&& decoder, PlaybackTimerCreator);
  94. void resume_playback();
  95. void pause_playback();
  96. void restart_playback();
  97. void seek_to_timestamp(Time, SeekMode = DEFAULT_SEEK_MODE);
  98. bool is_playing() const
  99. {
  100. return m_playback_handler->is_playing();
  101. }
  102. PlaybackState get_state() const
  103. {
  104. return m_playback_handler->get_state();
  105. }
  106. u64 number_of_skipped_frames() const { return m_skipped_frames; }
  107. Time current_playback_time();
  108. Time duration();
  109. Function<void(RefPtr<Gfx::Bitmap>)> on_video_frame;
  110. Function<void()> on_playback_state_change;
  111. Function<void(DecoderError)> on_decoder_error;
  112. Function<void(Error)> on_fatal_playback_error;
  113. Track const& selected_video_track() const { return m_selected_video_track; }
  114. private:
  115. class PlaybackStateHandler;
  116. // Abstract class to allow resuming play/pause after the state is completed.
  117. class ResumingStateHandler;
  118. class PlayingStateHandler;
  119. class PausedStateHandler;
  120. class BufferingStateHandler;
  121. class SeekingStateHandler;
  122. class StoppedStateHandler;
  123. static DecoderErrorOr<NonnullOwnPtr<PlaybackManager>> create_with_demuxer(NonnullOwnPtr<Demuxer> demuxer, PlaybackTimerCreator playback_timer_creator);
  124. void start_timer(int milliseconds);
  125. void timer_callback();
  126. Optional<Time> seek_demuxer_to_most_recent_keyframe(Time timestamp, Optional<Time> earliest_available_sample = OptionalNone());
  127. bool decode_and_queue_one_sample();
  128. void on_decode_timer();
  129. void dispatch_decoder_error(DecoderError error);
  130. void dispatch_new_frame(RefPtr<Gfx::Bitmap> frame);
  131. // Returns whether we changed playback states. If so, any PlaybackStateHandler processing must cease.
  132. [[nodiscard]] bool dispatch_frame_queue_item(FrameQueueItem&&);
  133. void dispatch_state_change();
  134. void dispatch_fatal_error(Error);
  135. Time m_last_present_in_media_time = Time::zero();
  136. NonnullOwnPtr<Demuxer> m_demuxer;
  137. Track m_selected_video_track;
  138. NonnullOwnPtr<VideoDecoder> m_decoder;
  139. NonnullOwnPtr<VideoFrameQueue> m_frame_queue;
  140. OwnPtr<PlaybackTimer> m_present_timer;
  141. unsigned m_decoding_buffer_time_ms = 16;
  142. OwnPtr<PlaybackTimer> m_decode_timer;
  143. NonnullOwnPtr<PlaybackStateHandler> m_playback_handler;
  144. Optional<FrameQueueItem> m_next_frame;
  145. u64 m_skipped_frames { 0 };
  146. // This is a nested class to allow private access.
  147. class PlaybackStateHandler {
  148. public:
  149. PlaybackStateHandler(PlaybackManager& manager)
  150. : m_manager(manager)
  151. {
  152. }
  153. virtual ~PlaybackStateHandler() = default;
  154. virtual StringView name() = 0;
  155. virtual ErrorOr<void> on_enter() { return {}; }
  156. virtual ErrorOr<void> play() { return {}; };
  157. virtual bool is_playing() const = 0;
  158. virtual PlaybackState get_state() const = 0;
  159. virtual ErrorOr<void> pause() { return {}; };
  160. virtual ErrorOr<void> buffer() { return {}; };
  161. virtual ErrorOr<void> seek(Time target_timestamp, SeekMode);
  162. virtual ErrorOr<void> stop();
  163. virtual Time current_time() const;
  164. virtual ErrorOr<void> on_timer_callback() { return {}; };
  165. virtual ErrorOr<void> on_buffer_filled() { return {}; };
  166. protected:
  167. template<class T, class... Args>
  168. ErrorOr<void> replace_handler_and_delete_this(Args... args);
  169. PlaybackManager& manager() const;
  170. PlaybackManager& manager()
  171. {
  172. return const_cast<PlaybackManager&>(const_cast<PlaybackStateHandler const*>(this)->manager());
  173. }
  174. private:
  175. PlaybackManager& m_manager;
  176. #if PLAYBACK_MANAGER_DEBUG
  177. bool m_has_exited { false };
  178. #endif
  179. };
  180. };
  181. }