⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cc

📁 这个软件的功能同我上次传的那个avifile.也是linux上的一个用于多媒体应用的源码。
💻 CC
📖 第 1 页 / 共 3 页
字号:
/* Copyright (C) Bram Avontuur (bram@avontuur.org) */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include	<stdio.h>#include	<unistd.h>#ifdef		HAVE_STDLIB_H#include	<stdlib.h>#endif		/* HAVE_STDLIB_H */#include	<errno.h>#include	<ctype.h>#include <string.h>#include <sys/time.h>#include <ctype.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include	<fcntl.h>#include <iostream>/* Custom headerfiles */#include "vcr.h"#include <creators.h>using namespace Creators;using namespace std;#include <signal.h>#include <getopt.h>#include <avifile.h>#include <videoencoder.h>#include "capproc.h"#include "v4lxif.h"#include "global.h"#include "parseconfig.h"#include "channel.h"#include "frequencies.h"#include VCR_SOUNDCARD_Husing namespace std;/* External variables/functions *//* Function prototypes */void init_v4l();void vcr_debug(const char*);void usage();void parse_arguments(int, char*argv[]);void init_debug();void init_globals();void verify_globals();void end_program(int);short add_attribute(const char*);short set_attributes();int get_codec_index(int);char **split_string(const char *);short parse_config_file();short set_error(const char *);void show_error();void vcr_warning(const char *);void vcr_notice(const char *);void vcr_notice(string&);void vcr_notice(ostringstream&);int set_rectime(const char *);void clear_attributes();void list_attributes(int fourcc, int indent_level = 0);void list_codecs();/* Global variables *///enum cmdopts { OPT_struct codec_attr {	char *name;	char *val;} *attributes;static short mp3_bitrates[2][2][6] = {	{ //22 Khz		{ //mono			32, 48, 56, 64, 96, 112		},		{ //stereo			64, 80, 96, 112, 128, 160		}	},	{ //44 Khz		{	//mono			56, 64, 96, 112, 128, 160		},		{ //stereo			112, 128, 160, 192, 256, 320		}	}};static struct STRTAB norms[] = {    {  0, "PAL" },    {  1, "NTSC" },    {  2, "SECAM" },    {  3, "AUTO" },    { -1, NULL }};CaptureProcess *cap = NULL;v4lxif *v4l = NULL;FILE	*vcr_debug_file = NULL;short	want_debug,	verbose;char	*prog_name = NULL,	*codec_name = NULL,	*rectime_str = NULL,	*attributes_str = NULL,	*input_source,	*preset,	*filename,	*config_file,	*norm,	*audio_mode,	*freqtab,	*error = NULL,	*debugfile = NULL,	*window_str = NULL,	*codec_preset = NULL,	*init_sound = NULL,	*sound_device = NULL,	*grabdevice;int	rectime,	codecID,	keyframes,	quality,	normID,	audio_freq,	audio_size,	audio_bitrate = -1,	vertical_flip = -1,	resolution = 0,	splitsize = -1,	attr_count = 0,	resolution_width = 0,	resolution_height = 0;avm::vector<AttributeInfo>	encoder_info;float	fps;window_t window;enum Sound_Freqs soundfreq;enum Sample_Sizes samplesize;enum Sound_Chans soundchan;enum Resolutions videores;void stop_record_handler(int arg){	cerr << "Caught CTRL+C: Stopping capture.\n" << endl;	cap->stopRecord();	signal(SIGINT, SIG_IGN); //otherwise this function will be called again}voidend_program(int exit_status){	if (cap)		delete cap;	if (v4l)	{		v4l->setCapture(0);		v4l->setAudioMute(1);		delete v4l;	}		exit(exit_status);}/* Kinda quick & dirty ... */voidlist_audiobitrates(){	cerr << "Available mp3 bitrates: " << endl << endl;	int f_index = 0, m_index = 0, b_index = 0;	for (f_index = 0; f_index < 2; f_index++)	{		const char *khz = (f_index ? "44 Khz" : "22 Khz");		for (m_index = 0; m_index < 2; m_index++)		{			if (!m_index)				cerr << khz << " mono  : ";			else				cerr << khz << " stereo: ";			for (b_index = 0; b_index < 6; b_index++)				cerr << mp3_bitrates[f_index][m_index][b_index] << " ";						cerr << endl;		}	}}voidlist_norms(){	cerr << "Available norms: ";	int i = 0;	while (norms[i].nr > -1)	{		cerr << norms[i++].str << " ";	}		cerr << endl;}voidlist_resolutions(){	int i = 0;	cerr << "Possible video sizes:" << endl;	while (restable[i].res != WNONE)	{		cerr << restable[i].width << "x" << restable[i].height << 			" (config value: " << restable[i].width << ")" << endl;		i++;	}}voidlist_presets(){	cerr << "Available presets are:" << endl << endl;	char **list;	for (list = cfg_list_sections(); *list != NULL; list++)	{		if (			!strcmp(*list, "defaults") ||			!strcmp(*list, "global") ||			!strcmp(*list, "launch") ||			cfg_get_str(*list, "codec") //codec => codec preset		)			continue;		cerr << "\"" << *list << "\" ";	}	cerr << endl;}voidlist_codec_presets(){	cerr << "Available codec presets are:" << endl << endl;	char **list;	for (list = cfg_list_sections(); *list != NULL; list++)	{		if (			!strcmp(*list, "defaults") ||			!strcmp(*list, "global") ||			!strcmp(*list, "launch") ||			!cfg_get_str(*list, "codec") //codec => codec preset		)			continue;		cerr << "\"" << *list << "\" ";	}	cerr << endl;}voidlist_sources(){	int 		i,		nrsources;	if (!v4l)	{		init_v4l();		if (!v4l)		{			cerr << "Error opening video4linux device; cannot show input sources." <<				endl;			end_program(1);		}	}	cerr << "Available input sources: ";  	nrsources = v4l->capCapChannelC();	for (i = 0; i < nrsources; i++)	{		cerr << v4l->capChannelName(i);		cerr << (i != nrsources - 1 ? ", " : ".");	}	cerr << endl;}voidlist_codecs(){	avm::vector<const CodecInfo*> codecList;	avm::vector<const CodecInfo*>::const_iterator it;	cerr << "Available codecs: " << endl << endl;	CodecInfo::Get(codecList);	for ( it = codecList.begin(); it != codecList.end(); it++)	{		if ((*it)->kind == CodecInfo::DShow_Dec)			continue; //probably not a usable codec..				if (!((*it)->direction & CodecInfo::Encode))			continue; //only interested in codecs that can encode		const char *cname = (*it)->GetName();		cerr << "\"" << cname << "\"" << endl;		list_attributes((*it)->fourcc, 1);	}	cerr << endl;}voidlist_attributes(int fourcc, int indent_level){	int defval;	const char *def_str;	avm::vector<const CodecInfo*> codecList;	int idx;	string indent(indent_level, ' ');	idx = get_codec_index(fourcc);	if (idx < 0)		return;	CodecInfo::Get(codecList);	avm::vector<AttributeInfo> encinfo = codecList[idx]->encoder_info;	if (0 == encinfo.size())	{		cerr << indent << "There are no attributes for this codec." << endl;		return;	}	cerr << indent << "These attributes are supported for this codec:" << 		endl;	avm::vector<AttributeInfo>::const_iterator it;	for(it=encinfo.begin(); it!=encinfo.end(); it++)	{		ostringstream att;		att << "\"" << it->GetName() << "\"";		cerr << indent << "Attribute ";		cerr.width(22);		cerr << right << att.str() << ": ";		switch(it->kind)		{		case AttributeInfo::Integer:		{			int status = avm::CodecGetAttr(*(codecList[idx]), it->GetName(), &defval);			cerr << indent << "Type: integer (default value: ";			if (status)				cerr << "none";			else				cerr << defval;			cerr << ")" << endl;			break;		}		case AttributeInfo::Select:		{			avm::CodecGetAttr(*(codecList[idx]), it->GetName(), &defval);			cerr << indent << "Type: select (default value: " << 				(defval < (int)it->options.size() ? it->options[defval] : "unknown") <<				")" << endl;			cerr << indent << "=>Possible values: ";			avm::vector<avm::string>::const_iterator sit;			for (sit=(it->options).begin(); sit!=(it->options).end(); sit++)			{				cerr << sit->c_str() << " ";			}			cerr << endl;			break;		}		case AttributeInfo::String:			GetCodecAttr(*(codecList[idx]), it->GetName(), (const char **)&def_str);			cerr << indent << "Type: string (default value: " << def_str <<				")"<< endl;			break;		case AttributeInfo::Float:			cerr << "Type: float" << endl;			break;		default:			break;		}	}}voidlist_freqtabs(){	int i = 0;	cerr << "Supported frequency tables:" << endl << endl;	while (chanlist_names[i].nr != -1)	{		cerr << chanlist_names[i].str << endl;		i++;	}}voidinit_v4l(){	if (grabdevice)		v4l = new v4l1if(0, grabdevice);	else		v4l = new v4l1if(0, V4L_DEVICE);}voidvcr_debug(const char *txt){	if (vcr_debug_file)	{		fwrite(txt, sizeof(char), strlen(txt), vcr_debug_file);		fflush(vcr_debug_file);	}}voidusage(){	cerr << "vcr " << VERSION << ": non-interactive video recorder." << endl <<		"Usage: " << prog_name << " [options] filename" << endl << endl <<		"Options with an asterisk (*) support a parameter 'list', to list the " <<		"options you can choose from." << endl << endl <<		"Options:" << endl <<		"  -a,  --codec-attribute a=b    set codec attribute" << endl <<		" *-b,  --audiobitrate RATE      set mp3 compression bitrate" << endl <<		" *-c,  --codec CODEC            set encoding codec" << endl <<		"  -d,  --debug [DEBUG]          write debugging information to DEBUG" << endl <<		"  -F,  --framerate RATE         set framerate (default=25)" << endl <<		"  -f,  --config-file FILE       read FILE for configuration" << endl <<		"  -g,  --grabdevice DEVICE      use DEVICE as capture device" << endl <<		"  -h,  --help                   display help" << endl <<		"  -k,  --keyframes NUM          set group of picture count" << endl <<		"  -m,  --audiomode MODE         set audio-capture to mono or stereo" << endl <<		" *-P,  --codec-preset PRESET    Use codec preset" << endl <<		" *-p,  --preset STATION         tune v4l into STATION" << endl <<		"  -q,  --quality QUAL           set quality of encoding percentage" << endl <<		" *-r,  --resolution RES         set frame size ('-r list' for a list)" << endl <<		"  -S,  --splitsize SIZE         split file in chunks of SIZE Megabytes" << endl <<		" *-s,  --source                 v4l input source (default=Television)" << endl <<		"  -t,  --rectime TIME           set recording time (see 'man vcr')" << endl <<		"  -v,  --verbose                verbose output during capturing" << endl <<		"  -w,  --window X,Y,W,H         crop frame size:(X,Y)=top left, (W,H)=size" << endl <<		endl;}voidinit_globals(){	input_source = NULL;	want_debug = 0;	rectime = 0;	codec_name = NULL;	rectime_str = NULL;	codecID = -1;	normID = -1;	keyframes = 0;	quality = 0;	audio_freq = 0;	audio_size = 0;	audio_bitrate = -1; // 0 => no mp3 compression	resolution = 0;	fps = -1;	verbose = 0;		window.x = -1; // to force resize to full resolution when no window is specified		preset = NULL;	filename = NULL;	attributes = NULL;	attr_count = 0;	config_file = NULL;	error = NULL;	norm = NULL;	audio_mode = NULL;	cap = NULL;	freqtab = NULL;	grabdevice = NULL;	debugfile = NULL;	window_str = NULL;	codec_preset = NULL;	init_sound = NULL;	attributes_str = NULL;}voidinit_debug(){	if (!debugfile)	{		char *homedir = get_homedir(NULL);		char *dbfile = new char[strlen(homedir) + 255];		strcpy(dbfile, homedir);		free(homedir);		strcat(dbfile, "/.vcrdebug");		vcr_debug_file = fopen(dbfile, "a");		delete[] dbfile;	}	else		vcr_debug_file = fopen(debugfile, "a");	if (!vcr_debug_file)	{		cerr << "Could not open debug file." << endl;		end_program(1);	}	vcr_debug("VCR Debugging started!\n");}intis_valid_audiobitrate(int kbps, enum Sound_Chans mode, enum Sound_Freqs freq){	int i = 0;	short foundit = 0;	short m_index = (mode == Stereo ? 1 : 0);	short f_index = (freq == F44 ? 1 : 0);	for (i = 0; i < 6; i++)	{		if (kbps == (int)mp3_bitrates[f_index][m_index][i])		{			foundit = true;			break;		}	}	if (foundit)		return (kbps * 1000) / 8;	return -1;}intis_valid_norm(const char *n){	if (!n)		return -1;	int i = 0;	while (norms[i].nr > -1)	{		if (!strcasecmp(norms[i].str, n))		{			return norms[i].nr;		}		i++;	}	return -1;}/* returns -1 if codec does not exist. * Otherwise, the codec's unique ID */intis_valid_codec(const char *cname){	if (!cname)		return -1;	int		found_codec = -1;	avm::vector<const CodecInfo*> codecList;	CodecInfo::Get(codecList);	avm::vector<const CodecInfo*>::iterator it;	for (it = codecList.begin(); it != codecList.end(); it++)	{		if ( (*it)->kind == CodecInfo::DShow_Dec)			continue;		if (!strcasecmp(cname, (*it)->GetName()))		{			found_codec = (*it)->fourcc;			encoder_info = (*it)->encoder_info;			break;		}	}	return found_codec;}shortset_resolution(int width){	int i = 0;	while (restable[i].width != width && restable[i].res != WNONE)		i++;	if (restable[i].res == WNONE)			return 0;			videores = restable[i].res;	resolution_width = restable[i].width;	resolution_height = restable[i].height;	return 1;}/* sndstring format: [/sound/device:][mixer_device_name:]volume * initialize_sound returns < 0 in case of failure, and sets global * error variable. */shortinitialize_sound(const char *sndstring){	//no ":"'s: just the volume (of /dev/mixer:line)	//1 ":" device (starts with '/'), else mixerdevname	//2 ":" device:mixerdevname:volume	char		dev[strlen(sndstring)+20],		mixdev[strlen(sndstring)+20];	int		temp;	unsigned int		volume;	temp = sscanf(sndstring, "%[^:]:%[^:]:%u", dev, mixdev, &volume);	if (temp < 1 || temp > 3)		return 0;	if (temp == 1) //only sound is specified.	{		volume = (unsigned int)atoi(dev);		strcpy(dev, "/dev/mixer");		strcpy(mixdev, "line");	}	else if (temp == 2) //sound device OR mixer name, and volume	{		volume = (unsigned int)atoi(mixdev);		if (strlen(dev) && dev[0] == '/') //sound dev		{			strcpy(mixdev, "line");		}		else		{			strcpy(mixdev, dev);			strcpy(dev, "/dev/mixer");		}	}	if (!volume)	{		return set_error("Invalid recording device volume given. A sane value "\			"would probably be in the range of 70..100.");	}	if (!strlen(dev) || !strlen(mixdev))		return set_error("No (or empty) sound- or mixer device given.");	if (volume < 50)		vcr_warning("Recording device volume is very low!");		ostringstream s;	s << "Using mixer " << dev << ", mixer device " << mixdev <<		"with volume " << volume << " to record audio from.";	vcr_notice(s);	int		i,		mixer = open(dev, O_RDWR);	unsigned int		available_devs,		available_recdevs;	short		found_label = 0;	if (mixer < 0)		return set_error("Could not open sound device.");	ioctl(mixer, MIXER_READ(SOUND_MIXER_DEVMASK), &available_devs);	ioctl(mixer, MIXER_READ(SOUND_MIXER_RECMASK), &available_recdevs);	static const char *mixer_labels[] = SOUND_DEVICE_LABELS;		char		*cropped_label = NULL;	//if label's found, mixerdevice-ID == i	for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -