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

📄 h323.cxx

📁 这是一个OPENH323中的MCU程序
💻 CXX
📖 第 1 页 / 共 3 页
字号:
    PTRACE(3,"Failed to set format to yuv420p");
    return FALSE;
  }

  if (ep.GetVideoFrameRate() != 0) {
    if (!grabber->SetFrameRate(ep.GetVideoFrameRate())) {
      PTRACE(3, "Failed to set framerate to " << ep.GetVideoFrameRate());
      return FALSE;
    }
  }

  if (!grabber->SetFrameSizeConverter(newFrameWidth,newFrameHeight,FALSE)) {
    PTRACE(3, "Failed to set frame size to " << newFrameWidth << "x" << newFrameHeight);
    return FALSE;
  }

  return TRUE;
}

#endif

void OpenMCUH323Connection::OnUserInputString(const PString & str)
{
  PWaitAndSignal m(connMutex);

  if (conferenceMember != NULL)
    conferenceMember->SendUserInputIndication(str);
}


BOOL OpenMCUH323Connection::OnIncomingAudio(const void * buffer, PINDEX amount)
{
  PWaitAndSignal m(connMutex);

  // If record file is open, write data to it
  if (recordFile.IsOpen()) {
    recordFile.Write(buffer, amount);

    recordDuration += amount / 2;
    if (recordDuration > recordLimit) {
      recordFile.Close();
      OnFinishRecording();
    }
    else {
      const WORD * samples = (const WORD *)buffer;
      PINDEX sampleCount = amount / 2;
      BOOL silence = TRUE;
      while (sampleCount-- > 0 && silence) {
        if (*samples > 100 || *samples < -100)
          silence = FALSE;
        ++samples;
      }
      if (!silence)
        recordSilenceCount = 0;
      else {
        recordSilenceCount += amount / 2;
        if ((recordSilenceThreshold > 0) && (recordSilenceCount >= recordSilenceThreshold)) {
          recordFile.Close();
          OnFinishRecording();
        }
      }
    }
  }

  else if (conferenceMember != NULL)
    conferenceMember->WriteAudio(buffer, amount);

  return TRUE;
}

void OpenMCUH323Connection::StartRecording(const PFilePath & filename, unsigned limit, unsigned threshold)
{
  if (!recordFile.Open(filename, PFile::ReadWrite, PFile::Create | PFile::Truncate))
    return;

  recordSilenceCount = 0;
  recordDuration = 0;

  recordSilenceThreshold = threshold * 8000;
  recordLimit            = limit * 8000;
}

void OpenMCUH323Connection::OnFinishRecording()
{
}

BOOL OpenMCUH323Connection::OnOutgoingAudio(void * buffer, PINDEX amount)
{
  // When the prodedure begins, play the welcome file
  if (welcomeState == NotStartedYet) {
    ChangeWelcomeState(PlayingWelcome);
  }

  for (;;) {
    // Do actions that are not triggered by events
    OnWelcomeProcessing();

    // If a wave is not playing, we may continue now
    if (!playFile.IsOpen())
      break;

    // Wait for wave file completion
    if (playFile.Read(buffer, amount)) {
      int len = playFile.GetLastReadCount();
      if (len < amount) {
        memset(((BYTE *)buffer)+len, 0, amount-len);
      }
      //playDelay.Delay(amount/16);

      // Exit now since the buffer is ready
      return TRUE;
    }

    PTRACE(4, "MCU\tFinished playing file");
    playFile.Close();

    // Wave completed, if no event should be fired
    //  then we may continue now
    if(!wavePlayingInSameState)
      break;

    // Fire wave completion event
    OnWelcomeWaveEnded();

    // We should repeat the loop now because the callback
    //  above might have started a new wave file
  }

  PWaitAndSignal m(connMutex);

  // If a we are connected to a conference and no wave
  //  is playing, read data from the conference
  if (conferenceMember != NULL) {
    conferenceMember->ReadAudio(buffer, amount);
    return TRUE;
  }

  // Generate silence
  return FALSE;
}

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

void OpenMCUH323Connection::ChangeWelcomeState(int newState)
{
  PWaitAndSignal m(connMutex);

  if(welcomeState != newState)
  {
    PTRACE(4, "MCU\tEntering welcome state " << newState);
    welcomeState = newState;
    wavePlayingInSameState = FALSE;
    OnWelcomeStateChanged();
  }
}

void OpenMCUH323Connection::PlayWelcomeFile(BOOL useTheFile, PFilePath & fileToPlay)
{
  playFile.Close();

  wavePlayingInSameState = TRUE;

  if(useTheFile) {
    if(playFile.Open(fileToPlay, PFile::ReadOnly))
    {
      PTRACE(4, "MCU\tPlaying welcome procedure file " << fileToPlay);
      return;
    }
    else
      PTRACE(3, "MCU\tFailed to play welcome procedure file " << fileToPlay);
  }

  // File not played, call the wave end callback anyway
  OnWelcomeWaveEnded();
}

void OpenMCUH323Connection::OnWelcomeStateChanged()
{
  PFilePath fn;

  OpenMCU & mcu = OpenMCU::Current();

  switch(welcomeState) {

    case PlayingWelcome:
      // Welcome file not implemented yet
      PlayWelcomeFile(FALSE, fn);
      break;

    case PlayingConnecting:
      PlayWelcomeFile(mcu.GetConnectingWAVFile(fn), fn);
      break;

    case CompleteConnection:
      JoinConference(requestedRoom);
      break;

    case JoinFailed:
    case ConferenceEnded:
      // Goodbye file not implemented yet
      PlayWelcomeFile(FALSE, fn);
      break;

    default:
      // Do nothing
      break;
  }
}

void OpenMCUH323Connection::OnWelcomeProcessing()
{
}

void OpenMCUH323Connection::OnWelcomeWaveEnded()
{
  switch(welcomeState) {

    case PlayingWelcome:
      ChangeWelcomeState(PlayingConnecting);
      break;

    case PlayingConnecting:
      ChangeWelcomeState(CompleteConnection);
      break;

    case JoinFailed:
    case ConferenceEnded:
      ClearCall();
      break;

    default:
      // Do nothing
      break;
  }
}

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

#if OPENMCU_VIDEO

//
// this function is called whenever a connection needs a frame of video for output
//

BOOL OpenMCUH323Connection::OnOutgoingVideo(void * buffer, int width, int height, PINDEX & amount)
{
  PWaitAndSignal m(connMutex);

  if (conferenceMember != NULL)
    conferenceMember->ReadVideo(buffer, width, height, amount);
  else if (!GetPreMediaFrame(buffer, width, height, amount)) {
    if ((width == CIF_WIDTH) && (height == CIF_HEIGHT))
      MCUVideoMixer::FillCIFYUVFrame(buffer, 0, 0, 0);
    else if ((width == QCIF_WIDTH) && (height == QCIF_HEIGHT))
      MCUVideoMixer::FillQCIFYUVFrame(buffer, 0, 0, 0);
  }

  return TRUE;
}

BOOL OpenMCUH323Connection::GetPreMediaFrame(void * buffer, int width, int height, PINDEX & amount)
{
  return OpenMCU::Current().GetPreMediaFrame(buffer, width, height, amount);
}

//
// this function is called whenever a connection receives a frame of video
//

BOOL OpenMCUH323Connection::OnIncomingVideo(const void * buffer, int width, int height, PINDEX amount)
{
  if (conferenceMember != NULL)
    conferenceMember->WriteVideo(buffer, width, height, amount);
  return TRUE;
}

#endif // OPENMCU_VIDEO


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

H323Connection_ConferenceMember::H323Connection_ConferenceMember(Conference * _conference, OpenMCUH323EndPoint & _ep, const PString & _h323Token, ConferenceMemberId _id, BOOL _isMCU)
  : ConferenceMember(_conference, _id, _isMCU), ep(_ep), h323Token(_h323Token)
{ 
  conference->AddMember(this);
}

H323Connection_ConferenceMember::~H323Connection_ConferenceMember()
{
  PTRACE(4, "H323Connection_ConferenceMember deleted");
}

void H323Connection_ConferenceMember::Close()
{
  OpenMCUH323Connection * conn = (OpenMCUH323Connection *)ep.FindConnectionWithLock(h323Token);
  if (conn != NULL) {
    conn->LeaveConference();
    conn->Unlock();
  }
}

PString H323Connection_ConferenceMember::GetTitle() const
{
  PString output;
  OpenMCUH323Connection * conn = (OpenMCUH323Connection *)ep.FindConnectionWithLock(h323Token);
  if (conn != NULL) {
    output = conn->GetRemoteName();
    conn->Unlock();
  }
  return output;
}

PString H323Connection_ConferenceMember::GetMonitorInfo(const PString & hdr)
{ 
  PStringStream output;
  OpenMCUH323Connection * conn = (OpenMCUH323Connection *)ep.FindConnectionWithLock(h323Token);
  if (conn != NULL) {
    output << hdr << "Remote Address: " << conn->GetRemotePartyAddress() << "\n"
           << hdr << "AudioCodecs: " << conn->GetAudioTransmitCodecName() << '/' << conn->GetAudioReceiveCodecName() << "\n"
#if OPENMCU_VIDEO
           << hdr << "VideoCodecs: " << conn->GetVideoTransmitCodecName() << '/' << conn->GetVideoReceiveCodecName() << "\n"
#endif           
           ;
    conn->Unlock();
  }
  return output;
}

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

void OpenMCUH323Connection::LogCall(const BOOL accepted)
{
  H323TransportAddress address = GetControlChannel().GetRemoteAddress();
  PIPSocket::Address ip;
  WORD port;
  PStringStream stringStream, timeStream;
  address.GetIpAndPort(ip, port);
  timeStream << GetConnectionStartTime().AsString("hh:mm:ss");
  stringStream << ' ' << "caller-ip:" << ip << ':' << port << ' '
	             << GetRemotePartyName() 
               << " room:" << ((conference != NULL) ? conference->GetNumber() : PString());

  if (accepted) {
    PStringStream connectionDuration;
    connectionDuration << setprecision(0) << setw(5) << (PTime() - GetConnectionStartTime());
    OpenMCU::Current().LogMessage(timeStream + stringStream	+ " connection duration:" + connectionDuration);
  }
  else 
    OpenMCU::Current().LogMessage(timeStream + " Call denied:" + stringStream);		
}

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

OutgoingAudio::OutgoingAudio(H323EndPoint & _ep, OpenMCUH323Connection & _conn)
  : ep(_ep), conn(_conn)
{
  os_handle = 0;
}

void OutgoingAudio::CreateSilence(void * buffer, PINDEX amount)
{
  memset(buffer, 0, amount);
  lastReadCount = amount;
}

BOOL OutgoingAudio::Read(void * buffer, PINDEX amount)
{
  PWaitAndSignal mutexR(audioChanMutex);
  
  if (!IsOpen())
    return FALSE;

  // do the read call here, by calling conn.OnOutgoingAudio():
  if (!conn.OnOutgoingAudio(buffer, amount))
    CreateSilence(buffer, amount);

  delay.Delay(amount / 16);

  lastReadCount = amount;

  return TRUE;
}

BOOL OutgoingAudio::Close()
{
  if (!IsOpen()) 
    return FALSE;

  PWaitAndSignal mutexC(audioChanMutex);
  os_handle = -1;

  return TRUE;
}

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

IncomingAudio::IncomingAudio(H323EndPoint & _ep, OpenMCUH323Connection & _conn)
  : ep(_ep), conn(_conn)
{
  os_handle = 0;
}

BOOL IncomingAudio::Write(const void * buffer, PINDEX amount)
{
  PWaitAndSignal mutexW(audioChanMutex);
  
  if (!IsOpen())
    return FALSE;

  conn.OnIncomingAudio(buffer, amount);

  delay.Delay(amount / 16);

  return TRUE;
}

BOOL IncomingAudio::Close()
{
  if (!IsOpen())
    return FALSE;

  PWaitAndSignal mutexA(audioChanMutex);
  os_handle = -1;

  return TRUE;
}

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

⌨️ 快捷键说明

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