media_streaming_player.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "media/streaming/media_streaming_common.h"
  9. #include "media/streaming/media_streaming_file_delegate.h"
  10. #include "base/weak_ptr.h"
  11. #include "base/timer.h"
  12. namespace Media {
  13. namespace Player {
  14. struct TrackState;
  15. } // namespace Player
  16. } // namespace Media
  17. namespace Media {
  18. namespace Streaming {
  19. class Reader;
  20. class File;
  21. class AudioTrack;
  22. class VideoTrack;
  23. class Instance;
  24. class Player final : private FileDelegate {
  25. public:
  26. // Public interfaces is used from the main thread.
  27. explicit Player(std::shared_ptr<Reader> reader);
  28. // Because we remember 'this' in calls to crl::on_main.
  29. Player(const Player &other) = delete;
  30. Player &operator=(const Player &other) = delete;
  31. void play(const PlaybackOptions &options);
  32. void pause();
  33. void resume();
  34. void stop();
  35. // Allow to irreversibly stop only audio track.
  36. void stopAudio();
  37. [[nodiscard]] bool active() const;
  38. [[nodiscard]] bool ready() const;
  39. [[nodiscard]] float64 speed() const;
  40. void setSpeed(float64 speed);
  41. void setWaitForMarkAsShown(bool wait);
  42. [[nodiscard]] bool playing() const;
  43. [[nodiscard]] bool buffering() const;
  44. [[nodiscard]] bool paused() const;
  45. [[nodiscard]] std::optional<Error> failed() const;
  46. [[nodiscard]] bool finished() const;
  47. [[nodiscard]] rpl::producer<Update, Error> updates() const;
  48. [[nodiscard]] rpl::producer<bool> fullInCache() const;
  49. [[nodiscard]] int64 fileSize() const;
  50. [[nodiscard]] QSize videoSize() const;
  51. [[nodiscard]] QImage frame(
  52. const FrameRequest &request,
  53. const Instance *instance = nullptr) const;
  54. [[nodiscard]] FrameWithInfo frameWithInfo(
  55. const FrameRequest &request,
  56. const Instance *instance = nullptr) const;
  57. [[nodiscard]] FrameWithInfo frameWithInfo(
  58. const Instance *instance = nullptr) const; // !requireARGB32
  59. [[nodiscard]] QImage currentFrameImage() const; // Converts if needed.
  60. void unregisterInstance(not_null<const Instance*> instance);
  61. bool markFrameShown();
  62. void setLoaderPriority(int priority);
  63. [[nodiscard]] Media::Player::TrackState prepareLegacyState() const;
  64. void lock();
  65. void unlock();
  66. [[nodiscard]] bool locked() const;
  67. [[nodiscard]] rpl::lifetime &lifetime();
  68. ~Player();
  69. private:
  70. enum class Stage {
  71. Uninitialized,
  72. Initializing,
  73. Ready,
  74. Started,
  75. };
  76. // Thread-safe.
  77. not_null<FileDelegate*> delegate();
  78. // FileDelegate methods are called only from the File thread.
  79. Mode fileOpenMode() override;
  80. bool fileReady(int headerSize, Stream &&video, Stream &&audio) override;
  81. void fileError(Error error) override;
  82. void fileWaitingForData() override;
  83. void fileFullInCache(bool fullInCache) override;
  84. bool fileProcessPackets(
  85. base::flat_map<int, std::vector<FFmpeg::Packet>> &packets) override;
  86. void fileProcessEndOfFile() override;
  87. bool fileReadMore() override;
  88. // Called from the main thread.
  89. void streamReady(Information &&information);
  90. void streamFailed(Error error);
  91. void start();
  92. void stop(bool stillActive);
  93. void provideStartInformation();
  94. void fail(Error error);
  95. void checkVideoStep();
  96. void checkNextFrameRender();
  97. void checkNextFrameAvailability();
  98. void renderFrame(crl::time now);
  99. void audioReceivedTill(crl::time position);
  100. void audioPlayedTill(crl::time position);
  101. void videoReceivedTill(crl::time position);
  102. void videoPlayedTill(crl::time position);
  103. void updatePausedState();
  104. [[nodiscard]] bool trackReceivedEnough(
  105. const TrackState &state,
  106. crl::time amount) const;
  107. [[nodiscard]] bool bothReceivedEnough(crl::time amount) const;
  108. [[nodiscard]] bool receivedTillEnd() const;
  109. void checkResumeFromWaitingForData();
  110. [[nodiscard]] crl::time getCurrentReceivedTill(crl::time duration) const;
  111. void savePreviousReceivedTill(
  112. const PlaybackOptions &options,
  113. crl::time previousReceivedTill);
  114. [[nodiscard]] crl::time loadInAdvanceFor() const;
  115. template <typename Track>
  116. int durationByPacket(const Track &track, const FFmpeg::Packet &packet);
  117. // Valid after fileReady call ends. Thread-safe.
  118. [[nodiscard]] crl::time computeAudioDuration() const;
  119. [[nodiscard]] crl::time computeVideoDuration() const;
  120. [[nodiscard]] crl::time computeTotalDuration() const;
  121. void setDurationByPackets();
  122. template <typename Track>
  123. void trackReceivedTill(
  124. const Track &track,
  125. TrackState &state,
  126. crl::time position);
  127. template <typename Track>
  128. void trackSendReceivedTill(
  129. const Track &track,
  130. TrackState &state);
  131. template <typename Track>
  132. void trackPlayedTill(
  133. const Track &track,
  134. TrackState &state,
  135. crl::time position);
  136. const std::unique_ptr<File> _file;
  137. // Immutable while File is active after it is ready.
  138. AudioMsgId _audioId;
  139. std::unique_ptr<AudioTrack> _audio;
  140. std::unique_ptr<VideoTrack> _video;
  141. // Immutable while File is active.
  142. base::has_weak_ptr _sessionGuard;
  143. // Immutable while File is active except '.speed'.
  144. // '.speed' is changed from the main thread.
  145. PlaybackOptions _options;
  146. // Belongs to the File thread while File is active.
  147. bool _readTillEnd = false;
  148. bool _waitingForData = false;
  149. std::atomic<bool> _pauseReading = false;
  150. // Belongs to the main thread.
  151. Information _information;
  152. Stage _stage = Stage::Uninitialized;
  153. std::optional<Error> _lastFailure;
  154. bool _pausedByUser = false;
  155. bool _pausedByWaitingForData = false;
  156. bool _paused = false;
  157. bool _audioFinished = false;
  158. bool _videoFinished = false;
  159. bool _remoteLoader = false;
  160. crl::time _startedTime = kTimeUnknown;
  161. crl::time _pausedTime = kTimeUnknown;
  162. crl::time _currentFrameTime = kTimeUnknown;
  163. crl::time _nextFrameTime = kTimeUnknown;
  164. base::Timer _renderFrameTimer;
  165. rpl::event_stream<Update, Error> _updates;
  166. rpl::event_stream<bool> _fullInCache;
  167. std::optional<bool> _fullInCacheSinceStart;
  168. crl::time _totalDuration = kTimeUnknown;
  169. crl::time _loopingShift = 0;
  170. crl::time _previousReceivedTill = kTimeUnknown;
  171. std::atomic<int> _durationByPackets = 0;
  172. int _durationByLastAudioPacket = 0;
  173. int _durationByLastVideoPacket = 0;
  174. int _locks = 0;
  175. rpl::lifetime _lifetime;
  176. rpl::lifetime _sessionLifetime;
  177. };
  178. } // namespace Streaming
  179. } // namespace Media