CVideo.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include "common.h"
  2. #include "CVideo.h"
  3. #include <pthread.h>
  4. #include <GL/glew.h>
  5. extern bool g_AudioEnabled;
  6. extern int g_AudioVolume;
  7. using namespace WallpaperEngine;
  8. using namespace WallpaperEngine::Render;
  9. void* get_proc_address (void* ctx, const char* name)
  10. {
  11. return reinterpret_cast <void*> (glfwGetProcAddress (name));
  12. }
  13. CVideo::CVideo (Core::CVideo* video, CRenderContext& context, CAudioContext& audioContext) :
  14. CWallpaper (video, Type, context, audioContext),
  15. m_width (16),
  16. m_height (16),
  17. m_mpvGl (nullptr)
  18. {
  19. double volume = g_AudioVolume * 100.0 / 128.0;
  20. // create mpv contexts
  21. this->m_mpv = mpv_create ();
  22. if (this->m_mpv == nullptr)
  23. sLog.exception ("Could not create mpv context");
  24. mpv_set_option_string (this->m_mpv, "terminal", "yes");
  25. mpv_set_option_string (this->m_mpv, "msg-level", "all=v");
  26. mpv_set_option_string (this->m_mpv, "input-cursor", "no");
  27. mpv_set_option_string (this->m_mpv, "cursor-autohide", "no");
  28. mpv_set_option_string (this->m_mpv, "config", "no");
  29. mpv_set_option_string (this->m_mpv, "fbo-format", "rgba8");
  30. if (mpv_initialize (this->m_mpv) < 0)
  31. sLog.exception ("Could not initialize mpv context");
  32. mpv_set_option_string (this->m_mpv, "hwdec", "auto");
  33. mpv_set_option_string (this->m_mpv, "loop", "inf");
  34. mpv_set_option (this->m_mpv, "volume", MPV_FORMAT_DOUBLE, &volume);
  35. // initialize gl context for mpv
  36. mpv_opengl_init_params gl_init_params {get_proc_address, nullptr};
  37. mpv_render_param params[] {
  38. {MPV_RENDER_PARAM_API_TYPE, const_cast <char*> (MPV_RENDER_API_TYPE_OPENGL)},
  39. {MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &gl_init_params},
  40. {MPV_RENDER_PARAM_INVALID, nullptr}
  41. };
  42. if (mpv_render_context_create (&this->m_mpvGl, this->m_mpv, params) < 0)
  43. sLog.exception ("Failed to initialize MPV's GL context");
  44. std::filesystem::path videopath = this->getVideo ()->getProject ().getContainer ()->resolveRealFile (this->getVideo ()->getFilename ());
  45. // build the path to the video file
  46. const char* command [] = {
  47. "loadfile", videopath.c_str (), nullptr
  48. };
  49. if (mpv_command (this->m_mpv, command) < 0)
  50. sLog.exception ("Cannot load video to play");
  51. if (!g_AudioEnabled)
  52. {
  53. const char* mutecommand [] = {
  54. "set", "mute", "yes", nullptr
  55. };
  56. mpv_command (this->m_mpv, mutecommand);
  57. }
  58. // setup framebuffers
  59. this->setupFramebuffers();
  60. }
  61. void CVideo::setSize (int64_t width, int64_t height)
  62. {
  63. this->m_width = width > 0 ? width : this->m_width;
  64. this->m_height = height > 0 ? height : this->m_height;
  65. // do not refresh the texture if any of the sizes are invalid
  66. if (this->m_width <= 0 || this->m_height <= 0)
  67. return;
  68. // reconfigure the texture
  69. glBindTexture (GL_TEXTURE_2D, this->getWallpaperTexture());
  70. glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, this->m_width, this->m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
  71. }
  72. void CVideo::renderFrame (glm::ivec4 viewport)
  73. {
  74. // read any and all the events available
  75. while (this->m_mpv)
  76. {
  77. mpv_event* event = mpv_wait_event (this->m_mpv, 0);
  78. if (event == nullptr || event->event_id == MPV_EVENT_NONE)
  79. break;
  80. // we do not care about any of the events
  81. if (event->event_id == MPV_EVENT_VIDEO_RECONFIG)
  82. {
  83. int64_t width, height;
  84. if (mpv_get_property (this->m_mpv, "dwidth", MPV_FORMAT_INT64, &width) >= 0 &&
  85. mpv_get_property (this->m_mpv, "dheight", MPV_FORMAT_INT64, &height) >= 0)
  86. this->setSize (width, height);
  87. }
  88. }
  89. // render the next
  90. glViewport (0, 0, this->getWidth (), this->getHeight ());
  91. mpv_opengl_fbo fbo {
  92. static_cast <int> (this->getWallpaperFramebuffer()),
  93. static_cast <int> (this->m_width),
  94. static_cast <int> (this->m_height),
  95. GL_RGBA8
  96. };
  97. // no need to flip as it'll be handled by the wallpaper rendering code
  98. int flip_y = 0;
  99. mpv_render_param params [] = {
  100. {MPV_RENDER_PARAM_OPENGL_FBO, &fbo},
  101. {MPV_RENDER_PARAM_FLIP_Y, &flip_y},
  102. {MPV_RENDER_PARAM_INVALID, nullptr}
  103. };
  104. mpv_render_context_render (this->m_mpvGl, params);
  105. }
  106. Core::CVideo* CVideo::getVideo ()
  107. {
  108. return this->getWallpaperData ()->as<Core::CVideo> ();
  109. }
  110. uint32_t CVideo::getWidth () const
  111. {
  112. return this->m_width;
  113. }
  114. uint32_t CVideo::getHeight () const
  115. {
  116. return this->m_height;
  117. }
  118. const std::string CVideo::Type = "video";