zoukankan      html  css  js  c++  java
  • mjpg-streamer摄像头远程传输UVC

      mjpg-streamer摄像头远程传输UVC


    1 下载源代码 

    mjpg-streamer的源代码地址  https://github.com/codewithpassion/mjpg-streamer

    嵌入式 mini2440版 https://github.com/vfonov/mjpg-streamer

    2 编译 

      mjpg-streamermake

    执行

    export LD_LIBRARY_PATH="$(pwd)"

    ./mjpg_streamer -i "./input_uvc.so -y" -o "./output_ http.so -w ./www" 


    电脑端 用火狐浏览器 输入  
    http://192.168.1.17:8080/?

    action=stream

    当中 192.168.1.17依据实际情况输入

    2源代码分析 

    从main開始 位于Mjpg_streamer.c 
    getopt_long_only:解析输入的參数
    global.in.init = dlsym(global.in.handle, "input_init"); // 让 global.in.init = input_init dlsym 取动态对象地址
    input_init (input_uvc.c )
    -->if (init_videoIn(videoIn, dev, width, height, fps, format, 1) < 0)
            init_videoIn(V4l2uvc.c (pluginsinput_uvc) 
                init_v4l2

    global.in.run = dlsym(global.in.handle, "input_run");
     input_run(input_uvc.c )
         -->pthread_create(&cam, 0, cam_thread, NULL);
            void *cam_thread( void *arg ) 
                 uvcGrab(videoIn) 
                if (videoIn->formatIn == V4L2_PIX_FMT_YUYV)
                      pglobal->size = compress_yuyv_to_jpeg(videoIn, pglobal->buf, videoIn->framesizeIn, gquality);
    else
      {
       pglobal->size = memcpy_picture(pglobal->buf, videoIn->tmpbuffer, videoIn->buf.bytesused);
      }

    global.out[i].init = dlsym(global.out[i].handle, "output_init"); 
      output_init(   output_http.c)
     servers[param->id].id = param->id;
     servers[param->id].pglobal = param->global;
     servers[param->id].conf.port = port;
     servers[param->id].conf.credentials = credentials;
     servers[param->id].conf.www_folder = www_folder;
     servers[param->id].conf.nocommands = nocommands;

    global.out[i].stop = dlsym(global.out[i].handle, "output_stop");
    output_stop
    pthread_cancel(servers[id].threadID);



    global.out[i].run = dlsym(global.out[i].handle, "output_run"); 

        output_run(output_http.c)
             pthread_create(&(servers[id].threadID), NULL, server_thread, &(servers[id])); // 创建一个线程 server_thread
             pthread_detach(servers[id].threadID); // 等待线程结束,以便回收

                server_thread (Httpd.cpluginsoutput_http)  
                      ->  client_thread
                            if ( strstr(buffer, "GET /?action=snapshot") != NULL )
     {
      req.type = A_SNAPSHOT; 
     }
     else if ( strstr(buffer, "GET /?action=stream") != NULL )
     {
      req.type = A_STREAM; 
     }
     else if ( strstr(buffer, "GET /?action=command") != NULL )
     {
                                req.type = A_COMMAND;
                        }

            switch ( req.type ){
    case A_SNAPSHOT:
       DBG("Request for snapshot ");
       send_snapshot(lcfd.fd);
       break;
      case A_STREAM:
       DBG("Request for stream ");
       send_stream(lcfd.fd);
       break;
    }


  • 相关阅读:
    SpringMVC的DispatcherServlet加载过程
    SpringMVC-HandlerMapping和HandlerAdapter
    FactoryBean简介
    Spring IOC过程
    redis基本数据类型和对应的底层数据结构
    工厂模式
    springmvc工作原理
    Java虚拟机系列-Java类加载机制
    2019年10月21日 数据库sql只取最新一条的数据
    洛谷 P2606 [ZJOI2010]排列计数
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5093551.html
Copyright © 2011-2022 走看看