c++ - 如何将解码缓冲区从 ffmpeg 映射到 QVideoFrame?

标签 c++ qt video ffmpeg h.264

我试图将解码的 ffmpeg 缓冲区放入 QFrame所以我可以把这个框架放入 QAbstractVideoBuffer然后将此缓冲区放入 QMediaPlayer

这是 VideoSurface 的代码。根据QT的文档,我只需要实现这两个函数:构造函数和bool present ,它将帧处理为 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->mediaStream.decodeFrame(frameBuffer, bufferSize) 。该行将新的 h264 帧解码为 frameBuffer YUV420P 格式。

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

那么...我应该如何将缓冲区映射到 QVideoFrameframe

我还注意到,当我输入 VideoSurface 时实例进入我的QMediaPlayer , present从未被调用过。我认为有些问题,即使是 player->play() 这很重要

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

我还注意到QMediaPlayer不是可显示的元素...那么哪个小部件将显示我的视频?这对我来说似乎很重要。

最佳答案

我认为你误解了每个类的作用。您正在对 QAbstractVideoSurface 进行子类化,它应该有助于访问准备演示的数据。在本方法中,您将获得一个已经解码的 QVideoFrame。如果您想在屏幕上显示此内容,则需要在 VideoSurface 类中实现它。

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

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

关于c++ - 如何将解码缓冲区从 ffmpeg 映射到 QVideoFrame?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54641515/

相关文章:

c++ - Boost JSON解析器和IP地址

c++ - 在比较中字符是否转换为整数?

c - FFmpeg C Api - 降低 fps 但保持视频持续时间

audio - 如何从mp4文件读取音频和视频数据包

ios - 使用 iOS 设备从 HLS 视频流中截取屏幕截图

c++ - 如果窗口服务被杀死,如何处理事件

c++ - 基于非虚拟模板的类 - 泄漏内存?

c++ - 在 Ubuntu 14.04 上使用 icpc 编译 Qt 时出现编译错误

c++ - 在 QtConcurrent::run 中使用 QSqlDatabase 连接(伪连接池)

multithreading - 在三个单独的QThread中绘制三个单独的QImage是否安全?