• mjpgstreamer源码分析


     

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

     

    Live together,or Die alone!
  • 相关阅读:
    虚拟机VirtualBox 共享挂载问题:mount: /mnt/xxx: wrong fs type, bad option, bad superblock on xxx
    git 设置和取消代理
    (转载)数据库连接池到底应该设多大?这篇文章可能会颠覆你的认知
    关于golang中IO相关的Buffer类浅析
    (转)golang获取当前时间、时间戳和时间字符串及它们之间的相互转换
    FFmpeg常用命令
    go cmd nohup 的坑
    Nginx配置详解(转)
    记录一次go性能调试的过程
    github徽标引入
  • 原文地址:https://www.cnblogs.com/hzhida/p/2523995.html
Copyright © 2020-2023  润新知