QopenglWidget在线程之间共享上下文

时间:2018-03-31 12:44:09

标签: c++ multithreading qt opengl

我想创建一个播放媒体的QOpengGlWidget(即:mov,mp4等)我试图使用媒体播放器,它可以工作,但视频没有alpha(我知道它是alpha混合的),当我处理QvideoFrame的类型是ARGB32但是如果我在OpengGlWidget上显示它我有一个黑色的背景。

所以我试着捕捉每一帧,创建QOpenGLTexture,并且通常在PaintGL中绘画,它可以工作但速度太慢。所以我想在Worker线程中加载纹理,并在完成后发出信号并绘制它们。但是我无法在两个线程之间共享上下文。 这是代码:

在我的小部件的班级成员中,我启动了媒体播放器:

bool VideoSurface::present(const QVideoFrame &frame)
  {


    emit newVideoFrame(frame);
             return true;
}

我分配到媒体播放器我的表面,我抓住了框架:

void VideoWidget::updateVideoFrame(QVideoFrame frame)
{
    qDebug()<<QOpenGLContext::currentContext();
    QOpenGLContext* ctx = new QOpenGLContext();
    QOpenGLContext* sharectx = QOpenGLContext::currentContext();
    ctx->setFormat(sharectx->format());
    ctx->setShareContext(sharectx);
    ctx->create();
    if (ctx->isValid()){

        qDebug()<<"valid";
    }


    WorkerThread *workerThread = new WorkerThread();
    ctx->moveToThread(workerThread);
    connect(workerThread,SIGNAL(resultReady(QOpenGLTexture*)), this, SLOT(updateTexture(QOpenGLTexture*)));
    connect(workerThread, &WorkerThread::finished, workerThread, &QObject::deleteLater);
    workerThread->setFrame(frame);

    workerThread->start();

}

信号在主线程中捕获并触发:

class WorkerThread : public QThread
{
    Q_OBJECT


    void run() override {
        //    Q_UNUSED(frame);

        // Handle the frame and do your processing
        QVideoFrame cloneFrame(frametexture);
        cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
        QImage image(cloneFrame.bits(),
                     cloneFrame.width(),
                     cloneFrame.height(),
                     //  QImage::Format_ARGB32);
                     QVideoFrame::imageFormatFromPixelFormat(cloneFrame.pixelFormat()));
        //    int  rand = qrand();

        //        image.save( QDir::currentPath()+"/"+QString::number(rand)+"__"+".png");
        qDebug()<<QOpenGLContext::currentContext();

        QOpenGLTexture* texture = new QOpenGLTexture(image);

        cloneFrame.unmap();
        //   emit resultReady(image);
    }

直到现在一切正常,但是在工作线程的运行中我尝试创建纹理Qt说上下文不是vali。这是工作线程的run():

{{1}}

QOpenGLTexture * texture = new QOpenGLTexture(image);

这是错误:QOpenGLTexture :: setData()需要有效的当前上下文 当前上下文返回:QOpenGLContext(0)

我对Qt和OpenGL很新,我读了很多关于sharecontext的内容,但实际上我知道我做的事情不好但我不知道。

0 个答案:

没有答案