Read rtsp using libvlc&opencv

来源:互联网 发布:头像卡通化软件 编辑:程序博客网 时间:2024/06/11 00:42

1. Problem

I need to read video frame from a rtsp device, and convert it to cv::Mat.

2. Solution

libvlc is a useful tool.

  1. sudo apt-get install libvlc-dev
  2. Create VLCReader class.

2.1 VLCReader.h

#ifndef VLCREADER_H#define VLCREADER_H#include <vlc/vlc.h>#include <opencv2/opencv.hpp>class VLCReader{public:    VLCReader(char* url=0);    ~VLCReader();    void start(int wantW = 640, int wantH=480);    void pause(bool paused);    cv::Mat frame(){ return img;}    int w, h;private:    char* rtspAddress = "rtsp://192.168.9.7/bs1";    libvlc_instance_t *inst;    libvlc_media_player_t *mp;    unsigned char *pixel;    cv::Mat img;    static void *cb_lock(void *opaque, void **plane);    static void cb_unlock(void *opaque, void *picture, void * const *plane);    static void cb_display(void *opaque, void *picture);    unsigned char * updataSize();};#endif // VLCREADER_H

2.2 VLCReader.cpp

#include "vlcreader.h"#include <cstdlib>#include <iostream>VLCReader::VLCReader(char*url)    : inst(0),mp(0), pixel(0), w(0), h(0), rtspAddress(url){    const char * const vlc_args[] = {        "-I", "dummy",      // Don't use any interface        "--ignore-config",  // Don't use VLC's config        "--no-audio",       // skip any audio track        "--verbose=1",      // change verbosity for debugging purpose    };    inst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);    mp = libvlc_media_player_new(inst);    libvlc_video_set_callbacks(mp, &cb_lock, &cb_unlock, &cb_display, this);}VLCReader::~VLCReader(){    libvlc_media_player_stop(mp);    libvlc_media_player_release(mp);    libvlc_release(inst);}void VLCReader::start(int wantW, int wantH){    libvlc_media_player_pause(mp);    libvlc_media_t *media = libvlc_media_new_location(inst, rtspAddress);    libvlc_media_player_set_media(mp, media);    libvlc_media_release(media);    libvlc_video_set_format(mp, "RV24", wantW, wantH, wantW*3);    libvlc_media_player_play(mp);}void VLCReader::pause(bool paused){    if(mp){        libvlc_media_player_set_pause(mp, paused);    }}unsigned char * VLCReader::updataSize(){    int w = libvlc_video_get_width(mp);    int h = libvlc_video_get_height(mp);    if (!w || !h)        return 0;    if (pixel && (this->w != w || this->h != h)){        delete[] pixel;        pixel = 0;    }    if (!pixel){        pixel = new unsigned char[w*h*3];        this->w = w;        this->h = h;    }    return pixel;}void* VLCReader::cb_lock(void *opaque, void **plane){    VLCReader *p = (VLCReader*) opaque;    *plane = p->updataSize();    return *plane;}void VLCReader::cb_unlock(void *opaque, void *picture, void * const *plane){    VLCReader *p = (VLCReader*) opaque;    unsigned char *pix = (unsigned char*)picture;    if (pix){        p->img = cv::Mat(p->h, p->w, CV_8UC3, pix);    }}void VLCReader::cb_display(void *opaque, void *picture){}

2.3 Test

#include <opencv2/opencv.hpp>#include "vlcreader.h"using namespace cv;int main(){    VLCReader r("rtsp://192.168.9.7/bs1");    int rtsp_w = 720, rtsp_h = 576;    r.start(rtsp_w, rtsp_h);    while(1){        Mat frame = r.frame();        if(!frame.empty()){            imshow("test", frame);            int ch = waitKey(20) & 0xFF;            if (ch == 113)                break;        }    }    return 0;}

3. ref

  1. vlccapture at github
  2. libvlc sample code
0 0
原创粉丝点击