将图像显示到 Qt 小部件的最快方法是什么?我已经使用 libavformat 和 libavcodec 解码了视频,因此我已经有了原始 RGB 或 YCbCr 4:2:0 帧。我目前正在使用 QGraphicsView 和包含 QGraphicsPixmapItem 的 QGraphicsScene 对象。我目前正在通过使用内存缓冲区中的 QImage 构造函数将帧数据获取到 QPixmap 中,并使用 QPixmap::fromImage() 将其转换为 QPixmap。
我喜欢这样的结果,而且看起来比较快,但我不禁认为一定有更有效的方法。我还听说 QImage 到 QPixmap 的转换很昂贵。我已经实现了一个在小部件上使用 SDL 覆盖的解决方案,但我想只使用 Qt,因为我能够使用 QGraphicsView 轻松捕获点击和与视频显示的其他用户交互。
我正在使用 libswscale 进行任何所需的视频缩放或色彩空间转换,因此我想知道是否有人有更有效的方法来在执行所有处理后显示图像数据。
Thanks.
感谢您的回答,但我最终重新审视了这个问题,并提出了一个相当简单的解决方案,可以提供良好的性能。它涉及源自QGLWidget
并覆盖paintEvent()
功能。在 - 的里面paintEvent()
函数,你可以调用QPainter::drawImage(...)
如果可用的话,它将使用硬件为您执行缩放到指定的矩形。所以它看起来像这样:
class QGLCanvas : public QGLWidget
{
public:
QGLCanvas(QWidget* parent = NULL);
void setImage(const QImage& image);
protected:
void paintEvent(QPaintEvent*);
private:
QImage img;
};
QGLCanvas::QGLCanvas(QWidget* parent)
: QGLWidget(parent)
{
}
void QGLCanvas::setImage(const QImage& image)
{
img = image;
}
void QGLCanvas::paintEvent(QPaintEvent*)
{
QPainter p(this);
//Set the painter to use a smooth scaling algorithm.
p.setRenderHint(QPainter::SmoothPixmapTransform, 1);
p.drawImage(this->rect(), img);
}
这样,我仍然需要将 YUV 420P 转换为 RGB32,但 ffmpeg 在 libswscale 中可以非常快速地实现该转换。主要收获来自两点:
- 无需软件缩放。缩放在视频卡上完成(如果可用)
- 转换自
QImage
to QPixmap
,这发生在QPainter::drawImage()
功能以原始图像分辨率执行,而不是按放大的全屏分辨率执行。
我用以前的方法将处理器固定在显示器上(解码是在另一个线程中完成的)。现在,我的显示线程仅使用大约 8-9% 的核心来进行全屏 1920x1200 30fps 播放。我确信如果我可以将 YUV 数据直接发送到视频卡,它可能会变得更好,但目前这已经足够好了。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)