2

在这个问题中,我想知道维护与 QImage 对象关联的外部缓冲区对象的生命周期的最佳实践。

背景

我正在用 QT 开发一个未压缩的图像文件查看器。它从文件中读取 YV12 数据,将其转换为 RGB 帧缓冲区,构造 QImage 对象,并将其传递到 UI 层进行渲染。

YV12 文件阅读器看起来像这样。

class YV12Frame
{
public:
    YV12Frame(std::string const& fileName)
    {
        // Initialize m_frameBuffer
        // ... (Omitted for brevity)
    }

    QImage GetQImage()
    {
        // Build QImage object
        return QImage(m_frameBuffer, WIDTH, HEIGHT, QImage::Format_RGB32); 
    }

private:
    unsigned char m_frameBuffer[WIDTH * HEIGHT * 4];
};

正如 QT 文档所说,我们需要在 QImage 对象的整个生命周期内保持 YV12Frame 对象有效。

UI 层可以通过浅拷贝或深拷贝来拷贝 QImage 对象。换句话说,一次可能有未知数量的 QImage 对象引用帧缓冲区。

问题

我们如何知道何时安全地删除 YV12Frame 对象?

预期答案

有一个通知(回调或其他)告诉“嘿,我是最后一个引用帧缓冲区的 QImage 对象,我即将被删除。你现在可以安全地删除帧缓冲区。”

但是,我找不到这样的通知。

4

1 回答 1

0

以下解决方法可能适合您的需要。

代替数组,存储一个真正的 QImage 对象作为 YV12Frame 的私有成员(使用正确的宽度和高度初始化)。GetQtImage()这是您需要从函数返回的对象。由于 QImage 隐式共享,您可以随时安全地删除 YV12Frame,因为任何其他 QImage 实例在发生时都会分离自己的像素数据。

在您的帧解码中,通过通常的setPixel()函数更改 QImage 的内容。

如果速度很关键,那么您不能使用 setPixel ,因此您需要直接操作像素数据。这里的技巧是防止 QImage 分离像素数据。因此,您需要使用constBits()constScanLine(),将其转换为非常量指针,然后直接访问它(丑陋,我知道)。

于 2013-01-08T06:07:15.143 回答