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

📄 conference.cxx

📁 这是一个OPENH323中的MCU程序
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/*
 * conference.cxx
 *
 * Conferencing functions for a simple MCU
 *
 * Copyright (c) 2000 Equivalence Pty. Ltd.
 * Copyright (c) 2004 Post Increment
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions of ths code were written by by Post Increment (http://www.postincrement.com) 
 * with the assistance of funding from Stonevoice, slc. http://www.stonevoice.com
 *
 * Portions of this code were written by Post Increment (http://www.postincrement.com) 
 * with the assistance of funding from Citron Networks (http://www.citron.com.tw)
 *
 * Contributor(s): Derek J Smithies (derek@indranet.co.nz)
 *                 Craig Southeren (craig@postincrement.com)
 *
 * $Log: conference.cxx,v $
 * Revision 1.1  2007/10/17 19:44:28  shorne
 * Initial Commit
 *
 * Revision 2.12  2006/08/07 06:18:22  csoutheren
 * Fix detection of MCU members
 * Add auto-removal of conferences only containing MCU members
 *
 * Revision 2.11  2006/07/21 08:01:40  csoutheren
 * Fixed conference member detect
 * Re-factored video mixer code slightly
 *
 * Revision 2.10  2006/07/21 05:52:51  csoutheren
 * Add flag to indicate if remote endpoint is an MCU
 *
 * Revision 2.9  2006/07/21 05:08:03  csoutheren
 * Stability fixes and more inline documentation
 * Thanks to Paolo Amadini of Stonevoice
 *
 * Revision 2.8  2006/06/09 04:39:59  csoutheren
 * Migrated VideoBranch to main trunk
 *
 * Revision 2.7.2.18  2006/06/06 08:24:16  csoutheren
 * Added support for echo test room
 * Fix problem with using high frame rates
 *
 * Revision 2.7.2.17  2006/05/31 08:48:02  csoutheren
 * Fixed crash on second call when entry/exit files do not exist
 * Fix crash when Cisco HOLD used. Thanks to Christian Bongiovanni of Stonevoice
 *
 * Revision 2.7.2.16  2006/05/16 02:20:39  csoutheren
 * Fixed problems compiling without video
 *
 * Revision 1.8  2006/05/16 00:29:18  craigs
 * Fixed compilation when video disabled
 *
 * Revision 1.7  2006/04/26 16:02:21  craigs
 * Update to latest public sources
 * Added ability to have per-conference timeout and reminders
 *
 * Revision 2.7.2.15  2006/04/26 15:03:16  csoutheren
 * Added better override for creating conferenc
 *
 * Revision 2.7.2.14  2006/04/26 13:09:08  csoutheren
 * Fix problem when connecting file not available
 * Add optional time limit for rooms
 *
 * Revision 2.7.2.13  2006/04/18 03:05:09  csoutheren
 * Fix video mix problem with > 3 members
 * Add test room
 *
 * Revision 2.7.2.12  2006/04/12 22:58:16  csoutheren
 * Removed return in function returning void
 *
 * Revision 2.7.2.11  2006/04/12 04:54:18  csoutheren
 * Fix more problems with audio-only members
 *
 * Revision 2.7.2.10  2006/04/11 03:46:46  csoutheren
 * Fixed problem with hangup during entering wav file play
 *
 * Revision 2.7.2.9  2006/04/06 08:20:29  csoutheren
 * Retyped conference member identifier to epxlicit type
 * Added support for H.245 terminal added and terminal left
 *
 * Revision 2.7.2.8  2006/04/06 01:11:16  csoutheren
 * Latest sources include
 *   - premedia blanking and optional image display
 *   - ablity to defer conference join for authentication if required
 *   - more bulletproofing on conference join
 *   - new video copy/fill functions
 *
 * Revision 2.7.2.7  2006/04/06 00:50:28  csoutheren
 * Latest changes (more to come)
 *
 * Revision 2.7.2.6  2006/03/28 05:13:38  csoutheren
 * Normalised file headers
 * Fixed problem with QCIF video
 * Seperated H.323 and MCU process functions into seperate files
 *
 * Revision 2.7.2.5  2006/03/24 22:49:24  csoutheren
 * Video now working
 *
 * Revision 2.7.2.4  2006/03/21 14:02:49  csoutheren
 * More video mixiing.
 * Still some crashes in video mixer code when members exit conference
 *
 * Revision 2.7.2.3  2006/03/17 07:00:24  csoutheren
 * More video implementation
 * Video mixing now working except copying subimage UV components causes overrun
 * Y is OK, which is why the images are grey. Also need to work out flipping requirements
 *
 * Revision 2.7.2.2  2006/03/14 08:02:50  csoutheren
 * More implemenrtation of video
 * Video mixing infrastructure implemented but not fully working
 *
 * Revision 2.7.2.1  2006/03/06 05:45:30  csoutheren
 * Start of implementation for video. Still in progress
 *
 * Revision 2.7  2006/02/08 06:54:44  csoutheren
 * Added extra information to monitoring page
 *
 * Revision 2.6  2006/02/03 07:21:41  csoutheren
 * Added INVITE function via web interface
 *
 * Revision 2.5  2004/09/22 22:39:26  csoutheren
 * Fixed race condition, thanks to Neil McCurdy
 *
 * Revision 2.4  2004/05/26 06:54:31  csoutheren
 * Changed to be a PHTTPServiceProcess
 * Added ability to play WAV files on member entry and exit
 * Added additional documentation on all classes
 * Preparation for re-introducing video
 *
 * Revision 2.3  2004/03/31 03:36:38  csoutheren
 * Fixed problem with user indication messages
 * Fixed problems with room listener and unlisten
 *
 * Revision 2.2  2004/03/30 11:27:23  csoutheren
 * Reverted to old mixing algorithm
 *
 * Revision 2.1  2004/03/23 11:40:06  csoutheren
 * Fixed problem where deleting map element in-place causes crash at end of call
 * Fixed problem where referencing map by iterator rather than ID
 * Fixed code formatting problems
 *
 * Revision 2.0  2004/03/08 02:06:24  csoutheren
 * Totally rewritten to use new connection locking mecahnism
 * Added ability to monitor conferences
 * Added initial support for H.323 MCU messages
 * Thanks to Citron Networks for supporting this work
 *
 */

#include <ptlib.h>

#include "conference.h"
#include "mcu.h"

#if OPENMCU_VIDEO
#include <ptlib/vconvert.h>
#endif

// size of a PCM data packet, in samples
#define PCM_PACKET_LEN          240

// size of a PCM data buffer, in bytes
#define PCM_BUFFER_LEN          (PCM_PACKET_LEN * 2)

// number of PCM buffers to keep
#define PCM_BUFFER_COUNT        2

#define PCM_BUFFER_SIZE         (PCM_BUFFER_LEN * PCM_BUFFER_COUNT)

////////////////////////////////////////////////////////////////////////////////////

ConferenceManager::ConferenceManager()
{
  maxConferenceCount = 0;
  monitor  = new ConferenceMonitor(*this);
}

ConferenceManager::~ConferenceManager()
{
  monitor->running = FALSE;
  monitor->WaitForTermination();
  delete monitor;
}


Conference * ConferenceManager::MakeAndLockConference(const PString & roomToCreate, const PString & name)
{
  PWaitAndSignal m(conferenceListMutex);

  OpalGloballyUniqueID conferenceID;
  ConferenceListType::const_iterator r;
  for (r = conferenceList.begin(); r != conferenceList.end(); ++r) {
    if (roomToCreate == r->second->GetNumber()) {
      conferenceID = r->second->GetID();
      break;
    }
  }

  return MakeAndLockConference(conferenceID, roomToCreate, name);
}


Conference * ConferenceManager::MakeAndLockConference(const OpalGloballyUniqueID & conferenceID, 
                                                                   const PString & roomToCreate, 
                                                                   const PString & name)
{
  conferenceListMutex.Wait();

  Conference * conference = NULL;
  BOOL newConference = FALSE;
  ConferenceListType::const_iterator r = conferenceList.find(conferenceID);
  if (r != conferenceList.end())
    conference = r->second;
  else {
    // create the conference
    conference = CreateConference(conferenceID, roomToCreate, name, mcuNumberMap.GetNumber(conferenceID));

    // insert conference into the map
    conferenceList.insert(ConferenceListType::value_type(conferenceID, conference));

    // set the conference count
    maxConferenceCount = PMAX(maxConferenceCount, (PINDEX)conferenceList.size());
    newConference = TRUE;
  }

  if (newConference)
    OnCreateConference(conference);

  return conference;
}

void ConferenceManager::OnCreateConference(Conference * conference)
{
  // set time limit, if there is one
  int timeLimit = OpenMCU::Current().GetRoomTimeLimit();
  if (timeLimit > 0)
    monitor->AddMonitorEvent(new ConferenceTimeLimitInfo(conference->GetID(), PTime() + timeLimit*1000));
}

Conference * ConferenceManager::CreateConference(const OpalGloballyUniqueID & _guid,
                                                              const PString & _number,
                                                              const PString & _name,
                                                                          int _mcuNumber)
{ 
#if OPENMCU_VIDEO
#if ENABLE_ECHO_MIXER
  if (_number *= "echo")
    return new Conference(*this, _guid, _guid.AsString(), _name, _mcuNumber, new EchoVideoMixer());
#endif
#if ENABLE_TEST_ROOMS
  if (_number.Left(8) == "testroom") {
    int count = _number.Mid(8).AsInteger();
    if (count > 0)
      return new Conference(*this, _guid, _number, _name, _mcuNumber, new TestVideoMixer(count));
  }
#endif
#endif

  return new Conference(*this, _guid, _number, _name, _mcuNumber
#if OPENMCU_VIDEO
                        ,OpenMCU::Current().CreateVideoMixer()
#endif
                        ); 
}

BOOL ConferenceManager::HasConference(const OpalGloballyUniqueID & conferenceID, PString & number)
{
  PWaitAndSignal m(conferenceListMutex);
  ConferenceListType::const_iterator r = conferenceList.find(conferenceID);
  if (r == conferenceList.end())
    return FALSE;
  number = r->second->GetNumber();
  return TRUE;
}

BOOL ConferenceManager::HasConference(const PString & number, OpalGloballyUniqueID & conferenceID)
{
  PWaitAndSignal m(conferenceListMutex);
  ConferenceListType::const_iterator r;
  for (r = conferenceList.begin(); r != conferenceList.end(); ++r) {
    if (r->second->GetNumber() == number) {
      conferenceID = r->second->GetID();
      return TRUE;
    }
  }
  return FALSE;
}

void ConferenceManager::RemoveConference(const OpalGloballyUniqueID & confId)
{
  PWaitAndSignal m(conferenceListMutex);
  ConferenceListType::iterator r = conferenceList.find(confId);
  if (r != conferenceList.end())  {
    Conference * conf = r->second;
    OnDestroyConference(conf);
    conferenceList.erase(confId);
    mcuNumberMap.RemoveNumber(conf->GetMCUNumber());
    monitor->RemoveForConference(conf->GetID());

    delete conf;
  }
}

void ConferenceManager::RemoveMember(const OpalGloballyUniqueID & confId, ConferenceMember * toRemove)
{
  PWaitAndSignal m(conferenceListMutex);
  Conference * conf = toRemove->GetConference();

  OpalGloballyUniqueID id = conf->GetID();  // make a copy of the ID because it may be about to disappear

  BOOL removeConf = conf->RemoveMember(toRemove);
  delete toRemove;
  if (removeConf)
    RemoveConference(id);
}

void ConferenceManager::AddMonitorEvent(ConferenceMonitorInfo * info)
{
  monitor->AddMonitorEvent(info);
}


///////////////////////////////////////////////////////////////

void ConferenceMonitor::Main()
{
  running = TRUE;

  for (;;) {

    if (!running)
      break;

    Sleep(1000);

    if (!running)
      break;

    PWaitAndSignal m(mutex);

    PTime now;
    MonitorInfoList::iterator r = monitorList.begin();
    while (r != monitorList.end()) {
      ConferenceMonitorInfo & info = **r;
      if (now < info.timeToPerform)
        ++r;
      else {
        BOOL deleteAfterPerform = TRUE;
        {
          PWaitAndSignal m2(manager.GetConferenceListMutex());
          ConferenceListType & confList = manager.GetConferenceList();
          ConferenceListType::iterator s = confList.find(info.guid);
          if (s != confList.end())
            deleteAfterPerform = info.Perform(*s->second);
        }
        if (!deleteAfterPerform)
          ++r;
        else {
          delete *r;
          monitorList.erase(r);
          r = monitorList.begin();
        }
      }
    }
  }
}

void ConferenceMonitor::AddMonitorEvent(ConferenceMonitorInfo * info)
{
  PWaitAndSignal m(mutex);
  monitorList.push_back(info);
}

void ConferenceMonitor::RemoveForConference(const OpalGloballyUniqueID & guid)
{
  PWaitAndSignal m(mutex);

  MonitorInfoList::iterator r = monitorList.begin();
  while (r != monitorList.end()) {
    ConferenceMonitorInfo & info = **r;
    if (info.guid != guid)
      ++r;
    else {
      delete *r;
      monitorList.erase(r);

⌨️ 快捷键说明

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