📄 h323.cxx
字号:
<< member->GetVideoTxFrameRate() << '/' << member->GetVideoRxFrameRate()
<< "</td>"
#endif
<< "</tr>";
}
}
members << "</table>";
SpliceMacro(insert, "RoomName", conference.GetNumber());
SpliceMacro(insert, "RoomMemberCount", PString(PString::Unsigned, (long)memberListSize));
SpliceMacro(insert, "RoomMembers", members);
substitution += insert;
}
return substitution;
}
PString OpenMCUH323EndPoint::GetMonitorText()
{
PStringStream output;
PWaitAndSignal m(conferenceManager.GetConferenceListMutex());
ConferenceListType & conferenceList = conferenceManager.GetConferenceList();
output << "Room Count: " << (int)conferenceList.size() << "\n"
<< "Max Room Count: " << conferenceManager.GetMaxConferenceCount() << "\n";
ConferenceListType::iterator r;
PINDEX confNum = 0;
for (r = conferenceList.begin(); r != conferenceList.end(); ++r) {
Conference & conference = *(r->second);
PWaitAndSignal m(conference.GetMutex());
Conference::MemberList & memberList = conference.GetMemberList();
output << "\n[Conference " << ++confNum << "]\n"
<< "Title: " << conference.GetNumber() << "\n"
<< "ID: " << conference.GetID() << "\n"
<< "Duration: " << (PTime() - conference.GetStartTime()) << "\n"
<< "Member Count: " << (int)memberList.size() << "\n"
<< "Max Member Count: " << conference.GetMaxMemberCount() << "\n";
Conference::MemberList::const_iterator s;
PINDEX num = 0;
for (s = memberList.begin(); s != memberList.end(); ++s) {
ConferenceMember * member = s->second;
if (member != NULL) {
PStringStream hdr; hdr << "Member " << ++num << " ";
output << hdr << "Title: " << member->GetTitle() << "\n"
<< hdr << "Duration: " << (PTime() - member->GetStartTime()) << "\n"
<< member->GetMonitorInfo(hdr);
}
}
}
return output;
}
BOOL OpenMCUH323EndPoint::OutgoingConferenceRequest(const PString & room)
{
// create/find the conference
BOOL stat = conferenceManager.MakeAndLockConference(room) != NULL;
conferenceManager.UnlockConference();
return stat;
}
PString OpenMCUH323EndPoint::IncomingConferenceRequest(H323Connection & connection,
const H323SignalPDU & setupPDU)
{
const H225_Setup_UUIE & setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
/*
Here is the algorithm used for joining a conference.
- If the conference goal is e_invite, then refuse the call
- if the conference ID matches the ID of an existing conference, then join that conference
- If there is no destination address, join the default conference
- If there is a destination address, try and match the destination address
to a conference number. If there is a match, join to that conference
- If the destination address does not match any conference, create a new conference
*/
// get the conference ID from the incoming call
OpalGloballyUniqueID conferenceID = setup.m_conferenceID;
PString roomToJoin;
// check the conference ID
if (conferenceManager.HasConference(conferenceID, roomToJoin)) {
PTRACE(3, "MCU\tUsing conference ID to join existing room " << roomToJoin);
return roomToJoin;
}
// look at destination addresses
PINDEX i;
for (i = 0; (i < setup.m_destinationAddress.GetSize()); i++) {
roomToJoin = H323GetAliasAddressString(setup.m_destinationAddress[i]);
if (conferenceManager.HasConference(roomToJoin)) {
PTRACE(3, "MCU\tJoining room specified by destination address " << roomToJoin);
return roomToJoin;
}
}
// look at Q931 called party number
if (roomToJoin.IsEmpty() && !setupPDU.GetQ931().GetCalledPartyNumber(roomToJoin) && roomToJoin.IsEmpty()) {
if (conferenceManager.HasConference(roomToJoin)) {
PTRACE(3, "MCU\tJoining room specified by Q.931 called party " << roomToJoin);
return roomToJoin;
}
}
// if there is a room to create, then join this call to that conference
if (roomToJoin.IsEmpty())
roomToJoin = OpenMCU::Current().GetDefaultRoomName();
if (!roomToJoin.IsEmpty()) {
PTRACE(3, "MCU\tJoining default room " << roomToJoin);
return roomToJoin;
}
PTRACE(3, "MCU\tRefusing call because no room specified, and no default room");
return PString::Empty();
}
///////////////////////////////////////////////////////////////
NotifyH245Thread::NotifyH245Thread(Conference & conference, BOOL _join, ConferenceMember * _memberToIgnore)
: PThread(10000, AutoDeleteThread), join(_join), memberToIgnore(_memberToIgnore)
{
mcuNumber = conference.GetMCUNumber();
terminalIdToSend = memberToIgnore->GetTerminalNumber();
// create list of connections to notify
Conference::MemberList::const_iterator r;
for (r = conference.GetMemberList().begin(); r != conference.GetMemberList().end(); r++) {
ConferenceMember * mbr = r->second;
if (mbr != memberToIgnore) {
H323Connection_ConferenceMember * h323Mbr = dynamic_cast<H323Connection_ConferenceMember *>(mbr);
if (h323Mbr != NULL)
tokens += h323Mbr->GetH323Token();
}
}
Resume();
}
void NotifyH245Thread::Main()
{
OpenMCUH323EndPoint & ep = OpenMCU::Current().GetEndpoint();
// send H.245 message on each connection in turn
PINDEX i;
for (i = 0; i < tokens.GetSize(); ++i) {
H323Connection * conn = ep.FindConnectionWithLock(tokens[i]);
if (conn != NULL) {
OpenMCUH323Connection * h323Conn = dynamic_cast<OpenMCUH323Connection *>(conn);
H323ControlPDU pdu;
H245_ConferenceIndication & ind = pdu.Build(H245_IndicationMessage::e_conferenceIndication);
ind.SetTag(join ? H245_ConferenceIndication::e_terminalJoinedConference : H245_ConferenceIndication::e_terminalLeftConference);
H245_TerminalLabel & terminalId = ind;
terminalId.m_mcuNumber = mcuNumber;
terminalId.m_terminalNumber = terminalIdToSend;
h323Conn->WriteControlPDU(pdu);
h323Conn->Unlock();
}
}
}
///////////////////////////////////////////////////////////////
OpenMCUH323Connection::OpenMCUH323Connection(OpenMCUH323EndPoint & _ep, unsigned callReference, void * userData)
: H323Connection(_ep, callReference), ep(_ep), isMCU(FALSE)
{
conference = NULL;
conferenceMember = NULL;
welcomeState = NotStartedYet;
if (userData != NULL) {
requestedRoom = *(PString *)userData;
delete (PString *)userData;
}
audioReceiveCodecName = audioTransmitCodecName = "none";
#if OPENMCU_VIDEO
videoGrabber = NULL;
videoDisplay = NULL;
videoReceiveCodecName = videoTransmitCodecName = "none";
#endif
}
OpenMCUH323Connection::~OpenMCUH323Connection()
{
}
BOOL OpenMCUH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
{
// get a good name from the other end
const H225_Setup_UUIE & setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
remoteName = setupPDU.GetQ931().GetDisplayName();
if (remoteName.IsEmpty()) {
if (setup.HasOptionalField(H225_Setup_UUIE::e_sourceAddress))
remoteName = H323GetAliasAddressString(setup.m_sourceAddress[0]);
}
if (remoteName.IsEmpty()) {
if (!setupPDU.GetQ931().GetCallingPartyNumber(remoteName))
remoteName.MakeEmpty();
}
if (remoteName.IsEmpty())
remoteName = GetRemotePartyName();
isMCU = setup.m_sourceInfo.m_mc;
return H323Connection::OnReceivedSignalSetup(setupPDU);
}
BOOL OpenMCUH323Connection::OnReceivedCallProceeding(const H323SignalPDU & proceedingPDU)
{
const H225_CallProceeding_UUIE & proceeding = proceedingPDU.m_h323_uu_pdu.m_h323_message_body;
isMCU = proceeding.m_destinationInfo.m_mc;
return H323Connection::OnReceivedCallProceeding(proceedingPDU);
}
void OpenMCUH323Connection::CleanUpOnCallEnd()
{
LeaveConference();
H323Connection::CleanUpOnCallEnd();
}
H323Connection::AnswerCallResponse OpenMCUH323Connection::OnAnswerCall(const PString & /*caller*/,
const H323SignalPDU & setupPDU,
H323SignalPDU & /*connectPDU*/)
{
requestedRoom = ep.IncomingConferenceRequest(*this, setupPDU);
if (requestedRoom.IsEmpty())
return AnswerCallDenied;
return AnswerCallNow;
}
void OpenMCUH323Connection::OnEstablished()
{
H323Connection::OnEstablished();
}
class MemberDeleteThread : public PThread
{
public:
MemberDeleteThread(OpenMCUH323EndPoint * _ep, Conference * _conf, ConferenceMember * _cm)
: PThread(10000, AutoDeleteThread), ep(_ep), conf(_conf), cm(_cm)
{
Resume();
}
void Main()
{
cm->WaitForClose();
if (conf->RemoveMember(cm))
ep->GetConferenceManager().RemoveConference(conf->GetID());
delete cm;
}
protected:
OpenMCUH323EndPoint * ep;
Conference * conf;
ConferenceMember * cm;
};
void OpenMCUH323Connection::JoinConference(const PString & roomToJoin)
{
PWaitAndSignal m(connMutex);
if (conference != NULL)
return;
BOOL joinSuccess = FALSE;
if (!roomToJoin.IsEmpty()) {
// create or join the conference
ConferenceManager & manager = ((OpenMCUH323EndPoint &)ep).GetConferenceManager();
Conference * newConf = manager.MakeAndLockConference(roomToJoin);
if (newConf != NULL) {
conference = newConf;
conferenceIdentifier = conference->GetID();
conferenceMember = new H323Connection_ConferenceMember(conference, ep, GetCallToken(), this, isMCU);
if (!conferenceMember->IsJoined())
PTRACE(1, "MCU\tMember connection refused");
else
joinSuccess = TRUE;
manager.UnlockConference();
if(!joinSuccess) {
new MemberDeleteThread(&ep, conference, conferenceMember);
conferenceMember = NULL;
conference = NULL;
}
}
}
if(!joinSuccess)
ChangeWelcomeState(JoinFailed);
}
void OpenMCUH323Connection::LeaveConference()
{
PWaitAndSignal m(connMutex);
if (conference != NULL && conferenceMember != NULL) {
LogCall();
new MemberDeleteThread(&ep, conference, conferenceMember);
conferenceMember = NULL;
conference = NULL;
// - called from another thread than usual
// - may clear the call immediately
ChangeWelcomeState(ConferenceEnded);
}
}
BOOL OpenMCUH323Connection::OpenAudioChannel(BOOL isEncoding, unsigned /* bufferSize */, H323AudioCodec & codec)
{
PWaitAndSignal m(connMutex);
PString codecName = codec.GetMediaFormat();
codec.SetSilenceDetectionMode( H323AudioCodec::NoSilenceDetection );
if (!isEncoding) {
audioReceiveCodecName = codecName;
codec.AttachChannel(new IncomingAudio(ep, *this), TRUE);
} else {
audioTransmitCodecName = codecName;
codec.AttachChannel(new OutgoingAudio(ep, *this), TRUE);
}
return TRUE;
}
#if OPENMCU_VIDEO
BOOL OpenMCUH323Connection::OpenVideoChannel(BOOL isEncoding, H323VideoCodec & codec)
{
PWaitAndSignal m(connMutex);
if (isEncoding) {
videoTransmitCodecName = codec.GetMediaFormat();
PVideoChannel * channel = new PVideoChannel;
videoGrabber = new PVideoInputDevice_OpenMCU(*this);
if (videoGrabber == NULL) {
PTRACE(3, "Cannot create MCU video input driver");
return FALSE;
}
if (!InitGrabber(videoGrabber, CIF_WIDTH, CIF_HEIGHT)) {
delete videoGrabber;
videoGrabber = NULL;
return FALSE;
}
codec.SetTxQualityLevel(ep.GetVideoTxQuality());
videoGrabber->Start();
channel->AttachVideoReader(videoGrabber);
if (!codec.AttachChannel(channel,TRUE))
return FALSE;
} else {
videoReceiveCodecName = codec.GetMediaFormat();
videoDisplay = new PVideoOutputDevice_OpenMCU(*this);
if (!videoDisplay->Open("")) {
delete videoDisplay;
return FALSE;
}
videoDisplay->SetFrameSize(codec.GetWidth(), codec.GetHeight()); // needed to enable resize
videoDisplay->SetColourFormatConverter("YUV420P");
PVideoChannel * channel = new PVideoChannel;
channel->AttachVideoPlayer(videoDisplay);
if (!codec.AttachChannel(channel,TRUE))
return FALSE;
}
return TRUE;
}
BOOL OpenMCUH323Connection::InitGrabber(PVideoInputDevice * grabber, int newFrameWidth, int newFrameHeight)
{
PTRACE(4, "Video grabber set to " << newFrameWidth << "x" << newFrameHeight);
//if (!(pfdColourFormat.IsEmpty()))
// grabber->SetPreferredColourFormat(pfdColourFormat);
if (!grabber->Open("", FALSE)) {
PTRACE(3, "Failed to open the video input device");
return FALSE;
}
//if (!grabber->SetChannel(ep.GetVideoPlayMode())) {
// PTRACE(3, "Failed to set channel to " << ep.GetVideoPlayMode());
// return FALSE;
//}
//if (!grabber->SetVideoFormat(
// ep.GetVideoIsPal() ? PVideoDevice::PAL : PVideoDevice::NTSC)) {
// PTRACE(3, "Failed to set format to " << (ep.GetVideoIsPal() ? "PAL" : "NTSC"));
// return FALSE;
//}
if (!grabber->SetColourFormatConverter("YUV420P") ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -