www.gusucode.com > 嵌入式linux系统的网络编程源码程序 > 嵌入式linux系统的网络编程源码程序/视频会议源码/main.cpp

    ///////////////////////////////////////////////////////
// FileName:	main.cpp
// Author:		b1gm0use
// Project:		myvideo

#include <qapplication.h>
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <poll.h>

#include "video_player.h"
#include "audio_player.h"
#include "network_ctrl.h"
#include "common.h"
#include "video.h"
#include "audio.h"
#include "network.h"
#include "avi.h"


using namespace std;

class network_send;
class network_cap;

///////////////////////////////////////////////////////
// Functions Declaration
///////////////////////////////////////////////////////

// 分析命令行内容
void parse_cmd ( int argc, char **argv, bool & zoom,
	const char *& video_dev, video_opt_t * video_opt, 
	const char *& audio_dev, bool & use_g723, 
	network_mode_t & net_mode, const char *& ip, 
	va_mode_t & va_mode, bool & show_local_video,
	bool & g723_high_bit_rate, bool & g723_voice_detect, 
	bool & use_multicast, const char *& mc_addr );

// 显示帮助
void show_help ( void );

// 对视频设备进行测试
extern void video_test ( const char * device, const char * filename );

///////////////////////////////////////////////////////
// Global Variables
///////////////////////////////////////////////////////

int verbose = 0;

///////////////////////////////////////////////////////
// Functions Implements
///////////////////////////////////////////////////////

int main( int argc, char **argv ) // {{{
{
	
	// Video Part Public Variables
	video_opt_t video_opt;
	video_opt.min_width = BASIC_WIDTH;
	video_opt.min_height = BASIC_HEIGHT;
	video_opt.factor = DEFAULT_FACTOR;
	video_opt.depth = DEFAULT_DEPTH;
	video_opt.palette = DEFAULT_PALETTE;
	video_opt.quality = DEFAULT_QUALITY;
	const char * video_dev = DEFAULT_VIDEO_DEVICE;

	// Audio Part Public Variables
	const char * audio_dev = DEFAULT_AUDIO_DEVICE;
	bool use_g723 = DEFAULT_USE_G723;
	bool g723_high_bit_rate = DEFAULT_G723_HIGH_BIT_RATE;
	bool g723_voice_detect = DEFAULT_G723_VOICE_DETECT;

	// Network Part Public Variables
	network_mode_t net_mode = STANDALONE;
	const char * ip = DEFAULT_IP;
	bool use_multicast = DEFAULT_USE_MULTICAST;
	const char * mc_addr = DEFAULT_MC_ADDR;

	// Other Part Public Variables
	va_mode_t va_mode = VIDEO_AUDIO;
	bool zoom = DEFAULT_ZOOM;
	bool show_local_video = false;


	verbose_output( 1, "parsing command arguments..." );

	// 分析命令行
	parse_cmd ( argc, argv, zoom, video_dev, &video_opt, 
		audio_dev, use_g723, net_mode, ip, va_mode, show_local_video,
		g723_high_bit_rate, g723_voice_detect, use_multicast, mc_addr );
	
	verbose_output( 1, "create a application." );

	// 设置程序外观
	QApplication::setColorSpec( QApplication::CustomColor );

	QApplication::setFont( QFont( "Helvetica", 12 ) );
	QApplication a( argc, argv );

	verbose_output( 1, "create main widget." );


	////////////////////////////////////////////////////////
	////////////////   first part    ///////////////////////
	
	avi * avi_ptr = new avi( 0, "AVI" );

	avi_ptr->init_video( video_dev, &video_opt/* , 
			video_send_semaphore, video_cap_semaphore */ );
	avi_ptr->init_audio( audio_dev, use_g723, 
			g723_high_bit_rate, g723_voice_detect/* , 
			audio_can_play_semaphore, audio_cap_semaphore, 
			snd_buff_semaphore */ );
	avi_ptr->init_network( LISTEN, ip, use_multicast, mc_addr );
	avi_ptr->init_other( va_mode/* , send_image_semaphore */, 
			show_local_video );
	avi_ptr->init();

	avi_ptr->show();

	avi * avi_ptr_2 = new avi( 0, "AVI" );

	avi_ptr_2->init_video( video_dev, &video_opt/* , video_send_semaphore, 
			video_cap_semaphore */ );
	avi_ptr_2->init_audio( audio_dev, use_g723, g723_high_bit_rate, 
			g723_voice_detect/* , audio_can_play_semaphore, 
			audio_cap_semaphore, snd_buff_semaphore */ );
	avi_ptr_2->init_network( CONNECT, ip, use_multicast, mc_addr );
	avi_ptr_2->init_other( va_mode/* , send_image_semaphore */, show_local_video );
	avi_ptr_2->init();

	a.setMainWidget( avi_ptr_2 );

	avi_ptr_2->setCaption("Video Player");
	
	avi_ptr_2->setFixedSize( video_opt.min_width * video_opt.factor, video_opt.min_height * video_opt.factor );

	avi_ptr_2->show();

	///////////////////////////////////////////////////////////

    QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));

	verbose_output( 1, "begin running." );

    return a.exec();

} // }}}


// 分析命令行参数,根据参数设置变量
// argc 和 argv 是接收到的命令行参数
// img 是设置的接收的图像大小
// msg 是一个字符串,用于传递IP或设备名
// zoom 表示是否要放大
void parse_cmd ( int argc, char **argv, bool & zoom,
	const char *& video_dev, video_opt_t * video_opt, 
	const char *& audio_dev, bool & use_g723, 
	network_mode_t & net_mode, const char *& ip, 
	va_mode_t & va_mode, bool & show_local_video,
	bool & g723_high_bit_rate, bool & g723_voice_detect,
	bool & use_multicast, const char *& mc_addr ) // {{{
{
	
	int c;
	char * filename = NULL;
	bool test = false;

	// 分析参数
	if ( argc > 1 )
	{
		int i = 0;
		while ( ( c = getopt( argc, argv, "vthd:s:P:D:o:T:I:zAVu:q:gr:lbcMR:" ) ) != -1 )
		{
			switch ( c )
			{
				// 调试输出
				case 'v':
					verbose++;
					break;

				// 设备测试
				case 't':
					test = true;
					break;
				
				// 显示帮助
				case 'h':
					show_help();
					break;

				// 设置设备名称
				case 'd':
					video_dev = optarg;
					break;

				// 图像大小
				case 's':
					i = atoi( &optarg[0] );

					if ( i <= 0 || i > MAX_FACTOR || i == DEFAULT_FACTOR )
					{
						// Do Nothing	
					}
					else
					{
						video_opt->factor = i;
					}
					break;
					
				// 调色板
				case 'P':
					video_opt->palette = atoi( optarg );
					break;

				// 色深
				case 'D':
					video_opt->depth = atoi( optarg );
					break;

				// 设备测试的输出文件名
				case 'o':
					filename = optarg;
					break;

				// 程序类型
				case 'T':
					switch( optarg[0] )
					{
						case 's':
							net_mode = STANDALONE;
							break;

						case 'l':
							net_mode = LISTEN;
							break;

						case 'c':
							net_mode = CONNECT;
							break;
					}
					break;

				// 监听方IP
				case 'I':
					ip = optarg;
					break;

				// 是否放大
				case 'z':
					zoom = true;
					break;

				// Audio Only
				case 'A':
					if ( va_mode == VIDEO_ONLY )
					{
						show_help();
					}

					va_mode = AUDIO_ONLY;

					break;
					
				// Video Only
				case 'V':
					if ( va_mode == AUDIO_ONLY )
					{
						show_help();
					}

					va_mode = VIDEO_ONLY;

					break;

				// 音频设备
				case 'u':
					audio_dev = optarg;
					break;

				// use for -qws
				case 'q':
					// nothing to do.
					break;

				// JPEG 压缩质量
				case 'r':
					i = atoi( &optarg[0] );

					if ( i <= 5 || i > 100 || i == DEFAULT_QUALITY )
					{
						// Do Nothing	
					}
					else
					{
						video_opt->quality = i;
					}
					
					break;

				// 使用G723 
				case 'g':
					use_g723 = true;
					break;

				case 'l':
					show_local_video = true;
					break;

				case 'b':
					g723_high_bit_rate = true;
					break;

				case 'c':
					g723_voice_detect = true;
					break;

				case 'M':
					use_multicast = true;
					break;

				case 'R':
					mc_addr = optarg;
					break;

				// 失败则显示帮助
				default:
					show_help();
			}
		}
	}

	if ( test )
	{
		verbose_output( 1, "begin testing...", video_dev );
		video_test( video_dev, filename );
		exit( 0 );
	}

	return;					

} // }}}


// 显示帮助
void show_help ( void ) // {{{
{

	cout << "Usage: myvideo [-h] [-v] [-T s|l|c] [-V|-A]" << endl;
	cout << "       [-d device] [-t [-o output_filename]]" << endl;
	cout << "       [-s num] [-p palette] [-e depth] [-z] [-g] [-j]" << endl;
	cout << "       [-l] [-b] [-c]" << endl << endl;;

	cout << "=== General Part ===" << endl << endl;;

	cout << "-h                   Show this help message." << endl;
	cout << "-v                   Verbose output." << endl;
	cout << "-T s|l|c             Network mode." << endl;
	cout << "                    *s:   standalone: no network, only capture & display." << endl;
	cout << "                     l:   listen: capture from device & send it to the network." << endl;
	cout << "                     c:   connect: capture from network & play it." << endl;
	cout << "-V                   Video Only. Can't be used with -A option." << endl;
	cout << "-A                   Audio Only. Can't be used with -V option." << endl << endl;;

	cout << "=== Video Part ===" << endl << endl;;

	cout << "-d device            use this device as video device." << endl;
	cout << "-t                   Test video device and output the test report." << endl;
	cout << "-o output_filename   Put the test report into a file, must be used with -t option." << endl;
	cout << "-s num               Size of the picture. 1 <= num <= 10" << endl;
	cout << "                     Actual width is " << BASIC_WIDTH << " * num," << endl;
	cout << "                     Actual height is " << BASIC_HEIGHT << " * num." << endl;
	cout << "                     The default num is " << DEFAULT_FACTOR << "."<< endl;
	cout << "-P palette           Use this palette." << endl;
	cout << "-D depth             Use this depth." << endl;
	cout << "-z                   Turn off zoom" << endl;
	cout << "-j                   Not use JPEG video compression." << endl;
	cout << "-r num               JPEG compression quality. 5 <= num <= 100." << endl;
	cout << "                     NOT implement." << endl;
	cout << "-l                   Show local video." << endl;
	cout << endl;

	cout << "=== Audio Part ===" << endl << endl;;

	cout << "-g                   Use G723 audio compression." << endl;
	cout << "-b                   Use G723 high bit rate." << endl;
	cout << "-c                   Use G723 voice activity detection." << endl;

	cout << "=== Network Part ===" << endl << endl;;

	cout << "-I                   Ip address of the listener, must be used with -Tc option." << endl;
	cout << "                     Default is 127.0.0.1" << endl;

	exit( 0 );

} // }}}