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

📄 h323.cxx

📁 这是一个OPENH323中的MCU程序
💻 CXX
📖 第 1 页 / 共 3 页
字号:
                << 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 + -