基于linux的视频服务器设计

来源:互联网 发布:猫咪淘宝客软件 编辑:程序博客网 时间:2024/05/07 07:23

         视频服务器软件需要从USB摄像头获取视频数据,将采集的数据经过处理之后,再发送给用户。为实现此功能,需要创建输入输出两个线程。输入线程实现视频采集,输出则响应来自用户的请求,并向用户发送视频图像数据。输入输出线程之间通过共享内存通信,输入线程将图像数据写入共享内存后,输出线程从共享内存中读取数据进行传输,整个流程如下:

 

USB摄像头-------->输入线程--------->共享内存----------->输出线程-----------用户

 

1.基于 V4L2 的视频信号采集

 

       V4L2(VideoFor Linux two)是 Linux 系统下视频设备驱动程序接口规范,为上层应用程序提供了一系列的接口函数,可实现对视频设备的操作,进而完成视频图像的采集。

一般情况下,通过 V4L2 接口采集视频数据的工作流程如下:

       (1)打开视频设备。调用open()函数打开/dev/video()视频设备文件;

       (2)获取设备信息。读取结构体中的摄像头,图像的基本信息。

       (3)设置视频采集的信息参数。视频格式,分辨率,帧速率等。

       (4)申请内核帧缓冲区,用来存放数据;

       (5)采用 mmap 方式将申请到的帧缓冲区从内核空间映射的用户空间,使用户可直接操作采集到的数据;

       (6)将申请到的帧缓冲全部放入视频采集输入队列排队,等待接收存放摄像头采集到的视频数据。

       (7)进行视频采集

       (8)把装有视频数据的帧缓冲区从输出队列取出,然后处理视频数据;

       (9)为了可以循环采集数据,需要将刚刚处理完的帧缓冲区再次放人采集输入队列尾部;

       (10)停止视频采集。

2 .采集程序的编程实现

       将USB摄像头采集的JPEG格式的视频图片拷贝到共享内存。首先创建input输入线程,input 线程首先调用初始化程序input_init,进行必要的初始化,如:打开视频设备,设置设备和图像属性,设置帧速率,申请帧缓冲区,mmap 映射,将缓冲区加入输入队列等工作。初始化完毕后进入 input_run程序中,这部分程序是视频采集的关键步骤,主要工作就是抓取一帧图片,并保存到共享内存中。主要就是调用 grab 模块,使摄像头采集图片到videoIn->tmpbuffer 中,然后使用memcpy_picture 把图片从videoIn->tmpbuffer 转移到pglobal->buf 共享内存里,循环调用 grab 模块,即实现了从 usb 摄像头驱动接口不断采集数据帧存入内存的功能。视频采集流程图如下:


3.视频服务器信号传输功能的设计与实现

       用户与视频服务器之间的通信主要包括用户请求和服务器响应,所以要求视频服务器应具有基于 TCP 协议建立 Socket 连接,监听接收客户端请求或者 HTTP 请求,分析请求,响应请求等功能。具体通信传输过程包含以下几个步骤:

(1)首先嵌入式视频服务器需要完成基本的初始化工作,例如创建环境变量,建立TCP SOCKET套接字,bind 绑定监听端口,listen 开始监听,循环等待客户端的连接请求。
(2)视频服务器监听客户端的连接请求,当在监听端口收到客户端发送的连接请求时,服务器开始接受客户端请求,并保存相应的请求信息。
(3)当服务器接收了来自客户端的请求后,要对接收到的请求进行分析,解析请求的方法,同时服务器还要根据收到的请求给出相应的处理。
(4)完成了相应的处理后,服务器根据请求信息向客户端发送响应信息和需要的数据。

4.传输程序的编程实现

视频服务器是通过标准 Socket 编程实现视频图像传输。总体思路是首先利用 Socket 建立一个 TCP 连接,然后创建一个输出线程 output 处理来自用户的请求,output 线程依据用户要求从共享内存空间中读取图像数据,在 TCP 协议上发送传输带有JPEG 数据的 HTTP 消息给用户中心。

首先是 output_init函数完成相应的初始化工作。初始化的参数包括端口号,存储内存等。接下来是output_run 程序,在程序中成功建立一个 Socket 套接字连接,bind()绑定端口,listen()监听端口,accep()接收数据等过程,然后读取客户端传送的HTTP请求,接下来对接收到HTTP请求消息进行解析,确定客户端的请求类型。如果解析后发现在端口收到请求信息为 GET/?action= stream,就会响应请求,从 pglobal->buf 共享内存中读取数据,运行 send()发送视频流数据到用户中心。这个过程就可以把在 input-plugin 中已经被放到内存的视频信息发送出去了。







原创粉丝点击