Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 原始像素数据中损坏的QImage_C++_Multithreading_Qt_Bitmap_Qimage - Fatal编程技术网

C++ 原始像素数据中损坏的QImage

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

基于我的工作,我尝试使用Qt的
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));
    }