?? mcuendpoint.cpp
字號:
// MCUEndPoint.cpp: implementation of the CMCUEndPoint class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "VISMCU.h"
#include "MCUEndPoint.h"
#include "MainFrm.h"
#include "Shlwapi.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMCUEndPoint::CMCUEndPoint(CMainFrame &mainFrm):CH323EndPoint(FALSE),m_mainFrm(mainFrm)
{
m_findingGK=FALSE;
}
CMCUEndPoint::~CMCUEndPoint()
{
for(int i=0;i<m_roomList.GetSize();i++)
{
CRoom *p=m_roomList.GetAt(i);
if(p)
delete p;
}
}
void CMCUEndPoint::OnAnswerCall(DWORD connID,const char *RoomID)
{//有終端呼入
m_mainFrm.Output(IDS_LOG_INCOMING_CALL,connID,RoomID);
if(AddMember(connID,RoomID))
{
AnswerCall(connID,TRUE);
}
else
{
AnswerCall(connID,FALSE);
}
}
void CMCUEndPoint::OnWaitForAnswer(DWORD connID)
{
}
void CMCUEndPoint::OnConnectionCleared(DWORD connID, DWORD duration,enum CallEndReason reason)
{
CRoom *room=(CRoom*)GetConnectionData(connID);
if(room->GetMemberCount()==1)//最后一個人離開會議,不必發送成員離開消息
room=NULL;
RemoveMember(connID);
m_mainFrm.Output(IDS_LOG_CALLEND,connID,duration,reason);
if(room)
{
//發送成員離開消息
CString str;
str.Format("MDEL %d",connID);
for(DWORD i=0;i<room->GetMemberCount();i++)
{
DWORD id=room->GetMembers()[i];
SendNonStandardMsg(id,str);
}
}
}
void CMCUEndPoint::OnConnectionEstablished(DWORD connID)
{
CString roomID;
char IP[256]="";
char appName[256]="";
CRoom *room=(CRoom*)GetConnectionData(connID);
roomID=room->GetName();
GetRemoteAddress(connID,IP,256);
GetRemoteApplication(connID,appName,256);
m_mainFrm.Output(IDS_LOG_ESTABLISHED,connID,roomID,GetRemoteName(connID),IP,appName);
//通知所在會議名稱
CString str;
str.Format("ROOM %s",roomID);
SendNonStandardMsg(connID,str);
//通知會議中其他成員,有人加入
str.Format("MADD %d %s",connID,GetRemoteName(connID));
for(DWORD i=0;i<room->GetMemberCount();i++)
{
DWORD id=room->GetMembers()[i];
if(id!=connID)
SendNonStandardMsg(id,str);
}
}
void CMCUEndPoint::OnReceiveUserInput(DWORD connID,const char* value)
{
}
//VIS MCU和VIS EP示例程序中利用nonstandard message來實現簡單的會議控制
//開發者可以利用nonstandard message實現符合自己需求的會議控制,以及電子
//白板、文件共享等功能
//
//VIS MCU\VIS EP中使用的簡單的控制命令如下
// [前綴] 含義
// "MADD" 由MCU發給EP,告訴EP有人加入會議
// "MDEL" 由MCU發給EP,告訴EP有人離開會議
// "LIST" 由EP發給MCU,向MCU索取會議成員列表
// "ROOM" 由MCU發給EP,告訴EP當前所在會議名
// "ANNO" 通知信息,由MCU發給所有EP
// "MSGA" 某個EP向所有人發話,由MCU發給EP
// "MSGP" 某個EP發話給另一個EP,由MCU發給EP
// "SMSG" EP發話給另一個EP,由EP發給MCU,MCU然后轉發成"MSGA"或者"MSGP"
// "SETA" EP發給MCU,告訴MCU要切換音頻
// "SETV" EP發給MCU,告訴MCU要切換視頻
void CMCUEndPoint::OnReceiveNonStandardMsg(DWORD connID,const char* value)
{
CString v=value;
CString prefix=v.Left(4);
if(prefix=="LIST")
{//終端請求成員列表
CRoom *room=(CRoom*)GetConnectionData(connID);
if(room)
{
CString str;
for(DWORD i=0;i<room->GetMemberCount();i++)
{
DWORD id=room->GetMembers()[i];
if(id!=connID)
{
str.Format("MADD %d %s",id,GetRemoteName(id));
SendNonStandardMsg(connID,str);
}
}
}
}
else if(prefix=="SMSG")
{//終端向其他終端發送文本信息
CString content=v.Right(v.GetLength()-4-1);
int index=content.Find(' ');
DWORD id=StrToInt(content.Left(index));
CString body=content.Right(content.GetLength()-index-1);
CString str;
if(id==0)//跟所有人說
{
str.Format("MSGA %d %s",connID,body);
CRoom *room=(CRoom*)GetConnectionData(connID);
if(room)
{
for(DWORD i=0;i<room->GetMemberCount();i++)
{
DWORD id=room->GetMembers()[i];
if(id!=connID)
{
SendNonStandardMsg(id,str);
}
}
}
}
else
{
str.Format("MSGP %d %s",connID,body);
SendNonStandardMsg(id,str);
}
}
else if(prefix=="SETV")
{//終端要求切換視頻
CString content=v.Right(v.GetLength()-4-1);
DWORD id=StrToInt(content);
CRoom *room=(CRoom*)GetConnectionData(connID);
if(room)
{
if(id==0)//終端要求切換到"所有人"
room->GetVideoMixer().SetMixerMode(connID,TRUE);
else//終端要求切換到某一個人
{
room->GetVideoMixer().SetMixerMode(connID,FALSE);
room->GetVideoMixer().SetOutgoingVideo(connID,1,&id);
}
}
}
else if(prefix=="SETA")
{//終端要求切換音頻
CString content=v.Right(v.GetLength()-4-1);
DWORD id=StrToInt(content);
CRoom *room=(CRoom*)GetConnectionData(connID);
if(room)
{
if(id==0)//終端要求切換到"所有人"
room->GetAudioMixer().SetMixerMode(connID,TRUE);
else//終端要求切換到某一個人
{
room->GetAudioMixer().SetMixerMode(connID,FALSE);
room->GetAudioMixer().SetOutgoingAudio(connID,1,&id);
}
}
}
}
BOOL CMCUEndPoint::OnRenderAudioFrame(DWORD connID,BYTE* frame,int len)
{
CRoom *room=(CRoom*)GetConnectionData(connID);
ASSERT(room!=NULL);
return room->GetAudioMixer().Write(connID,frame,len);
}
BOOL CMCUEndPoint::OnReadAudioFrame(DWORD connID,BYTE* frame,int len)
{
CRoom *room=(CRoom*)GetConnectionData(connID);
ASSERT(room!=NULL);
return room->GetAudioMixer().Read(connID,frame,len);
}
BOOL CMCUEndPoint::OnAudioStop(DWORD connID, BOOL outgoing,const char *CodecName)
{
m_mainFrm.Output(IDS_LOG_AUDIO_STOP,connID,outgoing?"發送":"接收",CodecName);
CRoom *room=(CRoom*)GetConnectionData(connID);
ASSERT(room!=NULL);
return room->GetAudioMixer().RemoveChannel(connID,outgoing);
}
BOOL CMCUEndPoint::OnAudioStart(DWORD connID,BOOL outgoing,const char *CodecName)
{
CRoom *room=(CRoom*)GetConnectionData(connID);
ASSERT(room!=NULL);
BOOL ret=room->GetAudioMixer().AddChannel(connID,outgoing);
if(ret)
m_mainFrm.Output(IDS_LOG_AUDIO_START,connID,outgoing?"發送":"接收",CodecName);
return ret;
}
BOOL CMCUEndPoint::OnRenderVideoFrame(DWORD connID,BYTE *frame, int width, int height)
{
CRoom *room=(CRoom*)GetConnectionData(connID);
ASSERT(room!=NULL);
return room->GetVideoMixer().Write(connID,frame,width,height,FALSE);//不需要delay
}
BOOL CMCUEndPoint::OnReadVideoFrame(DWORD connID,BYTE* frame,int width,int height)
{
CRoom *room=(CRoom*)GetConnectionData(connID);
ASSERT(room!=NULL);
return room->GetVideoMixer().Read(connID,frame,width,height);
}
BOOL CMCUEndPoint::OnVideoStop(DWORD connID,BOOL outgoing,const char *CodecName)
{
m_mainFrm.Output(IDS_LOG_VIDEO_STOP,connID,outgoing?"發送":"接收",CodecName);
CRoom *room=(CRoom*)GetConnectionData(connID);
ASSERT(room!=NULL);
return room->GetVideoMixer().RemoveChannel(connID,outgoing);
}
BOOL CMCUEndPoint::OnVideoStart(DWORD connID,BOOL outgoing,const char* CodecName)
{
CRoom *room=(CRoom*)GetConnectionData(connID);
ASSERT(room!=NULL);
BOOL ret= room->GetVideoMixer().AddChannel(connID,outgoing,
AfxGetApp()->GetProfileInt("",KEY_VIDEO_FPS,10),
AfxGetApp()->GetProfileInt("",KEY_VIDEO_BKCOLOR,0x00ff0000));
if(ret)
m_mainFrm.Output(IDS_LOG_VIDEO_START,connID,outgoing?"發送":"接收",CodecName);
return ret;
}
void CMCUEndPoint::OnUseGatekeeper(enum UseGKResult result,const char* name_GK)
{
m_findingGK=FALSE;
}
CRoom* CMCUEndPoint::AddRoom(CString name)
{//增加指定名稱的會議
if(name.GetLength()==0)//default room
name=AfxGetApp()->GetProfileString("",KEY_DEFAULT_ROOM,DEFAULT_ROOM);
//查找會議列表,看會議是否已經存在
for(int i=0;i<m_roomList.GetSize();i++)
{
CRoom *p=m_roomList.GetAt(i);
if(p&&p->GetName().CompareNoCase(name)==0)
return p;
}
//新建會議
CRoom * room=new CRoom;
room->SetName(name);
m_roomList.Add(room);
CListCtrl &listCtrl=m_mainFrm.GetRoomListCtrl();
int index=listCtrl.InsertItem(listCtrl.GetItemCount(),name);
listCtrl.SetItemData(index,(DWORD)room);
listCtrl.SetItemText(index,1,"0");
m_mainFrm.Output(IDS_LOG_ADDROOM,room->GetName());
return room;
}
BOOL CMCUEndPoint::RemoveRoom(LPCTSTR name)
{//刪除會議
for(int i=0;i<m_roomList.GetSize();i++)
{
CRoom *p=m_roomList.GetAt(i);
if(p&&p->GetName().CompareNoCase(name)==0)
{
if(p->GetMemberCount()==0)
{
m_roomList.RemoveAt(i);
CListCtrl &listCtrl=m_mainFrm.GetRoomListCtrl();
for(int j=0;j<listCtrl.GetItemCount();j++)
if(listCtrl.GetItemData(j)==((DWORD)p))
listCtrl.DeleteItem(j);
delete p;
m_mainFrm.Output(IDS_LOG_REMOVEROOM,name);
return TRUE;
}
break;
}
}
return FALSE;
}
BOOL CMCUEndPoint::AddMember(DWORD connID, LPCTSTR RoomID)
{//把終端加入指定名稱的會議
//嘗試新建會議
CRoom *room=AddRoom(RoomID);
if(room==NULL)
{
return FALSE;
}
if(room->GetMemberCount()>=AfxGetApp()->GetProfileInt("",KEY_ROOM_SIZE,DEFAULT_ROOM_SIZE))
{//會議已滿
m_mainFrm.Output(IDS_LOG_ROOMFULL,room->GetName(),AfxGetApp()->GetProfileInt("",KEY_ROOM_SIZE,DEFAULT_ROOM_SIZE),connID);
return FALSE;
}
CDWordArray& members=room->GetMembers();
members.Add(connID);
SetConnectionData(connID,(DWORD)room);
//更新成員列表
CListCtrl& roomListCtrl=m_mainFrm.GetRoomListCtrl();
for(int i=0;i<roomListCtrl.GetItemCount();i++)
{
if(roomListCtrl.GetItemText(i,0).CompareNoCase(room->GetName())==0)
{
CString num;
num.Format("%d",room->GetMemberCount());
roomListCtrl.SetItemText(i,1,num);
break;
}
}
int index=roomListCtrl.GetNextItem(-1,LVNI_SELECTED);
if(index>=0&&roomListCtrl.GetItemData(index)==((DWORD)room))
{
CListCtrl& memberListCtrl=m_mainFrm.GetMemberListCtrl();
int index=memberListCtrl.InsertItem(memberListCtrl.GetItemCount(),GetRemoteName(connID));
if(index>=0)
{
memberListCtrl.SetItemData(index,connID);
char str[256]="";
GetRemoteAddress(connID,str,256);
memberListCtrl.SetItemText(index,1,str);
GetRemoteApplication(connID,str,256);
memberListCtrl.SetItemText(index,2,str);
memberListCtrl.SetItemData(index,connID);
}
}
m_mainFrm.Output(IDS_LOG_ADDTOROOM,connID,room->GetName());
return TRUE;
}
CString CMCUEndPoint::GetRemoteName(DWORD connID)
{
CString ret;
char name[256]="";
GetRemotePartyName(connID,name,256);
ret=name;
int i=ret.ReverseFind('[');
if(i>=0)
{
ret.Delete(i,ret.GetLength()-i);
ret.TrimRight(' ');
}
return ret;
}
BOOL CMCUEndPoint::RemoveMember(DWORD connID)
{//成員離開會議
CRoom *room=(CRoom*)GetConnectionData(connID);
if(room==NULL)
return FALSE;
room->RemoveMember(connID);
CListCtrl &roomListCtrl=m_mainFrm.GetRoomListCtrl();
int index=roomListCtrl.GetNextItem(-1,LVNI_SELECTED);
if(index>=0&&roomListCtrl.GetItemText(index,0).CompareNoCase(room->GetName())==0)
{
CListCtrl& memberListCtrl=m_mainFrm.GetMemberListCtrl();
for(int i=0;i<memberListCtrl.GetItemCount();i++)
{
if(memberListCtrl.GetItemData(i)==connID)
{
memberListCtrl.DeleteItem(i);
break;
}
}
}
m_mainFrm.Output(IDS_LOG_LEAVE_ROOM,connID,room->GetName());
for(int i=0;i<roomListCtrl.GetItemCount();i++)
{
if(roomListCtrl.GetItemData(i)==((DWORD)room))
{
if(room->GetMemberCount()==0)
{
RemoveRoom(room->GetName());
}
else
{
CString num;
num.Format("%d",room->GetMemberCount());
roomListCtrl.SetItemText(i,1,num);
break;
}
}
}
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -