Chinaunix首页 | 论坛 | 博客
  • 博客访问: 376823
  • 博文数量: 263
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1975
  • 用 户 组: 普通用户
  • 注册时间: 2014-08-05 09:59
文章分类

全部博文(263)

文章存档

2015年(166)

2014年(97)

分类: LINUX

2015-04-29 08:52:44

原文地址:mjpg-streamer源码分析 作者:hxwxz

作者:曹忠明,讲师。

mjpg-streamer是一个很好的开源项目,用来做视频服务器,使用的是v4l2的接口。前面我们说了它的移植过程,但是在某些特定的情况下这个工程不能达到我们的需求,所以我们需要对源码进行修改,或者直接写一个自己的视频服务器。在修改源码或写自己的服务器之前我们分析下这个源码的代码。

这个代码里有三个部分是我们需要掌握的内容,第一是v4l2接口,第二个是socket编程,第三个是多线程编程。

一、 v4l2接口说明

这里涉及到我们如何从摄像头中把数据取出来,首先是封装一个结构体用来描述摄像头的一些信息,比如采集图片的宽高,图片的格式,等等。

struct vdIn {
                int fd;
                char *videodevice;
                char *status;
                char *pictName;
                struct v4l2_capability cap;
                struct v4l2_format fmt;
                struct v4l2_buffer buf;
                struct v4l2_requestbuffers rb;
                void *mem[NB_BUFFER];
                unsigned char *tmpbuffer;
                unsigned char *framebuffer;
                int isstreaming;
                int grabmethod;
                int width;
                int height;
                int fps;
                int formatIn;
                int formatOut;
                 int framesizeIn;
                int signalquit;
                int toggleAvi;
                int getPict;
                int rawFrameCapture;
                /* raw frame capture */
                unsigned int fileCounter;
                /* raw frame stream capture */
                unsigned int rfsFramesWritten;
                unsigned int rfsBytesWritten;
                /* raw stream capture */
                FILE *captureFile;
                unsigned int framesWritten;
                unsigned int bytesWritten;
                int framecount;
                int recordstart;
                int recordtime;
        };

接着是把这个结构体写入驱动中,用来初始化摄像头。这个操作通过ioctl完成,涉及到的命令包括VIDIOC_QUERYCAP、VIDIOC_S_FMT、VIDIOC_S_PARM、VIDIOC_REQBUFS,VIDIOC_QUERYBUF,并通过mmap完成内存的映射。

最后我们通过ioct命令完成图片的读取,涉及到的命令包括VIDIOC_QBUF和VIDIOC_DQBUF。然后把获得的数据写入到文件里就是图片,通过网络传输出去连续的图片就是视频。

二、 socket编程

在这个程序里使用的是tcp套接字,每有一个连接请求就创建一个线程单独和这个请求通信,这里涉及到的函数包括socket、bind、listen、accept和write。

三、 多线程编程

为了能同时响应多个客户端的请求,这里使用了多线程编程,为每一个请求建立一个连接,每个连接就是一个线程。这里涉及到的函数包括pthread_create、pthread_detach、pthread_cond_init、pthread_cond_destroy、pthread_mutex_init、pthread_mutex_destroy。

四、 mjpg-streamer工作流程
mjpg-streamer源码分析 - 乌云然 - 香烧间有歇 花落无还时

原文:

 

About the project   

mjpg-streamer源码分析 - 乌云然 - 香烧间有歇 花落无还时

"MJPG-streamer",是用于从webcam摄像头采集图像,把他们以流的形式通过基于ip的网络传输到浏览器如Firehox,Cambozola,VLC播放器,Windows的移动设备或者其他拥有浏览器的移动设备。她可以利用某些webcams的硬件压缩功能来降低服务器CPU的开销。她为嵌入式设备和一些常规服务器提供了一个轻量且更少CPU消耗的方案,因为她无需为视频帧压缩浪费大量的计算效率(这件事交给硬件了)。例子是:在一个主频200MHz的路由器上(一个例子是cisco经典无线的linkfs WRT54G路由,其可以运行openWRT(迷你linux系统),主频200MHz,4MRAM,16Flash),流编码一个960x720像素的视频,她可以减少10%的cpu使用。



Screenshot of the example webpage



Testpicture Frame #1



MJPEG-Client written in Lazarus (Free Pascal)



VideoLAN can display the stream


About the name

其他一些合适的名字有:MJPEG-streamer或者M-JPEG-streamer,由于在早期的项目中用的就是mpeg-streamer,所以我们决定保持原样。


What it does
我们需要一个input-plugin来提供图片。input-plugin负责产生图片并把这些复制到内存中去。相应的output-plugin则负责把这些内存中的图片取出来以便后续的处理。最常用的是webserver-output-plugin,他允许将图片传送到网络浏览器上。mjpg-streamer充当粘合剂的角色,把这单一的input-plugin和众多的output-plugin给连在一起,而几乎所有的工作都交给了这些个插件。


Plugins

Input-Plugins
像其他普通的input-plugin一样,这些个插件工作是把JPEG格式的图片拷贝到全局可访问内存中,接着给等待进程发送信号(告他:我来了!想干哈干哈吧)。


input_testpicture.so

这个模块编译的时候已经加入了图片(正如其名:test),就是说你没摄像头也能进行测试工作(你编译的对不对)。他也为你提供了一个模板,一个你想写自己的input-plugin的模板,因为他被实现的尽可能的简单易懂。它的作用就是把由testpictures模块得到的JPEG-files文件转变成一个头文件,这个头文件包含了一些被编译进testpictures模块的图片(前面说过了)。当被激活时就会不停的往复上面的那个动作:获得->转变。


input_uvc.so

如其名她从兼容Linux-UVC V4L2标准的设备中抓取图片。像Logitech Quickcam Sphere AF等等国产的有 ZC0303。她的源码是基于开源项目"luvcview",当然做了很多方面的修改了。与"luvcview"不同的是,他初始化罗技他们家的摄像头时用pan/tilt/focus命令即可。而无需库的帮忙、摆弄XML文件或者udev规则(设备文件在系统中出现的方式)。现在很流行这种输入插件,得益于它能够在不增加CPU负载的情况下以大于15fps(frame per second)速率来将相片编码成960x720象素大小。如果你有钱不用考虑CPU的负载问题,大可进行1600x1200象素(厉害)的无压缩的编码,然后用软件实现压缩并传到客户端!


input_control.so

这个模块只实现了pan/tilt的控制接口,就是说他把视频流的功能交给了其他程序(Linux中很推崇"简洁",就是一款软件一个功能,效率至上,功能有软件数量保证)。曾经用他提供了一个网络接口以允许通过网络实现pan/tilt我的罗技Orbit AF,当然Skype就来补充音、视频流的功能了。当我们通过Skype要开远程会议的时候,她工作的非常好,看不见的手时候还方便他们控制这个摄像头多好啊。


Output-Plugins
output_http.so

这绝对是个全版本的符合HTTP1.0标准的webserver。可以在单独的文件夹中提供文件访问,也可以执行一些命令。例子是,你可以访问从输入plugin(见上文)获得的JPEG文件,或者按照M-JPEG标准编码他们。可以从一个文件夹提供服务意味着你可以定制你自己的网页,比如嵌入图片啊神马的。你可以参见MJPG-streamer 包中的例子。有点重要的是,多个实例是可以并发运行的,这意味着多个server-threads进程可以处理不同的密码(不同的请求)啊,呈现的布局啊或者有限制的命令。

这个模块是用来把JPEG图片存储到指定的文件夹中。你一可以用来抓取图片并只是存取,当然你也可以在存储完之后通过执行命令把他们提交到FTP服务器上!你可以在output_file页参看更多的文档。


MoreProject Status
JavaScript Motion Detection
High resolution webcam with 1600x1200 pictures
Usage

阅读(1391) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~