1

我有自己的类,它继承自 Qt5.6 QGraphcisView。

我还有一个 QGraphicsPixmapItem 在现场。(忘了说) ANGLE 已启用!

CMyGraphicsView::CMyGraphicsView(QWidget *parent) : QGraphcisView(parent)
{
    QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
    QGLFormat fmt(QGL::SampleBuffers);
    fmt.setSwapInterval(2);
    gl = new QGLWidget(fmt);
    setViewport(gl);
....
}

我经常更新像素图以制作像视频一样的动画。实际上它是视频,因为我为 QMediaPlayer 实现了自己的 QAbstractVideoSurface,并且我收到了在场景中更新的视频帧。

bool MyPlayer::present(const QVideoFrame &Frame)
{
    MyPlayer* player = reinterpret_cast<MyPlayer*>(parent());
    if (Frame.isValid())
    {
        QVideoFrame myframe(Frame);

        if (!myframe.map(QAbstractVideoBuffer::ReadOnly))
            return false;

        QImage image(
            (const unsigned char*)myframe.bits(),
            myframe.width(),
            myframe.height(),
            myframe.bytesPerLine(),
            QVideoFrame::imageFormatFromPixelFormat( myframe.pixelFormat() )
        );

        QPixmap pixmap = QPixmap::fromImage(image, Qt::NoFormatConversion);
        pixmap_frame_->setPixmap(pixmap);
        myframe.unmap();
        return true;
    }
    return false;
}

问题是在英特尔集成视频卡上,我看到动画闪烁,就像更新与显示 VSYNC 不同步。

在 NVIDIA 卡上似乎一切正常,没有问题。

我从 Qt 文档中读到,制作 fmt.setSwapInterval(2) 应该允许我在每 2 次 VSYNC 刷新时更新屏幕,所以我希望在 60Hz 显示器上有平滑的 30fps 动画。除此之外,似乎 setSwapInterval() 对英特尔和英伟达都没有任何作用:

在 Intel 卡上它总是闪烁,而在 NVIDIA 卡上它总是很流畅,不依赖于 swapInterval() 或任何其他 QGLFormat 选项。

我也尝试过,fmt.setDoubleBuffer(true);但在英特尔卡的情况下也无济于事。如何解决闪烁问题?

当然,我可以直接在场景中放置 QGraphicsVideoItem - 然后没关系,但我不能使用此选项,因为稍后我需要动态修改帧像素 - 为此我需要 QAbstractVideoSurface。

4

0 回答 0