From cb04d5aeea8c55c8f55c1c5f60cfacc83b89c2e3 Mon Sep 17 00:00:00 2001 From: APTX Date: Sun, 20 Feb 2022 14:06:13 +0900 Subject: [PATCH] Add Handle classes for MPV handles Also fixes idle-active property format in observe call --- backendplugins/backend_mpv/CMakeLists.txt | 2 + backendplugins/backend_mpv/backendmpv.cpp | 76 +++++++++++------------ backendplugins/backend_mpv/backendmpv.h | 12 ++-- backendplugins/backend_mpv/mpvhandle.cpp | 47 ++++++++++++++ backendplugins/backend_mpv/mpvhandle.h | 37 +++++++++++ backendplugins/backend_mpv/mpvhelper.h | 8 +-- 6 files changed, 133 insertions(+), 49 deletions(-) create mode 100644 backendplugins/backend_mpv/mpvhandle.cpp create mode 100644 backendplugins/backend_mpv/mpvhandle.h diff --git a/backendplugins/backend_mpv/CMakeLists.txt b/backendplugins/backend_mpv/CMakeLists.txt index c848299..e075d7a 100644 --- a/backendplugins/backend_mpv/CMakeLists.txt +++ b/backendplugins/backend_mpv/CMakeLists.txt @@ -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 diff --git a/backendplugins/backend_mpv/backendmpv.cpp b/backendplugins/backend_mpv/backendmpv.cpp index 0e11985..6df7807 100644 --- a/backendplugins/backend_mpv/backendmpv.cpp +++ b/backendplugins/backend_mpv/backendmpv.cpp @@ -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); diff --git a/backendplugins/backend_mpv/backendmpv.h b/backendplugins/backend_mpv/backendmpv.h index 94885ff..88924f1 100644 --- a/backendplugins/backend_mpv/backendmpv.h +++ b/backendplugins/backend_mpv/backendmpv.h @@ -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 index 0000000..92c3b09 --- /dev/null +++ b/backendplugins/backend_mpv/mpvhandle.cpp @@ -0,0 +1,47 @@ +#include "mpvhandle.h" + +#include +#include + +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 index 0000000..9b9b48e --- /dev/null +++ b/backendplugins/backend_mpv/mpvhandle.h @@ -0,0 +1,37 @@ +#ifndef MPV_HANDLE_H +#define MPV_HANDLE_H + +#include + +struct mpv_handle; +struct mpv_render_context; + +namespace mpv { + +class Handle { + using HandlePtr = std::shared_ptr; + HandlePtr m_handle; + explicit Handle(HandlePtr handle); + +public: + mpv_handle *get() const; + + static Handle create(); +}; + +class RenderContextHandle { + using RenderHandlePtr = std::shared_ptr; + 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 diff --git a/backendplugins/backend_mpv/mpvhelper.h b/backendplugins/backend_mpv/mpvhelper.h index 0d5208c..d0612cb 100644 --- a/backendplugins/backend_mpv/mpvhelper.h +++ b/backendplugins/backend_mpv/mpvhelper.h @@ -1,6 +1,8 @@ #ifndef MPVHELPER_H #define MPVHELPER_H +#include "mpvhandle.h" + #include #include @@ -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 auto ReadFormat(const Handle &handle, Format format, const char *name) -> Outcome { 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::convert(value); int error = - mpv_set_property(handle, name, format.format, + mpv_set_property(handle.get(), name, format.format, const_cast(&data)); qCDebug(mpvHelper()).nospace() << "WriteFormat, property: " << name << ", error: " << error -- 2.52.0