reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
KurentoMediaStackAdapter.cxx
Go to the documentation of this file.
1
2#if (_MSC_VER >= 1600)
3#include <stdint.h> // Use Visual Studio's stdint.h
4#define _MSC_STDINT_H_ // This define will ensure that stdint.h in sipXport tree is not used
5#endif
6
7// resip includes
8#include <rutil/Log.hxx>
9#include <rutil/Logger.hxx>
10#include <rutil/Lock.hxx>
11#include <rutil/Random.hxx>
17
18#include "ReconSubsystem.hxx"
19#include "UserAgent.hxx"
23#include "Participant.hxx"
25#include "DtmfEvent.hxx"
27#include "Conversation.hxx"
29
30#include "cajun/json/elements.h"
31
32#if defined(WIN32) && !defined(__GNUC__)
33#pragma warning( disable : 4355 )
34#endif
35
36using namespace recon;
37using namespace resip;
38using namespace std;
39
40#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON
41
43: MediaStackAdapter(conversationManager),
44 mKurentoUri(kurentoUri),
45 mKurentoManager(std::chrono::seconds(5), std::chrono::seconds(2)), // FIXME - make this value configurable
46 mKurentoTOSValue(0) // FIXME - make this value configurable
47{
48 init();
49}
50
51KurentoMediaStackAdapter::KurentoMediaStackAdapter(ConversationManager& conversationManager, const Data& kurentoUri, int defaultSampleRate, int maxSampleRate)
52: MediaStackAdapter(conversationManager),
53 mKurentoUri(kurentoUri),
54 mKurentoManager(std::chrono::seconds(5000), std::chrono::seconds(2)), // FIXME - make this value configurable
55 mKurentoTOSValue(0) // FIXME - make this value configurable
56{
57 init(defaultSampleRate, maxSampleRate);
58}
59
60void
61KurentoMediaStackAdapter::init(int defaultSampleRate, int maxSampleRate)
62{
63 // Connect to the Kurento server
64 DebugLog(<<"trying to connect to Kurento host " << mKurentoUri);
65 mKurentoConnection = mKurentoManager.getKurentoConnection(mKurentoUri.c_str(), *this); // FIXME wait for connection
66
67}
68
69void
71{
72 // FIXME
73 // - if Kurento connection was dropped but the same Kurento instance is still
74 // running then mPipeline remains valid and we don't need to replace it
75 // - if it was a Kurento restart then mPipeline does need to be replaced and all
76 // calls need to be dropped at the SIP level so the clients reconnect
77
78 mPipeline = make_shared<kurento::MediaPipeline>(mKurentoConnection);
79 mPipeline->create([this]{
80 DebugLog(<<"pipeline created with ID " << mPipeline->getId());
81 }); // FIXME - wait for creation
82}
83
84void
86{
87 InfoLog(<<"KurentoMediaStackAdapter shutdown");
88 if(mPipeline)
89 {
90 mPipeline->release([this](){
91 InfoLog(<<"mPipeline has been released");
92 mKurentoConnection.reset();
93 });
94 }
95 else
96 {
97 mKurentoConnection.reset();
98 }
99 // FIXME - join / wait for any threads to stop
100}
101
103{
104 // FIXME - move to ::shutdown() ?
105 getBridgeMixer().reset(); // Make sure the mixer is destroyed before the media interface
106}
107
108void
112
113void
115{
116 // FIXME for Kurento
117// if (mMediaInterface)
118// {
119// // Enable/Disable DTMF digit logging according to UserAgentMasterProfile setting
120// mMediaInterface->allowLoggingDTMFDigits(userAgent->getUserAgentMasterProfile()->dtmfDigitLoggingEnabled());
121// }
122
123}
124
127{
128 if (isShuttingDown()) return 0; // Don't allow new things to be created when we are shutting down
129
131
132 CreateConversationCmd* cmd = new CreateConversationCmd(&getConversationManager(), convHandle, autoHoldMode, sharedMediaInterfaceConvHandle);
133 post(cmd);
134 return convHandle;
135}
136
137void
138KurentoMediaStackAdapter::outputBridgeMatrixImpl(ConversationHandle convHandle)
139{
140 // Note: convHandle of 0 only makes sense if sipXGlobalMediaInterfaceMode is enabled
141 if (convHandle == 0)
142 {
143 if (getBridgeMixer() != 0)
144 {
145 getBridgeMixer()->outputBridgeMixWeights();
146 }
147 else
148 {
149 WarningLog(<< "ConversationManager::outputBridgeMatrix request with no conversation handle is not appropriate for current MediaInterfaceMode");
150 }
151 }
152 else
153 {
154 Conversation* conversation = getConversation(convHandle);
155 if (conversation)
156 {
157 if (conversation->getBridgeMixer() != 0)
158 {
159 conversation->getBridgeMixer()->outputBridgeMixWeights();
160 }
161 else
162 {
163 WarningLog(<< "ConversationManager::outputBridgeMatrix requested conversation wihtout a mixer/media interface, conversationHandle=" << convHandle);
164 }
165 }
166 else
167 {
168 WarningLog(<< "ConversationManager::outputBridgeMatrix requested for non-existing conversationHandle=" << convHandle);
169 }
170 }
171}
172
173void
175 const std::vector<unsigned int>& codecIds, resip::SdpContents& sessionCaps)
176{
177 // FIXME Kurento:
178 // - check who calls this (called from testUA, reConServer, ...
179 // - adapt for Kurento
180
181 // as a hack, we populate it with a static copy of the SDP from Kurento
182
183 // FIXME: ipaddress is assumed to be IP4
184 Data caps("v=0\r\n"
185 "o=- 3843572881 3843572881 IN IP4 " + ipaddress + "\r\n"
186 "s=Kurento Media Server\r\n"
187 "c=IN IP4 " + ipaddress + "\r\n"
188 "t=0 0\r\n"
189 "m=audio 34712 RTP/AVP 0\r\n"
190 "a=sendrecv\r\n"
191 "a=rtcp:34713\r\n"
192 "a=rtpmap:0 PCMU/8000\r\n"
193 "a=ssrc:866007149 cname:user2141419334@host-99aef493\r\n"
194 "m=video 2962 RTP/AVP 97 126\r\n"
195 "a=sendrecv\r\n"
196 "a=rtcp:2963\r\n"
197 "a=rtpmap:97 H264/90000\r\n"
198 "a=rtpmap:126 H264/90000\r\n"
199 "a=fmtp:97 packetization-mode=0;profile-level-id=420016;max-br=5000;max-mbps=245000;max-fs=9000;max-smbps=245000;max-fps=6000;max-rcmd-nalu-size=3456000;sar-supported=16\r\n"
200 "a=fmtp:126 packetization-mode=1;profile-level-id=428016;max-br=5000;max-mbps=245000;max-fs=9000;max-smbps=245000;max-fps=6000;max-rcmd-nalu-size=3456000;sar-supported=16\r\n"
201 "a=ssrc:1014502683 cname:user2141419334@host-99aef493\r\n");
202
203 HeaderFieldValue hfv(caps.data(), caps.size());
204 Mime type("application", "sdp");
205 SdpContents sdp(hfv, type);
206 sessionCaps = sdp;
207}
208
209bool
214
215bool
217{
218 return false;
219}
220
223 RelatedConversationSet* relatedConversationSet, // Pass NULL to create new RelatedConversationSet
224 ConversationHandle sharedMediaInterfaceConvHandle,
226{
227 return new KurentoConversation(handle, getConversationManager(), *this, relatedConversationSet, sharedMediaInterfaceConvHandle, autoHoldMode);
228}
229
235
237KurentoMediaStackAdapter::createMediaResourceParticipantInstance(ParticipantHandle partHandle, const resip::Uri& mediaUrl, const std::shared_ptr<resip::Data>& audioBuffer, void* recordingCircularBuffer)
238{
239 return 0; // FIXME Kurento - implement MediaResourceParticipant in Kurento
240}
241
242void
244{
245 std::shared_ptr<ConfigParse> cfg = getConfig();
246 if(cfg)
247 {
248 krp->mRemoveExtraMediaDescriptors = cfg->getConfigBool("KurentoRemoveExtraMediaDescriptors", false);
249 krp->mSipRtpEndpoint = cfg->getConfigBool("KurentoSipRtpEndpoint", true);
250 krp->mReuseSdpAnswer = cfg->getConfigBool("KurentoReuseSdpAnswer", false);
251 krp->mWSAcceptsKeyframeRequests = cfg->getConfigBool("KurentoWebSocketAcceptsKeyframeRequests", true);
252 }
253}
254
262
270
274 std::shared_ptr<ConversationProfile> conversationProfile)
275{
276 return new KurentoRemoteParticipantDialogSet(getConversationManager(), *this, forkSelectMode, conversationProfile);
277}
278
279void
280KurentoMediaStackAdapter::process()
281{
282 mKurentoManager.process();
283}
284
285void
286KurentoMediaStackAdapter::initializeDtlsFactory(const resip::Data& defaultAoR)
287{
288 // FIXME Kurento
289}
290
291
292/* ====================================================================
293
294 Copyright (c) 2021-2022, SIP Spectrum, Inc. www.sipspectrum.com
295 Copyright (c) 2021, Daniel Pocock https://danielpocock.com
296 Copyright (c) 2007-2008, Plantronics, Inc.
297 All rights reserved.
298
299 Redistribution and use in source and binary forms, with or without
300 modification, are permitted provided that the following conditions are
301 met:
302
303 1. Redistributions of source code must retain the above copyright
304 notice, this list of conditions and the following disclaimer.
305
306 2. Redistributions in binary form must reproduce the above copyright
307 notice, this list of conditions and the following disclaimer in the
308 documentation and/or other materials provided with the distribution.
309
310 3. Neither the name of Plantronics nor the names of its contributors
311 may be used to endorse or promote products derived from this
312 software without specific prior written permission.
313
314 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
315 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
316 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
317 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
318 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
319 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
320 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
321 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
322 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
323 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
324 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
325
326 ==================================================================== */
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define WarningLog(args_)
Definition Logger.hxx:134
KurentoConnection::ptr getKurentoConnection(const std::string &uri, KurentoConnectionObserver &observer)
virtual void outputBridgeMixWeights()=0
Logs a multiline representation of the current state of the mixing matrix.
This class is one of two main classes of concern to an application using the UserAgent library.
This class is used to manage membership of participants.
BridgeMixer * getBridgeMixer() noexcept
The classes defined here are used to pass commands from the application thread to the UserAgent threa...
KurentoMediaStackAdapter(ConversationManager &conversationManager, const resip::Data &kurentoUri)
Note: Kurentotapi Media Interfaces have a finite number of supported endpoints that are allowed in ea...
virtual void configureRemoteParticipantInstance(KurentoRemoteParticipant *krp)
virtual MediaResourceParticipant * createMediaResourceParticipantInstance(ParticipantHandle partHandle, const resip::Uri &mediaUrl, const std::shared_ptr< resip::Data > &audioBuffer, void *recordingCircularBuffer) override
virtual bool supportsMultipleMediaInterfaces() override
virtual void conversationManagerReady(ConversationManager *conversationManager) override
virtual void buildSessionCapabilities(const resip::Data &ipaddress, const std::vector< unsigned int > &codecIds, resip::SdpContents &sessionCaps) override
Builds a session capabilties SDPContents based on the passed in ipaddress and codec ordering.
virtual LocalParticipant * createLocalParticipantInstance(ParticipantHandle partHandle) override
virtual RemoteParticipantDialogSet * createRemoteParticipantDialogSetInstance(ConversationManager::ParticipantForkSelectMode forkSelectMode=ConversationManager::ForkSelectAutomatic, std::shared_ptr< ConversationProfile > conversationProfile=nullptr) override
virtual bool canConversationsShareParticipants(Conversation *conversation1, Conversation *conversation2) override
virtual ConversationHandle createSharedMediaInterfaceConversation(ConversationHandle sharedMediaInterfaceConvHandle, ConversationManager::AutoHoldMode autoHoldMode=ConversationManager::AutoHoldEnabled)
Only applicable if KurentoConversationMediaInterfaceMode is used.
virtual Conversation * createConversationInstance(ConversationHandle handle, RelatedConversationSet *relatedConversationSet, ConversationHandle sharedMediaInterfaceConvHandle, ConversationManager::AutoHoldMode autoHoldMode) override
virtual void setUserAgent(UserAgent *userAgent) override
virtual RemoteParticipant * createRemoteParticipantInstance(resip::DialogUsageManager &dum, RemoteParticipantDialogSet &rpds) override
This class represent a remote participant.
This class represents a local participant.
This class represents a media resource participant.
This class is one of two main classes of concern to an application.
ConversationManager & getConversationManager()
Conversation * getConversation(ConversationHandle convHandle)
std::shared_ptr< resip::ConfigParse > getConfig()
ConversationHandle getNewConversationHandle()
std::shared_ptr< BridgeMixer > & getBridgeMixer()
void post(resip::Message *message)
This is used to keep a mapping between all related conversations.
This class is used by Invite DialogSets.
This class represent a remote participant.
This class is one of two main classes of concern to an application using the UserAgent library.
Definition UserAgent.hxx:56
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
const char * c_str() const
Returns a null-terminated string representing.
Definition Data.cxx:1097
size_type size() const noexcept
Returns the number of bytes in this Data.
Definition Data.hxx:599
const char * data() const noexcept
Returns a pointer to the contents of this Data.
Definition Data.hxx:608
Represents the "media-type" element in the RFC 3261 grammar.
Definition Mime.hxx:20
Provides an interface to process and generate SDP bodies (MIME content-type application/sdp).
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
unsigned int ConversationHandle
unsigned int ParticipantHandle
dcm! – add UnusedChecking(_enum) below;