int main(int argc, char ** argv) { mode = program_mode(argv[0]); /* Initialise settings from configuration files. */ dvswitch_read_config(handle_config); /* Parse arguments. */ int opt; while ((opt = getopt_long(argc, argv, "c:h:p:i:t", options, NULL)) != -1) { switch (opt) { case 'c': free(firewire_card); firewire_card = strdup(optarg); break; case 'F': mode = mode_firewire; break; case 'V': mode = mode_v4l2; break; case 'h': free(mixer_host); mixer_host = strdup(optarg); break; case 'p': free(mixer_port); mixer_port = strdup(optarg); break; case 't': do_tally = 1; break; case 'i': { long id = strtoul(optarg, NULL, 10); mixer_id = (id < 255) ? id-1 : 255; } break; case 'H': /* --help */ usage(argv[0]); return 0; default: usage(argv[0]); return 2; } } if (optind != argc) { free(device_name); device_name = strdup(argv[optind++]); } if (!mixer_host || !mixer_port) { fprintf(stderr, "%s: mixer hostname and port not defined\n", argv[0]); return 2; } if (optind != argc) { fprintf(stderr, "%s: excess argument \"%s\"\n", argv[0], argv[optind]); usage(argv[0]); return 2; } if (mode == mode_firewire) { if (device_name) printf("INFO: Reading from Firewire device %s\n", device_name); else if (firewire_card) printf("INFO: Reading from Firewire card %s\n", firewire_card); else printf("INFO: Reading from first Firewire card with camera\n"); } else if (mode == mode_v4l2) { if (!device_name) device_name = "/dev/video"; printf("INFO: Reading from V4L2 device %s\n", device_name); } else { fprintf(stderr, "%s: mode not defined (Firewire or V4L2)\n", argv[0]); return 2; } /* Connect to the mixer, set that as stdout, and run dvgrab. */ printf("INFO: Connecting to %s:%s\n", mixer_host, mixer_port); int sock = create_connected_socket(mixer_host, mixer_port); assert(sock >= 0); /* create_connected_socket() should handle errors */ if (write(sock, do_tally ? GREETING_ACT_SOURCE : GREETING_SOURCE, GREETING_SIZE-1) != GREETING_SIZE-1) { perror("ERROR: write"); exit(1); } if (write(sock, &mixer_id, sizeof(mixer_id)) != sizeof(mixer_id)) { perror("ERROR: write"); exit(1); } if (do_tally) { fflush(NULL); int child_pid = fork(); if (child_pid < 0) { perror("ERROR: fork"); return 1; } if (child_pid == 0) { tally(sock); _exit(0); } } if (dup2(sock, STDOUT_FILENO) < 0) { perror("ERROR: dup2"); return 1; } close(sock); char * dvgrab_argv[7]; char ** argp = dvgrab_argv; *argp++ = "dvgrab"; if (mode == mode_v4l2) *argp++ = "-v4l2"; if (device_name) { *argp++ = "-input"; *argp++ = device_name; } else if (firewire_card) { *argp++ = "-card"; *argp++ = firewire_card; } *argp++ = "-noavc"; *argp++ = "-"; *argp = NULL; assert(argp < dvgrab_argv + sizeof(dvgrab_argv) / sizeof(dvgrab_argv[0])); execvp("dvgrab", dvgrab_argv); perror("ERROR: execvp"); return 1; }
int main(int argc, char ** argv) { // Initialise settings from configuration files. dvswitch_read_config(handle_config); // Parse arguments. int opt; while ((opt = getopt_long(argc, argv, "c:v", options, NULL)) != -1) { switch (opt) { case 'c': fw_port_name = optarg; break; case 'h': listen_host = optarg; break; case 'p': listen_port = optarg; break; case 'v': verbose = true; break; case 'H': // --help usage(argv[0]); return 0; default: usage(argv[0]); return 2; } } if (optind != argc) fw_port_name = argv[optind++]; if (optind != argc) { fprintf(stderr, "%s: excess argument \"%s\"\n", argv[0], argv[optind]); usage(argv[0]); return 2; } // Catch SIGINT. struct sigaction sigint_action; sigint_action.sa_handler = handle_sigint; sigemptyset(&sigint_action.sa_mask); sigint_action.sa_flags = SA_RESTART; if (sigaction(SIGINT, &sigint_action, NULL)) { perror("ERROR: sigaction"); return 1; } // Set up liveMedia framework BasicTaskScheduler * sched = BasicTaskScheduler::createNew(); BasicUsageEnvironment * env = BasicUsageEnvironment::createNew(*sched); RTSPServer * server = RTSPServer::createNew(*env, 8554, NULL); if (server == NULL) { *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n"; return 1; } OutPacketBuffer::maxSize = DIF_MAX_FRAME_SIZE; // Set up session std::string stream_name("firewire"); stream_name.append(fw_port_name); std::string stream_desc("DV stream from Firewire port "); stream_desc.append(fw_port_name); ServerMediaSession * sms = ServerMediaSession::createNew(*env, stream_name.c_str(), stream_desc.c_str(), stream_desc.c_str()); sms->addSubsession(new firewire_subsession(*env, fw_port_name)); server->addServerMediaSession(sms); // Loop until SIGINT received if (verbose) printf("INFO: Serving at rtsp://*:8554/%s\n", stream_name.c_str()); sched->doEventLoop(&received_sigint); env->reclaim(); return 0; }