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設計模式帶來的靈活性,即一套接口,多種實現。接口定義的通用性和可擴展性自然不言而喻了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章