📄 croleadmin.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 + -