summaryrefslogtreecommitdiffstats
path: root/DOCS
diff options
context:
space:
mode:
Diffstat (limited to 'DOCS')
-rw-r--r--DOCS/client_api_examples/qml/main.qml3
-rw-r--r--DOCS/client_api_examples/qml/mpvrenderer.cpp58
-rw-r--r--DOCS/client_api_examples/qml/mpvrenderer.h10
-rw-r--r--DOCS/client_api_examples/qml/mpvtest.pro2
4 files changed, 35 insertions, 38 deletions
diff --git a/DOCS/client_api_examples/qml/main.qml b/DOCS/client_api_examples/qml/main.qml
index d921e2a86c..4b31406554 100644
--- a/DOCS/client_api_examples/qml/main.qml
+++ b/DOCS/client_api_examples/qml/main.qml
@@ -34,6 +34,7 @@ Item {
anchors.right: renderer.right
anchors.margins: 100
wrapMode: Text.WordWrap
- text: "QtQuick and mpv are both rendering stuff."
+ text: "QtQuick and mpv are both rendering stuff.\n
+ Click to load ../../../test.mkv"
}
}
diff --git a/DOCS/client_api_examples/qml/mpvrenderer.cpp b/DOCS/client_api_examples/qml/mpvrenderer.cpp
index ab92a2388f..13c1f0a747 100644
--- a/DOCS/client_api_examples/qml/mpvrenderer.cpp
+++ b/DOCS/client_api_examples/qml/mpvrenderer.cpp
@@ -7,7 +7,6 @@
#include <QtGui/QOpenGLFramebufferObject>
#include <QtQuick/QQuickWindow>
-#include <qsgsimpletexturenode.h>
class MpvRenderer : public QQuickFramebufferObject::Renderer
{
@@ -19,11 +18,12 @@ class MpvRenderer : public QQuickFramebufferObject::Renderer
return (void *)glctx->getProcAddress(QByteArray(name));
}
- mpv_opengl_cb_context *mpv_gl;
+ mpv::qt::Handle mpv;
QQuickWindow *window;
+ mpv_opengl_cb_context *mpv_gl;
public:
- MpvRenderer(mpv_opengl_cb_context *a_mpv_gl)
- : mpv_gl(a_mpv_gl), window(NULL)
+ MpvRenderer(const MpvObject *obj)
+ : mpv(obj->mpv), window(obj->window()), mpv_gl(obj->mpv_gl)
{
int r = mpv_opengl_cb_init_gl(mpv_gl, NULL, get_proc_address, NULL);
if (r < 0)
@@ -32,47 +32,40 @@ public:
virtual ~MpvRenderer()
{
+ // Before we can really destroy the OpenGL state, we must make sure
+ // that the video output is destroyed. This is important for some
+ // forms of hardware decoding, where the decoder shares some state
+ // with the video output and the OpenGL context.
+ // Deselecting the video track is the easiest way to achieve this in
+ // a synchronous way. If no file is playing, setting the property
+ // will fail and do nothing.
+ mpv::qt::set_property_variant(mpv, "vid", "no");
+
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;
- return new QOpenGLFramebufferObject(size, format);
- }
-
-protected:
- virtual void synchronize(QQuickFramebufferObject *item)
- {
- window = item->window();
- }
};
MpvObject::MpvObject(QQuickItem * parent)
- : QQuickFramebufferObject(parent)
+ : QQuickFramebufferObject(parent), mpv_gl(0)
{
- mpv = mpv_create();
+ mpv = mpv::qt::Handle::FromRawHandle(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);
+ if (mpv_initialize(mpv) < 0)
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");
@@ -80,20 +73,21 @@ MpvObject::MpvObject(QQuickItem * parent)
// Request hw decoding, just for testing.
mpv::qt::set_option_variant(mpv, "hwdec", "auto");
+ // Setup the callback that will make QtQuick update and redraw if there
+ // is a new video frame. Use a queued connection: this makes sure the
+ // doUpdate() function is run on the GUI thread.
mpv_gl = (mpv_opengl_cb_context *)mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB);
- if (!mpv_gl) {
- mpv_terminate_destroy(mpv);
+ if (!mpv_gl)
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);
+ mpv_opengl_cb_set_update_callback(mpv_gl, MpvObject::on_update, (void *)this);
+ connect(this, &MpvObject::onUpdate, this, &MpvObject::doUpdate,
+ Qt::QueuedConnection);
}
MpvObject::~MpvObject()
{
- mpv_terminate_destroy(mpv);
+ if (mpv_gl)
+ mpv_opengl_cb_set_update_callback(mpv_gl, NULL, NULL);
}
void MpvObject::on_update(void *ctx)
@@ -120,5 +114,5 @@ QQuickFramebufferObject::Renderer *MpvObject::createRenderer() const
{
window()->setPersistentOpenGLContext(true);
window()->setPersistentSceneGraph(true);
- return new MpvRenderer(mpv_gl);
+ return new MpvRenderer(this);
}
diff --git a/DOCS/client_api_examples/qml/mpvrenderer.h b/DOCS/client_api_examples/qml/mpvrenderer.h
index 68e690ff55..700505ad20 100644
--- a/DOCS/client_api_examples/qml/mpvrenderer.h
+++ b/DOCS/client_api_examples/qml/mpvrenderer.h
@@ -1,25 +1,27 @@
#ifndef MPVRENDERER_H_
#define MPVRENDERER_H_
-#include <assert.h>
-
#include <QtQuick/QQuickFramebufferObject>
#include <mpv/client.h>
#include <mpv/opengl_cb.h>
#include <mpv/qthelper.hpp>
+class MpvRenderer;
+
class MpvObject : public QQuickFramebufferObject
{
Q_OBJECT
- mpv_handle *mpv;
+ mpv::qt::Handle mpv;
mpv_opengl_cb_context *mpv_gl;
+ friend class MpvRenderer;
+
public:
MpvObject(QQuickItem * parent = 0);
virtual ~MpvObject();
- Renderer *createRenderer() const;
+ virtual Renderer *createRenderer() const;
public slots:
void loadfile(const QString& filename);
signals:
diff --git a/DOCS/client_api_examples/qml/mpvtest.pro b/DOCS/client_api_examples/qml/mpvtest.pro
index 6681fa1884..df497e4dba 100644
--- a/DOCS/client_api_examples/qml/mpvtest.pro
+++ b/DOCS/client_api_examples/qml/mpvtest.pro
@@ -4,7 +4,7 @@ HEADERS += mpvrenderer.h
SOURCES += mpvrenderer.cpp main.cpp
CONFIG += link_pkgconfig debug
-PKGCONFIG = mpv
+PKGCONFIG += mpv
RESOURCES += mpvtest.qrc