www.pudn.com > AVChat1.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" 
 
#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) 
{ 
	mRemoteVideoGraph = NULL; 
	mRemoteAudioGraph = NULL; 
	mLocalVideoGraph  = NULL; 
	mLocalAudioGraph  = NULL; 
 
	mVideoReceiver = NULL; 
	mAudioReceiver = NULL; 
	mVideoSender   = NULL; 
	mAudioSender   = NULL; 
 
	// 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 (mRemoteVideoGraph) 
	{ 
		mRemoteVideoGraph->Stop(); 
	} 
	if (mRemoteAudioGraph) 
	{ 
		mRemoteAudioGraph->Stop(); 
	} 
	if (mLocalVideoGraph) 
	{ 
		mLocalVideoGraph->Stop(); 
	} 
	if (mLocalAudioGraph) 
	{ 
		mLocalAudioGraph->Stop(); 
	} 
	return TRUE; 
} 
 
bool CRoleAdmin::ReceiveMessage(MessageT inMessage,  
								void * ioParam,  
								void * ioParam2) 
{ 
	switch (inMessage) 
	{ 
	case msg_MediaTypeReceived: 
		{ 
			// Finish building the receiving graphs 
			BOOL * isVideo = (BOOL*) ioParam; 
			if (*isVideo) 
			{ 
				CompleteVideoReceivingGraph(); 
			} 
			else 
			{ 
				CompleteAudioReceivingGraph(); 
			} 
			return true; 
		} 
	} 
 
	return CMsgReceiver::ReceiveMessage(inMessage, ioParam, ioParam2); 
} 
 
void CRoleAdmin::CompleteVideoReceivingGraph(void) 
{ 
	if (mRemoteVideoGraph && mVideoReceiver && mVideoRenderer) 
	{ 
		IPin * pOut = mVideoReceiver->GetPin(0); 
		IPin * pIn  = mVideoRenderer->GetPin(TRUE); 
		// Try intelligent connect 
		HRESULT hr = mRemoteVideoGraph->GetGraph()->Connect(pOut, pIn); 
		if (mVideoWindow) 
		{ 
			mVideoWindow->SetGraph(mRemoteVideoGraph); 
		} 
		mRemoteVideoGraph->Run(); 
	} 
} 
 
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 video 
	if ((mDeviceConfig & Remote_Has_Video) == Remote_Has_Video) 
	{ 
		mRemoteVideoGraph = new CDXGraph(); 
		pass = mRemoteVideoGraph->Create(); 
	} 
	// Prepare to receive remote audio 
	if ((mDeviceConfig & Remote_Has_Audio) == Remote_Has_Audio) 
	{ 
		mRemoteAudioGraph = new CDXGraph(); 
		pass = mRemoteAudioGraph->Create(); 
	} 
	// Prepare to send local video 
	if ((mDeviceConfig & Local_Has_Video) == Local_Has_Video) 
	{ 
		mLocalVideoGraph = new CDXGraph(); 
		pass = mLocalVideoGraph->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(mRemoteVideoGraph); 
	SAFE_DELETE(mRemoteAudioGraph); 
	SAFE_DELETE(mLocalVideoGraph); 
	SAFE_DELETE(mLocalAudioGraph); 
} 
 
BOOL CRoleAdmin::CreateInputFilters(void) 
{ 
	BOOL  pass = FALSE; 
	HRESULT hr = NOERROR; 
 
	// Create net receiver filters 
	if ((mDeviceConfig & Remote_Has_Video) == Remote_Has_Video) 
	{		 
		mVideoReceiver = new CFilterNetReceiver(NULL, &hr); 
		IBaseFilter * pFilter = NULL; 
		mVideoReceiver->QueryInterface(IID_IBaseFilter, (void**)&pFilter); 
		pass |= mRemoteVideoGraph->AddFilter(pFilter, L"Video Receiver"); 
		// Listen to the message frome video receiver 
		mVideoReceiver->AddMsgReceiver(this); 
	} 
	if ((mDeviceConfig & Remote_Has_Audio) == Remote_Has_Audio) 
	{ 
		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_Video) == Local_Has_Video) 
	{ 
		mVideoFilter = new CVideoCaptureFilter2(mLocalVideoGraph->GetGraph()); 
		((CVideoCaptureFilter2 *)mVideoFilter)->SetDevice(mVideoDevice); 
		pass |= mVideoFilter->CreateFilter(); 
	} 
	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(mVideoReceiver); 
	SAFE_RELEASE(mAudioReceiver); 
	SAFE_DELETE(mVideoFilter); 
	SAFE_DELETE(mAudioFilter); 
} 
 
BOOL CRoleAdmin::CreateOutputFilters(void) 
{ 
	BOOL  pass = FALSE; 
	HRESULT hr = NOERROR; 
 
	// Create video renderer and audio renderer for playback 
	if ((mDeviceConfig & Remote_Has_Video) == Remote_Has_Video) 
	{ 
		mVideoRenderer = new CDXFilter(mRemoteVideoGraph->GetGraph(),  
			CLSID_VideoRenderer, "Video Renderer"); 
		pass |= mVideoRenderer->CreateFilter(); 
	} 
	if ((mDeviceConfig & Remote_Has_Audio) == Remote_Has_Audio) 
	{ 
		mAudioRenderer = new CDXFilter(mRemoteAudioGraph->GetGraph(),  
			CLSID_DSoundRender, "Audio Renderer"); 
		pass |= mAudioRenderer->CreateFilter(); 
	} 
	// Create net sender filters 
	if ((mDeviceConfig & Local_Has_Video) == Local_Has_Video) 
	{ 
		mVideoSender = new CFilterNetSender(NULL, &hr); 
		IBaseFilter * pFilter = NULL; 
		mVideoSender->QueryInterface(IID_IBaseFilter, (void**)&pFilter); 
		pass |= mLocalVideoGraph->AddFilter(pFilter, L"Video Sender"); 
	} 
	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(mVideoSender); 
	SAFE_RELEASE(mAudioSender); 
} 
 
BOOL CRoleAdmin::ConnectFilters(void) 
{ 
	BOOL   pass = TRUE; 
	IPin * pOut = NULL; 
	IPin * pIn  = NULL; 
 
	// Only connect sending filter graphs 
	if (mLocalVideoGraph && mVideoFilter && mVideoSender) 
	{		 
		if (mVideoDevice->IsDVDevice()) // DV camcorder 
		{ 
			pOut = mVideoFilter->GetPin(FALSE, "DV Vid Out"); 
			pIn  = mVideoSender->GetPin(0); 
			pass = RenderDVVideo(mLocalVideoGraph, pOut, pIn); 
		} 
		else // USB camera 
		{ 
			pOut = mVideoFilter->GetPin(FALSE, "Capture"); 
			pIn  = mVideoSender->GetPin(0); 
			pass = mLocalVideoGraph->ConnectFilters(pOut, pIn); 
		} 
	} 
 
	if (mLocalAudioGraph && mAudioFilter && mAudioSender) 
	{ 
		pOut = mAudioFilter->GetPin(FALSE); 
		pIn  = mAudioSender->GetPin(0); 
		pass = mLocalAudioGraph->ConnectFilters(pOut, pIn); 
	} 
 
	return pass; 
} 
 
BOOL CRoleAdmin::AfterBuildGraph(void) 
{ 
	// Set video socket to video receiver and sender 
	BOOL   socketUsed  = FALSE; 
	SOCKET videoSocket = GetVideoStreamSocket(); 
	if (mVideoReceiver && videoSocket != INVALID_SOCKET) 
	{ 
		// Fastest playback without Reference Clock! 
		mRemoteVideoGraph->SetSyncSource(NULL); 
		mVideoReceiver->SetStreamSocket(videoSocket); 
		mVideoReceiver->StartReceiving(); // Begin to receive 
		socketUsed = TRUE; 
	} 
	if (mVideoSender && videoSocket != INVALID_SOCKET) 
	{ 
		mVideoSender->SetStreamSocket(videoSocket); 
		socketUsed = TRUE; 
	} 
	// If video socket not used, release it! 
	if (!socketUsed && videoSocket != INVALID_SOCKET)  
	{ 
		closesocket(videoSocket); 
	} 
 
	// Set audio socket to audio receiver and sender 
	socketUsed  = FALSE; 
	SOCKET audioSocket = GetAudioStreamSocket(); 
	if (mAudioReceiver && audioSocket != INVALID_SOCKET) 
	{ 
		mAudioReceiver->SetStreamSocket(audioSocket); 
		mAudioReceiver->StartReceiving(); // Begin to receive 
		socketUsed = TRUE; 
	} 
	if (mAudioSender && audioSocket != INVALID_SOCKET) 
	{ 
		mAudioSender->SetStreamSocket(audioSocket); 
		socketUsed = TRUE; 
	} 
	// If audio socket not used, release it! 
	if (!socketUsed && audioSocket != INVALID_SOCKET)  
	{ 
		closesocket(audioSocket); 
	} 
 
	// Start sending filter graphs 
	if (mLocalVideoGraph) 
	{ 
		mLocalVideoGraph->Run(); 
	} 
	if (mLocalAudioGraph) 
	{ 
		mLocalAudioGraph->Run(); 
	} 
	return TRUE; 
} 
 
SOCKET CRoleAdmin::GetVideoStreamSocket(void) 
{ 
	return INVALID_SOCKET; 
} 
 
SOCKET CRoleAdmin::GetAudioStreamSocket(void) 
{ 
	return INVALID_SOCKET; 
}