media_view_pip.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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 "data/data_file_origin.h"
  9. #include "media/streaming/media_streaming_instance.h"
  10. #include "media/media_common.h"
  11. #include "ui/effects/animations.h"
  12. #include "ui/round_rect.h"
  13. #include "ui/rp_widget.h"
  14. #include <QtCore/QPointer>
  15. class HistoryItem;
  16. namespace base {
  17. class PowerSaveBlocker;
  18. } // namespace base
  19. namespace Data {
  20. class DocumentMedia;
  21. } // namespace Data
  22. namespace Ui {
  23. class IconButton;
  24. template <typename Widget>
  25. class FadeWrap;
  26. namespace GL {
  27. struct ChosenRenderer;
  28. struct Capabilities;
  29. } // namespace GL
  30. } // namespace Ui
  31. namespace Media::Player {
  32. struct TrackState;
  33. } // namespace Media::Player
  34. namespace Media::Streaming {
  35. class Document;
  36. } // namespace Media::Streaming
  37. namespace Media::View {
  38. class PlaybackProgress;
  39. [[nodiscard]] QRect RotatedRect(QRect rect, int rotation);
  40. [[nodiscard]] bool UsePainterRotation(int rotation);
  41. [[nodiscard]] QSize FlipSizeByRotation(QSize size, int rotation);
  42. [[nodiscard]] QImage RotateFrameImage(QImage image, int rotation);
  43. class PipPanel final {
  44. public:
  45. struct Position {
  46. RectParts attached = RectPart(0);
  47. RectParts snapped = RectPart(0);
  48. QRect geometry;
  49. QRect screen;
  50. };
  51. PipPanel(
  52. QWidget *parent,
  53. Fn<Ui::GL::ChosenRenderer(Ui::GL::Capabilities)> renderer);
  54. void init();
  55. [[nodiscard]] not_null<QWidget*> widget() const;
  56. [[nodiscard]] not_null<Ui::RpWidgetWrap*> rp() const;
  57. void update();
  58. void setGeometry(QRect geometry);
  59. void setAspectRatio(QSize ratio);
  60. [[nodiscard]] Position countPosition() const;
  61. void setPosition(Position position);
  62. [[nodiscard]] QRect inner() const;
  63. [[nodiscard]] RectParts attached() const;
  64. [[nodiscard]] bool useTransparency() const;
  65. void setDragDisabled(bool disabled);
  66. [[nodiscard]] bool dragging() const;
  67. void handleWaylandResize(QSize size);
  68. void handleScreenChanged(not_null<QScreen*> screen);
  69. void handleMousePress(QPoint position, Qt::MouseButton button);
  70. void handleMouseRelease(QPoint position, Qt::MouseButton button);
  71. void handleMouseMove(QPoint position);
  72. [[nodiscard]] rpl::producer<> saveGeometryRequests() const;
  73. private:
  74. void setPositionDefault();
  75. void setPositionOnScreen(Position position, QRect available);
  76. QScreen *myScreen() const;
  77. void startSystemDrag();
  78. void processDrag(QPoint point);
  79. void finishDrag(QPoint point);
  80. void updatePositionAnimated();
  81. void updateOverState(QPoint point);
  82. void moveAnimated(QPoint to);
  83. void updateDecorations();
  84. const std::unique_ptr<Ui::RpWidgetWrap> _content;
  85. const QPointer<QWidget> _parent;
  86. RectParts _attached = RectParts();
  87. RectParts _snapped = RectParts();
  88. QSize _ratio;
  89. bool _useTransparency = true;
  90. bool _dragDisabled = false;
  91. bool _inHandleWaylandResize = false;
  92. style::margins _padding;
  93. RectPart _overState = RectPart();
  94. std::optional<RectPart> _pressState;
  95. QPoint _pressPoint;
  96. QRect _dragStartGeometry;
  97. std::optional<RectPart> _dragState;
  98. rpl::event_stream<> _saveGeometryRequests;
  99. QPoint _positionAnimationFrom;
  100. QPoint _positionAnimationTo;
  101. Ui::Animations::Simple _positionAnimation;
  102. };
  103. class Pip final {
  104. public:
  105. class Delegate {
  106. public:
  107. virtual void pipSaveGeometry(QByteArray geometry) = 0;
  108. [[nodiscard]] virtual QByteArray pipLoadGeometry() = 0;
  109. [[nodiscard]] virtual float64 pipPlaybackSpeed() = 0;
  110. [[nodiscard]] virtual QWidget *pipParentWidget() = 0;
  111. };
  112. Pip(
  113. not_null<Delegate*> delegate,
  114. not_null<DocumentData*> data,
  115. Data::FileOrigin origin,
  116. not_null<DocumentData*> chosenQuality,
  117. HistoryItem *context,
  118. VideoQuality quality,
  119. std::shared_ptr<Streaming::Document> shared,
  120. FnMut<void()> closeAndContinue,
  121. FnMut<void()> destroy);
  122. ~Pip();
  123. [[nodiscard]] std::shared_ptr<Streaming::Document> shared() const;
  124. private:
  125. enum class OverState {
  126. None,
  127. Close,
  128. Enlarge,
  129. Playback,
  130. VolumeToggle,
  131. VolumeController,
  132. Other,
  133. };
  134. enum class ThumbState {
  135. Empty,
  136. Inline,
  137. Thumb,
  138. Good,
  139. Cover,
  140. };
  141. struct Button {
  142. QRect area;
  143. QRect icon;
  144. OverState state = OverState::None;
  145. Ui::Animations::Simple active;
  146. };
  147. struct ContentGeometry {
  148. QRect inner;
  149. RectParts attached = RectParts();
  150. float64 fade = 0.;
  151. QSize outer;
  152. int rotation = 0;
  153. int videoRotation = 0;
  154. bool useTransparency = false;
  155. };
  156. struct StaticContent {
  157. QImage image;
  158. bool blurred = false;
  159. };
  160. using FrameRequest = Streaming::FrameRequest;
  161. class Renderer;
  162. class RendererGL;
  163. class RendererSW;
  164. void setupPanel();
  165. void setupButtons();
  166. void setupStreaming();
  167. void playbackPauseResume();
  168. void volumeChanged(float64 volume);
  169. void volumeToggled();
  170. void volumeControllerUpdate(QPoint position);
  171. void waitingAnimationCallback();
  172. void handleStreamingUpdate(Streaming::Update &&update);
  173. void handleStreamingError(Streaming::Error &&error);
  174. void saveGeometry();
  175. void updatePlaybackState();
  176. void updatePowerSaveBlocker(const Player::TrackState &state);
  177. void updatePlayPauseResumeState(const Player::TrackState &state);
  178. void restartAtSeekPosition(crl::time position);
  179. [[nodiscard]] bool canUseVideoFrame() const;
  180. [[nodiscard]] QImage videoFrame(const FrameRequest &request) const;
  181. [[nodiscard]] Streaming::FrameWithInfo videoFrameWithInfo() const; // YUV
  182. [[nodiscard]] QImage staticContent() const;
  183. [[nodiscard]] OverState computeState(QPoint position) const;
  184. void setOverState(OverState state);
  185. void setPressedState(std::optional<OverState> state);
  186. [[nodiscard]] OverState shownActiveState() const;
  187. [[nodiscard]] float64 activeValue(const Button &button) const;
  188. void updateActiveState(OverState was);
  189. void updatePlaybackTexts(int64 position, int64 length, int64 frequency);
  190. [[nodiscard]] static OverState ResolveShownOver(OverState state);
  191. [[nodiscard]] Ui::GL::ChosenRenderer chooseRenderer(
  192. Ui::GL::Capabilities capabilities);
  193. void paint(not_null<Renderer*> renderer) const;
  194. void handleMouseMove(QPoint position);
  195. void handleMousePress(QPoint position, Qt::MouseButton button);
  196. void handleMouseRelease(QPoint position, Qt::MouseButton button);
  197. void handleDoubleClick(Qt::MouseButton button);
  198. void handleLeave();
  199. void handleClose();
  200. void paintRadialLoadingContent(
  201. QPainter &p,
  202. const QRect &inner,
  203. QColor fg) const;
  204. void paintButtons(not_null<Renderer*> renderer, float64 shown) const;
  205. void paintPlayback(not_null<Renderer*> renderer, float64 shown) const;
  206. void paintPlaybackContent(QPainter &p, QRect outer, float64 shown) const;
  207. void paintPlaybackProgress(QPainter &p, QRect outer) const;
  208. void paintProgressBar(
  209. QPainter &p,
  210. const QRect &rect,
  211. float64 progress,
  212. int radius,
  213. float64 active) const;
  214. void paintPlaybackTexts(QPainter &p, QRect outer) const;
  215. void paintVolumeController(
  216. not_null<Renderer*> renderer,
  217. float64 shown) const;
  218. void paintVolumeControllerContent(
  219. QPainter &p,
  220. QRect outer,
  221. float64 shown) const;
  222. [[nodiscard]] QRect countRadialRect() const;
  223. void applyVideoQuality(VideoQuality value);
  224. [[nodiscard]] QImage currentVideoFrameImage() const;
  225. void seekUpdate(QPoint position);
  226. void seekProgress(float64 value);
  227. void seekFinish(float64 value);
  228. const not_null<Delegate*> _delegate;
  229. const not_null<DocumentData*> _data;
  230. const Data::FileOrigin _origin;
  231. DocumentData *_chosenQuality = nullptr;
  232. HistoryItem *_context = nullptr;
  233. Media::VideoQuality _quality;
  234. std::optional<Streaming::Instance> _instance;
  235. bool _opengl = false;
  236. PipPanel _panel;
  237. QSize _size;
  238. std::unique_ptr<base::PowerSaveBlocker> _powerSaveBlocker;
  239. std::unique_ptr<PlaybackProgress> _playbackProgress;
  240. std::shared_ptr<Data::DocumentMedia> _dataMedia;
  241. QImage _qualityChangeFrame;
  242. bool _qualityChangeFinished = false;
  243. crl::time _lastUpdatePosition = 0;
  244. bool _showPause = false;
  245. bool _startPaused = false;
  246. bool _pausedBySeek = false;
  247. QString _timeAlready, _timeLeft;
  248. int _timeLeftWidth = 0;
  249. int _rotation = 0;
  250. float64 _lastPositiveVolume = 1.;
  251. crl::time _seekPositionMs = -1;
  252. crl::time _lastDurationMs = 0;
  253. OverState _over = OverState::None;
  254. std::optional<OverState> _pressed;
  255. std::optional<OverState> _lastHandledPress;
  256. Button _close;
  257. Button _enlarge;
  258. Button _playback;
  259. Button _play;
  260. Button _volumeToggle;
  261. Button _volumeController;
  262. Ui::Animations::Simple _controlsShown;
  263. FnMut<void()> _closeAndContinue;
  264. FnMut<void()> _destroy;
  265. mutable QImage _preparedCoverStorage;
  266. mutable ThumbState _preparedCoverState = ThumbState::Empty;
  267. };
  268. } // namespace Media::View