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

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

#include <iostream>
#include <qwaitcondition.h>

#include "network_ctrl.h"
#include "capture_event.h"
#include "network_ctrl_send_thread.h"
#include "network_ctrl_recv_thread.h"
#include "video.h"
#include "audio.h"
#include "network.h"
#include "avi.h"

using namespace std;

///////////////////////////////////////////////////////
// Public Functions
///////////////////////////////////////////////////////

// 构造函数
// 其余三个为widget的子类要求的参数
network_ctrl::network_ctrl( avi * avi_ptr_in, QWidget *parent, const char *name, int wFlags ) 
		: QWidget( parent, name, wFlags ) // {{{
{
	verbose_output( 2, "create network_ctrl." );

	ncrt = NULL;
	ncst = NULL;

	audio_send_buff_sema = NULL;
	video_send_buff_sema = NULL;
	
	ready_to_send_audio = NULL;
	ready_to_send_video = NULL;

	audio_buff[0] = audio_buff[1] = audio_buff[2] = NULL;
	video_buff[0] = video_buff[1] = video_buff[2] = NULL;

	video_frame = audio_frame = 0;

	avi_ptr = avi_ptr_in;

	term_sub_thread_sema = NULL;
	term_sub_thread = false;

} // }}}


// 析构函数
network_ctrl::~network_ctrl( void ) // {{{
{
	verbose_output( 2, "delete network_ctrl." );

	if ( avi_ptr->net_mode == CONNECT && NULL != ncrt )
	{
		if ( ncrt->running() )
		{
			ncrt->terminate();
		}

		delete ncrt;
	}

	if ( avi_ptr->net_mode == LISTEN && NULL != ncst )
	{
		if ( ncst->running() )
		{
			ncst->terminate();
		}

		delete ncst;
	}

	delete audio_send_buff_sema;
	delete video_send_buff_sema;
	delete ready_to_send_audio;
	delete ready_to_send_video;
	delete [] audio_buff[0];
	delete [] audio_buff[1];
	delete [] audio_buff[2];
	delete [] video_buff[0];
	delete [] video_buff[1];
	delete [] video_buff[2];
	delete term_sub_thread_sema;

} // }}}


// 初始化函数
int network_ctrl::init ( void ) // {{{
{

	verbose_output( 2, "init network_ctrl." );

	audio_send_buff_sema = new QSemaphore( 1 );
	video_send_buff_sema = new QSemaphore( 1 );
	
	ready_to_send_audio = new QWaitCondition;
	ready_to_send_video = new QWaitCondition;

	BUFF * temp;

	term_sub_thread_sema = new QSemaphore( 1 );

	// 如果做做为LISTEN方,则要接收数据帧
	// 开辟缓冲区
	if ( avi_ptr->net_mode == LISTEN )
	{
		if ( avi_ptr->use_g723 )
		{
			for ( int i=0; i<3; i++ )
			{
				temp = new BUFF [ BUFF_SIZE_G723 * LENGTH ];
				audio_buff[i] = new buff_t( temp, BUFF_SIZE_G723 * LENGTH );
			}
		}
		else
		{
			for ( int i=0; i<3; i++ )
			{
				temp = new BUFF [ BUFF_SIZE_G711 * LENGTH ];
				audio_buff[i] = new buff_t( temp, BUFF_SIZE_G711 * LENGTH );
			}
		}

		for ( int i=0; i<3; i++ )
		{
			temp = new BUFF [ avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor * 3 ];
			video_buff[i] = new buff_t( temp, avi_ptr->video_opt.min_width * avi_ptr->video_opt.factor * avi_ptr->video_opt.min_height * avi_ptr->video_opt.factor * 3 );
		}
	}


	return SUCCEED;

} // }}}


void network_ctrl::stop_running ( void ) // {{{
{

	if ( avi_ptr->net_mode == LISTEN )
	{
		if ( NULL != ncst )
		{
			(*term_sub_thread_sema)++;
			term_sub_thread = true;
			(*term_sub_thread_sema)--;
			
			cout << "before ncst wait" << endl;
			if ( ncst->wait() )
			{
				cout << "before ncst wait" << endl;
				delete ncst;
				term_sub_thread = false;
				cout << "kill ok" << endl;
				ncst = NULL;
				return;
			}
		}
	}
	else
	{
		if ( avi_ptr->net_mode == CONNECT )
		{
			if ( NULL != ncrt )
			{
				(*term_sub_thread_sema)++;
				term_sub_thread = true;
				(*term_sub_thread_sema)--;

				cout << "before wait" << endl;
				if ( ncrt->wait() )
				{
				cout << "after wait" << endl;
					delete ncrt;
					term_sub_thread = false;
					ncrt = NULL;
					cout << "kill ok" << endl;
					return;
				}
			}
		}
	}

	return;

} // }}}


void network_ctrl::begin_running ( void ) // {{{
{
	
	// 创建不同的连接线程
	if ( avi_ptr->net_mode == LISTEN && NULL == ncst )
	{
		ncst = new network_ctrl_send_thread( avi_ptr, this );
		ncst->start();
	}
	else
	{
		if ( avi_ptr->net_mode == CONNECT && NULL == ncrt )
		{
			ncrt = new network_ctrl_recv_thread( avi_ptr, this );
			ncrt->start();
		}
	}

	return;

} // }}}


bool network_ctrl::running ( void ) // {{{
{

	if ( avi_ptr->net_mode == LISTEN  )
	{
		if ( NULL != ncst )
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else
	{
		if ( avi_ptr->net_mode == CONNECT )
		{
			if ( NULL != ncrt )
			{
				return true;
			}
			else
			{
				return false;
			}
		}
	}

	return false;

} // }}}


///////////////////////////////////////////////////////
// Protected Functions
///////////////////////////////////////////////////////


// 内部函数,用于接收自定义的事件
void network_ctrl::customEvent ( QCustomEvent * e ) // {{{
{
	verbose_output( 4, "network_ctrl change image event." );

	// 判断事件类型,是否正确
	if ( e->type() == VIDEO_NET_SEND_EVENT )
	{
		// 视频数据
		capture_event * new_event = (capture_event *) e;
		BUFF * temp = new_event->get_buff();
		int size = new_event->get_size();

		(*video_send_buff_sema)++;

		memcpy( video_buff[video_frame]->buff_ptr, temp, size );
		video_buff[video_frame]->buff_size = size;

		(*video_send_buff_sema)--;

		video_frame = (video_frame+1) % 3;

		ready_to_send_video->wakeAll();

	}
	else
	{

		if ( e->type() == AUDIO_NET_SEND_EVENT )
		{
			// 音频数据
			capture_event * new_event = (capture_event*) e;
			BUFF * temp = new_event->get_buff();
			int size = new_event->get_size();

			(*audio_send_buff_sema)++;

			memcpy( audio_buff[audio_frame]->buff_ptr, temp, size );
			audio_buff[audio_frame]->buff_size = size;

			(*audio_send_buff_sema)--;

			audio_frame = (audio_frame + 1) % 3;

			ready_to_send_audio->wakeAll();

		}
		else
		{
			cerr << "Error! You shouldn't be here!" << endl;
			cerr << "Error in network_ctrl." << endl;
			exit( 1 );
		}
	}

} // }}}