Поврежденный QImage из необработанных данных пикселей

Основываясь на моей работе от этот ответ, Я пытаюсь использовать Qt’s 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);
}

Что тут происходит?

0

Решение

Я забыл что 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));
}
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]