在这个问题中,我想知道维护与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对象,我即将被删除。你现在可以安全地删除帧缓冲区。”
但是,我找不到这样的通知。
答案 0 :(得分:0)
以下解决方法可能符合您的需求。
将实际的QImage对象存储为YV12Frame的私有成员(使用正确的宽度和高度初始化),而不是数组。这是您需要从GetQtImage()
函数返回的对象。由于QImage隐式共享,您可以随时安全地删除YV12Frame,因为任何其他QImage实例在发生时都会分离自己的像素数据。
在帧解码中,通过常用的setPixel()函数更改QImage的内容。
如果速度很关键,那么就不能使用setPixel,因此需要直接操作像素数据。这里的技巧是防止QImage分离像素数据。因此,您需要使用constBits()或constScanLine(),将其强制转换为非常量指针,然后直接访问它(丑陋,我知道)。