www.pudn.com > AVChat0926.rar > CRoleAdmin.cpp


// 
// CRoleAdmin.cpp 
// 
 
/*-----------------------------------------------------*\ 
			HQ Tech, Make Technology Easy!        
 More information, please go to http://hqtech.nease.net. 
/*-----------------------------------------------------*/ 
 
#include "stdafx.h" 
#include  
#include "CRoleAdmin.h" 
#include "GlobalDefs.h" 
#include "CDXGraph.h" 
#include "CVideoWindow.h" 
#include "CAVDevice.h" 
#include "CVideoCaptureFilter2.h" 
#include "CAudioCaptureFilter2.h" 
#include "CFilterNetReceiver.h" 
#include "CFilterNetSender.h" 
#include ".\croleadmin.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////// 
CRoleAdmin::CRoleAdmin() : mDeviceConfig(0), mLocalUDPPort(0), 
mTargetUDPPort(0), mTargetIP(0x7f000001) 
{ 
	mRemoteAudioGraph = NULL; 
	mLocalAudioGraph  = NULL; 
 
	mAudioReceiver = NULL; 
	mAudioSender   = NULL; 
	 
	//命令传输端口号 
	mLocalUDPPort  = CLIENT_UDP_PORT;		//表示在CLIENT_UDP_PORT端口建立一个UDP监听 
	mTargetUDPPort = SERVER_UDP_PORT;		//表示命令要发送到远程主机的SERVER_UDP_PORT端口 
 
	//媒体数据必须要设置的接收数据的端口号 
	//这里最好使用灵活的设置方式,端口号,IP地址均可自由设置,由构造函数带进来或直接设置 
	mAudioStream.SetLocalPort(AUDIO_UDP_PORT); 
 
	mMulticastIP   = 0xef080808;	//239.8.8.8 
 
	// Receive message from UDP Receiver 
	// mUdpManager.AddMsgReceiver(this); 
} 
 
CRoleAdmin::~CRoleAdmin() 
{ 
	Deactivate(); 
	Uninit(); 
} 
 
void CRoleAdmin::SetDeviceConfig(long inConfig) 
{ 
	mDeviceConfig |= inConfig; 
} 
 
void CRoleAdmin::SetTargetIP(DWORD inTarget) 
{ 
	mTargetIP = inTarget; 
	mUdpManager.SetTargetIP(inTarget); 
} 
 
BOOL CRoleAdmin::Init(void) 
{ 
	// Currently, the target IP may be unknown 
	// As client, the target (server) IP is set by user. 
	// As server, the target (client) IP is retrieved by UDP receiver. 
	mUdpManager.SetLocalPort(mLocalUDPPort); 
	mUdpManager.SetTargetPort(mTargetUDPPort); 
	mUdpManager.CreateSender(); 
 
	// Set up command listening 
	BOOL pass = mUdpManager.CreateReceiver(); 
	if (pass) 
	{ 
		pass = mUdpManager.StartReceiving(); 
	} 
	 
	return pass; 
} 
 
void CRoleAdmin::Uninit(void) 
{ 
	mUdpManager.StopReceiving(); 
} 
 
BOOL CRoleAdmin::CallServer(void) 
{ 
	return FALSE; 
} 
 
void CRoleAdmin::Disconnect(BOOL inNotifyPeer) 
{ 
	// Notify the remote to disconnect 
	if (inNotifyPeer) 
	{ 
		SendSimpleCommand(cmd_DisconnectRequest); 
	} 
	// Release all the local resources 
	Deactivate(); 
	Uninit(); 
} 
 
BOOL CRoleAdmin::StopGraph(void) 
{ 
	if (mRemoteAudioGraph) 
	{ 
		mRemoteAudioGraph->Stop(); 
	} 
	if (mLocalAudioGraph) 
	{ 
		mLocalAudioGraph->Stop(); 
	} 
	return TRUE; 
} 
 
bool CRoleAdmin::ReceiveMessage(MessageT inMessage,  
								void * ioParam,  
								void * ioParam2) 
{ 
	return CMsgReceiver::ReceiveMessage(inMessage, ioParam, ioParam2); 
} 
 
void CRoleAdmin::CompleteAudioReceivingGraph(void) 
{ 
	if (mRemoteAudioGraph && mAudioReceiver && mAudioRenderer) 
	{ 
		IPin * pOut = mAudioReceiver->GetPin(0); 
		IPin * pIn  = mAudioRenderer->GetPin(TRUE); 
		// Try intelligent connect 
		HRESULT hr = mRemoteAudioGraph->GetGraph()->Connect(pOut, pIn); 
		mRemoteAudioGraph->Run(); 
	} 
} 
 
BOOL CRoleAdmin::SendSimpleCommand(long inCommand) 
{ 
	UDP_Pack myPack; 
	ZeroMemory(&myPack, sizeof(myPack)); 
 
	myPack.command = inCommand; 
	myPack.my_hton(); 
	return mUdpManager.Send((char*)&myPack, sizeof(myPack)); 
} 
 
BOOL CRoleAdmin::SendLocalDeviceConfigToPeer(void) 
{ 
	UDP_Pack myPack; 
	ZeroMemory(&myPack, sizeof(myPack)); 
 
	myPack.command = cmd_DeviceConfig; 
	myPack.param1  = (mDeviceConfig & Local_Device_Mask); 
	myPack.my_hton(); 
	return mUdpManager.Send((char*)&myPack, sizeof(myPack)); 
} 
 
BOOL CRoleAdmin::CreateGraph(void) 
{ 
	BOOL pass = TRUE; 
 
	// Prepare to receive remote audio 
	mRemoteAudioGraph = new CDXGraph(); 
	pass = mRemoteAudioGraph->Create(); 
 
	// Prepare to send local audio 
	if ((mDeviceConfig & Local_Has_Audio) == Local_Has_Audio) 
	{ 
		mLocalAudioGraph = new CDXGraph(); 
		pass = mLocalAudioGraph->Create(); 
	} 
	 
	return pass; 
} 
 
void CRoleAdmin::DeleteGraph(void) 
{ 
	// Clean up the video window 
	if (mVideoWindow) 
	{ 
		mVideoWindow->SetGraph(0); 
	} 
 
	SAFE_DELETE(mRemoteAudioGraph); 
	SAFE_DELETE(mLocalAudioGraph); 
} 
 
BOOL CRoleAdmin::CreateInputFilters(void) 
{ 
	BOOL  pass = FALSE; 
	HRESULT hr = NOERROR; 
 
	mAudioReceiver = new CFilterNetReceiver(NULL, &hr); 
	IBaseFilter * pFilter = NULL; 
	mAudioReceiver->QueryInterface(IID_IBaseFilter, (void**)&pFilter); 
	pass |= mRemoteAudioGraph->AddFilter(pFilter, L"Audio Receiver"); 
	// Listen to the message frome video receiver 
	mAudioReceiver->AddMsgReceiver(this); 
 
	// Create local video and audio devices 
	if ((mDeviceConfig & Local_Has_Audio) == Local_Has_Audio) 
	{ 
		mAudioFilter = new CAudioCaptureFilter2(mLocalAudioGraph->GetGraph()); 
		((CAudioCaptureFilter2 *)mAudioFilter)->SetDevice(mAudioDevice); 
		pass |= mAudioFilter->CreateFilter(); 
	} 
 
	return pass; 
} 
 
void CRoleAdmin::ReleaseInputFilters(void) 
{ 
	SAFE_RELEASE(mAudioReceiver); 
	SAFE_DELETE(mAudioFilter); 
} 
 
BOOL CRoleAdmin::CreateOutputFilters(void) 
{ 
	BOOL  pass = FALSE; 
	HRESULT hr = NOERROR; 
 
	// Create video renderer and audio renderer for playback 
	mAudioRenderer = new CDXFilter(mRemoteAudioGraph->GetGraph(),  
		CLSID_DSoundRender, "Audio Renderer"); 
	pass |= mAudioRenderer->CreateFilter(); 
	// Create net sender filters 
	if ((mDeviceConfig & Local_Has_Audio) == Local_Has_Audio) 
	{ 
		mAudioSender = new CFilterNetSender(NULL, &hr); 
		IBaseFilter * pFilter = NULL; 
		mAudioSender->QueryInterface(IID_IBaseFilter, (void**)&pFilter); 
		pass |= mLocalAudioGraph->AddFilter(pFilter, L"Audio Sender"); 
	} 
	 
	return pass; 
} 
 
void CRoleAdmin::ReleaseOutputFilters(void) 
{ 
	SAFE_DELETE(mVideoRenderer); 
	SAFE_DELETE(mAudioRenderer); 
	SAFE_RELEASE(mAudioSender); 
} 
 
BOOL CRoleAdmin::ConnectFilters(void) 
{ 
	BOOL   pass = TRUE; 
	IPin * pOut = NULL; 
	IPin * pIn  = NULL; 
 
	if (mLocalAudioGraph && mAudioFilter && mAudioSender) 
	{ 
		pOut = mAudioFilter->GetPin(FALSE); 
		pIn  = mAudioSender->GetPin(0); 
		pass = mLocalAudioGraph->ConnectFilters(pOut, pIn); 
	} 
 
	return pass; 
} 
 
BOOL CRoleAdmin::AfterBuildGraph(void) 
{ 
	// Set audio socket to audio receiver and sender 
	SOCKET audioSocketSender = GetAudioStreamSocketSender(); 
	WORD   audioReceivePort  = GetAudioStreamReceivePort(); 
	int nFormatSize = 0; 
	BYTE * pbFormat = NULL; 
	if (mAudioSender && audioSocketSender != INVALID_SOCKET) 
	{ 
		mAudioSender->SetStreamSocket(audioSocketSender); 
		mAudioSender->SetTargetAddress(GetAudioTargetAddr()); 
	} 
	if (mLocalAudioGraph) 
	{ 
		mLocalAudioGraph->Run(); 
	} 
	if (mAudioSender) 
	{ 
		pbFormat = mAudioSender->GetPinpbFormat(nFormatSize); 
	} 
 
	if (mAudioReceiver && audioReceivePort) 
	{ 
		mAudioReceiver->SetupMediaType(0,(char*)pbFormat,nFormatSize); 
		mAudioReceiver->SetReceivePort(audioReceivePort); 
		mAudioReceiver->StartReceiving(); // Begin to receive 
	} 
	return TRUE; 
} 
 
WORD CRoleAdmin::GetVideoStreamReceivePort(void) 
{ 
	return 0; 
} 
SOCKET CRoleAdmin::GetVideoStreamSocketSender(void) 
{ 
	return INVALID_SOCKET; 
} 
 
WORD CRoleAdmin::GetAudioStreamReceivePort(void) 
{ 
	return mAudioStream.GetLocalPort(); 
} 
 
SOCKET CRoleAdmin::GetAudioStreamSocketSender(void) 
{ 
	return mAudioStream.GetSocketSender(); 
} 
 
SOCKADDR_IN CRoleAdmin::GetAudioTargetAddr(void) 
{ 
	SOCKADDR_IN Addr; 
	memset(&Addr,0,sizeof(Addr)); 
	memset((char *) &Addr, 0, sizeof(Addr));   
	Addr.sin_family      = AF_INET; 
	Addr.sin_addr.s_addr = htonl(mMulticastIP); 
	Addr.sin_port        = htons(AUDIO_UDP_PORT); 
	return Addr; 
} 
 
SOCKADDR_IN CRoleAdmin::GetVideoTargetAddr(void) 
{ 
	SOCKADDR_IN addr; 
	memset(&addr,0,sizeof(addr)); 
	return addr; 
} 
 
// 开始语音视频通信,建立发送和接收用的SOCKET和线程 
BOOL CRoleAdmin::StartAVChat(void) 
{	 
	BOOL isBuilding = TRUE;		//是否创建GRAPH的标志 
	BOOL bPass = FALSE;			//创建发送SOCKET是否成功的标志 
 
	mAudioStream.SetTargetIP(mMulticastIP); 
	mAudioStream.SetTargetPort(AUDIO_UDP_PORT); 
	bPass = mAudioStream.CreateSender(); 
    if (bPass == FALSE) 
    { 
		return FALSE; 
    } 
 
	Broadcast(msg_ModifyFilterGraph, &isBuilding); 
 
	CompleteAudioReceivingGraph(); 
	return TRUE; 
} 
 
// 停止语音视频通信 
void CRoleAdmin::StopAVChat(void) 
{ 
	BOOL isBuilding = FALSE; 
	Broadcast(msg_ModifyFilterGraph, &isBuilding); 
}