C++ 原始像素数据中损坏的QImage
基于我的工作,我尝试使用Qt的C++ 原始像素数据中损坏的QImage,c++,multithreading,qt,bitmap,qimage,C++,Multithreading,Qt,Bitmap,Qimage,基于我的工作,我尝试使用Qt的QGLWidget来渲染视频,但我遇到了一些问题。当我在视频解码线程中解码后立即保存帧时,结果很好: 但在画的时候,它被弄得乱七八糟: 看起来像是正在复制图像,但复制没有完成,但是 我使用互斥来确保在绘制代码时图像不会被触摸 我将指向QImage的指针传递给绘图代码,因此它应该是相同的内存块 在解码线程中,我有以下内容: /* Read in the frame up here, skipped for brevity */ // Set a new imag
QGLWidget
来渲染视频,但我遇到了一些问题。当我在视频解码线程中解码后立即保存帧时,结果很好:
但在画的时候,它被弄得乱七八糟:
看起来像是正在复制图像,但复制没有完成,但是
QImage
的指针传递给绘图代码,因此它应该是相同的内存块/* Read in the frame up here, skipped for brevity */
// Set a new image
auto frameImage = make_shared<QImage>(nextFrame->getPixels(),
nextFrame->getWidth(),
nextFrame->getHeight(),
QImage::Format_RGB888);
canvas->setImage(frameImage);
// Post a new order to repaint.
// Done this way because another thread cannot directly call repaint()
QCoreApplication::postEvent(canvas, new QPaintEvent(canvas->rect()));
这是怎么回事?我忘了当给定像素数据时,
QImage
是浅拷贝,而不是深拷贝。只要QImage存在,就保持分配的实际帧数据,从而解决了该问题,如下所示:
void QGLCanvas::setFrame(const std::shared_ptr<VideoFrame>& newFrame)
{
// Keep the QGL canvas from drawing while we change the image
lock_guard<mutex> pixelLock(pixelsMutex);
// Keep a shared_ptr reference to our frame data
frame = newFrame;
// Create a new QImage, which is just a shallow copy of the frame.
img.reset(new QImage(frame->getPixels(),
frame->getWidth(),
frame->getHeight(),
QImage::Format_RGB888));
}
void QGLCanvas::setFrame(const std::shared_ptr&newFrame)
{
//更改图像时,不要绘制QGL画布
锁定保护像素锁定(PixelsUtex);
//保持对帧数据的共享\u ptr引用
帧=新帧;
//创建一个新的QImage,它只是帧的一个浅拷贝。
重置图像(新图像(帧->获取像素(),
框架->获取宽度(),
框架->获取高度(),
格式(RGB888);
}
您是否在单独的线程中解码视频?如果在使用nextFrame->getPixels()数据创建图像后立即保存图像内容,会得到什么?@Vasaka-这就是我所做的。原来这是一个内存分配问题——请看我的答案。
void QGLCanvas::setFrame(const std::shared_ptr<VideoFrame>& newFrame)
{
// Keep the QGL canvas from drawing while we change the image
lock_guard<mutex> pixelLock(pixelsMutex);
// Keep a shared_ptr reference to our frame data
frame = newFrame;
// Create a new QImage, which is just a shallow copy of the frame.
img.reset(new QImage(frame->getPixels(),
frame->getWidth(),
frame->getHeight(),
QImage::Format_RGB888));
}