Commit 8b695901 authored by Ghislain MARY's avatar Ghislain MARY

Use CoreAccessor in call related classes.

parent 6ef2937a
......@@ -6883,7 +6883,7 @@ void linphone_core_set_media_encryption_mandatory(LinphoneCore *lc, bool_t m) {
}
void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *params) {
L_GET_CPP_PTR_FROM_C_OBJECT(params)->initDefault(lc);
L_GET_CPP_PTR_FROM_C_OBJECT(params)->initDefault(lc->cppCore);
}
void linphone_core_set_device_identifier(LinphoneCore *lc,const char* device_id) {
......
......@@ -176,7 +176,7 @@ int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, sock
/* this functions runs a simple stun test and return the number of milliseconds to complete the tests, or -1 if the test were failed.*/
int linphone_run_stun_tests(LinphoneCore *lc, int audioPort, int videoPort, int textPort,
char *audioCandidateAddr, int *audioCandidatePort, char *videoCandidateAddr, int *videoCandidatePort, char *textCandidateAddr, int *textCandidatePort) {
LinphonePrivate::StunClient *client = new LinphonePrivate::StunClient(lc);
LinphonePrivate::StunClient *client = new LinphonePrivate::StunClient(lc->cppCore);
int ret = client->run(audioPort, videoPort, textPort);
strncpy(audioCandidateAddr, client->getAudioCandidate().address.c_str(), LINPHONE_IPADDR_SIZE);
*audioCandidatePort = client->getAudioCandidate().port;
......
......@@ -502,7 +502,7 @@ LinphoneCallParams *linphone_call_params_new (LinphoneCore *core) {
LinphoneCallParams *params = _linphone_CallParams_init();
auto mediaSessionParams = new LinphonePrivate::MediaSessionParams();
L_SET_CPP_PTR_FROM_C_OBJECT(params, mediaSessionParams);
L_GET_CPP_PTR_FROM_C_OBJECT(params)->initDefault(core);
L_GET_CPP_PTR_FROM_C_OBJECT(params)->initDefault(core->cppCore);
delete mediaSessionParams;
return params;
}
......
......@@ -86,7 +86,7 @@ CallSessionParams &CallSessionParams::operator= (const CallSessionParams &src) {
// -----------------------------------------------------------------------------
void CallSessionParams::initDefault (LinphoneCore *core) {
void CallSessionParams::initDefault (const std::shared_ptr<Core> &core) {
L_D();
d->inConference = false;
d->privacy = LinphonePrivacyDefault;
......
......@@ -20,6 +20,8 @@
#ifndef _CALL_SESSION_PARAMS_H_
#define _CALL_SESSION_PARAMS_H_
#include <memory>
#include "object/clonable-object.h"
#include "linphone/types.h"
......@@ -31,6 +33,7 @@
LINPHONE_BEGIN_NAMESPACE
class CallSessionParamsPrivate;
class Core;
class CallSessionParams : public ClonableObject {
friend class CallSession;
......@@ -44,7 +47,7 @@ public:
CallSessionParams &operator= (const CallSessionParams &src);
virtual void initDefault (LinphoneCore *core);
virtual void initDefault (const std::shared_ptr<Core> &core);
const std::string& getSessionName () const;
void setSessionName (const std::string &sessionName);
......
......@@ -22,6 +22,7 @@
#include "media-session-params.h"
#include "core/core.h"
#include "logger/logger.h"
#include "private.h"
......@@ -223,27 +224,28 @@ MediaSessionParams &MediaSessionParams::operator= (const MediaSessionParams &src
// -----------------------------------------------------------------------------
void MediaSessionParams::initDefault (LinphoneCore *core) {
void MediaSessionParams::initDefault (const std::shared_ptr<Core> &core) {
L_D();
CallSessionParams::initDefault(core);
LinphoneCore *cCore = core->getCCore();
d->audioEnabled = true;
d->videoEnabled = linphone_core_video_enabled(core) && core->video_policy.automatically_initiate;
if (!linphone_core_video_enabled(core) && core->video_policy.automatically_initiate) {
d->videoEnabled = linphone_core_video_enabled(cCore) && cCore->video_policy.automatically_initiate;
if (!linphone_core_video_enabled(cCore) && cCore->video_policy.automatically_initiate) {
lError() << "LinphoneCore has video disabled for both capture and display, but video policy is to start the call with video. "
"This is a possible mis-use of the API. In this case, video is disabled in default LinphoneCallParams";
}
d->realtimeTextEnabled = !!linphone_core_realtime_text_enabled(core);
d->encryption = linphone_core_get_media_encryption(core);
d->avpfEnabled = (linphone_core_get_avpf_mode(core) == LinphoneAVPFEnabled);
d->_implicitRtcpFbEnabled = !!lp_config_get_int(linphone_core_get_config(core), "rtp", "rtcp_fb_implicit_rtcp_fb", true);
d->avpfRrInterval = static_cast<uint16_t>(linphone_core_get_avpf_rr_interval(core));
d->realtimeTextEnabled = !!linphone_core_realtime_text_enabled(cCore);
d->encryption = linphone_core_get_media_encryption(cCore);
d->avpfEnabled = (linphone_core_get_avpf_mode(cCore) == LinphoneAVPFEnabled);
d->_implicitRtcpFbEnabled = !!lp_config_get_int(linphone_core_get_config(cCore), "rtp", "rtcp_fb_implicit_rtcp_fb", true);
d->avpfRrInterval = static_cast<uint16_t>(linphone_core_get_avpf_rr_interval(cCore));
d->audioDirection = LinphoneMediaDirectionSendRecv;
d->videoDirection = LinphoneMediaDirectionSendRecv;
d->earlyMediaSendingEnabled = !!lp_config_get_int(linphone_core_get_config(core), "misc", "real_early_media", false);
d->audioMulticastEnabled = !!linphone_core_audio_multicast_enabled(core);
d->videoMulticastEnabled = !!linphone_core_video_multicast_enabled(core);
d->updateCallWhenIceCompleted = !!lp_config_get_int(linphone_core_get_config(core), "sip", "update_call_when_ice_completed", true);
d->mandatoryMediaEncryptionEnabled = !!linphone_core_is_media_encryption_mandatory(core);
d->earlyMediaSendingEnabled = !!lp_config_get_int(linphone_core_get_config(cCore), "misc", "real_early_media", false);
d->audioMulticastEnabled = !!linphone_core_audio_multicast_enabled(cCore);
d->videoMulticastEnabled = !!linphone_core_video_multicast_enabled(cCore);
d->updateCallWhenIceCompleted = !!lp_config_get_int(linphone_core_get_config(cCore), "sip", "update_call_when_ice_completed", true);
d->mandatoryMediaEncryptionEnabled = !!linphone_core_is_media_encryption_mandatory(cCore);
}
// -----------------------------------------------------------------------------
......
......@@ -43,7 +43,7 @@ public:
MediaSessionParams &operator= (const MediaSessionParams &src);
void initDefault (LinphoneCore *core) override;
void initDefault (const std::shared_ptr<Core> &core) override;
bool audioEnabled () const;
bool audioMulticastEnabled () const;
......
......@@ -35,10 +35,11 @@ LINPHONE_BEGIN_NAMESPACE
shared_ptr<CallSession> ParticipantPrivate::createSession (
const Conference &conference, const CallSessionParams *params, bool hasMedia, CallSessionListener *listener
) {
L_Q();
if (hasMedia && (!params || dynamic_cast<const MediaSessionParams *>(params))) {
session = make_shared<MediaSession>(conference, params, listener);
session = make_shared<MediaSession>(conference.getCore(), q->getSharedFromThis(), params, listener);
} else {
session = make_shared<CallSession>(conference, params, listener);
session = make_shared<CallSession>(conference.getCore(), params, listener);
}
return session;
}
......
......@@ -50,6 +50,8 @@ class Participant : public Object {
friend class ServerGroupChatRoomPrivate;
public:
L_OVERRIDE_SHARED_FROM_THIS(Participant);
explicit Participant (const IdentityAddress &address);
explicit Participant (IdentityAddress &&address);
......
......@@ -31,8 +31,7 @@ LINPHONE_BEGIN_NAMESPACE
class CallSessionPrivate : public ObjectPrivate {
public:
CallSessionPrivate (const Conference &conference, const CallSessionParams *params, CallSessionListener *listener);
virtual ~CallSessionPrivate ();
CallSessionPrivate () = default;
int computeDuration () const;
virtual void initializeParamsAccordingToIncomingCallParams ();
......@@ -41,7 +40,6 @@ public:
bool startPing ();
void setPingTime (int value) { pingTime = value; }
LinphoneCore *getCore () const { return core; }
CallSessionParams *getCurrentParams () const { return currentParams; }
LinphoneProxyConfig * getDestProxy () const { return destProxy; }
SalCallOp * getOp () const { return op; }
......@@ -61,6 +59,8 @@ public:
virtual void updating (bool isUpdate);
protected:
void init ();
void accept (const CallSessionParams *params);
virtual LinphoneStatus acceptUpdate (const CallSessionParams *csp, LinphoneCallState nextState, const std::string &stateInfo);
LinphoneStatus checkForAcceptation () const;
......@@ -85,8 +85,6 @@ private:
LinphoneAddress * getFixedContact () const;
protected:
const Conference &conference;
LinphoneCore *core = nullptr;
CallSessionListener *listener = nullptr;
CallSessionParams *params = nullptr;
......
This diff is collapsed.
......@@ -34,8 +34,9 @@ LINPHONE_BEGIN_NAMESPACE
class CallPrivate;
class CallSessionPrivate;
class Content;
class Core;
class LINPHONE_PUBLIC CallSession : public Object {
class LINPHONE_PUBLIC CallSession : public Object, public CoreAccessor {
friend class CallPrivate;
friend class ClientGroupChatRoom;
friend class ClientGroupChatRoomPrivate;
......@@ -46,7 +47,8 @@ class LINPHONE_PUBLIC CallSession : public Object {
public:
L_OVERRIDE_SHARED_FROM_THIS(CallSession);
CallSession (const Conference &conference, const CallSessionParams *params, CallSessionListener *listener);
CallSession (const std::shared_ptr<Core> &core, const CallSessionParams *params, CallSessionListener *listener);
virtual ~CallSession ();
LinphoneStatus accept (const CallSessionParams *csp = nullptr);
LinphoneStatus acceptUpdate (const CallSessionParams *csp);
......@@ -80,7 +82,7 @@ public:
std::string getRemoteUserAgent () const;
protected:
explicit CallSession (CallSessionPrivate &p);
explicit CallSession (CallSessionPrivate &p, const std::shared_ptr<Core> &core);
private:
L_DECLARE_PRIVATE(CallSession);
......
......@@ -37,8 +37,7 @@ LINPHONE_BEGIN_NAMESPACE
class MediaSessionPrivate : public CallSessionPrivate {
public:
MediaSessionPrivate (const Conference &conference, const CallSessionParams *params, CallSessionListener *listener);
virtual ~MediaSessionPrivate ();
MediaSessionPrivate () = default;
public:
static void stunAuthRequestedCb (void *userData, const char *realm, const char *nonce, const char **username, const char **password, const char **ha1);
......@@ -69,7 +68,9 @@ public:
MediaSessionParams *getCurrentParams () const { return static_cast<MediaSessionParams *>(currentParams); }
MediaSessionParams *getParams () const { return static_cast<MediaSessionParams *>(params); }
MediaSessionParams *getRemoteParams () const { return static_cast<MediaSessionParams *>(remoteParams); }
void setCurrentParams (MediaSessionParams *msp);
void setParams (MediaSessionParams *msp);
void setRemoteParams (MediaSessionParams *msp);
IceSession *getIceSession () const { return iceAgent->getIceSession(); }
......@@ -99,6 +100,7 @@ private:
static float aggregateQualityRatings (float audioRating, float videoRating);
std::shared_ptr<Participant> getMe () const;
void setState (LinphoneCallState newState, const std::string &message) override;
void computeStreamsIndexes (const SalMediaDescription *md);
......@@ -244,6 +246,8 @@ private:
static const std::string ecStateStore;
static const int ecStateMaxLen;
std::weak_ptr<Participant> me;
AudioStream *audioStream = nullptr;
OrtpEvQueue *audioStreamEvQueue = nullptr;
LinphoneCallStats *audioStats = nullptr;
......
This diff is collapsed.
......@@ -28,8 +28,10 @@
LINPHONE_BEGIN_NAMESPACE
class CallPrivate;
class Core;
class IceAgent;
class MediaSessionPrivate;
class Participant;
class LINPHONE_PUBLIC MediaSession : public CallSession {
friend class Call;
......@@ -37,7 +39,8 @@ class LINPHONE_PUBLIC MediaSession : public CallSession {
friend class IceAgent;
public:
MediaSession (const Conference &conference, const CallSessionParams *params, CallSessionListener *listener);
MediaSession (const std::shared_ptr<Core> &core, std::shared_ptr<Participant> me, const CallSessionParams *params, CallSessionListener *listener);
virtual ~MediaSession ();
LinphoneStatus accept (const MediaSessionParams *msp = nullptr);
LinphoneStatus acceptEarlyMedia (const MediaSessionParams *msp = nullptr);
......
......@@ -22,6 +22,7 @@
#include "private.h"
#include "conference/session/media-session-p.h"
#include "core/core.h"
#include "logger/logger.h"
#include "ice-agent.h"
......@@ -43,7 +44,7 @@ void IceAgent::checkSession (IceRole role, bool isReinvite) {
if (iceSession)
return;
LinphoneConfig *config = linphone_core_get_config(mediaSession.getPrivate()->getCore());
LinphoneConfig *config = linphone_core_get_config(mediaSession.getCore()->getCCore());
if (isReinvite && (lp_config_get_int(config, "net", "allow_late_ice", 0) == 0))
return;
......@@ -128,7 +129,7 @@ bool IceAgent::prepare (const SalMediaDescription *localDesc, bool incomingOffer
bool hasVideo = false;
if (incomingOffer) {
remoteDesc = mediaSession.getPrivate()->getOp()->get_remote_media_description();
hasVideo = linphone_core_video_enabled(mediaSession.getPrivate()->getCore()) &&
hasVideo = linphone_core_video_enabled(mediaSession.getCore()->getCCore()) &&
linphone_core_media_description_contains_video_stream(remoteDesc);
} else
hasVideo = mediaSession.getMediaParams()->videoEnabled();
......@@ -214,7 +215,7 @@ void IceAgent::updateFromRemoteMediaDescription (
if (!iceParamsFoundInRemoteMediaDescription(remoteDesc)) {
// Response from remote does not contain mandatory ICE attributes, delete the session.
deleteSession();
mediaSession.getPrivate()->enableSymmetricRtp(!!linphone_core_symmetric_rtp_enabled(mediaSession.getPrivate()->getCore()));
mediaSession.getPrivate()->enableSymmetricRtp(!!linphone_core_symmetric_rtp_enabled(mediaSession.getCore()->getCCore()));
return;
}
......@@ -237,7 +238,7 @@ void IceAgent::updateFromRemoteMediaDescription (
if (ice_session_nb_check_lists(iceSession) == 0) {
deleteSession();
mediaSession.getPrivate()->enableSymmetricRtp(!!linphone_core_symmetric_rtp_enabled(mediaSession.getPrivate()->getCore()));
mediaSession.getPrivate()->enableSymmetricRtp(!!linphone_core_symmetric_rtp_enabled(mediaSession.getCore()->getCCore()));
}
}
......@@ -319,7 +320,7 @@ void IceAgent::updateLocalMediaDescriptionFromIce (SalMediaDescription *desc) {
if (!sal_stream_description_active(stream) || !cl)
continue;
if (ice_check_list_state(cl) == ICL_Completed) {
LinphoneConfig *config = linphone_core_get_config(mediaSession.getPrivate()->getCore());
LinphoneConfig *config = linphone_core_get_config(mediaSession.getCore()->getCCore());
// TODO: Remove `ice_uses_nortpproxy` option, let's say in December 2018.
bool useNoRtpProxy = !!lp_config_get_int(config, "sip", "ice_uses_nortpproxy", false);
if (useNoRtpProxy)
......@@ -413,7 +414,7 @@ void IceAgent::addLocalIceCandidates (int family, const char *addr, IceCheckList
LinphoneCallStats *audioStats = mediaSession.getPrivate()->getStats(LinphoneStreamTypeAudio);
_linphone_call_stats_set_ice_state(audioStats, LinphoneIceStateInProgress);
}
LinphoneCore *core = mediaSession.getPrivate()->getCore();
LinphoneCore *core = mediaSession.getCore()->getCCore();
if (linphone_core_video_enabled(core) && videoCl && (ice_check_list_state(videoCl) != ICL_Completed) && !ice_check_list_candidates_gathered(videoCl)) {
int rtpPort = mediaSession.getPrivate()->getRtpPort(LinphoneStreamTypeVideo);
int rtcpPort = mediaSession.getPrivate()->getRtcpPort(LinphoneStreamTypeVideo);
......@@ -583,7 +584,7 @@ int IceAgent::gatherIceCandidates () {
lWarning() << "Failed to resolve STUN server for ICE gathering, continuing without STUN";
} else
lWarning() << "ICE is used without STUN server";
LinphoneCore *core = mediaSession.getPrivate()->getCore();
LinphoneCore *core = mediaSession.getCore()->getCCore();
ice_session_enable_forced_relay(iceSession, core->forced_ice_relay);
ice_session_enable_short_turn_refresh(iceSession, core->short_turn_refresh);
......@@ -649,6 +650,7 @@ const struct addrinfo *IceAgent::getIcePreferredStunServerAddrinfo (const struct
if (it->ai_family == AF_INET6) {
struct sockaddr_storage ss;
socklen_t sslen = sizeof(ss);
memset(&ss, 0, sizeof(ss));
bctbx_sockaddr_remove_nat64_mapping(it->ai_addr, (struct sockaddr *)&ss, &sslen);
if (ss.ss_family == AF_INET) break;
}
......
......@@ -30,13 +30,13 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE
int StunClient::run (int audioPort, int videoPort, int textPort) {
if (linphone_core_ipv6_enabled(core)) {
if (linphone_core_ipv6_enabled(getCore()->getCCore())) {
lWarning() << "STUN support is not implemented for ipv6";
return -1;
}
if (!linphone_core_get_stun_server(core))
if (!linphone_core_get_stun_server(getCore()->getCCore()))
return -1;
const struct addrinfo *ai = linphone_core_get_stun_server_addrinfo(core);
const struct addrinfo *ai = linphone_core_get_stun_server_addrinfo(getCore()->getCCore());
if (!ai) {
lError() << "Could not obtain STUN server addrinfo";
return -1;
......@@ -47,13 +47,13 @@ int StunClient::run (int audioPort, int videoPort, int textPort) {
if (sockAudio == -1)
return -1;
ortp_socket_t sockVideo = -1;
if (linphone_core_video_enabled(core)) {
if (linphone_core_video_enabled(getCore()->getCCore())) {
sockVideo = createStunSocket(videoPort);
if (sockVideo == -1)
return -1;
}
ortp_socket_t sockText = -1;
if (linphone_core_realtime_text_enabled(core)) {
if (linphone_core_realtime_text_enabled(getCore()->getCCore())) {
sockText = createStunSocket(textPort);
if (sockText == -1)
return -1;
......
......@@ -24,23 +24,25 @@
#include <ortp/port.h>
#include "core/core.h"
#include "core/core-accessor.h"
#include "linphone/utils/general.h"
// =============================================================================
L_DECL_C_STRUCT_PREFIX_LESS(SalMediaDescription);
L_DECL_C_STRUCT(LinphoneCore);
LINPHONE_BEGIN_NAMESPACE
class StunClient {
class StunClient : public CoreAccessor {
struct Candidate {
std::string address;
int port;
};
public:
StunClient (LinphoneCore *core) : core(core) {}
StunClient (const std::shared_ptr<Core> &core) : CoreAccessor(core) {}
int run (int audioPort, int videoPort, int textPort);
void updateMediaDescription (SalMediaDescription *md) const;
......@@ -62,7 +64,6 @@ public:
int sendStunRequest (ortp_socket_t sock, const struct sockaddr *server, socklen_t addrlen, int id, bool changeAddr);
private:
LinphoneCore *core = nullptr;
Candidate audioCandidate;
Candidate videoCandidate;
Candidate textCandidate;
......
......@@ -128,7 +128,7 @@ void PayloadTypeHandler::assignPayloadTypeNumbers (const bctbx_list_t *codecs) {
}
if (number == -1) {
int dynNumber = core->codecs_conf.dyn_pt;
int dynNumber = getCore()->getCCore()->codecs_conf.dyn_pt;
while (dynNumber < 127) {
if (isPayloadTypeNumberAvailable(codecs, dynNumber, nullptr)) {
payload_type_set_number(pt, dynNumber);
......@@ -159,7 +159,7 @@ void PayloadTypeHandler::assignPayloadTypeNumbers (const bctbx_list_t *codecs) {
bctbx_list_t *PayloadTypeHandler::createSpecialPayloadTypes (const bctbx_list_t *codecs) {
bctbx_list_t *result = createTelephoneEventPayloadTypes(codecs);
if (linphone_core_generic_comfort_noise_enabled(core)) {
if (linphone_core_generic_comfort_noise_enabled(getCore()->getCCore())) {
OrtpPayloadType *cn = payload_type_clone(&payload_type_cn);
payload_type_set_number(cn, 13);
result = bctbx_list_append(result, cn);
......@@ -179,8 +179,8 @@ bctbx_list_t *PayloadTypeHandler::createTelephoneEventPayloadTypes (const bctbx_
// Let it choose the number dynamically as for normal codecs.
payload_type_set_number(tev, -1);
// But for first telephone-event, prefer the number that was configured in the core.
if (!result && isPayloadTypeNumberAvailable(codecs, core->codecs_conf.telephone_event_pt, nullptr))
payload_type_set_number(tev, core->codecs_conf.telephone_event_pt);
if (!result && isPayloadTypeNumberAvailable(codecs, getCore()->getCCore()->codecs_conf.telephone_event_pt, nullptr))
payload_type_set_number(tev, getCore()->getCCore()->codecs_conf.telephone_event_pt);
result = bctbx_list_append(result, tev);
}
return result;
......@@ -189,8 +189,8 @@ bctbx_list_t *PayloadTypeHandler::createTelephoneEventPayloadTypes (const bctbx_
bool PayloadTypeHandler::isPayloadTypeUsable (const OrtpPayloadType *pt) {
return isPayloadTypeUsableForBandwidth(
pt, getMinBandwidth(
linphone_core_get_download_bandwidth(core),
linphone_core_get_upload_bandwidth(core)
linphone_core_get_download_bandwidth(getCore()->getCCore()),
linphone_core_get_upload_bandwidth(getCore()->getCCore())
)
);
}
......@@ -276,13 +276,13 @@ bctbx_list_t *PayloadTypeHandler::makeCodecsList (SalStreamType type, int bandwi
switch (type) {
default:
case SalAudio:
allCodecs = core->codecs_conf.audio_codecs;
allCodecs = getCore()->getCCore()->codecs_conf.audio_codecs;
break;
case SalVideo:
allCodecs = core->codecs_conf.video_codecs;
allCodecs = getCore()->getCCore()->codecs_conf.video_codecs;
break;
case SalText:
allCodecs = core->codecs_conf.text_codecs;
allCodecs = getCore()->getCCore()->codecs_conf.text_codecs;
break;
}
......
......@@ -23,6 +23,8 @@
#include "linphone/utils/general.h"
#include "c-wrapper/internal/c-sal.h"
#include "core/core.h"
#include "core/core-accessor.h"
#define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0
#define PAYLOAD_TYPE_BITRATE_OVERRIDE PAYLOAD_TYPE_USER_FLAG_3
......@@ -30,8 +32,6 @@
// =============================================================================
L_DECL_C_STRUCT(LinphoneCore);
LINPHONE_BEGIN_NAMESPACE
struct VbrCodecBitrate {
......@@ -40,9 +40,11 @@ struct VbrCodecBitrate {
int recommendedBitrate;
};
class PayloadTypeHandler {
class Core;
class PayloadTypeHandler : public CoreAccessor {
public:
explicit PayloadTypeHandler (LinphoneCore *core) : core(core) {}
explicit PayloadTypeHandler (const std::shared_ptr<Core> &core) : CoreAccessor(core) {}
bctbx_list_t *makeCodecsList (SalStreamType type, int bandwidthLimit, int maxCodecs, const bctbx_list_t *previousList);
......@@ -69,8 +71,6 @@ private:
static const int rtpHeaderSize;
static const int ipv4HeaderSize;
static const VbrCodecBitrate defaultVbrCodecBitrates[];
LinphoneCore *core = nullptr;
};
LINPHONE_END_NAMESPACE
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment