📄 call.cxx
字号:
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 + -