我有一种流媒体应用程序,它应该捕获窗口的内容。在窗口中,QGLWidget绘制内容。目前我在每个绘制周期中使用widget.grabFrameBuffer
(必须是实时)。该应用程序使用100%的CPU,没有widget.grabFrameBuffer
它下降到10-20%。我想通了,调用image.bits()
(我需要的,用于发送QImage数据)创建了一个副本(不是解决问题的好方法)。有人知道如何获得指向帧缓冲区或图像数据的指针,还是我必须使用opengl命令?
答案 0 :(得分:1)
QImage::bits()
只会执行深层复制,因为您要求它。
对于常量数据,正确的方法是在QImage
中复制已经存在的数据,而是:
const QImage & frame(widget.grabFrameBuffer());
// compiler enforces const on uchar
const uchar * bits = frame.constBits();
// or
// if you forget const on uchar, this would deep copy
const uchar * bits = frame.constBits();
如果传递位的代码由于不是常量而被破坏,则可以转换位:
class AssertNoImageModifications {
const char * m_bits;
int m_len;
quint16 m_checksum;
Q_DISABLE_COPY(AssertNoImageModifications)
public:
explicit AssertNoImageModifications(const QImage & image) :
m_bits(reinterpret_cast<const char*>(image.constBits())),
m_len(image.byteCount())
{
Q_ASSERT((m_checksum = qChecksum(m_bits, m_len)) || true);
}
~AssertNoImageModifications() {
Q_ASSERT(m_checksum == qChecksum(m_bits, m_len));
}
};
...
AssertNoImageModifications ani1(frame);
stupidAPI(const_cast<uchar*>(bits));
当然grabFrameBuffer()
必须将数据从GPU的内存复制到系统内存,但这不应该是非常昂贵的。应该使用DMA来完成。
如果要在将数据转储到图像之前缩小/重新采样数据,可以通过运行downsampler shader program并从FBO获取图像来节省CPU和系统内存带宽。