主题 : 哪位大侠能帮忙分析下下面的程序结构~不尽感激~ 复制链接 | 浏览器收藏 | 打印
大家互相帮忙一下可以吗?请大家互相帮忙一下啊!
级别: 新手上路
UID: 27546
精华: 0
发帖: 40
金钱: 210 两
威望: 42 点
综合积分: 80 分
注册时间: 2010-08-27
最后登录: 2013-09-17
楼主  发表于: 2011-03-23 14:28

 哪位大侠能帮忙分析下下面的程序结构~不尽感激~

/*******************************************************************************
#                                                                              #
#      MJPG-streamer allows to stream JPG frames from an input-plugin          #
#      to several output plugins                                               #
#                                                                              #
#      Copyright (C) 2007 Tom St枚veken                                         #
#                                                                              #
# This program is free software; you can redistribute it and/or modify         #
# it under the terms of the GNU General Public License as published by         #
# the Free Software Foundation; version 2 of the License.                      #
#                                                                              #
# This program is distributed in the hope that it will be useful,              #
# but WITHOUT ANY WARRANTY; without even the implied warranty of               #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                #
# GNU General Public License for more details.                                 #
#                                                                              #
# You should have received a copy of the GNU General Public License            #
# along with this program; if not, write to the Free Software                  #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA    #
#                                                                              #
*******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <linux/videodev.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <getopt.h>
#include <pthread.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <syslog.h>

///yumen+++++++++++++                                                                                  
#include <sys/select.h>                                                                              
#include <sys/time.h>                                                                                
#include <string.h>
///yumen++++++++++++


#include "utils.h"
#include "mjpg_streamer.h"

/* globals */
static globals global;


///yumen++++++++++++++++
static int led_fd;                                                                                  
static int type = 1;                                                                                
static int period = 1;  
///yumen+++++++++++++


/******************************************************************************
Description.: Display a help message
Input Value.: argv[0] is the program name and the parameter progname
Return Value: -
******************************************************************************/
void help(char *progname)
{
  fprintf(stderr, "-----------------------------------------------------------------------\n");
  fprintf(stderr, "Usage: %s\n" \
                  "  -i | --input \"<input-plugin.so> [parameters]\"\n" \
                  "  -o | --output \"<output-plugin.so> [parameters]\"\n" \
                  " [-h | --help ]........: display this help\n" \
                  " [-v | --version ].....: display version information\n" \
                  " [-b | --background]...: fork to the background, daemon mode\n", progname);
  fprintf(stderr, "-----------------------------------------------------------------------\n");
  fprintf(stderr, "Example #1:\n" \
                  " To open an UVC webcam \"/dev/video1\" and stream it via HTTP:\n" \
                  "  %s -i \"input_uvc.so -d /dev/video1\" -o \"output_http.so\"\n", progname);
  fprintf(stderr, "-----------------------------------------------------------------------\n");
  fprintf(stderr, "Example #2:\n" \
                  " To open an UVC webcam and stream via HTTP port 8090:\n" \
                  "  %s -i \"input_uvc.so\" -o \"output_http.so -p 8090\"\n", progname);
  fprintf(stderr, "-----------------------------------------------------------------------\n");
  fprintf(stderr, "Example #3:\n" \
                  " To get help for a certain input plugin:\n" \
                  "  %s -i \"input_uvc.so --help\"\n", progname);
  fprintf(stderr, "-----------------------------------------------------------------------\n");
  fprintf(stderr, "In case the modules (=plugins) can not be found:\n" \
                  " * Set the default search path for the modules with:\n" \
                  "   export LD_LIBRARY_PATH=/path/to/plugins,\n" \
                  " * or put the plugins into the \"/lib/\" or \"/usr/lib\" folder,\n" \
                  " * or instead of just providing the plugin file name, use a complete\n" \
                  "   path and filename:\n" \
                  "   %s -i \"/path/to/modules/input_uvc.so\"\n", progname);
  fprintf(stderr, "-----------------------------------------------------------------------\n");
}

/******************************************************************************
Description.: pressing CTRL+C sends signals to this process instead of just
              killing it plugins can tidily shutdown and free allocated
              ressources. The function prototype is defined by the system,
              because it is a callback function.
Input Value.: sig tells us which signal was received
Return Value: -
******************************************************************************/
void signal_handler(int sig)
{
  int i;

  /* signal "stop" to threads */
  LOG("setting signal to stop\n");
  global.stop = 1;
  usleep(1000*1000);

  /* clean up threads */
  LOG("force cancelation of threads and cleanup ressources\n");
  global.in.stop();
  for(i=0; i<global.outcnt; i++) {
    global.out.stop(global.out.param.id);
  }
  usleep(1000*1000);

  /* close handles of input plugins */
  dlclose(&global.in.handle);
  for(i=0; i<global.outcnt; i++) {
    /* skip = 0;
    DBG("about to decrement usage counter for handle of %s, id #%02d, handle: %p\n", \
        global.out.plugin, global.out.param.id, global.out.handle);
    for(j=i+1; j<global.outcnt; j++) {
      if ( global.out.handle == global.out[j].handle ) {
        DBG("handles are pointing to the same destination (%p == %p)\n", global.out.handle, global.out[j].handle);
        skip = 1;
      }
    }
    if ( skip ) {
      continue;
    }

    DBG("closing handle %p\n", global.out.handle);
    */
    dlclose(global.out.handle);
  }
  DBG("all plugin handles closed\n");

  pthread_cond_destroy(&global.db_update);
  pthread_mutex_destroy(&global.db);

  LOG("done\n");

  closelog();
  exit(0);
  return;
}

///yumen+++++++++++++++++++++++++++++++++++++

static void push_leds(void)                                                                       {    
    switch(type)                                                                                
    {                                                                                            
    case 0:                                                                                      
        {                                                                                    
                                                                                        
            ioctl(led_fd, 1, 0);                                                        
            ioctl(led_fd, 0, 1);                                                        
                                                                                        
        }                                                                                    
        break;                                                                              
    case 1:                                                                                      
        {                                                                                    
                                                                                        
            ioctl(led_fd, 0, 0);                                                        
            ioctl(led_fd, 1, 1);                                                        
                                                                                        
        }                                                                                    
        break;                                                                              
    default:                                                                                    
        {                                                                                    
            ioctl(led_fd, 0, 0);                                                        
            ioctl(led_fd, 0, 1);                                                        
                                                                                        
        }                                                                                    
    }                                                                                            
}

int damo_player(void)
{
    int led_control_pipe;                                                                        
    int null_writer_fd; // for read endpoint not blocking when control process exit              
                                                                                                    
                                                                                                    
    led_fd = open("/dev/dynamo", 0);                                                            
    if (led_fd < 0)                                                                              
    {                                                                                            
        led_fd = open("/dev/dynamo", 0);                                                    
    }                                                                                            
    if (led_fd < 0)                                                                              
    {                                                                                            
        perror("open device dynamo");                                                        
        exit(1);                                                                            
    }                                                                                            
    unlink("/tmp/led-control");                                                                  
    mkfifo("/tmp/led-control", 0666);                                                          
                                                                                                
                                                                                                    
    fprintf(stderr, "Yumen-ok %d, open-dynamo %d\n", type, period);                              
                                                                                                    
                                                                                                    
    led_control_pipe = open("/tmp/led-control", O_RDONLY | O_NONBLOCK);                          
    if (led_control_pipe < 0)                                                                    
    {                                                                                            
        perror("open control pipe for read");                                                
        exit(1);                                                                            
    }                                                                                            
                                                                                                
    null_writer_fd = open("/tmp/led-control", O_WRONLY | O_NONBLOCK);                            
    if (null_writer_fd < 0)                                                                      
    {                                                                                            
        perror("open control pipe for write");                                              
        exit(1);                                                                            
    }                                                                                            
                                                                                                    
    for (;;)                                                                                    
    {                                                                                            
        fd_set rds;                                                                          
                                                                                                    
        int ret;                                                                            
                                                                                                    
                                                                                                    
                                                                                                    
               // push_leds();       ///////////                                                
                                                                                                    
                                                                                                    
                                                                                                    
        FD_ZERO(&rds);                                                                      
        FD_SET(led_control_pipe, &rds);                                                      
                                                                                                    
        ret = select(led_control_pipe + 1, &rds, NULL, NULL, NULL);                          
        if (ret < 0)                                                                        
        {                                                                                    
            perror("select");                                                            
            exit(1);                                                                    
        }                                                                                    
        if (ret == 0)                                                                        
        {                                                                                    
            push_leds();                                                                
        }                                                                                    
        else if (FD_ISSET(led_control_pipe, &rds))                                          
         {                                                                                  
            static char buffer[200];                                                    
            for (;;)                                                                    
            {                                                                            
                char c;                                                              
                int len = strlen(buffer);                                            
                                                                                                    
                                                                                                    
                push_leds();       ///////////                                      
                                                                                                    
                                                                                                    
                if (len >= sizeof buffer - 1)                                        
                {                                                                    
                    memset(buffer, 0, sizeof buffer);                            
                    break;                                                      
                }                                                                    
                if (read(led_control_pipe, &c, 1) != 1)                              
                {                                                                    
                    break;                                                      
                }                                                                    
                if (c == '\r')                                                      
                {                                                                    
                    continue;                                                    
                }                                                                    
                if (c == '\n')                                                      
                {                                                                    
                    int tmp_type;                                                
                    double tmp_period;                                          
                    if (sscanf(buffer,"%d%lf", &tmp_type, &tmp_period) == 2)    
                    {                                                            
                        type = tmp_type;                                    
                        period = tmp_period;                                
                    }                                                            
                    fprintf(stderr, "type is %d, period is %d\n", type, period);
                                                                                                    
                                                                                                    
                     push_leds();       ///////////                              
                                                                                                    
                                                                                                    
                    memset(buffer, 0, sizeof buffer);                            
                    break;                                                      
                }                                                                    
                buffer[len] = c;                                                    
            }                                                                            
        }                                                                                    
    }                                                                                            
                                                                                                    
    close(led_fd);                                                                              
    return 0;      
}
////yumen++++++++++++++++++++++++++++++++++=

/****************************************************************************
Description.:
Input Value.:
Return Value:
******************************************************************************/
int main(int argc, char *argv[])
{
  char *input  = "input_uvc.so --resolution 640x480 --fps 5 --device /dev/video0";
  char *output[MAX_OUTPUT_PLUGINS];
  int daemon=0, i;
  size_t tmp=0;

  output[0] = "output_http.so --port 8080";
  global.outcnt = 0;

  /* parameter parsing */
  while(1) {
    int option_index = 0, c=0;
    static struct option long_options[] = \
    {
      {"h", no_argument, 0, 0},
      {"help", no_argument, 0, 0},
      {"i", required_argument, 0, 0},
      {"input", required_argument, 0, 0},
      {"o", required_argument, 0, 0},
      {"output", required_argument, 0, 0},
      {"v", no_argument, 0, 0},
      {"version", no_argument, 0, 0},
      {"b", no_argument, 0, 0},
      {"background", no_argument, 0, 0},
      {0, 0, 0, 0}
    };

    c = getopt_long_only(argc, argv, "", long_options, &option_index);

    /* no more options to parse */
    if (c == -1) break;

    /* unrecognized option */
    if(c=='?'){ help(argv[0]); return 0; }

    switch (option_index) {
      /* h, help */
      case 0:
      case 1:
        help(argv[0]);
        return 0;
        break;

      /* i, input */
      case 2:
      case 3:
        input = strdup(optarg);
        break;

      /* o, output */
      case 4:
      case 5:
        output[global.outcnt++] = strdup(optarg);
        break;

      /* v, version */
      case 6:
      case 7:
        printf("MJPG Streamer Version: %s\n" \
               "Compilation Date.....: %s\n" \
               "Compilation Time.....: %s\n", SOURCE_VERSION, __DATE__, __TIME__);
        return 0;
        break;

      /* b, background */
      case 8:
      case 9:
        daemon=1;
        break;

      default:
        help(argv[0]);
        return 0;
    }
  }
  
  openlog("MJPG-streamer ", LOG_PID|LOG_CONS, LOG_USER);
  //openlog("MJPG-streamer ", LOG_PID|LOG_CONS|LOG_PERROR, LOG_USER);
  syslog(LOG_INFO, "starting application");

  /* fork to the background */
  if ( daemon ) {
    LOG("enabling daemon mode");
    daemon_mode();
  }

  /* initialise the global variables */
  global.stop      = 0;
  global.buf       = NULL;
  global.size      = 0;
  global.in.plugin = NULL;

  /* this mutex and the conditional variable are used to synchronize access to the global picture buffer */
  if( pthread_mutex_init(&global.db, NULL) != 0 ) {
    LOG("could not initialize mutex variable\n");
    closelog();
    exit(EXIT_FAILURE);
  }
  if( pthread_cond_init(&global.db_update, NULL) != 0 ) {
    LOG("could not initialize condition variable\n");
    closelog();
    exit(EXIT_FAILURE);
  }

  /* ignore SIGPIPE (send by OS if transmitting to closed TCP sockets) */
  signal(SIGPIPE, SIG_IGN);

  /* register signal handler for <CTRL>+C in order to clean up */
  if (signal(SIGINT, signal_handler) == SIG_ERR) {
    LOG("could not register signal handler\n");
    closelog();
    exit(EXIT_FAILURE);
  }

  /*
   * messages like the following will only be visible on your terminal
   * if not running in daemon mode
   */
  LOG("MJPG Streamer Version.: %s\n", SOURCE_VERSION);

  /* check if at least one output plugin was selected */
  if ( global.outcnt == 0 ) {
    /* no? Then use the default plugin instead */
    global.outcnt = 1;
  }

  /* open input plugin */
  tmp = (size_t)(strchr(input, ' ')-input);
  global.in.plugin = (tmp > 0)?strndup(input, tmp):strdup(input);
  global.in.handle = dlopen(global.in.plugin, RTLD_LAZY);
  if ( !global.in.handle ) {
    LOG("ERROR: could not find input plugin\n");
    LOG("       Perhaps you want to adjust the search path with:\n");
    LOG("       # export LD_LIBRARY_PATH=/path/to/plugin/folder\n");
    LOG("       dlopen: %s\n", dlerror() );
    closelog();
    exit(EXIT_FAILURE);
  }
  global.in.init = dlsym(global.in.handle, "input_init");
  if ( global.in.init == NULL ) {
    LOG("%s\n", dlerror());
    exit(EXIT_FAILURE);
  }
  global.in.stop = dlsym(global.in.handle, "input_stop");
  if ( global.in.stop == NULL ) {
    LOG("%s\n", dlerror());
    exit(EXIT_FAILURE);
  }
  global.in.run = dlsym(global.in.handle, "input_run");
  if ( global.in.run == NULL ) {
    LOG("%s\n", dlerror());
    exit(EXIT_FAILURE);
  }
  /* try to find optional command */
  global.in.cmd = dlsym(global.in.handle, "input_cmd");

  global.in.param.parameter_string = strchr(input, ' ');
  global.in.param.global = &global;

  if ( global.in.init(&global.in.param) ) {
    LOG("input_init() return value signals to exit");
    closelog();
    exit(0);
  }

  /* open output plugin */
  for (i=0; i<global.outcnt; i++) {
      
      ///yumen+++
      damo_player( );
      ///yumem+++
      
    tmp = (size_t)(strchr(output, ' ')-output);
    global.out.plugin = (tmp > 0)?strndup(output, tmp):strdup(output);
    global.out.handle = dlopen(global.out.plugin, RTLD_LAZY);
    if ( !global.out.handle ) {
      LOG("ERROR: could not find output plugin %s\n", global.out.plugin);
      LOG("       Perhaps you want to adjust the search path with:\n");
      LOG("       # export LD_LIBRARY_PATH=/path/to/plugin/folder\n");
      LOG("       dlopen: %s\n", dlerror() );
      closelog();
      exit(EXIT_FAILURE);
    }
    global.out.init = dlsym(global.out.handle, "output_init");
    if ( global.out.init == NULL ) {
      LOG("%s\n", dlerror());
      exit(EXIT_FAILURE);
    }
    global.out.stop = dlsym(global.out.handle, "output_stop");
    if ( global.out.stop == NULL ) {
      LOG("%s\n", dlerror());
      exit(EXIT_FAILURE);
    }
    global.out.run = dlsym(global.out.handle, "output_run");
    if ( global.out.run == NULL ) {
      LOG("%s\n", dlerror());
      exit(EXIT_FAILURE);
    }
    /* try to find optional command */
    global.out.cmd = dlsym(global.out.handle, "output_cmd");

    global.out.param.parameter_string = strchr(output, ' ');
    global.out.param.global = &global;
    global.out.param.id = i;
    if ( global.out.init(&global.out.param) ) {
      LOG("output_init() return value signals to exit");
      closelog();
      exit(0);
    }
  }

  /* start to read the input, push pictures into global buffer */
  DBG("starting input plugin\n");
  syslog(LOG_INFO, "starting input plugin");
  global.in.run();

  DBG("starting %d output plugin(s)\n", global.outcnt);
  for(i=0; i<global.outcnt; i++) {
    syslog(LOG_INFO, "starting output plugin: %s (ID: %02d)", global.out.plugin, global.out.param.id);
    global.out.run(global.out.param.id);
  }

  /* wait for signals */
  pause();

  return 0;
}
级别: 新手上路
UID: 45907
精华: 0
发帖: 1
金钱: 5 两
威望: 1 点
综合积分: 2 分
注册时间: 2011-05-09
最后登录: 2011-05-09
1楼  发表于: 2011-05-09 10:19

 回 楼主(weiqifa0) 的帖子

你这个程序搞定没?搞定的话发给我一下啊,急需,谢谢啦
级别: 新手上路
UID: 32670
精华: 0
发帖: 38
金钱: 190 两
威望: 38 点
综合积分: 76 分
注册时间: 2010-11-19
最后登录: 2012-07-26
2楼  发表于: 2011-06-30 09:58
和楼上同求啊,源码搞不懂,做个屁项目啊shwen@mail.ustc.edu.cn