2013-07-02 92 views
0

我的工作離開this answer,我試圖使用Qt的QGLWidget來呈現視頻,但我遇到了一些問題。當保存我在我的視頻解碼線程解碼後立即框架,它出來就好了:從原始像素數據損壞的QImage

intact frame

但繪製時,它出來的可怕的錯位:

mangled frame

它幾乎好像圖像被複制和拷貝沒有完成,但

  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

您是在單獨的線程中解碼視頻嗎?如果您保存圖片的內容後馬上與nextFrame->的getPixels()數據創建的,你得到了什麼? – Vasaka

+0

@Vasaka - 這是我在做什麼。事實證明,這是一個內存分配的問題 - 看到我的回答。 –

回答

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)); 
}