Qt从视频中获取每一帧数据

参考了以下文章:https://blog.csdn.net/jxbinwd/article/details/81034339

我按照上面文章的描述写程序,解析出来的图像保存成图片。保存的图片有很多乱码。后来在保存图像时,停止播放视频,这样乱码就没了。

这个程序只是为了获取帧数据并存成图像,没有显示功能。

在.pro文件中需要增加

QT      += multimedia

qtvideotest.h

#ifndef QTVIDEOTEST_H
#define QTVIDEOTEST_H

#include <QWidget>
#include <QMediaPlayer>
#include "videosurface.h"

class QtVideoTest : public QWidget
{
    Q_OBJECT

public:
    QtVideoTest(QWidget *parent = 0);
    ~QtVideoTest();

public slots:
    void ProcessFrame(QVideoFrame &frame);

private:
    QMediaPlayer *mediaPlayer;
};

#endif // QTVIDEOTEST_H

qtvideotest.cpp

#include "qtvideotest.h"
#include <QDebug>
#include <QUrl>
#include <QMetaType>

QtVideoTest::QtVideoTest(QWidget *parent)
    : QWidget(parent)
{
    qRegisterMetaType<QVideoFrame>("QVideoFrame&");
    mediaPlayer  = new QMediaPlayer;
    VideoSurface *videoSurface = new VideoSurface();
    mediaPlayer->setVideoOutput(videoSurface);
    mediaPlayer->setMedia(QUrl("../video.flv"));
    mediaPlayer->setMuted(true);
    mediaPlayer->play();

    connect(videoSurface, SIGNAL(frameAvailable(QVideoFrame &)), this, SLOT(ProcessFrame(QVideoFrame &)), Qt::QueuedConnection);
}

QtVideoTest::~QtVideoTest()
{
}
void QtVideoTest::ProcessFrame(QVideoFrame &frame)
{
    static int count=0;
    count++;

    if (count % 5 == 0)
    {
        mediaPlayer->pause();
        frame.map(QAbstractVideoBuffer::ReadOnly);
        QImage recvImage(frame.bits(), frame.width(), frame.height(), QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()));
        recvImage.save(QString("./images/%1.jpg").arg(count), "JPG");
        frame.unmap();
        mediaPlayer->play();
    }

}

这里我每隔5帧保存一张图片,也可以每一帧都保存。

videosurface.h

#ifndef VIDEOSURFACE_H
#define VIDEOSURFACE_H

#include <QAbstractVideoSurface>

class VideoSurface : public QAbstractVideoSurface
{
    Q_OBJECT
public:
    VideoSurface(QObject *parent = Q_NULLPTR);
    ~VideoSurface();

    QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType = QAbstractVideoBuffer::NoHandle) const;
    bool present(const QVideoFrame &frame);

signals:
    void frameAvailable(QVideoFrame &frame);
};

#endif // VIDEOSURFACE_H

videosurface.cpp

#include "videosurface.h"
#include <QVideoSurfaceFormat>
#include <QDebug>

VideoSurface::VideoSurface(QObject *parent):QAbstractVideoSurface (parent)
{
}

VideoSurface::~VideoSurface()
{
}

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

    listPixelFormats.append(QVideoFrame::Format_ARGB32);
    listPixelFormats.append(QVideoFrame::Format_ARGB32_Premultiplied);
    listPixelFormats.append(QVideoFrame::Format_RGB32);
    listPixelFormats.append(QVideoFrame::Format_RGB24);
    listPixelFormats.append(QVideoFrame::Format_RGB565);
    listPixelFormats.append(QVideoFrame::Format_RGB555);
    listPixelFormats.append(QVideoFrame::Format_ARGB8565_Premultiplied);
    listPixelFormats.append(QVideoFrame::Format_BGRA32);
    listPixelFormats.append(QVideoFrame::Format_BGRA32_Premultiplied);
    listPixelFormats.append(QVideoFrame::Format_BGR32);
    listPixelFormats.append(QVideoFrame::Format_BGR24);
    listPixelFormats.append(QVideoFrame::Format_BGR565);
    listPixelFormats.append(QVideoFrame::Format_BGR555);
    listPixelFormats.append(QVideoFrame::Format_BGRA5658_Premultiplied);

    listPixelFormats.append(QVideoFrame::Format_Jpeg);

    listPixelFormats.append(QVideoFrame::Format_CameraRaw);
    listPixelFormats.append(QVideoFrame::Format_AdobeDng);

    return listPixelFormats;
}

bool VideoSurface::present(const QVideoFrame &frame)
{
    if (this->surfaceFormat().pixelFormat() != frame.pixelFormat() || this->surfaceFormat().frameSize() != frame.size())
    {
        setError(IncorrectFormatError);
        stop();
        qDebug()<<"error format";
        return false;
    }
    QVideoFrame cloneFrame(frame);
    emit frameAvailable(cloneFrame);


    return true;
}

 

 

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值