6#include <sdp/SdpCodec.h>
7#include <os/OsConfigDb.h>
8#include <mp/MpCodecFactory.h>
9#include <mp/MprBridge.h>
10#include <mp/MpResourceFactory.h>
11#include <mp/MpResourceTopology.h>
12#include <mi/CpMediaInterfaceFactoryFactory.h>
13#include <CpTopologyGraphFactoryImpl.h>
40#if defined(WIN32) && !defined(__GNUC__)
41#pragma warning( disable : 4355 )
49std::string getExecutableDir()
52 memset(buf, 0,
sizeof(buf));
53 DWORD len = GetModuleFileNameA(GetModuleHandle(NULL), buf,
sizeof(buf) - 1);
55 for (
char* p = buf + len; p > buf; p--) {
61 return std::string(buf);
65#define RESIPROCATE_SUBSYSTEM ReconSubsystem::RECON
73 mLocalAudioEnabled(localAudioEnabled),
74 mMediaInterfaceMode(mediaInterfaceMode),
75 mEnableExtraPlayAndRecordResources(enableExtraPlayAndRecordResources),
84 mLocalAudioEnabled(localAudioEnabled),
85 mMediaInterfaceMode(mediaInterfaceMode),
86 mEnableExtraPlayAndRecordResources(enableExtraPlayAndRecordResources),
90 init(defaultSampleRate, maxSampleRate);
94SipXMediaStackAdapter::init(
int defaultSampleRate,
int maxSampleRate)
99 UtlString codecPaths[] = {
".", getExecutableDir().c_str(),
"../../../x64/Debug"};
102 UtlString codecPaths[] = {
".", getExecutableDir().c_str(),
"../../../Win32/Debug" };
104 UtlString codecPaths[] = {
"." };
111 UtlString codecPaths[] = {
".", getExecutableDir().c_str(),
"../../../x64/Release" };
114 UtlString codecPaths[] = {
".", getExecutableDir().c_str(),
"../../../Win32/Release" };
116 UtlString codecPaths[] = {
"." };
122 int codecPathsNum =
sizeof(codecPaths)/
sizeof(codecPaths[0]);
123 OsStatus rc = CpTopologyGraphFactoryImpl::addCodecPaths(codecPathsNum, codecPaths);
128 OsConfigDb sipXconfig;
129 sipXconfig.set(
"PHONESET_MAX_ACTIVE_CALLS_ALLOWED",300);
130 mMediaFactory =
dynamic_cast<CpTopologyGraphFactoryImpl*
>(sipXmediaFactoryFactory(&sipXconfig, 0, maxSampleRate, defaultSampleRate, mLocalAudioEnabled)->getFactoryImplementation());
134 mMediaFactory =
dynamic_cast<CpTopologyGraphFactoryImpl*
>(sipXmediaFactoryFactory(
nullptr, 0, maxSampleRate, defaultSampleRate, mLocalAudioEnabled)->getFactoryImplementation());
137 if (mMediaFactory ==
nullptr)
139 CritLog(<<
"Error creating media factory for sipX Topology Graph. Cannot start.");
143 if (mEnableExtraPlayAndRecordResources)
145 if (!addExtraPlayAndRecordResourcesToTopology())
147 CritLog(<<
"Error adjusting resource Topology. Cannot start.");
153 MpCodecFactory *pCodecFactory = MpCodecFactory::getMpCodecFactory();
154 unsigned int count = 0;
155 const MppCodecInfoV1_1 **codecInfoArray;
156 pCodecFactory->getCodecInfoArray(count, codecInfoArray);
162 InfoLog(<<
"No statically linked codecs or no codecs found with default filter, trying without a filter");
163 pCodecFactory->loadAllDynCodecs(NULL,
"");
164 pCodecFactory->getCodecInfoArray(count, codecInfoArray);
167 CritLog( <<
"No static codecs or dynamic codec plugins found in search paths. Cannot start.");
172 InfoLog( <<
"Loaded codecs are:");
173 for(
unsigned int i =0; i < count; i++)
175 InfoLog( <<
" " << codecInfoArray[i]->codecName
176 <<
"(" << codecInfoArray[i]->codecManufacturer <<
") "
177 << codecInfoArray[i]->codecVersion
178 <<
" MimeSubtype: " << codecInfoArray[i]->mimeSubtype
179 <<
" Rate: " << codecInfoArray[i]->sampleRate
180 <<
" Channels: " << codecInfoArray[i]->numChannels);
189 createMediaInterfaceAndMixer(mLocalAudioEnabled ,
198 InfoLog(<<
"SipXMediaStackAdapter shutdown");
204 mMediaInterface.reset();
205 sipxDestroyMediaFactoryFactory();
235 WarningLog(<<
"Calling createSharedMediaInterfaceConversation is not appropriate when using sipXGlobalMediaInterfaceMode");
258 WarningLog(<<
"ConversationManager::outputBridgeMatrix request with no conversation handle is not appropriate for current MediaInterfaceMode");
272 WarningLog(<<
"ConversationManager::outputBridgeMatrix requested conversation wihtout a mixer/media interface, conversationHandle=" << convHandle);
277 WarningLog(<<
"ConversationManager::outputBridgeMatrix requested for non-existing conversationHandle=" << convHandle);
285 OsStatus status = mMediaFactory->setSpeakerVolume(volume);
286 if(status != OS_SUCCESS)
288 WarningLog(<<
"setSpeakerVolume failed: status=" << status);
295 OsStatus status = mMediaFactory->setMicrophoneGain(gain);
296 if(status != OS_SUCCESS)
298 WarningLog(<<
"setMicrophoneGain failed: status=" << status);
305 OsStatus status = mMediaFactory->muteMicrophone(mute? TRUE : FALSE);
306 if(status != OS_SUCCESS)
308 WarningLog(<<
"muteMicrophone failed: status=" << status);
315 OsStatus status = mMediaFactory->setAudioAECMode(enable ? MEDIA_AEC_CANCEL : MEDIA_AEC_DISABLED);
316 if(status != OS_SUCCESS)
318 WarningLog(<<
"enableEchoCancel failed: status=" << status);
322 mMediaInterface->getInterface()->defocus();
323 mMediaInterface->getInterface()->giveFocus();
330 OsStatus status = mMediaFactory->enableAGC(enable ? TRUE : FALSE);
331 if(status != OS_SUCCESS)
333 WarningLog(<<
"enableAutoGainControl failed: status=" << status);
337 mMediaInterface->getInterface()->defocus();
338 mMediaInterface->getInterface()->giveFocus();
345 OsStatus status = mMediaFactory->setAudioNoiseReductionMode(enable ? MEDIA_NOISE_REDUCTION_MEDIUM : MEDIA_NOISE_REDUCTION_DISABLED);
346 if(status != OS_SUCCESS)
348 WarningLog(<<
"enableNoiseReduction failed: status=" << status);
352 mMediaInterface->getInterface()->defocus();
353 mMediaInterface->getInterface()->giveFocus();
365 if(!ipaddress.
empty())
382 MpCodecFactory *pCodecFactory = MpCodecFactory::getMpCodecFactory();
383 SdpCodecList codecList;
384 pCodecFactory->addCodecsToList(codecList);
385 codecList.bindPayloadTypes();
397 bool firstCodecAdded =
false;
398 for(std::vector<unsigned int>::const_iterator idIter = codecIds.begin();
399 idIter != codecIds.end(); idIter++)
401 const unsigned int& codecId = *idIter;
402 const SdpCodec* sdpcodec = codecList.getCodec((SdpCodec::SdpCodecTypes)codecId);
406 sdpcodec->getMediaType(mediaType);
408 if(mediaType.compareTo(
"audio", UtlString::ignoreCase) == 0)
410 UtlString mimeSubType;
411 sdpcodec->getEncodingName(mimeSubType);
414 int capabilityRate = sdpcodec->getSampleRate();
415 if(mimeSubType ==
"G722")
417 capabilityRate = 8000;
420 Data codecName(mimeSubType.data());
431 if(sdpcodec->getNumChannels() > 1)
437 if(mimeSubType.compareTo(
"telephone-event", UtlString::ignoreCase) == 0)
444 sdpcodec->getSdpFmtpField(fmtpField);
445 if(fmtpField.length() != 0)
451 DebugLog(<<
"Added codec to session capabilites: id=" << codecId
452 <<
" type=" << mimeSubType.data()
453 <<
" rate=" << sdpcodec->getSampleRate()
454 <<
" plen=" << sdpcodec->getPacketLength()
455 <<
" payloadid=" << sdpcodec->getCodecPayloadFormat()
461 firstCodecAdded =
true;
472 session.addMedium(medium);
473 sessionCaps.
session() = session;
477SipXMediaStackAdapter::createMediaInterfaceAndMixer(
bool giveFocus,
478 std::shared_ptr<SipXMediaInterface>& mediaInterface,
479 std::shared_ptr<BridgeMixer>& bridgeMixer)
481 UtlString localRtpInterfaceAddress(
"127.0.0.1");
485 mediaInterface = std::make_shared<SipXMediaInterface>(
getConversationManager(), (CpTopologyGraphInterface*)mMediaFactory->createMediaInterface(NULL,
486 localRtpInterfaceAddress,
505 mediaInterface->getInterface()->setNotificationDispatcher(mediaInterface.get());
508 mediaInterface->getInterface()->setNotificationsEnabled(
true);
514 mediaInterface->allowLoggingDTMFDigits(
getUserAgent()->getUserAgentMasterProfile()->dtmfDigitLoggingEnabled());
519 mediaInterface->getInterface()->giveFocus();
522 bridgeMixer = std::make_shared<SipXBridgeMixer>(*(mediaInterface->getInterface()));
577 std::shared_ptr<ConversationProfile> conversationProfile)
583SipXMediaStackAdapter::addExtraPlayAndRecordResourcesToTopology()
585 MpResourceTopology* resourceTopology = mMediaFactory->getInitialResourceTopology();
590 if (result == OS_SUCCESS)
596 if (result == OS_SUCCESS)
603 if (result == OS_SUCCESS)
606 result = resourceTopology->addConnection(
DEFAULT_FROM_FILE_2_RESOURCE_NAME, 0, DEFAULT_BRIDGE_RESOURCE_NAME, MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT);
609 if (result == OS_SUCCESS)
612 result = resourceTopology->addConnection(
DEFAULT_FROM_FILE_3_RESOURCE_NAME, 0, DEFAULT_BRIDGE_RESOURCE_NAME, MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT);
615 if (result == OS_SUCCESS)
618 result = resourceTopology->addConnection(DEFAULT_BRIDGE_RESOURCE_NAME, MpResourceTopology::MP_TOPOLOGY_NEXT_AVAILABLE_PORT,
DEFAULT_RECORDER_2_RESOURCE_NAME, 0);
629 return result == OS_SUCCESS;
633SipXMediaStackAdapter::process()
639SipXMediaStackAdapter::setRTCPEventLoggingHandler(std::shared_ptr<flowmanager::RTCPEventLoggingHandler> h)
646SipXMediaStackAdapter::initializeDtlsFactory(
const resip::Data& defaultAoR)
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
void setRTCPEventLoggingHandler(std::shared_ptr< RTCPEventLoggingHandler > handler) noexcept
void initializeDtlsFactory(const char *certAor)
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.
ParticipantForkSelectMode
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...
This class represents a local participant.
This class is used by Invite DialogSets.
This class represent a remote participant.
This class is used to manage membership of participants.
This class represents a local participant.
This class is one of two main classes of concern to an application using the UserAgent library.
std::shared_ptr< UserAgentMasterProfile > getUserAgentMasterProfile() const noexcept
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
const char * c_str() const
Returns a null-terminated string representing.
bool empty() const noexcept
Checks whether the Data is empty.
Data & lowercase()
Converts this Data to lowercase.
parameters for a specific codec are stored in this class.
const Data & encodingParameters() const
returns the encoding parameters associated with this codec
const Data & parameters() const
returns the parameters associated with this codec
Process c= (connection) lines in SDP.
process m= (media announcement) blocks
void addAttribute(const Data &key, const Data &value=Data::Empty)
add a media attribute line
void addCodec(const Codec &codec)
add a codec to the m= line
processes o= lines in SDP
Process t= (start/stop time) lines in SDP.
Provides an interface to read and modify SDP bodies.
Provides an interface to process and generate SDP bodies (MIME content-type application/sdp).
static const SdpContents Empty
Session & session()
get the parsed SDP
Represents a network address.
IpVersion ipVersion() const
Returns V4 or V6 as appropriate.
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
unsigned int ConversationHandle
unsigned int ParticipantHandle
dcm! – add UnusedChecking(_enum) below;