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

📄 network_audio_send_thread.cpp

📁 嵌入式linux系统的网络编程(C++) 在ARM上实现视频会议 此程序获得全国研究生电子大赛一等奖 压缩包内为全部源码
💻 CPP
字号:
///////////////////////////////////////////////////////// FileName:	network_audio_send_thread.cpp// Author:		b1gm0use// Project:		myvideo#include <iostream>#include <sys/types.h>#include <sys/socket.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>#include <qapplication.h>#include <poll.h>#include "network_audio_send_thread.h"#include "capture_event.h"#include "network_audio_send.h"#include "network_ctrl.h"#include "network.h"#include "common.h"#include "audio.h"#include "avi.h"using namespace std;///////////////////////////////////////////////////////// Public Functions///////////////////////////////////////////////////////// 构造函数// 传入参数为// nc_in 上层network_ctrl对象指针// stackSize QThread所用的参数network_audio_send_thread::network_audio_send_thread ( avi * avi_ptr_in, 		network_ctrl * nc_in, unsigned int stackSize )		:QThread( stackSize ) // {{{{	verbose_output( 2, "create network_audio_send_thread." );	nc = nc_in;	fd_audio = 0;	audio_frame = 0;	recv_buff = new BUFF [ PACKET_LENGTH ];	send_buff = new BUFF [ PACKET_LENGTH ];	merge_buff = NULL;	max_size = 0;	addr_accept = new sockaddr_in;	acclen = new socklen_t;	packet_num = 0;	expect_num = 0;	to_be_send = NULL;	avi_ptr = avi_ptr_in;} // }}}// 析构函数network_audio_send_thread::~network_audio_send_thread ( void ) // {{{{	if ( 0 != fd_audio )	{		close( fd_audio );	}	delete [] recv_buff;	delete [] send_buff;	delete [] merge_buff;	delete addr_accept;	delete acclen;	delete [] to_be_send;} // }}}// 运行部分,线程代码在这里void network_audio_send_thread::run ( void ) // {{{{	verbose_output( 1, "network audio send thread running..." );	max_size = MAX_AUDIO_BUFF_SIZE;	to_be_send = new BUFF [ max_size + DATA_OFFSET ];	if ( avi_ptr->use_multicast )	{		listen_init_mc();		listen_handle_mc();	}	else	{		listen_init();		listen_handle();	}	return;} // }}}///////////////////////////////////////////////////////// Private Functions///////////////////////////////////////////////////////// 连接初始化,创建套接字void network_audio_send_thread::listen_init ( void ) // {{{{	verbose_output( 3, "network audio send thread init." );	/////////////////////////////////////////	// 创建音频端口	/////////////////////////////////////////		sockaddr_in addr_listen;	socklen_t len = sizeof( addr_listen );	int port = DEFAULT_AUDIO_PORT;		// 创建一个等待server daemon的监听端口	// 创建控制端监听socket	verbose_output( 3, "creating audio listen socket..." );	fd_audio = socket( AF_INET, SOCK_DGRAM, 0 );			// 绑定指定端口	memset( &addr_listen, 0, sizeof( addr_listen ) );	addr_listen.sin_family = AF_INET;	addr_listen.sin_addr.s_addr = htonl( INADDR_ANY );	addr_listen.sin_port = htons( port );		// 绑定端口	if ( bind( fd_audio, (sockaddr*) & addr_listen, len ) == -1 )	{		cerr << "Can't bind to the listen port [" << port << "]" << endl;		::exit( 1 );	}	verbose_output( 3, "waiting for audio connection...", avi_ptr->ip );	*acclen = sizeof( *addr_accept );	memset( addr_accept, 0, *acclen );	return;} // }}}// 处理连接进入后的数据发送工作void network_audio_send_thread::listen_handle ( void ) // {{{{	verbose_output( 3, "network audio send thread handle." );	BUFF * pos = NULL;	audio_frame = 0;	// 接收进来的连接	BUFF * buff = NULL;	bool read_ok = false;	bool should_exit = false;	packet_head_t * packet_head = NULL;	do	{		// 判断是否应该退出		(*(nc->term_sub_thread_sema))++;		should_exit = nc->term_sub_thread;		(*(nc->term_sub_thread_sema))--;		if ( should_exit )		{			return;		}		pollfd connect_in = { fd_audio, POLLIN, DEFAULT_TIMEOUT };		int result = poll( &connect_in, 1, 0 );		if ( result < 0 )		{			perror( "Error in audio listening" );		}		if ( result == 0 )		{			// 超时			continue;		}				if ( ( connect_in.revents & POLLIN ) != 0 )		{			// 有数据可读?			recv_line( fd_audio, addr_accept, recv_buff, buff, packet_head );			if ( !TEST_CTRL_SYN_BIT( packet_head->opt_bits ) )			{				cerr << "not audio welcome number" << endl;				continue;			}			read_ok = true;			send_data( fd_audio, addr_accept, send_buff, NULL, 0, packet_num, SYN );		}	}	while( !read_ok );	int size = max_size;	// 处理发送数据	while( 1 )	{		// 判断是否应该退出		(*(nc->term_sub_thread_sema))++;		should_exit = nc->term_sub_thread;		(*(nc->term_sub_thread_sema))--;		if ( should_exit )		{			return;		}		// 等待可发送数据		nc->ready_to_send_audio->wait();		(*(nc->audio_send_buff_sema))++;		size = nc->audio_buff[audio_frame]->buff_size;		memcpy( to_be_send + DATA_OFFSET, nc->audio_buff[audio_frame]->buff_ptr, size );				(*(nc->audio_send_buff_sema))--;		audio_frame = (audio_frame + 1) % 3;		pos = to_be_send;		memcpy( pos, "ABGN", 4 );		memcpy( pos+4, (char*) &size, sizeof( int ) );		pollfd connect_in = { fd_audio, POLLIN | POLLOUT, 0 };		int result = poll( &connect_in, 1, 0 );		if ( result < 0 )		{			perror( "Error in audio listening" );		}				if ( ( connect_in.revents & POLLIN ) != 0 )		{			// 有数据可读?			recv_line( fd_audio, addr_accept, recv_buff, buff, packet_head );			if ( TEST_CTRL_SYN_BIT( packet_head->opt_bits ) )			{				send_data( fd_audio, addr_accept, send_buff, NULL, 0, packet_num, SYN );			}			else			{				cerr << "Warning! read in unknown audio packet" << endl;			}		}		if ( ( connect_in.revents & POLLOUT ) != 0 )		{			// 可以写入数据			*acclen = sizeof( *addr_accept );			send_data( fd_audio, addr_accept, send_buff, to_be_send, size+DATA_OFFSET, packet_num );		}		pos = NULL;	}} // }}}// 组播初始化,创建套接字void network_audio_send_thread::listen_init_mc ( void ) // {{{{	verbose_output( 3, "network audio send thread Multicast init." );	/////////////////////////////////////////	// 创建音频端口	/////////////////////////////////////////		*acclen = sizeof( *addr_accept );	memset( addr_accept, 0, *acclen );		// 网络连接的参数设置	addr_accept->sin_family = AF_INET;	addr_accept->sin_port = htons( DEFAULT_MC_AUDIO_PORT );	inet_pton( AF_INET, static_cast< const char* >( avi_ptr->mc_addr ), 			&addr_accept->sin_addr );	// 创建控制端发送socket	fd_audio = socket( AF_INET, SOCK_DGRAM, 0 );		// 初始化组播	ip_mreq mreq;	memcpy( &mreq.imr_multiaddr, &(((sockaddr_in*) addr_accept)->sin_addr),			sizeof( in_addr ) );	mreq.imr_interface.s_addr = htonl( INADDR_ANY );	// 加入组播	setsockopt( fd_audio, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof( mreq ) );	return;} // }}}// 处理组播连接后的数据接收工作void network_audio_send_thread::listen_handle_mc ( void ) // {{{{	verbose_output( 3, "network audio send thread Multicast handle." );	BUFF * pos = NULL;	audio_frame = 0;	int size = max_size;	bool should_exit = false;	// 处理发送数据	while( 1 )	{		// 判断是否应该退出		(*(nc->term_sub_thread_sema))++;		should_exit = nc->term_sub_thread;		(*(nc->term_sub_thread_sema))--;		if ( should_exit )		{			return;		}		// 等待可发送数据		nc->ready_to_send_audio->wait();		// 取出等待发送的数据		(*(nc->audio_send_buff_sema))++;		size = nc->audio_buff[audio_frame]->buff_size;		memcpy( to_be_send + DATA_OFFSET, nc->audio_buff[audio_frame]->buff_ptr, size );				(*(nc->audio_send_buff_sema))--;		audio_frame = (audio_frame + 1) % 3;		// 处理头信息		pos = to_be_send;		memcpy( pos, "ABGN", 4 );		memcpy( pos+4, (char*) &size, sizeof( int ) );		// 写入数据		*acclen = sizeof( *addr_accept );		send_data( fd_audio, addr_accept, send_buff, to_be_send, size+DATA_OFFSET, packet_num );		pos = NULL;	}	return;} // }}}

⌨️ 快捷键说明

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