]> Some of my projects - aniplayer.git/commitdiff
Add Handle classes for MPV handles
authorAPTX <marek321@gmail.com>
Sun, 20 Feb 2022 05:06:13 +0000 (14:06 +0900)
committerAPTX <marek321@gmail.com>
Mon, 21 Feb 2022 15:14:57 +0000 (00:14 +0900)
Also fixes idle-active property format in observe call

backendplugins/backend_mpv/CMakeLists.txt
backendplugins/backend_mpv/backendmpv.cpp
backendplugins/backend_mpv/backendmpv.h
backendplugins/backend_mpv/mpvhandle.cpp [new file with mode: 0644]
backendplugins/backend_mpv/mpvhandle.h [new file with mode: 0644]
backendplugins/backend_mpv/mpvhelper.h

index c848299a07bac394676e77c16cb42cbd6ba395ca..e075d7aec7c26a9c5af167c61e27b9fa7a6c9a87 100644 (file)
@@ -18,10 +18,12 @@ set(backend_mpv_LIBS
 
 set(backend_mpv_SOURCES
     backendmpv.cpp
+    mpvhandle.cpp
 )
 
 set(backend_mpv_HEADERS
     backendmpv.h
+    mpvhandle.h
     mpvhelper.h
     qthelper.hpp
     backend_mpv_global.h
index 0e1198557243278973803d8d6a21bd6215136be5..6df780790247b9e6d6dff6d6cc5e4188289e8df4 100644 (file)
@@ -31,77 +31,75 @@ BackendInstance *BackendMpv::createInstance(PlayerPluginInterface *player) {
 
 MpvInstance::MpvInstance(PlayerPluginInterface *playerInterface,
                          QObject *parent)
-    : QObject{parent}, m_player{playerInterface} {
+    : QObject{parent}, m_player{playerInterface}, m_handle{
+                                                      mpv::Handle::create()} {
   qCDebug(mpvBackend) << "Initialize";
-  m_handle = mpv_create();
-
-  Q_CHECK_PTR(m_handle);
 
   qCDebug(mpvBackend()).nospace()
       << "Client API version: " << (mpv_client_api_version() >> 16) << '.'
       << (mpv_client_api_version() & ~(~0u << 16));
 
-  int error = mpv_initialize(m_handle);
+  int error = mpv_initialize(m_handle.get());
   if (error) {
     qCCritical(mpvBackend) << "Error initializing mpv"
                            << mpv_error_string(error);
     return;
   }
 
-  mpv_set_wakeup_callback(m_handle, mpvWakeupCb, this);
+  mpv_set_wakeup_callback(m_handle.get(), mpvWakeupCb, this);
   {
     const auto ret =
-        mpv_observe_property(m_handle, 0, "pause", MPV_FORMAT_FLAG);
+        mpv_observe_property(m_handle.get(), 0, "pause", MPV_FORMAT_FLAG);
     qCDebug(mpvBackend) << "register pause" << ret;
   }
   {
     const auto ret =
-        mpv_observe_property(m_handle, 0, "duration", MPV_FORMAT_DOUBLE);
+        mpv_observe_property(m_handle.get(), 0, "duration", MPV_FORMAT_DOUBLE);
     qCDebug(mpvBackend) << "register duration" << ret;
   }
   {
-    const auto ret =
-        mpv_observe_property(m_handle, 0, "playback-time", MPV_FORMAT_DOUBLE);
+    const auto ret = mpv_observe_property(m_handle.get(), 0, "playback-time",
+                                          MPV_FORMAT_DOUBLE);
     qCDebug(mpvBackend) << "register playback-time" << ret;
   }
   {
     const auto ret =
-        mpv_observe_property(m_handle, 0, VOLUME, MPV_FORMAT_DOUBLE);
+        mpv_observe_property(m_handle.get(), 0, VOLUME, MPV_FORMAT_DOUBLE);
     qCDebug(mpvBackend) << "register" << VOLUME << ret;
   }
   {
     const auto ret =
-        mpv_observe_property(m_handle, 0, "track-list", MPV_FORMAT_NODE);
+        mpv_observe_property(m_handle.get(), 0, "track-list", MPV_FORMAT_NODE);
     qCDebug(mpvBackend) << "register track-list" << ret;
   }
   {
     const auto ret =
-        mpv_observe_property(m_handle, 0, "vid", MPV_FORMAT_STRING);
+        mpv_observe_property(m_handle.get(), 0, "vid", MPV_FORMAT_STRING);
 
     qCDebug(mpvBackend) << "register vid" << ret;
   }
   {
     const auto ret =
-        mpv_observe_property(m_handle, 0, "aid", MPV_FORMAT_STRING);
+        mpv_observe_property(m_handle.get(), 0, "aid", MPV_FORMAT_STRING);
     qCDebug(mpvBackend) << "register aid" << ret;
   }
   {
     const auto ret =
-        mpv_observe_property(m_handle, 0, "sid", MPV_FORMAT_STRING);
+        mpv_observe_property(m_handle.get(), 0, "sid", MPV_FORMAT_STRING);
     qCDebug(mpvBackend) << "register sid" << ret;
   }
   {
-    const auto ret =
-        mpv_observe_property(m_handle, 0, "chapter-list", MPV_FORMAT_NODE);
+    const auto ret = mpv_observe_property(m_handle.get(), 0, "chapter-list",
+                                          MPV_FORMAT_NODE);
     qCDebug(mpvBackend) << "register chapter-list" << ret;
   }
   {
     const auto ret =
-        mpv_observe_property(m_handle, 0, "idle-active", MPV_FORMAT_NODE);
+        mpv_observe_property(m_handle.get(), 0, "idle-active", MPV_FORMAT_FLAG);
     qCDebug(mpvBackend) << "register chapter-list" << ret;
   }
   {
-    const auto ret = mpv_request_log_messages(m_handle, "info");
+    const auto ret = mpv_request_log_messages(m_handle.get(), "info");
     qCDebug(mpvBackend) << "request log messages" << ret;
   }
   {
@@ -113,7 +111,7 @@ MpvInstance::MpvInstance(PlayerPluginInterface *playerInterface,
 
 MpvInstance::~MpvInstance() {
   qCDebug(mpvBackend) << "Deinitialize";
-  mpv_terminate_destroy(m_handle);
+  mpv_terminate_destroy(m_handle.get());
 }
 
 VideoRendererBase *MpvInstance::createRenderer(VideoUpdateInterface *vui) {
@@ -126,7 +124,7 @@ bool MpvInstance::open(const QUrl &source) {
   const QByteArray tmp = source.toLocalFile().toUtf8();
 
   const char *args[] = {"loadfile", tmp.constData(), nullptr};
-  mpv_command_async(m_handle, 1, args);
+  mpv_command_async(m_handle.get(), 1, args);
   pause();
   m_currentlyLoading = source;
 
@@ -255,7 +253,7 @@ int MpvInstance::readTrackIndex(struct mpv_event_property *property) {
 void MpvInstance::processMpvEvents() {
   struct mpv_event *event = nullptr;
   do {
-    event = mpv_wait_event(m_handle, 0);
+    event = mpv_wait_event(m_handle.get(), 0);
     if (event->event_id == MPV_EVENT_NONE)
       break;
     qCDebug(mpvVerboseBackend).nospace()
@@ -431,9 +429,9 @@ void MpvInstance::mpvWakeupCb(void *obj) {
   QMetaObject::invokeMethod(self, "processMpvEvents", Qt::QueuedConnection);
 }
 
-VideoRendererMpv::VideoRendererMpv(mpv_handle *handle,
+VideoRendererMpv::VideoRendererMpv(mpv::Handle handle,
                                    VideoUpdateInterface *vui)
-    : m_handle{handle} {
+    : m_handle{std::move(handle)} {
   qCDebug(mpvBackend, "VideoRendererMpv::VideoRendererMpv");
   mpv_opengl_init_params opengl_init_params;
   opengl_init_params.get_proc_address = getProcAddress;
@@ -444,29 +442,29 @@ VideoRendererMpv::VideoRendererMpv(mpv_handle *handle,
       {MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &opengl_init_params},
       {MPV_RENDER_PARAM_INVALID, nullptr}};
 
-  int error = mpv_render_context_create(&m_renderCtx, m_handle, render_params);
-  if (error) {
-    qCCritical(mpvBackend())
-        << "Error initializing mpv ogl context:" << mpv_error_string(error);
-    m_renderCtx = nullptr;
-  }
-  if (!m_renderCtx) {
-    qCDebug(mpvBackend) << "Error obtaining mpv render context";
-    return;
+  {
+    mpv_render_context *ctx = nullptr;
+    int error = mpv_render_context_create(&ctx, m_handle.get(), render_params);
+    if (error) {
+      qCCritical(mpvBackend()) << "Error initializing mpv render context:"
+                               << mpv_error_string(error);
+      ctx = nullptr;
+    }
+    if (!ctx) {
+      qCDebug(mpvBackend) << "Error obtaining mpv render context";
+      return;
+    }
+    m_renderCtx = mpv::RenderContextHandle::create(ctx);
   }
 
   qCDebug(mpvBackend, "setting callback");
-  mpv_render_context_set_update_callback(m_renderCtx, mpvUpdate, vui);
+  mpv_render_context_set_update_callback(m_renderCtx.get(), mpvUpdate, vui);
   qCDebug(mpvBackend, "initializing gl context");
 
   qCDebug(mpvBackend, "all done");
 }
 
 VideoRendererMpv::~VideoRendererMpv() {
-  if (m_renderCtx) {
-    mpv_render_context_free(m_renderCtx);
-    m_renderCtx = nullptr;
-  }
 }
 
 void VideoRendererMpv::render(QOpenGLFramebufferObject *fbo) {
@@ -480,7 +478,7 @@ void VideoRendererMpv::render(QOpenGLFramebufferObject *fbo) {
   opengl_fbo.internal_format = fbo->format().internalTextureFormat();
   mpv_render_param render_param{MPV_RENDER_PARAM_OPENGL_FBO, &opengl_fbo};
 
-  int error = mpv_render_context_render(m_renderCtx, &render_param);
+  int error = mpv_render_context_render(m_renderCtx.get(), &render_param);
   if (error)
     qCCritical(mpvBackend) << "Error rendering mpv frame:"
                            << mpv_error_string(error);
index 94885ff87ba980171b13a8295712cd0b1a307455..88924f13547984a3e8fbd3e732b0dcc4d6168b3e 100644 (file)
@@ -7,9 +7,9 @@
 #include "backend_mpv_global.h"
 #include "aniplayer/backendpluginbase.h"
 
-struct mpv_handle;
+#include "mpvhandle.h"
+
 struct mpv_event_property;
-struct mpv_render_context;
 struct mpv_event_log_message;
 struct mpv_event_end_file;
 
@@ -64,7 +64,7 @@ private:
   int readTrackIndex(struct mpv_event_property *);
 
   PlayerPluginInterface *m_player = nullptr;
-  mpv_handle *m_handle = nullptr;
+  mpv::Handle m_handle;
   Volume m_volumeToSet = -1;
   QUrl m_currentlyLoading;
   bool m_loadedFile = false;
@@ -74,13 +74,13 @@ private:
 
 class BACKEND_MPVSHARED_EXPORT VideoRendererMpv : public VideoRendererBase {
 public:
-  explicit VideoRendererMpv(mpv_handle *, VideoUpdateInterface *);
+  explicit VideoRendererMpv(mpv::Handle, VideoUpdateInterface *);
   ~VideoRendererMpv() override;
   void render(QOpenGLFramebufferObject *) override;
 
 private:
-  mpv_handle *m_handle = nullptr;
-  mpv_render_context *m_renderCtx = nullptr;
+  mpv::Handle m_handle;
+  mpv::RenderContextHandle m_renderCtx;
 
   static void *getProcAddress(void *, const char *name);
   static void mpvUpdate(void *);
diff --git a/backendplugins/backend_mpv/mpvhandle.cpp b/backendplugins/backend_mpv/mpvhandle.cpp
new file mode 100644 (file)
index 0000000..92c3b09
--- /dev/null
@@ -0,0 +1,47 @@
+#include "mpvhandle.h"
+
+#include <mpv/client.h>
+#include <mpv/render.h>
+
+namespace mpv {
+namespace {
+struct MpvHandleDeleter
+{
+  void operator()(mpv_handle *handle) {
+    if (handle) {
+      mpv_terminate_destroy(handle);
+    }
+  }
+};
+
+struct MpvRenderContextHandleDeleter
+{
+  void operator()(mpv_render_context *handle) {
+    if (handle) {
+      mpv_render_context_free(handle);
+    }
+  }
+};
+} // namespace
+
+Handle::Handle(HandlePtr handle) : m_handle{std::move(handle)} {}
+
+mpv_handle *Handle::get() const { return m_handle.get(); }
+
+Handle Handle::create() {
+  return Handle{HandlePtr(mpv_create(), MpvHandleDeleter())};
+}
+
+RenderContextHandle::RenderContextHandle(RenderHandlePtr handle)
+    : m_handle{std::move(handle)} {}
+
+RenderContextHandle::operator bool() { return !!m_handle; }
+
+mpv_render_context *RenderContextHandle::get() const { return m_handle.get(); }
+
+RenderContextHandle RenderContextHandle::create(mpv_render_context *ctx) {
+  return RenderContextHandle{
+      RenderHandlePtr(ctx, MpvRenderContextHandleDeleter())};
+}
+
+} // namespace mpv
diff --git a/backendplugins/backend_mpv/mpvhandle.h b/backendplugins/backend_mpv/mpvhandle.h
new file mode 100644 (file)
index 0000000..9b9b48e
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef MPV_HANDLE_H
+#define MPV_HANDLE_H
+
+#include <memory>
+
+struct mpv_handle;
+struct mpv_render_context;
+
+namespace mpv {
+
+class Handle {
+  using HandlePtr = std::shared_ptr<mpv_handle>;
+  HandlePtr m_handle;
+  explicit Handle(HandlePtr handle);
+
+public:
+  mpv_handle *get() const;
+
+  static Handle create();
+};
+
+class RenderContextHandle {
+  using RenderHandlePtr = std::shared_ptr<mpv_render_context>;
+  RenderHandlePtr m_handle;
+  explicit RenderContextHandle(RenderHandlePtr handle);
+
+public:
+  RenderContextHandle() = default;
+  explicit operator bool();
+  mpv_render_context *get() const;
+
+  static RenderContextHandle create(mpv_render_context *ctx);
+};
+
+} // namespace mpv
+
+#endif // MPV_HANDLE_H
index 0d5208c8b2887938875bfbe60c5e57ba9d694eb5..d0612cbb14167244b1665c0605ba51ce95936fb9 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef MPVHELPER_H
 #define MPVHELPER_H
 
+#include "mpvhandle.h"
+
 #include <mpv/client.h>
 
 #include <QString>
@@ -14,8 +16,6 @@ Q_LOGGING_CATEGORY(mpvHelper, "mpv.helper")
 
 namespace mpv {
 
-using Handle = mpv_handle *;
-
 struct Error
 {
   using ErrorType = int;
@@ -166,7 +166,7 @@ template<typename Format>
 auto ReadFormat(const Handle &handle, Format format, const char *name)
     -> Outcome<typename Format::type> {
   typename Format::MpvInternalType data;
-  int error = mpv_get_property(handle, name, format.format, &data);
+  int error = mpv_get_property(handle.get(), name, format.format, &data);
   qCDebug(mpvHelper()).nospace()
       << "ReadFormat, property: " << name << ", error: " << error
       << ", original value: " << data;
@@ -184,7 +184,7 @@ int WriteFormat(const Handle &handle, Format format, const char *name,
       TypeConversion<typename Format::type,
                      typename Format::MpvInternalType>::convert(value);
   int error =
-      mpv_set_property(handle, name, format.format,
+      mpv_set_property(handle.get(), name, format.format,
                        const_cast<typename Format::MpvInternalType *>(&data));
   qCDebug(mpvHelper()).nospace()
       << "WriteFormat, property: " << name << ", error: " << error