我想创建一个播放媒体的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的内容,但实际上我知道我做的事情不好但我不知道。