diff --git a/gui/include/avopenglframeuploader.h b/gui/include/avopenglframeuploader.h index 3d0ab48..ff7e0d0 100644 --- a/gui/include/avopenglframeuploader.h +++ b/gui/include/avopenglframeuploader.h @@ -23,6 +23,7 @@ class AVOpenGLWidget; class VideoDecoder; +class QSurface; class AVOpenGLFrameUploader: public QObject { @@ -31,12 +32,14 @@ class AVOpenGLFrameUploader: public QObject private: VideoDecoder *decoder; AVOpenGLWidget *widget; + QOpenGLContext *context; + QSurface *surface; private slots: void UpdateFrame(); public: - AVOpenGLFrameUploader(VideoDecoder *decoder, AVOpenGLWidget *widget); + AVOpenGLFrameUploader(VideoDecoder *decoder, AVOpenGLWidget *widget, QOpenGLContext *context, QSurface *surface); }; #endif // CHIAKI_AVOPENGLFRAMEUPLOADER_H diff --git a/gui/include/avopenglwidget.h b/gui/include/avopenglwidget.h index 47dbb1b..2396547 100644 --- a/gui/include/avopenglwidget.h +++ b/gui/include/avopenglwidget.h @@ -52,7 +52,9 @@ class AVOpenGLWidget: public QOpenGLWidget AVOpenGLFrame frames[2]; int frame_fg; QMutex frames_mutex; + QOpenGLContext *frame_uploader_context; AVOpenGLFrameUploader *frame_uploader; + QThread *frame_uploader_thread; public: explicit AVOpenGLWidget(VideoDecoder *decoder, QWidget *parent = nullptr); diff --git a/gui/src/avopenglframeuploader.cpp b/gui/src/avopenglframeuploader.cpp index 811fce9..6431218 100644 --- a/gui/src/avopenglframeuploader.cpp +++ b/gui/src/avopenglframeuploader.cpp @@ -22,17 +22,21 @@ #include #include -AVOpenGLFrameUploader::AVOpenGLFrameUploader(VideoDecoder *decoder, AVOpenGLWidget *widget) +AVOpenGLFrameUploader::AVOpenGLFrameUploader(VideoDecoder *decoder, AVOpenGLWidget *widget, QOpenGLContext *context, QSurface *surface) : QObject(nullptr), decoder(decoder), - widget(widget) + widget(widget), + context(context), + surface(surface) { - connect(decoder, SIGNAL(FramesAvailable()), this, SLOT(UpdateFrame())); } void AVOpenGLFrameUploader::UpdateFrame() { + if(QOpenGLContext::currentContext() != context) + context->makeCurrent(surface); + AVFrame *next_frame = decoder->PullFrame(); if(!next_frame) return; diff --git a/gui/src/avopenglwidget.cpp b/gui/src/avopenglwidget.cpp index bbf4759..0abb34c 100644 --- a/gui/src/avopenglwidget.cpp +++ b/gui/src/avopenglwidget.cpp @@ -22,6 +22,7 @@ #include #include #include +#include //#define DEBUG_OPENGL @@ -85,12 +86,18 @@ AVOpenGLWidget::AVOpenGLWidget(VideoDecoder *decoder, QWidget *parent) #endif setFormat(format); + frame_uploader_context = nullptr; frame_uploader = nullptr; + frame_uploader_thread = nullptr; } AVOpenGLWidget::~AVOpenGLWidget() { + frame_uploader_thread->quit(); + frame_uploader_thread->wait(); + delete frame_uploader_thread; delete frame_uploader; + delete frame_uploader_context; } void AVOpenGLWidget::SwapFrames() @@ -127,7 +134,7 @@ bool AVOpenGLFrame::Update(AVFrame *frame) f->glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, frame->data[i]); } - f->glFinish(); // TODO: fence + f->glFinish(); return true; } @@ -210,8 +217,22 @@ void AVOpenGLWidget::initializeGL() f->glEnable(GL_CULL_FACE); f->glClearColor(0.0, 0.0, 0.0, 1.0); - frame_uploader = new AVOpenGLFrameUploader(decoder, this); + frame_uploader_context = new QOpenGLContext(nullptr); + frame_uploader_context->setFormat(context()->format()); + frame_uploader_context->setShareContext(context()); + if(!frame_uploader_context->create()) + { + printf("Failed to create upload context!\n"); // TODO: log to somewhere else + return; + } + + frame_uploader = new AVOpenGLFrameUploader(decoder, this, frame_uploader_context, context()->surface()); frame_fg = 0; + + frame_uploader_thread = new QThread(this); + frame_uploader_context->moveToThread(frame_uploader_thread); + frame_uploader->moveToThread(frame_uploader_thread); + frame_uploader_thread->start(); } void AVOpenGLWidget::resizeGL(int w, int h) @@ -258,5 +279,5 @@ void AVOpenGLWidget::paintGL() f->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - f->glFinish(); // TODO: fence + f->glFinish(); }