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

📄 rtpreceiver.cxx

📁 MiniSip Client with DomainKeys Authentication, Sip, Audio communications, Echo Cancel
💻 CXX
字号:
/* Copyright (C) 2004-2006 the Minisip Team  This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.  This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.  You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA *//* Copyright (C) 2004, 2005  * * Authors: Erik Eliasson <eliasson@it.kth.se> *          Johan Bilien <jobi@via.ecp.fr>*/#include <config.h>#include<libminisip/mediahandler/RtpReceiver.h>#include<libmnetutil/UDPSocket.h>#include<libmnetutil/NetworkException.h>#include<libmutil/Thread.h>#include<libminisip/rtp/SRtpPacket.h>#include<libminisip/codecs/Codec.h>#include<iostream>#include<libminisip/mediahandler/MediaStream.h>#include<libminisip/ipprovider/IpProvider.h>#include<libmutil/itoa.h> //for debug ... remove ... cesc#include<stdio.h>#include<sys/types.h>#include<stdlib.h> //for rand#ifdef WIN32#include<winsock2.h>#endif#ifdef _MSC_VER#else#include<sys/time.h>#include<unistd.h>#include<errno.h>#endif#ifdef _WIN32_WCE#	include"../include/minisip_wce_extra_includes.h"#endif//Set the range of rtp usable ports ... starting at min and spanning a range, up to max#define RTP_LOCAL_PORT_RANGE_MIN 30000#define RTP_LOCAL_PORT_RANGE 5000#define RTP_LOCAL_PORT_RANGE_MAX RTP_LOCAL_PORT_RANGE_MIN + RTP_LOCAL_PORT_RANGE#define RTP_RECEIVER_MAX_RETRIES 5using namespace std;RtpReceiver::RtpReceiver( MRef<IpProvider *> ipProvider){	socket = NULL;		int portretry = 0;	for (; portretry<RTP_RECEIVER_MAX_RETRIES; portretry++ ) {		//generate a random port, even number, in the given range		float randPartial =  (float)rand()  /  RAND_MAX;		int port = (int) (RTP_LOCAL_PORT_RANGE * randPartial );		port = (int) ( 2 * (int)(port/2 ) ); //turn this into an even number		port += RTP_LOCAL_PORT_RANGE_MIN; //add the min port to set it within the range		#ifdef DEBUG_OUTPUT			printf( "RtpReceiver:: final trying port = %d\n", port );		#endif		try{			socket = new UDPSocket( port );			if( socket ) {				break;			}		}		catch( NetworkException &  ){			// FIXME: do something nice// 			merr << "Minisip could not create a UDP socket!" << end;// 			merr << "Check your network settings." << end;// 			exit( 1 );			#ifdef DEBUG_OUTPUT			cerr << "RtpReceiver: Could not create UDP socket" << endl;			#endif		}	}	if( portretry == RTP_RECEIVER_MAX_RETRIES && !socket ) {			merr << "Minisip could not create a UDP socket!" << end;			merr << "Check your network settings." << end << "Quitting badly" << end;			exit( 1 );	}		externalPort = ipProvider->getExternalPort( socket );	kill = false;	thread = new Thread(this);}RtpReceiver::~RtpReceiver(){	thread->join();	delete thread;	socket->close();}/**	register a mediaStreamReceiver ... if the receiver is already registered,	update the exhisting one to point to the new receiver.*/void RtpReceiver::registerMediaStream( MRef<MediaStreamReceiver *> mediaStream ){	list< MRef<MediaStreamReceiver *> >::iterator iter;	mediaStreamsLock.lock();	/* Don't register new streams if the receiver is being closed */	if( !kill ){		bool found = false;		//cerr << "RtpReceiver::registerMediaStream: register done!" << endl;		for( iter = mediaStreams.begin();				iter != mediaStreams.end();				iter++ ) {			if( (*iter)->getId() == mediaStream->getId() ) {				found = true;			#ifdef DEBUG_OUTPUT				cerr << "RtpRcvr::registerMediaStream: media stream already registered. Updating MRef." << endl;			#endif								(*iter) = mediaStream;				break;			}		}		if( !found ) {			mediaStreams.push_back( mediaStream );		}	}	mediaStreamsLock.unlock();}void RtpReceiver::unregisterMediaStream( MRef<MediaStreamReceiver *> mediaStream ){#ifdef DEBUG_OUTPUT	// cerr << "RtpReceiver::unregisterMediaStream: Before taking lock" << endl;#endif		mediaStreamsLock.lock();	mediaStreams.remove( mediaStream );	if( mediaStreams.size() == 0 ){		/* End the thread */		kill = true;	}	mediaStreamsLock.unlock();#ifdef DEBUG_OUTPUT	// cerr << "RtpReceiver::unregisterMediaStream: After taking lock" << endl;#endif}uint16_t RtpReceiver::getPort(){	return externalPort;}MRef<UDPSocket *> RtpReceiver::getSocket(){	return socket;}			void RtpReceiver::run(){	MRef<SRtpPacket *> packet;		while( !kill ){		list< MRef<MediaStreamReceiver *> >::iterator i;		fd_set rfds;		struct timeval tv;		int ret = -1;		FD_ZERO( &rfds );		#ifdef WIN32		FD_SET( (uint32_t) socket->getFd(), &rfds );		#else		FD_SET( socket->getFd(), &rfds );		#endif		tv.tv_sec = 0;		tv.tv_usec = 100000;				while( ret < 0 ){			ret = select( socket->getFd() + 1, &rfds, NULL, NULL, &tv );			if( ret < 0 ){				#ifdef DEBUG_OUTPUT					//FIXME: do something better					cerr << "RtpReceiver::run() - select returned -1" << endl;				#endif				#ifndef _WIN32_WCE					if( errno == EINTR ) { continue; }				#else					if( errno == WSAEINTR ) { continue; }				#endif					else {						kill = true;						break;					}			}		}		if( kill ) {			break;		}				if( ret == 0 /* timeout */ ){			//notify the mediaStreams of the timeout			for( i = mediaStreams.begin(); 					i != mediaStreams.end(); i++ ){				(*i)->handleRtpPacket( NULL );			}			continue;		}		try{			packet = SRtpPacket::readPacket( **socket );		}		catch (NetworkException &  ){			continue;		}		if( !packet ){			continue;		}		mediaStreamsLock.lock();		for( i = mediaStreams.begin(); i != mediaStreams.end(); i++ ){			std::list<MRef<Codec *> > codecs = (*i)->getAvailableCodecs();			std::list<MRef<Codec *> >::iterator iC;			//printf( "|" );			for( iC = codecs.begin(); iC != codecs.end(); iC ++ ){				if ( (*iC)->getSdpMediaType() == packet->getHeader().getPayloadType() ) {					(*i)->handleRtpPacket( packet );					//printf( "~" );					break;				}			}		}				mediaStreamsLock.unlock();				packet = NULL;	}}

⌨️ 快捷键说明

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