GLPlayer.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #pragma once
  2. #include "MemoryStreamProtocol.h"
  3. #include "WallpaperEngine/Render/RenderContext.h"
  4. #include <GL/glew.h>
  5. #include <mpv/client.h>
  6. #include <mpv/render.h>
  7. #include <optional>
  8. #include <string>
  9. #include <unordered_map>
  10. namespace WallpaperEngine::VideoPlayback::MPV {
  11. class GLPlayer : public Helpers::ContextAware {
  12. friend struct MemoryStreamProtocol;
  13. public:
  14. GLPlayer (
  15. RenderContext& context, GLuint outputTexture, const std::filesystem::path& file, int64_t baseWidth,
  16. int64_t baseHeight, GLuint fbo = GL_NONE
  17. );
  18. GLPlayer (
  19. RenderContext& context, GLuint outputTexture, MemoryStreamProtocolUniquePtr stream, int64_t baseWidth,
  20. int64_t baseHeight, GLuint fbo = GL_NONE
  21. );
  22. ~GLPlayer () override;
  23. /** Refcounts playback: starts mpv on the first user */
  24. void incrementUsageCount ();
  25. /** Refcounts playback: stops mpv once the last user releases it */
  26. void decrementUsageCount ();
  27. void setUntimed ();
  28. /** For videos that are only ever a texture. Must be called before playback starts */
  29. void disableAudio ();
  30. void clearUntimed ();
  31. void setMuted ();
  32. void clearMuted ();
  33. void setVolume (double volume);
  34. void setSpeed (double speed);
  35. [[nodiscard]] double getSpeed () const { return this->m_speed; }
  36. void setPaused ();
  37. void clearPaused ();
  38. void setLoop (bool loop);
  39. /** Jumps to a position in seconds, remembered and applied once the file has loaded if playback hasn't got that far */
  40. void seek (double seconds);
  41. /** Whether a non-looping video has played through to its end since the last seek */
  42. [[nodiscard]] bool hasEnded () const { return this->m_ended; }
  43. [[nodiscard]] bool isPaused () const { return this->m_paused; }
  44. [[nodiscard]] bool isLooping () const { return this->m_loop; }
  45. /** Total length in seconds, or 0 while it isn't known yet */
  46. double getDuration () const;
  47. void render () const;
  48. int getWidth () const;
  49. int getHeight () const;
  50. /** Current playback position in seconds, or 0 if playback hasn't started yet */
  51. double getPlaybackPosition () const;
  52. /** Time spent in render () since the last reset, only collected while LWE_FRAME_STATS is set */
  53. static double s_statsMillis;
  54. private:
  55. void prepareGL ();
  56. void init ();
  57. void play ();
  58. void setSource (MemoryStreamProtocolUniquePtr source);
  59. void setSource (const std::filesystem::path& file);
  60. void stop ();
  61. protected:
  62. bool m_doWeOwnFramebuffer;
  63. GLuint m_outputTexture;
  64. GLuint m_fbo = GL_NONE;
  65. mutable int64_t m_width;
  66. mutable int64_t m_height;
  67. mpv_handle* m_handle = nullptr;
  68. mpv_render_context* m_renderContext = nullptr;
  69. double m_volume = 0.0f;
  70. double m_speed = 1.0;
  71. bool m_muted = false;
  72. bool m_untimed = false;
  73. bool m_paused = false;
  74. bool m_loop = true;
  75. bool m_audio = true;
  76. // a texture we own only needs redrawing when mpv has a new frame, or after its size changed
  77. mutable bool m_needsRedraw = true;
  78. mutable bool m_fileLoaded = false;
  79. mutable bool m_ended = false;
  80. mutable std::optional<double> m_pendingSeek;
  81. std::optional<std::filesystem::path> m_file;
  82. std::optional<MemoryStreamProtocolUniquePtr> m_stream;
  83. uint32_t m_usageCount = 0;
  84. // tracks the currently playing instance for each video path, so a player starting
  85. // the same video another monitor is already showing can pick up around the same spot
  86. // instead of always restarting from zero
  87. static std::unordered_map<std::filesystem::path, GLPlayer*> s_activePlayers;
  88. };
  89. using GLPlayerUniquePtr = std::unique_ptr<GLPlayer>;
  90. using GLPlayerSharedPtr = std::shared_ptr<GLPlayer>;
  91. };