Read rtsp using libvlc&opencv

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值