lavrec.c
来自「Motion JPEG编解码器源代码」· C语言 代码 · 共 1,166 行 · 第 1/3 页
C
1,166 行
if (nerr==0) /* channel list - get the channel spec */ { /*printf("channel list count is %d\n", chanlists[chlist].count); */ while (strcmp((chanlists[chlist].list)[chan].name, &(value[colin+1]))!=0) { chan++; if (chan > (chanlists[chlist].count)) { mjpeg_error("bad channel spec (see e g xawtv, channel editor, for channel spec)"); nerr++; break; } /*printf("Searching for channel: chan: %d %s\n", chan, (chanlists[chlist].list)[chan].name);*/ } } if (nerr==0) while (strcmp((chanlists[chlist].list)[chan].name, &(value[colin+1]))!=0) { if ((chanlists[chlist].list)[chan++].name==NULL) { mjpeg_error("bad channel spec"); nerr++; } } if (nerr==0) { printf("Ok, found channel %s with frequency %d\n", (chanlists[chlist].list)[chan].name, (chanlists[chlist].list)[chan].freq); info->tuner_frequency=(chanlists[chlist].list)[chan].freq; } } else if (strcmp(name, "software-encoding")==0) { info->software_encoding = 1; /* set the number of enoding processes to the number of processors */ if (info->num_encoders == 0) info->num_encoders = sysconf(_SC_NPROCESSORS_ONLN); } else if (strcmp(name, "num-procs")==0) { info->num_encoders = atoi(value); } else if (strcmp(name, "max-file-size")==0) { info->max_file_size_mb = atoi(optarg); } else if (strcmp(name, "max-file-frames")==0) { info->max_file_frames = atoi(optarg); } else if (strcmp(name, "file-flush")==0) { info->flush_count = atoi(optarg); if( info->flush_count < 0 ) info->flush_count = 0; } else nerr++; /* unknown option - error */ return nerr;}static void check_command_line_options(int argc, char *argv[]){ int n, nerr, option_index = 0; char option[2]; char* dotptr;#ifdef HAVE_GETOPT_LONG /* getopt_long options */ static struct option long_options[]={ {"format" ,1,0,0}, /* -f/--format */ {"input" ,1,0,0}, /* -i/--input */ {"decimation" ,1,0,0}, /* -d/--decimation */ {"verbose" ,1,0,0}, /* -v/--verbose */ {"quality" ,1,0,0}, /* -q/--quality */ {"geometry" ,1,0,0}, /* -g/--geometry */ {"time" ,1,0,0}, /* -t/--time */ {"single-frame" ,1,0,0}, /* -S/--single-frame */ {"time-lapse" ,1,0,0}, /* -T/--time-lapse */ {"wait" ,0,0,0}, /* -w/--wait */ {"batch" ,0,0,0}, /* -b/--batch */ {"audio-bitsize" ,1,0,0}, /* -a/--audio-size */ {"audio-bitrate" ,1,0,0}, /* -r/--audio-rate */ {"stereo" ,0,0,0}, /* -s/--stereo */ {"audio-volume" ,1,0,0}, /* -l/--audio-volume */ {"mute" ,0,0,0}, /* -m/--mute */ {"audio-source" ,1,0,0}, /* -R/--audio-source */ {"synchronization" ,1,0,0}, /* -c/--synchronization */ {"mjpeg-buffers" ,1,0,0}, /* -n/--mjpeg_buffers */ {"mjpeg-buffer-size",1,0,0}, /* -b/--mjpeg-buffer-size */ {"channel" ,1,0,0}, /* -C/--channel */ {"use-read" ,0,0,0}, /* -U/--use-read */ {"software-encoding",0,0,0}, /* --software-encoding */ {"num-procs" ,1,0,0}, /* --num-procs */ {"max-file-size" ,1,0,0}, /* --max-file-size */ {"max-file-frames" ,1,0,0}, /* --max-file-frames */ {"file-flush" ,1,0,0}, /* --file-flush */ {"frequency" ,1,0,0}, /* --frequency/-F */ {0,0,0,0} };#endif /* check usage */ if (argc < 2) Usage(argv[0]); /* Get options */ nerr = 0;#ifdef HAVE_GETOPT_LONG while( (n=getopt_long(argc,argv,"v:f:i:d:g:q:t:ST:wa:r:sl:mUBR:c:n:b:C:F:", long_options, &option_index)) != EOF)#else while( (n=getopt(argc,argv,"v:f:i:d:g:q:t:ST:wa:r:sl:mUBR:c:n:b:C:F:")) != EOF)#endif { switch(n) {#ifdef HAVE_GETOPT_LONG /* getopt_long values */ case 0: nerr += set_option(long_options[option_index].name, optarg); break;#endif /* These are the old getopt-values (non-long) */ default: sprintf(option, "%c", n); nerr += set_option(option, optarg); break; } } if (getenv("LAV_VIDEO_DEV")) info->video_dev = getenv("LAV_VIDEO_DEV"); else { struct stat vstat; if((stat("/dev/video", &vstat) == 0) && S_ISCHR(vstat.st_mode)) info->video_dev = "/dev/video"; else if(stat("/dev/video0", &vstat) == 0 && S_ISCHR(vstat.st_mode)) info->video_dev = "/dev/video0"; else if(stat("/dev/v4l/video0", &vstat) == 0 && S_ISCHR(vstat.st_mode)) info->video_dev = "/dev/v4l/video0"; else if(stat("/dev/v4l0", &vstat) == 0 && S_ISCHR(vstat.st_mode)) info->video_dev = "/dev/v4l0"; else if(stat("/dev/v4l", &vstat) == 0 && S_ISCHR(vstat.st_mode)) info->video_dev = "/dev/v4l"; } if (getenv("LAV_AUDIO_DEV")) info->audio_dev = getenv("LAV_AUDIO_DEV"); else { struct stat astat; if(stat("/dev/dsp", &astat) == 0 && S_ISCHR(astat.st_mode)) info->audio_dev = "/dev/dsp"; else if(stat("/dev/sound/dsp", &astat) == 0 && S_ISCHR(astat.st_mode)) info->audio_dev = "/dev/sound/dsp"; else if(stat("/dev/audio", &astat) == 0 && S_ISCHR(astat.st_mode)) info->audio_dev = "/dev/audio"; } if (getenv("LAV_MIXER_DEV")) info->mixer_dev = getenv("LAV_MIXER_DEV"); else { struct stat mstat; if(stat("/dev/mixer", &mstat) == 0 && S_ISCHR(mstat.st_mode)) info->mixer_dev = "/dev/mixer"; else if(stat("/dev/sound/mixer", &mstat) == 0 && S_ISCHR(mstat.st_mode)) info->mixer_dev = "/dev/sound/mixer"; } if(optind>=argc) nerr++; if(nerr) Usage(argv[0]); mjpeg_default_handler_verbosity(verbose); /* disable audio for jpeg */ if (info->video_format == 'j') info->audio_size = 0; info->num_files = argc - optind; info->files = argv + optind; /* If the first filename contains a '%', the user wants file patterns */ if(strstr(argv[optind],"%")) info->num_files = 0; /* Try to guess the file type by looking at the extension. */ if(info->video_format == '\0') { if((dotptr = strrchr(argv[optind], '.'))) {#ifdef HAVE_LIBQUICKTIME if(!strcasecmp(dotptr+1, "mov") || !strcasecmp(dotptr+1, "qt") || !strcasecmp(dotptr+1, "moov")) info->video_format = 'q';#endif if(!strcasecmp(dotptr+1, "avi")) info->video_format = 'a'; } if(info->video_format == '\0') info->video_format = 'a'; }}/* Simply prints recording parameters */static void lavrec_print_properties(void){ const char *source; char *tmsg; mjpeg_info("Recording parameters:"); if (info->video_format=='q') tmsg = "Quicktime"; else if (info->video_format=='j') tmsg = "JPEG"; else tmsg = "AVI"; mjpeg_info("Output format: %s", tmsg); switch(input_source) { case 'p': source = info->software_encoding?"BT8x8 1st input PAL\n":"Composite PAL\n"; break; case 'P': source = info->software_encoding?"BT8x8 2nd input PAL\n":"S-Video PAL\n"; break; case 'n': source = info->software_encoding?"BT8x8 1st input NTSC\n":"Composite NTSC\n"; break; case 'N': source = info->software_encoding?"BT8x8 2nd input PAL\n":"S-Video NTSC\n"; break; case 's': source = info->software_encoding?"BT8x8 1st input SECAM\n":"Composite SECAM\n"; break; case 'S': source = info->software_encoding?"BT8x8 2nd input PAL\n":"S-Video SECAM\n"; break; case 't': source = info->software_encoding?"BT8x8 3rd input PAL\n":"PAL TV-tuner\n"; break; case 'T': source = info->software_encoding?"BT8x8 3rd input PAL\n":"NTSC TV-tuner\n"; break; case 'f': source = info->software_encoding?"BT8x8 3rd input PAL\n":"SECAM TV-tuner\n"; break; default: source = "Auto detect\n"; } mjpeg_info("Input Source: %s", source); if(info->horizontal_decimation == info->vertical_decimation) mjpeg_info("Decimation: %d", info->horizontal_decimation); else mjpeg_info("Decimation: %d (hor) x %d (ver)", info->horizontal_decimation, info->vertical_decimation); mjpeg_info("Quality: %d",info->quality); mjpeg_info("Recording time: %d sec",info->record_time); if(info->time_lapse>1) mjpeg_info("Time lapse factor: %d",info->time_lapse); mjpeg_info(" "); mjpeg_info("MJPEG buffer size: %d KB",info->MJPG_bufsize); mjpeg_info("# of MJPEG buffers: %d",info->MJPG_numbufs); if(info->audio_size) { mjpeg_info("Audio parameters:"); mjpeg_info("Audio sample size: %d bit",info->audio_size); mjpeg_info("Audio sampling rate: %d Hz",info->audio_rate); mjpeg_info("Audio is %s",info->stereo ? "STEREO" : "MONO"); if(info->audio_level!=-1) { mjpeg_info("Audio input recording level: %d%%", info->audio_level); mjpeg_info("%s audio output during recording", info->mute?"Mute":"Don\'t mute"); mjpeg_info("Recording source: %c",info->audio_src); } else mjpeg_info("Audio input recording level: Use mixer setting"); mjpeg_info("Level of correction for Audio/Video synchronization:"); switch(info->sync_correction) { case 0: mjpeg_info("No lost frame compensation, No frame drop/insert"); break; case 1: mjpeg_info("Lost frame compensation, No frame drop/insert"); break; case 2: mjpeg_info("Lost frame compensation and frame drop/insert"); break; } } else mjpeg_info("Audio disabled");}static void print_summary(void){ MPEG_timecode_t tc; mpeg_timecode(&tc, num_frames, ((info->video_norm==1)?4:3), ((info->video_norm==1)?(30000/1001):25.)); printf("Recording time : %2d.%2.2d.%2.2d:%2.2d\n" "Lost frames : %3.3d\n" "A/V sync ins/del: %3.3d/%3.3d\n" "Audio errors : %3.3d\n", tc.h, tc.m, tc.s, tc.f, num_lost, num_ins, num_del, num_aerr);}static void *signal_catcher_thread (void * arg){ sigset_t * sigs = arg; int sig; sigwait(sigs, &sig); lavrec_stop(info); return 0;}static voidsignal_forwarder (int sig){ pthread_kill(signal_thread, sig);}static voidforward_signals (sigset_t * sigs){ struct sigaction sa; int sig; sa.sa_handler = signal_forwarder; sigfillset(&sa.sa_mask); sa.sa_flags = SA_RESTART; for (sig = 1; sig < 32; sig++) if (sigismember(sigs, sig) > 0) sigaction(sig, &sa, 0); pthread_sigmask(SIG_UNBLOCK, sigs, 0);}int main(int argc, char **argv){ sigset_t sigmask; pthread_t input_thread; /* no root please (only during audio setup) */ if (getuid() != geteuid()) { if (setfsuid(getuid()) < 0) { mjpeg_error("Failed to set filesystem user ID: %s", strerror(errno)); return 0; } } info = lavrec_malloc(); info->state_changed = statechanged; info->msg_callback = input; check_command_line_options(argc, argv); lavrec_print_properties();/* if( batch_mode ) *//* info->output_statistics = batch_stats; *//* else */ info->output_statistics = output_stats; sem_init(&state_changed, 0, 0); state = LAVREC_STATE_PAUSED; /* Block all signals */ sigfillset(&sigmask); pthread_sigmask(SIG_SETMASK, &sigmask, 0); sigemptyset(&sigmask); sigaddset(&sigmask, SIGHUP); sigaddset(&sigmask, SIGINT); sigaddset(&sigmask, SIGQUIT); sigaddset(&sigmask, SIGTERM); /* Start signal catching thread */ pthread_create(&signal_thread, NULL, signal_catcher_thread, &sigmask); /* Catch and forward selected signals to the signal catcher */ forward_signals(&sigmask); lavrec_main(info); if (!wait_for_start) lavrec_start(info); if (!batch_mode) pthread_create(&input_thread, NULL, user_input_thread, NULL); lavrec_busy(info); pthread_cancel(signal_thread); pthread_join(signal_thread, 0); if (!batch_mode) { pthread_cancel(input_thread); pthread_join(input_thread, 0); } sem_destroy(&state_changed); fprintf(stderr, "\n"); print_summary(); lavrec_free(info); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?