mjpgstreamer源码分析

摘要:
Mjpg流媒体是一个很好的开源项目,它用作视频服务器并使用v4l2接口。我们在修改源代码或编写自己的服务器之前分析源代码。我们需要掌握这段代码的三个部分。第一个是v4l2接口,第二个是套接字编程,第三个是多线程编程。structvdIn{intfd;char*videodevice;char*status;char*pictName;structv4l2_capabilitycap;structv4l2_formatfmt;structf4l2_bufferbuff;struct 4l2_requestbuffersrb;void*mem[NB_BUFFER] ; 未签名的缓存*tmpbuffer;unsignedchar*帧缓冲区;初始拉伸;积分法;intwidth;八岁;intfps;intformatIn;intformatOut;intframesizeIn;intsignal退出;inttoggleAvi;intgetPict;intrawFrameCapture;/*rawframecapture*/unsignedtfileCounter;/*rawframestreamcapture*/unsignedtrfsFramesWritten;未签名trfsBytesWritten;/*rawstreamcapture*/FILE*captureFile;未签名的框架已编写;未签名的字节已写入;intframecount;无畏启动;intercordtime;};接下来,将此结构写入驱动程序以初始化相机。

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工作流程

mjpgstreamer源码分析第1张

免责声明:文章转载自《mjpgstreamer源码分析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Object-c 内存管理负载均衡技术(二)———常用负载均衡服务介绍下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

mac 获得进程信息的方法

NSProcessInfo可以获得当前进程的信息。获得所有活动进程信息可以尝试使用下面的方法。 进程的信息可以通过ps命令得到也可以通过sysctl方法得到。 但是我总是不能获取进程的流量信息,关于这一点很纠结,现在的想法就是如果能够获取进程的网络端口,然后对端口进行监听,统计其流量,但是如何能够获取进程的网络端口? 在linux中可以通过netstat...

用C#中的键值对遍历数组或字符串元素的次数

代码如下: string strs = "ad6la4ss42d6s3"; Dictionary<char, int> dic = new Dictionary<char, int>(); foreach(var item in strs) {...

cocos2d-x关于CCTableView的“乱序问题”的理解

Cocos2d-x有一个不错的控件CCTableView。之前用的时候发现有cell的顺序错乱和重复出现的问题。后来仔细看了一下源码,发现是自己用法错误。但是网上有人说是一个bug,要改源码。我发现2.04以上的源码都是没问题的。 先来看看网上说的改源码是怎么样改的: CCTableViewCell*CCTableView::dequeueCell() {...

windows的磁盘操作之八——格式化分区的思考

格式化分区平常在我们看来是再普通不过的操作了,点两下鼠标就可以搞定的事情,但是在程序中实现的的确确不太容易。可能有人说直接调个format命令不就好了,没错,但系统命令存在我们第一节http://cutebunny.blog.51cto.com/301216/624027中阐述的种种问题。 算上format命令,目前我发现有三种方法, 1.Windows...

abp vnext2.0核心组件之模块加载组件源码解析

abp vnext是abp官方在abp的基础之上构建的微服务框架,说实话,看完核心组件源码的时候,很兴奋,整个框架将组件化的细想运用的很好,真的超级解耦.老版整个框架依赖Castle的问题,vnext对其进行了解耦,支持AutoFac或者使用.Net Core的默认容器.vnext依然沿用EF core为主,其余ORM为辅助的思想,当然EF core来实现...

织网的日子里——第一章:TCP时间获取之客户端和服务器端程序

环境: Ubuntu10.04 g++ / gcc 4.4.3 特别标注: 有些网站转载我的文章不标明出处,并且转载不到位,没有把相应的链接一块转过去,比如说下载链接或相关文献的链接等,导致一些网友阅读和使用出现障碍和知识的不连续,所以在此特别标注:我的这篇文章发表在CSDN—— jasonque的博客上,可以到CSDN博客来阅读。 正文: 开始啃《UN...