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

📄 conference.cxx

📁 这是一个OPENH323中的MCU程序
💻 CXX
📖 第 1 页 / 共 3 页
字号:
      r = monitorList.begin();
    }
  }
}

BOOL ConferenceTimeLimitInfo::Perform(Conference & conference)
{
  Conference::MemberList & list = conference.GetMemberList();
  Conference::MemberList::iterator r;
  for (r = list.begin(); r != list.end(); ++r)
    r->second->Close();
  return TRUE;
}

BOOL ConferenceRepeatingInfo::Perform(Conference & conference)
{
  this->timeToPerform = PTime() + repeatTime;
  return FALSE;
}


BOOL ConferenceMCUCheckInfo::Perform(Conference & conference)
{
  // see if any member of this conference is a not an MCU
  Conference::MemberList & list = conference.GetMemberList();
  Conference::MemberList::iterator r;
  for (r = list.begin(); r != list.end(); ++r)
    if (!r->second->IsMCU())
      break;

  // if there is any non-MCU member, check again later
  if (r != list.end())
    return ConferenceRepeatingInfo::Perform(conference);

  // else shut down the conference
  for (r = list.begin(); r != list.end(); ++r)
    r->second->Close();

  return TRUE;
}


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

Conference::Conference(        ConferenceManager & _manager,
                       const OpalGloballyUniqueID & _guid,
                                    const PString & _number,
                                    const PString & _name,
                                                int _mcuNumber
#if OPENMCU_VIDEO
                                    ,MCUVideoMixer * _videoMixer
#endif
)
  : manager(_manager), guid(_guid), number(_number), name(_name), mcuNumber(_mcuNumber), mcuMonitorRunning(FALSE)
#if OPENMCU_VIDEO
    ,videoMixer(_videoMixer)
#endif
{ 
  maxMemberCount = 0;

  PTRACE(3, "Conference\tNew conference started: ID=" << guid << ", number = " << number);
}

Conference::~Conference()
{
#if OPENMCU_VIDEO
  delete videoMixer;
#endif
}

int Conference::GetVisibleMemberCount() const
{
  PWaitAndSignal m(memberListMutex);
  int visibleMembers = 0;
  std::map<void *, ConferenceMember *>::const_iterator r;
  for (r = memberList.begin(); r != memberList.end(); r++) {
    if (r->second->IsVisible())
      ++visibleMembers;
  }
  return visibleMembers;
}

void Conference::AddMonitorEvent(ConferenceMonitorInfo * info)
{ 
  manager.AddMonitorEvent(info); 
}


BOOL Conference::AddMember(ConferenceMember * memberToAdd)
{
  PTRACE(3, "Conference\tAbout to add member " << memberToAdd->GetTitle() << " to conference " << guid);

  // see if the callback refuses the new member
  if (!BeforeMemberJoining(memberToAdd))
    return FALSE;

  // add the member to the conference
  if (!memberToAdd->AddToConference(this))
    return FALSE;

  {
    // lock the member list
    PWaitAndSignal m(memberListMutex);

#if OPENMCU_VIDEO
    if (UseSameVideoForAllMembers() && memberToAdd->IsVisible()) {
      if (!videoMixer->AddVideoSource(memberToAdd->GetID(), *memberToAdd)) 
        return FALSE;
    }
#endif

    PTRACE(3, "Conference\tAdding member " << memberToAdd->GetTitle() << " to conference " << guid);

    // add this member to the conference member list
    memberList.insert(MemberList::value_type(memberToAdd->GetID(), memberToAdd));

    int tid = terminalNumberMap.GetNumber(memberToAdd->GetID());
    memberToAdd->SetTerminalNumber(tid);

    // make sure each member has a connection created for the new member
    // make sure the new member has a connection created for each existing member
    PINDEX visibleMembers = 0;
    std::map<void *, ConferenceMember *>::const_iterator r;
    for (r = memberList.begin(); r != memberList.end(); r++) {
      ConferenceMember * conn = r->second;
      if (conn != memberToAdd) {
        conn->AddConnection(memberToAdd);
        memberToAdd->AddConnection(conn);
#if OPENMCU_VIDEO
        if (!UseSameVideoForAllMembers()) {
          if (conn->IsVisible())
            memberToAdd->AddVideoSource(conn->GetID());
          if (memberToAdd->IsVisible())
            conn->AddVideoSource(memberToAdd->GetID());
        }
#endif
      }
      if (conn->IsVisible())
        ++visibleMembers;
    }

    // update the statistics
    if (memberToAdd->IsVisible()) {
      maxMemberCount = PMAX(maxMemberCount, visibleMembers);

      // trigger H245 thread for join message
      new NotifyH245Thread(*this, TRUE, memberToAdd);
    }
  }

  // notify that member is joined
  memberToAdd->SetJoined(TRUE);

  // call the callback function
  OnMemberJoining(memberToAdd);

  if (memberToAdd->IsMCU() && !mcuMonitorRunning) {
    manager.AddMonitorEvent(new ConferenceMCUCheckInfo(GetID(), 1000));
    mcuMonitorRunning = TRUE;
  }

  return TRUE;
}

BOOL Conference::RemoveMember(ConferenceMember * memberToRemove)
{
  if(!memberToRemove->IsJoined())
  {
    PTRACE(4, "Conference\tNo need to remove call " << memberToRemove->GetTitle() << " from conference " << guid);
    return (memberList.size() == 0);
  }

  PTRACE(3, "Conference\tRemoving call " << memberToRemove->GetTitle() << " from conference " << guid << " with size " << (PINDEX)memberList.size());
  cout << memberToRemove->GetTitle() << " leaving conference " << number << "(" << guid << ")" << endl;

  BOOL closeConference;
  {
    PWaitAndSignal m(memberListMutex);

    // remove this member from the connection lists for all other members
    MemberList::iterator r;
    for (r = memberList.begin(); r != memberList.end(); r++) {
      ConferenceMember * conn = r->second;
      if (conn != memberToRemove) {
        r->second->RemoveConnection(memberToRemove->GetID());
#if OPENMCU_VIDEO
        if (!UseSameVideoForAllMembers()) {
          if (memberToRemove->IsVisible())
            conn->RemoveVideoSource(memberToRemove->GetID());
          if (conn->IsVisible())
            memberToRemove->RemoveVideoSource(conn->GetID());
        }
#endif
      }
    }

#if OPENMCU_VIDEO
    if (UseSameVideoForAllMembers() && memberToRemove->IsVisible())
      videoMixer->RemoveVideoSource(memberToRemove->GetID(), *memberToRemove);
#endif

    // trigger H245 thread for leave message
    if (memberToRemove->IsVisible())
      new NotifyH245Thread(*this, FALSE, memberToRemove);

    terminalNumberMap.RemoveNumber(memberToRemove->GetTerminalNumber());

    // remove this connection from the member list
    memberList.erase(memberToRemove->GetID());

    // return TRUE if conference is empty 
    closeConference = memberList.size() == 0;
  }

  // notify that member is not joined anymore
  memberToRemove->SetJoined(FALSE);

  // call the callback function
  if (!closeConference)
    OnMemberLeaving(memberToRemove);

  return closeConference;
}


void Conference::ReadMemberAudio(ConferenceMember * member, void * buffer, PINDEX amount)
{
  // get number of channels to mix
  ConferenceMember::ConnectionListType & connectionList = member->GetConnectionList();
  ConferenceMember::ConnectionListType::iterator r;
  for (r = connectionList.begin(); r != connectionList.end(); ++r) 
    if (r->second != NULL)
      r->second->ReadAndMixAudio((BYTE *)buffer, amount, (PINDEX)connectionList.size());
}

void Conference::WriteMemberAudioLevel(ConferenceMember * member, unsigned audioLevel)
{
#if OPENMCU_VIDEO
  if (UseSameVideoForAllMembers()) {
    if (videoMixer != NULL)
      videoMixer->SetAudioLevel(member->GetID(), audioLevel);
  }
  else 
#endif // OPENMCU_VIDEO
  {
    PWaitAndSignal m(memberListMutex);
    MemberList::iterator r;
    for (r = memberList.begin(); r != memberList.end(); r++)
      r->second->OnExternalSetAudioLevel(member->GetID(), audioLevel);
  }
}

#if OPENMCU_VIDEO

void Conference::ReadMemberVideo(ConferenceMember * member, void * buffer, int width, int height, PINDEX & amount)
{
  if (videoMixer == NULL)
    return;

  if (videoMixer->ReadFrame(*member, buffer, width, height, amount))
    return;

  // find the other member and copy it's video
  PWaitAndSignal m(memberListMutex);
  MemberList::iterator r;
  for (r = memberList.begin(); r != memberList.end(); r++) {
    if ((r->second != member) && r->second->IsVisible()) {
      void * frameStore = r->second->OnExternalReadVideo(member->GetID(), width, height, amount);  
      if (frameStore != NULL) {
        memcpy(buffer, frameStore, amount);
        r->second->UnlockExternalVideo();
      }
    }
  }
}

BOOL Conference::WriteMemberVideo(ConferenceMember * member, const void * buffer, int width, int height, PINDEX amount)
{
  if (UseSameVideoForAllMembers()) {
    if (videoMixer != NULL)
      return videoMixer->WriteFrame(member->GetID(), buffer, width, height, amount);
  }
  else {
    PWaitAndSignal m(memberListMutex);
    MemberList::iterator r;
    for (r = memberList.begin(); r != memberList.end(); r++)
      r->second->OnExternalSendVideo(member->GetID(), buffer, width, height, amount);
  }
  return TRUE;
}

#endif

BOOL Conference::BeforeMemberJoining(ConferenceMember * member)
{ 
  return manager.BeforeMemberJoining(this, member); 
}

void Conference::OnMemberJoining(ConferenceMember * member)
{ 
  manager.OnMemberJoining(this, member); 
}

void Conference::OnMemberLeaving(ConferenceMember * member)
{ 
  manager.OnMemberLeaving(this, member); 
}


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

ConferenceMember::ConferenceMember(Conference * _conference, ConferenceMemberId _id, BOOL _isMCU)
  : conference(_conference), id(_id), isMCU(_isMCU)
{
  audioLevel = 0;
  terminalNumber = -1;
  memberIsJoined = FALSE;

#if OPENMCU_VIDEO
  videoMixer = NULL;
  fsConverter = PColourConverter::Create("YUV420P", "YUV420P", CIF_WIDTH, CIF_HEIGHT);
  MCUVideoMixer::FillCIFYUVFrame(memberFrameStores.GetFrameStore(CIF_WIDTH, CIF_HEIGHT).data.GetPointer(), 0, 0, 0);
  totalVideoFramesReceived = 0;
  firstFrameReceiveTime = -1;
  totalVideoFramesSent = 0;
  firstFrameSendTime = -1;
#endif
}

ConferenceMember::~ConferenceMember()
{
#if OPENMCU_VIDEO
  delete videoMixer;
#endif
}


BOOL ConferenceMember::AddToConference(Conference * _conference)
{
  //if (conference != NULL)
  //  return FALSE;
  //conference = _conference;

#if OPENMCU_VIDEO
  if (!conference->UseSameVideoForAllMembers())
    videoMixer = conference->GetVideoMixer()->Clone();
#endif

  return TRUE;
}

void ConferenceMember::RemoveFromConference()
{
  if (conference != NULL) {
    if (conference->RemoveMember(this))
      conference->GetManager().RemoveConference(conference->GetID());
  }
}

void ConferenceMember::AddConnection(ConferenceMember * memberToAdd)
{
  ConferenceMemberId newID = memberToAdd->GetID();
  PTRACE(3, "Conference\tAdding " << newID << " to connection " << id);
  if (lock.Wait(TRUE)) {
    ConferenceConnection * conn = memberToAdd->CreateConnection();
    memberList.insert(MemberListType::value_type(newID, memberToAdd));
    connectionList.insert(ConnectionListType::value_type(newID, conn));
    lock.Signal(TRUE);
  }
}

void ConferenceMember::RemoveConnection(ConferenceMemberId idToDelete)
{
  PTRACE(3, "Conference\tRemoving member " << idToDelete << " from connection " << id);
  if (lock.Wait(TRUE)) {
    memberList.erase(idToDelete);
    connectionList.erase(idToDelete);
    lock.Signal(TRUE);
  }
}

void ConferenceMember::SendUserInputIndication(const PString & str)
{ 
  PTRACE(3, "Conference\tConnection " << id << " sending user indication " << str);
  if (lock.Wait()) {
    MemberListType::iterator r;
    for (r = memberList.begin(); r != memberList.end(); ++r)
      if (r->second != NULL)
        r->second->OnReceivedUserInputIndication(str);
    lock.Signal();
  }
}

void ConferenceMember::WriteAudio(const void * buffer, PINDEX amount)
{
  // calculate average signal level for this member
  unsigned signalLevel = 0;
  {
    int sum = 0;
    const short * pcm = (short *)buffer;

⌨️ 快捷键说明

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