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

📄 call.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
      if (conn->SetAlerting(connection.GetRemotePartyName(), hasMedia))
        ok = TRUE;
    }
  }

  return ok;
}

OpalConnection::AnswerCallResponse
       OpalCall::OnAnswerCall(OpalConnection & /*connection*/,
                               const PString & /*caller*/)
{
  return OpalConnection::NumAnswerCallResponses;
}

void OpalCall::AnsweringCall(OpalConnection::AnswerCallResponse /*response*/)
{
}

BOOL OpalCall::OnConnected(OpalConnection & connection)
{
  PTRACE(3, "Call\tOnConnected " << connection);

  if (!LockReadOnly())
    return FALSE;

  BOOL ok = connectionsActive.GetSize() == 1 && !partyB.IsEmpty();

  UnlockReadOnly();

  if (ok) {
    if (!manager.MakeConnection(*this, partyB))
      connection.Release(OpalConnection::EndedByNoUser);
    return OnSetUp(connection);
  }

  BOOL createdOne = FALSE;

  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (conn != &connection) {
      if (conn->SetConnected())
        ok = TRUE;
    }

    OpalMediaFormatList formats = GetMediaFormats(*conn, TRUE);
    if (OpenSourceMediaStreams(*conn, formats, OpalMediaFormat::DefaultAudioSessionID))
      createdOne = TRUE;
    if (OpenSourceMediaStreams(*conn, formats, OpalMediaFormat::DefaultVideoSessionID))
      createdOne = TRUE;
  }

  if (ok && createdOne) {
    for (PSafePtr<OpalConnection> conn = connectionsActive; conn != NULL; ++conn)
      conn->StartMediaStreams();
  }

  return ok;
}

BOOL OpalCall::OnProgress(OpalConnection & connection)
{
  PTRACE(3, "Call\tOnProgress " << connection);

  if (!LockReadOnly())
    return FALSE;

  BOOL ok = connectionsActive.GetSize() == 1 && !partyB.IsEmpty();

  UnlockReadOnly();

  if (ok) {
    if (!manager.MakeConnection(*this, partyB))
      connection.Release(OpalConnection::EndedByNoUser);
    return OnSetUp(connection);
  }

  BOOL createdOne = FALSE;

  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (conn != &connection) {
      if (conn->SetConnected())
        ok = TRUE;
    }

    OpalMediaFormatList formats = GetMediaFormats(*conn, TRUE);
    if (OpenSourceMediaStreams(*conn, formats, OpalMediaFormat::DefaultAudioSessionID))
      createdOne = TRUE;
    if (OpenSourceMediaStreams(*conn, formats, OpalMediaFormat::DefaultVideoSessionID))
      createdOne = TRUE;
  }

  if (ok && createdOne) {
    for (PSafePtr<OpalConnection> conn = connectionsActive; conn != NULL; ++conn)
      conn->StartMediaStreams();
  }

  return ok;
}


BOOL OpalCall::OnEstablished(OpalConnection & PTRACE_PARAM(connection))
{
  PTRACE(3, "Call\tOnEstablished " << connection);

  PSafeLockReadWrite lock(*this);
  if (!lock.IsLocked())
    return FALSE;

  if (isEstablished)
    return TRUE;

  if (connectionsActive.GetSize() < 2)
    return FALSE;

  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (conn->GetPhase() != OpalConnection::EstablishedPhase)
      return FALSE;
  }

  isEstablished = TRUE;
  OnEstablishedCall();

  return TRUE;
}


PSafePtr<OpalConnection> OpalCall::GetOtherPartyConnection(const OpalConnection & connection) const
{
  PTRACE(3, "Call\tGetOtherPartyConnection " << connection);

  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (conn != &connection)
      return conn;
  }

  return NULL;
}


OpalMediaFormatList OpalCall::GetMediaFormats(const OpalConnection & connection,
                                              BOOL includeSpecifiedConnection)
{
  OpalMediaFormatList commonFormats;

  BOOL first = TRUE;

  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (includeSpecifiedConnection || conn != &connection) {
      OpalMediaFormatList possibleFormats = OpalTranscoder::GetPossibleFormats(conn->GetMediaFormats());
      if (first) {
        commonFormats = possibleFormats;
        first = FALSE;
      }
      else {
        // Want intersaction of the possible formats for all connections.
        for (PINDEX i = 0; i < commonFormats.GetSize(); i++) {
          if (possibleFormats.GetValuesIndex(commonFormats[i]) == P_MAX_INDEX)
            commonFormats.RemoveAt(i--);
        }
      }
    }
  }

  connection.AdjustMediaFormats(commonFormats);

  PTRACE(3, "Call\tGetMediaFormats for " << connection << '\n'
         << setfill('\n') << commonFormats << setfill(' '));

  return commonFormats;
}


BOOL OpalCall::OpenSourceMediaStreams(const OpalConnection & connection,
                                      const OpalMediaFormatList & mediaFormats,
                                      unsigned sessionID)
{
  PTRACE(2, "Call\tOpenSourceMediaStreams for session " << sessionID
         << " with media " << setfill(',') << mediaFormats << setfill(' '));

  BOOL startedOne = FALSE;

  OpalMediaFormatList adjustableMediaFormats;
  // Keep the media formats for the session ID
  for (PINDEX i = 0; i < mediaFormats.GetSize(); i++) {
    if (mediaFormats[i].GetDefaultSessionID() == sessionID)
      adjustableMediaFormats += mediaFormats[i];
  }

  if (adjustableMediaFormats.GetSize() == 0)
    return FALSE;
  
  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (conn != &connection) {
      if (conn->OpenSourceMediaStream(adjustableMediaFormats, sessionID)) {
        startedOne = TRUE;
        // If opened the source stream, then reorder the media formats so we
        // have a preference for symmetric codecs on subsequent connection(s)
        PWaitAndSignal m(conn->GetMediaStreamMutex());
        OpalMediaStream * otherStream = conn->GetMediaStream(sessionID, TRUE);
        if (otherStream != NULL && adjustableMediaFormats[0] != otherStream->GetMediaFormat()) {
          adjustableMediaFormats.Reorder(otherStream->GetMediaFormat());
          PTRACE(4, "Call\tOpenSourceMediaStreams for session " << sessionID
                 << " adjusted media to " << setfill(',') << adjustableMediaFormats << setfill(' '));
        }
      }
    }
  }

  return startedOne;
}


void OpalCall::CloseMediaStreams()
{
  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) 
    conn->CloseMediaStreams();
}


void OpalCall::RemoveMediaStreams()
{
  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) 
    conn->RemoveMediaStreams();
}


BOOL OpalCall::PatchMediaStreams(const OpalConnection & connection,
                                 OpalMediaStream & source)
{
  PTRACE(3, "Call\tPatchMediaStreams " << connection);

  PSafeLockReadOnly lock(*this);
  if (!lock.IsLocked())
    return FALSE;

  OpalMediaPatch * patch = NULL;

  {
    for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
      if (conn != &connection) {
        OpalMediaStream * sink = conn->OpenSinkMediaStream(source);
        if (sink == NULL)
          return FALSE;
        if (source.RequiresPatchThread()) {
          if (patch == NULL) {
            patch = manager.CreateMediaPatch(source);
            if (patch == NULL)
              return FALSE;
          }
          patch->AddSink(sink, conn->GetRTPPayloadMap());
        }
      }
    }
  }

  {
    for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
      if (patch)
        conn->OnPatchMediaStream(conn == &connection, *patch);
    }
  }
  
  return TRUE;
}


BOOL OpalCall::IsMediaBypassPossible(const OpalConnection & connection,
                                     unsigned sessionID) const
{
  PTRACE(3, "Call\tCanDoMediaBypass " << connection << " session " << sessionID);

  BOOL ok = FALSE;

  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (conn != &connection) {
      ok = manager.IsMediaBypassPossible(connection, *conn, sessionID);
      break;
    }
  }

  return ok;
}


void OpalCall::OnUserInputString(OpalConnection & connection, const PString & value)
{
  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (conn != &connection)
    {
      conn->SetSendUserInputMode( connection.GetSendUserInputMode() );
      conn->SendUserInputString(value);
    }else
      connection.SetUserInput(value);
  }
}


void OpalCall::OnUserInputTone(OpalConnection & connection,
                               char tone,
                               int duration)
{
  for (PSafePtr<OpalConnection> conn(connectionsActive, PSafeReadOnly); conn != NULL; ++conn) {
    if (conn != &connection)
    {
      conn->SetSendUserInputMode( connection.GetSendUserInputMode() );
      conn->SendUserInputTone(tone, duration);
    }else {
      if (duration > 0 && tone != ' ')
        connection.OnUserInputString(tone);
    }
  }
}


void OpalCall::OnReleased(OpalConnection & connection)
{
  PTRACE(3, "Call\tOnReleased " << connection);

  SetCallEndReason(connection.GetCallEndReason());

  connectionsActive.Remove(&connection);

  // A call will evaporate when one connection left, at some point this is
  // to be changes so can have "parked" connections.
  PSafePtr<OpalConnection> last = connectionsActive.GetAt(0, PSafeReference);
  if (last != NULL && connectionsActive.GetSize() == 1)
    last->Release(connection.GetCallEndReason());

  if (connectionsActive.IsEmpty()) {
    OnCleared();
    manager.activeCalls.RemoveAt(GetToken());
  }
}


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

⌨️ 快捷键说明

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