reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
KurentoConversation.cxx
Go to the documentation of this file.
1
2#include <rutil/Log.hxx>
3
5#include "Participant.hxx"
9#include "UserAgent.hxx"
11#include "ReconSubsystem.hxx"
13
14
15#include <rutil/Logger.hxx>
17
18using namespace recon;
19using namespace resip;
20
21#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON
22
23// The Kurento integration is currently only designed to
24// bridge two participants. Kurento itself can support
25// rooms with more than two participants.
26// FIXME: adapt to support rooms with more than two participants
27#define MAX_PARTICIPANTS 2
28
30 ConversationManager& conversationManager,
31 KurentoMediaStackAdapter& kurentoMediaStackAdapter,
32 RelatedConversationSet* relatedConversationSet,
33 ConversationHandle sharedMediaInterfaceConvHandle,
35: Conversation(handle, conversationManager, relatedConversationSet, sharedMediaInterfaceConvHandle, autoHoldMode, MAX_PARTICIPANTS),
36 mKurentoMediaStackAdapter(kurentoMediaStackAdapter),
37 mKurentoReInviteOnParticipantsPresent(true)
38{
39 if(mKurentoMediaStackAdapter.supportsMultipleMediaInterfaces())
40 {
41
42 // FIXME Kurento
44 {
45 //KurentoConversation* sharedFlowConversation = dynamic_cast<KurentoConversation*>(mKurentoMediaStackAdapter.getConversation(sharedMediaInterfaceConvHandle));
46 //mMediaInterface = sharedFlowConversation->getMediaInterface();
47 }
48 else
49 {
50 //std::shared_ptr<BridgeMixer> mixer;
51 //mKurentoMediaStackAdapter.createMediaInterfaceAndMixer(false /* giveFocus?*/, // Focus will be given when local participant is added
52 // mMediaInterface,
53 // mixer);
54 //setBridgeMixer(mixer);
55 }
56 }
57 //InfoLog(<< "mBridgeMixer " << getBridgeMixerShared().use_count() << " " << getBridgeMixer());
58
59 std::shared_ptr<ConfigParse> cfg = getConfig();
60 if(cfg)
61 {
62 mKurentoReInviteOnParticipantsPresent = cfg->getConfigBool("KurentoReInviteOnParticipantsPresent",
63 mKurentoReInviteOnParticipantsPresent);
64 }
65}
66
68{
69 getBridgeMixerShared().reset(); // Make sure the mixer is destroyed before the media interface
70 //mMediaInterface.reset();
71}
72
73void
77
78void
79KurentoConversation::disconnectWaitingMode(KurentoRemoteParticipant *krp, kurento::ContinuationVoid c)
80{
81 std::shared_ptr<kurento::BaseRtpEndpoint> ep = krp->getEndpoint();
82 std::shared_ptr<kurento::MediaElement> wm = krp->getWaitingModeElement();
83
84 if(!wm)
85 {
86 c();
87 }
88 else
89 {
90 wm->disconnect([this, ep, wm, c]{
91 ep->disconnect([this, wm, c]{
92 c();
93 }, *wm);
94 }, *ep);
95 }
96}
97
98void
100{
101 DebugLog(<<"confirmParticipant handle: " << getHandle()
102 << " numRemote: " << getNumRemoteParticipants()
103 << " participant: " << participant->getParticipantHandle());
104 KurentoRemoteParticipant *_p = dynamic_cast<KurentoRemoteParticipant*>(participant);
105 std::shared_ptr<kurento::BaseRtpEndpoint> answeredEndpoint = _p->getEndpoint();
107 {
108 DebugLog(<<"we are first in the conversation");
109 //_p->waitingMode(); // FIXME - loopback is setup in buildSdpOffer/buildSdpAnswer logic
110 return;
111 }
113 {
114 WarningLog(<<"participants already here, can't join, numRemoteParticipants = " << getNumRemoteParticipants());
115 return;
116 }
117 DebugLog(<<"joining a Conversation with an existing Participant");
118
119 if(!answeredEndpoint)
120 {
121 ErrLog(<<"our endpoint is not initialized"); // FIXME
122 return;
123 }
124 if(!_p->getWaitingModeElement()->valid())
125 {
126 DebugLog(<<"the local endpoint is not yet in a valid state");
127 return;
128 }
129 DebugLog(<<"attempting to join two RemoteParticipants");
130 disconnectWaitingMode(_p, [this, _p, answeredEndpoint]{
131 // Find the other Participant / endpoint
132
134 KurentoRemoteParticipant* krp = 0; // FIXME - better to use shared_ptr
135 Conversation::ParticipantMap::iterator _it = m.begin();
136 for(;_it != m.end() && krp == 0; _it++)
137 {
138 krp = dynamic_cast<KurentoRemoteParticipant*>(_it->second.getParticipant());
139 if(krp == _p)
140 {
141 krp = 0;
142 }
143 }
144 resip_assert(krp);
145 std::shared_ptr<kurento::BaseRtpEndpoint> otherEndpoint = krp->getEndpoint();
146
147 disconnectWaitingMode(krp, [this, _p, answeredEndpoint, otherEndpoint, krp]{
148 otherEndpoint->connect([this, _p, answeredEndpoint, otherEndpoint, krp]{
149 answeredEndpoint->connect([this, _p, answeredEndpoint, otherEndpoint, krp]{
150 InfoLog(<<"peers connected");
151 if(mKurentoReInviteOnParticipantsPresent)
152 {
153 krp->reInvite();
154 }
155
156 // set up schedule to repeatedly ask peer for keyframes
159
160 if(getConversationManager().sendKeyframesAtStart())
161 {
162 // ask local encoders to send some keyframes to their peers at
163 // beginning of the session
164 ParticipantHandle partHandle1 = _p->getParticipantHandle();
165 ParticipantHandle partHandle2 = krp->getParticipantHandle();
166 for(int i = 1000; i <= 5000; i+=1000)
167 {
168 std::chrono::milliseconds _i = std::chrono::milliseconds(i);
169 getConversationManager().requestKeyframe(partHandle1, _i);
170 getConversationManager().requestKeyframe(partHandle2, _i);
171 }
172 }
173
174 }, *otherEndpoint);
175 }, *answeredEndpoint);
176 }); // disconnectWaitingMode
177 }); // disconnectWaitingMode
178}
179
180void
182{
183 DebugLog(<<"onParticipantRemoved, checking for remaining participants");
184 KurentoRemoteParticipant *_p = dynamic_cast<KurentoRemoteParticipant*>(participant);
185 std::shared_ptr<kurento::BaseRtpEndpoint> myEndpoint = _p->getEndpoint();
187 KurentoRemoteParticipant* krp = 0; // FIXME - better to use shared_ptr
188 Conversation::ParticipantMap::iterator _it = m.begin();
189 for(;_it != m.end() && krp == 0; _it++)
190 {
191 krp = dynamic_cast<KurentoRemoteParticipant*>(_it->second.getParticipant());
192 if(krp == _p)
193 {
194 krp = 0;
195 }
196 }
197 if(krp)
198 {
199 DebugLog(<<"remaining participant found");
200 std::shared_ptr<kurento::BaseRtpEndpoint> otherEndpoint = krp->getEndpoint();
201 if(otherEndpoint->valid())
202 {
203 otherEndpoint->disconnect([this, krp, myEndpoint, otherEndpoint](){
204 if(myEndpoint->valid())
205 {
206 myEndpoint->disconnect([this, krp](){
207 krp->waitingMode();
208 }, *otherEndpoint);
209 }
210 else
211 {
212 krp->waitingMode();
213 }
214 }, *myEndpoint);
215 }
216 }
217
218 return;
219}
220
221/* ====================================================================
222
223 Copyright (c) 2021, SIP Spectrum, Inc. www.sipspectrum.com
224 Copyright (c) 2021, Daniel Pocock https://danielpocock.com
225 Copyright (c) 2007-2008, Plantronics, Inc.
226 All rights reserved.
227
228 Redistribution and use in source and binary forms, with or without
229 modification, are permitted provided that the following conditions are
230 met:
231
232 1. Redistributions of source code must retain the above copyright
233 notice, this list of conditions and the following disclaimer.
234
235 2. Redistributions in binary form must reproduce the above copyright
236 notice, this list of conditions and the following disclaimer in the
237 documentation and/or other materials provided with the distribution.
238
239 3. Neither the name of Plantronics nor the names of its contributors
240 may be used to endorse or promote products derived from this
241 software without specific prior written permission.
242
243 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
244 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
245 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
246 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
247 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
248 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
249 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
250 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
251 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
253 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
254
255 ==================================================================== */
#define MAX_PARTICIPANTS
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define WarningLog(args_)
Definition Logger.hxx:134
#define ErrLog(args_)
Definition Logger.hxx:137
#define resip_assert(x)
This file needs to work for both C and C++ code.
This class is one of two main classes of concern to an application using the UserAgent library.
virtual void requestKeyframe(ParticipantHandle partHandle, std::chrono::duration< double > durationMs)
This class is used to manage membership of participants.
ParticipantMap & getParticipants()
unsigned int getNumRemoteParticipants()
std::shared_ptr< resip::ConfigParse > getConfig()
virtual ConversationManager & getConversationManager()
std::shared_ptr< BridgeMixer > getBridgeMixerShared()
ConversationHandle getHandle()
virtual bool isSharingMediaInterfaceWithAnotherConversation()
std::map< ParticipantHandle, ConversationParticipantAssignment > ParticipantMap
KurentoConversation(ConversationHandle handle, ConversationManager &conversationManager, KurentoMediaStackAdapter &kurentoMediaStackAdapter, RelatedConversationSet *relatedConversationSet, ConversationHandle sharedMediaInterfaceConvHandle, ConversationManager::AutoHoldMode autoHoldMode)
virtual void confirmParticipant(Participant *participant)
virtual void onParticipantRemoved(Participant *participant)
virtual void onParticipantAdded(Participant *participant)
This class is one of two main classes of concern to an application using the UserAgent library.
virtual bool supportsMultipleMediaInterfaces() override
This class represent a remote participant.
virtual std::shared_ptr< kurento::MediaElement > getWaitingModeElement()
virtual std::shared_ptr< kurento::BaseRtpEndpoint > getEndpoint()
This is the base class for a RemoteParticipant, LocalParticipant and a MediaResourceParticipant.
virtual ParticipantHandle getParticipantHandle()
This is used to keep a mapping between all related conversations.
virtual void requestKeyframeFromPeerTimeout(bool reset)
std::function< void(void) > ContinuationVoid
unsigned int ConversationHandle
unsigned int ParticipantHandle
dcm! – add UnusedChecking(_enum) below;