【问题标题】:Corrupted QImage from raw pixel data来自原始像素数据的损坏的 QImage
【发布时间】:2013-07-02 14:19:41
【问题描述】:

基于this answer 的工作,我正在尝试使用Qt 的QGLWidget 来渲染视频,但我遇到了一些问题。当我在我的视频解码线程中解码后立即保存一帧时,结果很好:

但是在绘制它时,它会严重损坏:

似乎正在复制图像并且复制没有完成,但是

  1. 我正在使用互斥锁来确保在绘制代码绘制时不会触及图像。

  2. 我将指向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()));

然后,在画布中(源自QGLWidget):

void QGLCanvas::setImage(const std::shared_ptr<QImage>& image)
{
    // Keep the QGL canvas from drawing while we change the image
    lock_guard<mutex> pixelLock(pixelsMutex);
    img = image; // img is just a shared_ptr
}

void QGLCanvas::paintEvent(QPaintEvent*)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::SmoothPixmapTransform, 1);

    // Lock the image so that other threads can't access it at the same time
    lock_guard<mutex> pixelLock(pixelsMutex);
    painter.drawImage(this->rect(), *img);
}

这是怎么回事?

【问题讨论】:

  • 您是否在单独的线程中解码视频?如果您在使用 nextFrame->getPixels() 数据创建图像后立即保存图像内容,您会得到什么?
  • @Vasaka - 我就是这么做的。事实证明这是一个内存分配问题 - 请参阅我的答案。

标签: c++ multithreading qt bitmap qimage


【解决方案1】:

我忘记了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));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    相关资源
    最近更新 更多