使用 QMediaPlayer 实现平滑的视频清理?

问题描述

我有一个应用程序,它是一个相当传统的“媒体播放器”。它是在 C++17 中为 Windows 实现的,Qt5 提供了 GUI。

其中一个“关键”功能是进度滑块,您可以抓住它以滑动到视频中的任何位置。 (这有助于直观地搜索视频。)不幸的是,性能(即 QMediaPlayer 在擦洗时实际更新视频显示区域的频率)比预期要差得多。

考虑一下,在播放视频时,更新速率是平滑的,通常在 15 到 60 Hz 之间。擦洗时,视频可能只会以 2 或 3 赫兹的频率更新。

视频以一种直接的方式加载:

    this->player.setMedia(QUrl::fromLocalFile(fileDialogResult->FilePath.string().c_str()));

清理也是通过一个简单的槽回调完成的:

    this->connect(this->sliderPlayback,&QSlider::sliderMoved,this,[this](auto position) {
        this->blockSignals(true);

        this->pimpl->player.play();
        this->pimpl->player.setPosition(position);
        this->pimpl->player.pause();
        
        this->blockSignals(false);
    });

为了找出瓶颈在哪里,我通过英特尔 VTune 运行了代码。它实际上将所有时间(在清理时)都花在了编解码器上。经过更多的实验,我发现未压缩的(原始)视频实际上表现得非常好。压缩视频在关键帧后立即表现良好,然后当您移向下一个关键帧时表现会变差。

有没有办法用 RAM 换取性能并每次都播放视频的解码版本? (即,为预先解码付出代价,将未压缩的帧保留在内存中,并将其用于播放?)

我尝试加载视频并将其推送到缓冲区中,但这对性能没有有意义的影响。

    QFile mediafile(fileDialogResult->FilePath.string().c_str());
    mediafile.open(qiodevice::ReadOnly);
    auto ba = new QByteArray();
    ba->append(mediafile.readAll());
    auto buffer = new QBuffer(ba);
    buffer->open(qiodevice::ReadOnly);
    buffer->reset();
    this->player.setMedia(QMediaContent(),buffer);

如果缓冲区包含解码(未压缩)的视频,我觉得这可能是正确的轨道。如果我可以授权商业图书馆来解决问题,我也很乐意调查。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)