ESM6802主板支持多路网络视频监控--技术天地

技术天地

ESM6802主板支持多路网络视频监控作者:黄志超    发布时间:2019-7-17 17:07:59    被阅览数:

  我们已经介绍过在ESM7100主板上支持多路模拟摄像头的方案,详细资料可以参考《Linux主板多通道视频采集方案》。在很多工业现场中还会使用到网络摄像头,它的优点是可以通过网络获取数据,没有距离的限制,只需要提供一个常用的普通网络接口就可以进行通讯,非常灵活。但是网络摄像头传输的数据都是通过了编码(现在常见格式有 H.264、MPEG-4、MJPEG)的,在接收到数据后,如果要在主板上进行处理和显示,就需要对数据进行解码。实现解码功能需要硬件的支持,依靠软件解码会消耗大量的CPU资源,而且性能也不理想,所以如果要连接网络摄像头,就只能够使用拥有硬件编解码功能的ESM6802这一款核心板。


  ESM6802的处理器为双核Crotex-A9,主频1GHz的i.MX6DL,CPU内部集成了一个拥有编解码功能的VPU(Video Processing Unit),通过VPU进行解码不会消耗过多的CPU资源,而ESM6802内部的VPU可以支持多种格式的解码,包括了常见的H.264、MPEG-4、MJPEG等格式,能够支持的最大分辨率为1920x1088,同时最多可以处理4路摄像头的数据。下面我们就以ESM6802为例,介绍如何使用在Qt界面中显示网络摄像头的数据。


  软件上同样还是使用gstreamer和Qt来实现,ESM6802的文件系统中已经集成了gstreamer和Qt5.8相关的库和工具,并且包含了处理网络摄像头通讯协议rtsp和操作VPU编解码的插件,而gstreamer能够支持多种图形系统包括Qt。所以利用gstreame能够快速方便的获取网络摄像头的数据并显示到Qt界面中,关于gstreamer的详细介绍,可以参考网站https://gstreamer.freedesktop.org/documentation/index.html?gi-language=c


  考虑到部分客户可能对gstreamer不熟悉,玖玖热99公司在gstreamer提供的API函数基础上重新封装了一层,通过库文件libemgst.so提供三个API函数和一个包含网络摄像头信息的结构体变量,利用这三个API函数,客户就可以将视频数据显示在Qt实现的界面上,而不需要使用代码对gstreamer单独进行操作,客户可以专注于Qt程序的开发。下面就详细介绍libemgst.so的三个API函数和结构体变量:



/**

 *    初始化gstreamer

*

*    本函数在C的main函数中调用,将会初始化gstreamer库

*

*    参数说明:

*    使用main函数的两个参数填入,gstramer初始化时需要读取main函数的两个参数

*

  *      返回值说明:

*    无返回值

*

 */

void init_emgst(int argc, char **argv);

 

/**

 *    包含网络摄像头设备信息的结构体

*    访问网络摄像头需要有ip地址,用户名和密码。如果是播放录像文件,还需要填入

*    录像文件的地址,如果是播放实时数据,路径填写为NULL即可。

*

*    参数说明:

*    ip:指向网络摄像头ip地址的指针

*    user:指向网络摄像头的用户名的指针

*    passwd:指向网络摄像头密码的指针

*    file:指向录像文件路径的指针,如果播放实时图像,赋值为NULL

*

 */

typedefstruct _Rtsp_config {

char *ip;

char *user;

char *passwd;

char *file;

} Rtsp_config;

 

/**

 *    配置gstreamer,并显示到指定Qt窗口

*

*    函数会配置gstreamer,显示多个网络摄像头的数据到xwinid所指定的窗口,窗口的大

小通过参数width和height来确定,而网络摄像头的信息由指针rtsp_config传入,listsize

*    指定同时显示的通道数量。因为要动态建立网络摄像头的连接,函数不会退出,所以

需要在线程中调用。

*

*    参数说明:

*  xwinid:Qt窗口的id号,每一个窗口类中都包含这个成员变量。

*    width:显示视频数据所使用的窗口控件的宽度,单位pixel

*    height:显示视频数据所使用的窗口控件的高度,单位pixel

*rtsp_config:指向设备信息结构体的指针,通常是一组包含设备信息的结构体指针。

*    详细解释可以查看对结构体Rtsp_config的说明

*  listsize:显示的视频通道数最多支持同时显示4路。支持1,2,4这三个值,函数会按

*    照固定模式对显示进行排列

*

 *    返回值说明:

*    0表示正常退出gstreamer

*  -1 表示填入参数出现错误,启动gstreamer失败

*

 */

int config_emrtsp(unsignedint xwinid, int width,int height, Rtsp_config *rtsp_config, int listsize);

 

/**

*    关闭gstreamer,释放资源

*

*    函数会关闭gstreamer输出,并释放相关资源

*

*    返回值说明:

*    无返回值

*

*/

void release_emrtsp(void);


  init_emgst函数进行gstreamer的初始化,在启动gstreamer功能之前需要调用一次,客户配合Qt使用时在main函数中调用即可:



int main(int argc, char *argv[])

{

       //初始化玖玖热99主板gstreamer功能

       init_emgst(argc, argv);

 

       //Qt窗口初始化,由QtCreator自动生成

       QApplicationa(argc, argv);

       MainWindow w;

       w.show();

 

       return a.exec();

}


  config_emrtsp函数会配置并启动gstreamer,要将网络摄像头的数据显示在指定的窗口中,客户只要得到用来显示视频的窗口控件的id就可以了,在每一个Qt窗口控件类中都有对应的成员变量,可以很简单的获取到。通过rtsp_config填入网络摄像头的信息,包含网络摄像头的ip,用户名,密码和录像文件路径,如果只是播放实时图像,录像文件路径填为NULL就行了,函数会动态监测网络摄像头的连接,只有当播放完成才会退出,比如录像文件播放完毕或者手动关闭的情况,所以建议在线程中调用函数config_emrtsp。和网络摄像头的连接建立后,ESM6802主板会根据网络摄像头的编码格式自行选择合适的解码方式,不需要客户做任何设置,网络摄像头常用的H.264、MPEG-4、MJPEG编码格式都可以支持。


  config_emrtsp函数会根据width和height的值自动分配显示区域,listsize指定同时显示的通道数,支持的值为1、2、4,显示的方式如下图:


ESM6802主板支持多路网络摄像头.png

视频数据显示排列方式


  函数调用后gstreamer会将对应通道数的视频显示在指定的Qt窗口控件中,每一个区域所显示的网络摄像头数据是通过结构体指针rtsp_config指定的,下面是部分参考代码,创建了一个线程,通过一个按钮启动,把将graphicsView控件的id传给gstreamer,并显示设置的网络摄像头数据:



//派生一个Qt线程类,用获取config_emrtsp函数的参数,并在线程中启动

class Rtsp_pThread :public QThread

{

    Q_OBJECT

 

public:

void run();

 

       //窗口控件的宽度

int width;

//窗口控件的高度

int height;

//显示的通道数量

int num_of_chan;

//窗口控件ID

WIdxwinid;

//包含网络摄像头信息的结构体指针

Rtsp_config *rtsp_config;

};

void MainWindow::on_confirm_released()

{

       //初始化结构体指针

rtsp_config = (Rtsp_config*)malloc(max_chan*sizeof(Rtsp_config));

 

//填入每一路网络摄像头的ip,用户名和密码,因为不是播放录像文件,所以file一项填写的NULL。示例是显示了四路网络摄像头的数据,因为都是访问的同一个摄像头,所以填写的信息是一致的

for(i=0; i<max_chan; i++){

       //网络摄像头的ip地址

       (rtsp_config+i)->ip = (char*)malloc(20*sizeof(char));

       sprintf((rtsp_config+i)->ip, "192.168.201.84");

 

       //网络摄像头的用户名

       (rtsp_config+i)->user = (char*)malloc(20*sizeof(char));

       sprintf((rtsp_config+i)->user, "admin");

 

       //网络摄像头的密码

       (rtsp_config+i)->passwd = (char*)malloc(20*sizeof(char));

       sprintf((rtsp_config+i)->passwd, "******");

 

       (rtsp_config+i)->file = NULL;

}

 

       //将显示区域的宽度,高度和等信息值赋给线程类的成员变量

rtsp_thread.width = ui->graphicsView->width();

rtsp_thread.height = ui->graphicsView->height();

rtsp_thread.num_of_chan = max_chan;

rtsp_thread.rtsp_config = rtsp_config;

 

//启动线程

rtsp_thread.start();

}

void Rtsp_pThread::run()

{

       //在线程中调用函数config_emrtsp,启动显示

config_emrtsp(xwinid, width, height, rtsp_config, num_of_chan);

}

release_emgst函数会停止gstreamer输出,并释放资源,在程序退出或者需要切换显示的时候调用,下面的代码是通过检测Qt按钮控件的点击事件,关闭显示:

void MainWindow::on_setting_released()

{

int i;

 

//停止显示,并释放相关资源

release_emrtsp();

//退出线程

rtsp_thread.quit();

}


  库文件libemgst.so已经预装在ESM6802主板的文件系统中了,客户不需要针对主板再做任何设置。在开发程序的时候,Qt工程中需要将玖玖热99公司提供的emgst.h头文件和libemgst.so库文件添加进去。头文件添加的方法十分简单,增加一个新的头文件即可。关于外部库的添加,Qt的开发工具QtCreator提供了非常简便的方法,客户只需要将libemgst.so拷贝到工程目录下,然后在QtCreator中的项目栏用鼠标右键单击工程,选择添加库(外部库),如下图:


ESM6802主板支持多路网络摄像头.png

添加库操作界面


  选择外部库后,点击下一步,按照下图设置,在库文件一栏中选择到工程下的libemgst.so文件,如下图:


ESM6802主板支持多路网络摄像头.png

选择库文件


  这样就完成了外部库的设置,客户可以在代码中调用libemgst.so提供的API函数了。玖玖热99公司提供了一个通过按钮切换显示视频通道数的例程,效果如下:


ESM6802主板支持多路网络摄像头.png


  通过这种方式,玖玖热99公司希望能够帮助客户缩短开发周期,让客户可以专注于Qt程序的开发,而不用花时间去学习并在代码中设置gstreamer。对于例程感兴趣的客户可以和工程师联系,索取相关代码。

Go Top
友情链接: 69rng.space    boot06.com