如何将解码后的缓冲区从ffmpeg映射到QVideoFrame?

问题描述 投票:2回答:1

我试图通过解码的ffmpeg缓冲区放入QFrame,这样我就可以将这个帧放入QAbstractVideoBuffer然后将这个缓冲区放入QMediaPlayer

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

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)。该行以YUV420P格式将新的h264帧解码为frameBuffer

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

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

我也注意到,当我把我的VideoSurface实例放入我的QMediaPlayer时,present从未被调用过。我觉得有些不对劲,即使使用player->play()也很重要。

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

我还注意到QMediaPlayer不是一个可显示的元素......那么Widget会显示我的视频?这对我来说很重要。

c++ qt video ffmpeg h.264
1个回答
2
投票

我认为你误解了每个班级的作用。您是QAbstractVideoSurface的子类,它应该帮助访问准备好呈现的数据。在本方法中,为您提供已解码的QVideoFrame。如果您想在屏幕上显示此内容,则需要在VideoSurface类中实现它。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.