summaryrefslogtreecommitdiffstats
path: root/DOCS/client_api_examples/qml/mpvrenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'DOCS/client_api_examples/qml/mpvrenderer.cpp')
-rw-r--r--DOCS/client_api_examples/qml/mpvrenderer.cpp58
1 files changed, 26 insertions, 32 deletions
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);
}