diff options
Diffstat (limited to 'DOCS')
-rw-r--r-- | DOCS/client-api-changes.rst | 4 | ||||
-rw-r--r-- | DOCS/client_api_examples/qml/main.cpp | 19 | ||||
-rw-r--r-- | DOCS/client_api_examples/qml/main.qml | 39 | ||||
-rw-r--r-- | DOCS/client_api_examples/qml/mpvrenderer.cpp | 125 | ||||
-rw-r--r-- | DOCS/client_api_examples/qml/mpvrenderer.h | 33 | ||||
-rw-r--r-- | DOCS/client_api_examples/qml/mpvtest.pro | 11 | ||||
-rw-r--r-- | DOCS/client_api_examples/qml/mpvtest.qrc | 5 |
7 files changed, 236 insertions, 0 deletions
diff --git a/DOCS/client-api-changes.rst b/DOCS/client-api-changes.rst index 918d986ee6..69458d0d49 100644 --- a/DOCS/client-api-changes.rst +++ b/DOCS/client-api-changes.rst @@ -25,6 +25,10 @@ API changes :: + 1.11 - add OpenGL rendering interop API - allows an application to combine + its own and mpv's OpenGL rendering + Warning: this API is not stable yet - anything in opengl_cb.h might + be changed in completely incompatible ways in minor API bumps --- mpv 0.7.0 is released --- 1.10 - deprecate/disable everything directly related to script_dispatch (most likely affects nobody) diff --git a/DOCS/client_api_examples/qml/main.cpp b/DOCS/client_api_examples/qml/main.cpp new file mode 100644 index 0000000000..cc86302be6 --- /dev/null +++ b/DOCS/client_api_examples/qml/main.cpp @@ -0,0 +1,19 @@ +#include <QGuiApplication> + +#include <QtQuick/QQuickView> + +#include "mpvrenderer.h" + +int main(int argc, char **argv) +{ + QGuiApplication app(argc, argv); + + qmlRegisterType<MpvObject>("mpvtest", 1, 0, "MpvObject"); + + QQuickView view; + view.setResizeMode(QQuickView::SizeRootObjectToView); + view.setSource(QUrl("qrc:///mpvtest/main.qml")); + view.show(); + + return app.exec(); +} diff --git a/DOCS/client_api_examples/qml/main.qml b/DOCS/client_api_examples/qml/main.qml new file mode 100644 index 0000000000..d921e2a86c --- /dev/null +++ b/DOCS/client_api_examples/qml/main.qml @@ -0,0 +1,39 @@ +import QtQuick 2.0 +import QtQuick.Controls 1.0 + +import mpvtest 1.0 + +Item { + width: 1280 + height: 720 + + MpvObject { + id: renderer + anchors.fill: parent + + MouseArea { + anchors.fill: parent + onClicked: renderer.loadfile("../../../test.mkv") + } + } + + Rectangle { + id: labelFrame + anchors.margins: -50 + radius: 5 + color: "white" + border.color: "black" + opacity: 0.8 + anchors.fill: label + } + + Text { + id: label + anchors.bottom: renderer.bottom + anchors.left: renderer.left + anchors.right: renderer.right + anchors.margins: 100 + wrapMode: Text.WordWrap + text: "QtQuick and mpv are both rendering stuff." + } +} diff --git a/DOCS/client_api_examples/qml/mpvrenderer.cpp b/DOCS/client_api_examples/qml/mpvrenderer.cpp new file mode 100644 index 0000000000..af62fd2762 --- /dev/null +++ b/DOCS/client_api_examples/qml/mpvrenderer.cpp @@ -0,0 +1,125 @@ +#include "mpvrenderer.h" + +#include <QObject> +#include <QtGlobal> +#include <QOpenGLContext> + +#include <QtGui/QOpenGLFramebufferObject> + +#include <QtQuick/QQuickWindow> +#include <qsgsimpletexturenode.h> + +class MpvRenderer : public QQuickFramebufferObject::Renderer +{ + static void *get_proc_address(void *ctx, const char *name) { + (void)ctx; + QOpenGLContext *glctx = QOpenGLContext::currentContext(); + if (!glctx) + return NULL; + return (void *)glctx->getProcAddress(QByteArray(name)); + } + + mpv_opengl_cb_context *mpv_gl; + QQuickWindow *window; +public: + MpvRenderer(mpv_opengl_cb_context *a_mpv_gl) + : mpv_gl(a_mpv_gl), window(NULL) + { + int r = mpv_opengl_cb_init_gl(mpv_gl, NULL, get_proc_address, NULL); + if (r < 0) + throw "could not initialize OpenGL"; + } + + virtual ~MpvRenderer() + { + mpv_opengl_cb_uninit_gl(mpv_gl); + } + + void render() + { + assert(window); // must have been set by synchronize() + + QOpenGLFramebufferObject *fbo = framebufferObject(); + int vp[4] = {0, 0, fbo->width(), fbo->height()}; + window->resetOpenGLState(); + mpv_opengl_cb_render(mpv_gl, fbo->handle(), vp); + window->resetOpenGLState(); + } + + QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) + { + QOpenGLFramebufferObjectFormat format; + format.setSamples(4); + return new QOpenGLFramebufferObject(size, format); + } + +protected: + virtual void synchronize(QQuickFramebufferObject *item) + { + window = item->window(); + } +}; + +MpvObject::MpvObject(QQuickItem * parent) + : QQuickFramebufferObject(parent) +{ + mpv = mpv_create(); + if (!mpv) + throw "could not create mpv context"; + + mpv_set_option_string(mpv, "terminal", "yes"); + mpv_set_option_string(mpv, "msg-level", "all=v"); + + if (mpv_initialize(mpv) < 0) { + mpv_terminate_destroy(mpv); + throw "could not initialize mpv context"; + } + + // Make use of the MPV_SUB_API_OPENGL_CB API. + mpv::qt::set_option_variant(mpv, "vo", "opengl-cb"); + + // Request hw decoding, just for testing. + mpv::qt::set_option_variant(mpv, "hwdec", "auto"); + + mpv_gl = (mpv_opengl_cb_context *)mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB); + if (!mpv_gl) { + mpv_terminate_destroy(mpv); + throw "OpenGL not compiled in"; + } + + mpv_opengl_cb_set_update_callback(mpv_gl, on_update, (void *)this); + + connect(this, &MpvObject::onUpdate, this, &MpvObject::doUpdate, Qt::QueuedConnection); +} + +MpvObject::~MpvObject() +{ + mpv_terminate_destroy(mpv); +} + +void MpvObject::on_update(void *ctx) +{ + MpvObject *self = (MpvObject *)ctx; + emit self->onUpdate(); +} + +// connected to onUpdate(); signal makes sure it runs on the GUI thread +void MpvObject::doUpdate() +{ + update(); +} + +void MpvObject::loadfile(const QString& filename) +{ + QVariantList cmd; + cmd.append("loadfile"); + cmd.append(filename); + mpv::qt::command_variant(mpv, cmd); +} + +QQuickFramebufferObject::Renderer *MpvObject::createRenderer() const +{ + window()->setPersistentOpenGLContext(true); + window()->setPersistentSceneGraph(true); + return new MpvRenderer(mpv_gl); +} diff --git a/DOCS/client_api_examples/qml/mpvrenderer.h b/DOCS/client_api_examples/qml/mpvrenderer.h new file mode 100644 index 0000000000..d0bedf720b --- /dev/null +++ b/DOCS/client_api_examples/qml/mpvrenderer.h @@ -0,0 +1,33 @@ +#ifndef MPVRENDERER_H_ +#define MPVRENDERER_H_ + +#include <assert.h> + +#include <QtQuick/QQuickFramebufferObject> + +#include "libmpv/client.h" +#include "libmpv/opengl_cb.h" +#include "libmpv/qthelper.hpp" + +class MpvObject : public QQuickFramebufferObject +{ + Q_OBJECT + + mpv_handle *mpv; + mpv_opengl_cb_context *mpv_gl; + +public: + MpvObject(QQuickItem * parent = 0); + virtual ~MpvObject(); + Renderer *createRenderer() const; +public slots: + void loadfile(const QString& filename); +signals: + void onUpdate(); +private slots: + void doUpdate(); +private: + static void on_update(void *ctx); +}; + +#endif diff --git a/DOCS/client_api_examples/qml/mpvtest.pro b/DOCS/client_api_examples/qml/mpvtest.pro new file mode 100644 index 0000000000..6681fa1884 --- /dev/null +++ b/DOCS/client_api_examples/qml/mpvtest.pro @@ -0,0 +1,11 @@ +QT += qml quick + +HEADERS += mpvrenderer.h +SOURCES += mpvrenderer.cpp main.cpp + +CONFIG += link_pkgconfig debug +PKGCONFIG = mpv + +RESOURCES += mpvtest.qrc + +OTHER_FILES += main.qml diff --git a/DOCS/client_api_examples/qml/mpvtest.qrc b/DOCS/client_api_examples/qml/mpvtest.qrc new file mode 100644 index 0000000000..bb672657e5 --- /dev/null +++ b/DOCS/client_api_examples/qml/mpvtest.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/mpvtest"> + <file>main.qml</file> + </qresource> +</RCC> |