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; }