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

📄 croleadmin.cpp

📁 陆其明的实务精选中附带光盘中的视频聊天源代码
💻 CPP
字号:
//
// CRoleAdmin.cpp
//

/*-----------------------------------------------------*\
			HQ Tech, Make Technology Easy!       
 More information, please go to http://hqtech.nease.net.
/*-----------------------------------------------------*/

#include "stdafx.h"
#include <streams.h>
#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;
}

⌨️ 快捷键说明

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