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 + -
显示快捷键?