【问题标题】:How to map a decoded buffer from ffmpeg into QVideoFrame?如何将解码缓冲区从 ffmpeg 映射到 QVideoFrame?
【发布时间】:2019-07-05 14:15:34
【问题描述】:

我正在尝试将解码后的 ffmpeg 缓冲区放入QFrame,这样我就可以将此帧放入QAbstractVideoBuffer,然后将此缓冲区放入QMediaPlayer

这是 VideoSurface 的代码。根据QT的文档,我只需要实现这两个函数:constructor和bool present,将frame处理成QVideoFrame命名为frame

QList<QVideoFrame::PixelFormat> VideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const
{
    Q_UNUSED(handleType);

    // Return the formats you will support
    return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_YUV420P;
}

bool VideoSurface::present(const QVideoFrame &frame)
{
    //Q_UNUSED(frame);
    std:: cout << "VideoSurface processing 1 frame " << std::endl; 

    QVideoFrame frametodraw(frame);

    if(!frametodraw.map(QAbstractVideoBuffer::ReadOnly))
    {
        setError(ResourceError);
        return false;
    } 
    // Handle the frame and do your processing
    const size_t bufferSize = 398304;
    uint8_t frameBuffer[bufferSize];
    this->mediaStream->receiveFrame(frameBuffer, bufferSize);
    //Frame is now in frameBuffer, we must put into frametodraw, I guess
    // ------------What should I do here?-------------
    frametodraw.unmap();
    return true;
}

看看this-&gt;mediaStream.decodeFrame(frameBuffer, bufferSize)。此行将新的 h264 帧解码为 YUV420P 格式的frameBuffer

我的想法是使用map 函数,然后尝试使用frametodraw.bits() 函数接收缓冲区指针,并尝试将该指针指向另一事物,但我认为这不是方法。我想我应该将frameBuffer的内容复制到这个指针,但是这个指针并没有告诉我它的大小,例如,所以我想这也不是办法。

那么...我应该如何将我的缓冲区映射到名为 frameQVideoFrame 中?

我还注意到,当我将 VideoSurface 实例放入 QMediaPlayer 时,永远不会调用 present。我认为有问题,即使是 player-&gt;play() 这很重要

我也没有frameBuffer 内解码图像的大小,我只有它的总大小。我想这也应该是个问题。

我还注意到QMediaPlayer 不是可显示元素...那么哪个小部件会显示我的视频?这在我看来很重要。

【问题讨论】:

  • 我可能是错的,但你可以在QVideoWidget 发布之前使用这个旧的example

标签: c++ qt video ffmpeg h.264


【解决方案1】:

我认为您误解了每个班级的角色。您正在继承 QAbstractVideoSurface,它应该有助于访问准备好呈现的数据。在本方法中,为您提供了一个已解码的 QVideoFrame。如果您想在屏幕上显示此内容,则需要在 VideoSurface 类中实现它。

可以在QMediaPlayer上设置VideoSurface,媒体播放器已经处理了视频的解码和像素格式的协商。您在当前 VideoSurface 中收到的 QVideoFrame 已经具有来自媒体播放器的高度/宽度和像素格式。媒体播放器的典型用途是让它加载和解码文件,并通过视频小部件显示在屏幕上。

如果您需要使用自己的自定义 ffmpeg 解码器,我的建议是将帧从 yuv420 转换为 rgb(libswscale?),创建您自己的自定义小部件,您也可以传递帧数据并可以在屏幕上渲染它QPainter 在将其加载到 QPixmap 后使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 2014-01-14
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 2013-03-26
    • 2021-08-21
    相关资源
    最近更新 更多