Qt实战--基于OpenCV的VideoCapture实现视频引擎类

文章目录


上一节中我们给出了播放引擎接口类HVideoPlayer,下面我们给出基于OpenCV的VideoCapture类实现的播放引擎实现类HVideoCapture

HVideoCapture

首先播放引擎类从媒体源中获取帧,解码,push到缓存区等工作我们放到另外一个线程中做,以免阻塞GUI线程,为此HVideoPlayer多重继承自HVideoPlayer和HThread

头文件:

#ifndef HVIDEOCAPTURE_H
#define HVIDEOCAPTURE_H

#include "hvideoplayer.h"
#include "hthread.h"
#include "opencv2/opencv.hpp"

class HVideoCapture : public HVideoPlayer, public HThread
{
public:
    HVideoCapture() : HVideoPlayer(), HThread() {}

    virtual int start();

    virtual int stop();

    virtual int pause() {return HThread::pause();}
    virtual int resume() {return HThread::resume();}

    virtual void doTask();

protected:
    cv::VideoCapture vc;
};

#endif // HVIDEOCAPTURE_H

源文件:

#include "hvideocapture.h"
#include "opencv_util.h"

#include "qtheaders.h"
int HVideoCapture::start(){
    switch (media.type) {
    case MEDIA_TYPE_CAPTURE:
        vc.open(media.index, cv::CAP_DSHOW);
        break;
    case MEDIA_TYPE_FILE:
    case MEDIA_TYPE_NETWORK:
        vc.open(media.src.c_str(), cv::CAP_FFMPEG);
        break;
    default:
        return -10;
    }

    if (!vc.isOpened())
        return -20;

    vc.set(cv::CAP_PROP_FPS, 25);

    return HThread::start();
}

int HVideoCapture::stop(){
    HThread::stop();
    vc.release();
    return 0;
}

void HVideoCapture::doTask(){
    cv::Mat mat;
    if (!vc.read(mat))
        return;

    //...ALG

    HFrame frame;
    Mat2HFrame(mat, frame);
    push_frame(&frame);
}

代码很简单,利用VideoCapture类open打开媒体源,read获取视频帧;
而后我们使用Mat2HFrame将cv::Mat赋值给我们定义的帧结构体HFrame,然后push_frame到帧缓存中;

PIMPL

至此,我们就可以将HVideoWidget中的HVideoPlayer* pImpl = new HVideoCapture;,实现一个完整的播放器了。

类似的,你也可以实现一个基于FFmpeg的视频引擎类HFFmpegPlayer : public HVideoPlayer, public HThread,有兴趣的小伙伴可以尝试下。这是我们采用了PIMPL设计模式带来的灵活性,即一套接口,多种实现。接口定义的通用性和可扩展性自然不言而喻了。

ithewei CSDN认证博客专家 c/c++ Qt libhv
编程之路,其路漫漫,吾将上下而求索
https://github.com/ithewei
https://hewei.blog.csdn.net
©️2020 CSDN 皮肤主题: 代码科技 设计师:Amelia_0503 返回首页