mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1091242 - Part 6: Wiring the new JSEP handler code in. See https://github.com/unicorn-wg/gecko-dev/tree/multistream_rebase for more history. r=jesup, r=smaug
This commit is contained in:
parent
43300ec021
commit
3af28ea884
@ -507,7 +507,7 @@ class Automation(object):
|
||||
env['NS_TRACE_MALLOC_DISABLE_STACKS'] = '1'
|
||||
|
||||
# Set WebRTC logging in case it is not set yet
|
||||
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5')
|
||||
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
|
||||
env.setdefault('R_LOG_LEVEL', '6')
|
||||
env.setdefault('R_LOG_DESTINATION', 'stderr')
|
||||
env.setdefault('R_LOG_VERBOSE', '1')
|
||||
|
@ -410,7 +410,7 @@ def environment(xrePath, env=None, crashreporter=True, debugger=False, dmdPath=N
|
||||
env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1')
|
||||
|
||||
# Set WebRTC logging in case it is not set yet
|
||||
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5')
|
||||
env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5')
|
||||
env.setdefault('R_LOG_LEVEL', '6')
|
||||
env.setdefault('R_LOG_DESTINATION', 'stderr')
|
||||
env.setdefault('R_LOG_VERBOSE', '1')
|
||||
|
@ -862,7 +862,7 @@ DOMInterfaces = {
|
||||
},
|
||||
|
||||
'PeerConnectionImpl': {
|
||||
'nativeType': 'sipcc::PeerConnectionImpl',
|
||||
'nativeType': 'mozilla::PeerConnectionImpl',
|
||||
'headerFile': 'PeerConnectionImpl.h',
|
||||
'wrapperCache': False
|
||||
},
|
||||
|
@ -25,7 +25,7 @@ const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
|
||||
const PC_SENDER_CONTRACT = "@mozilla.org/dom/rtpsender;1";
|
||||
const PC_RECEIVER_CONTRACT = "@mozilla.org/dom/rtpreceiver;1";
|
||||
|
||||
const PC_CID = Components.ID("{00e0e20d-1494-4776-8e0e-0f0acbea3c79}");
|
||||
const PC_CID = Components.ID("{bdc2e533-b308-4708-ac8e-a8bfade6d851}");
|
||||
const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
|
||||
const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
|
||||
const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
|
||||
@ -849,7 +849,7 @@ RTCPeerConnection.prototype = {
|
||||
|
||||
this._impl.addIceCandidate(cand.candidate, cand.sdpMid || "",
|
||||
(cand.sdpMLineIndex === null) ? 0 :
|
||||
cand.sdpMLineIndex + 1);
|
||||
cand.sdpMLineIndex);
|
||||
},
|
||||
|
||||
addStream: function(stream) {
|
||||
@ -1122,7 +1122,7 @@ PeerConnectionObserver.prototype = {
|
||||
const reasonName = [
|
||||
"",
|
||||
"InternalError",
|
||||
"InternalError",
|
||||
"InvalidCandidateError",
|
||||
"InvalidParameter",
|
||||
"InvalidStateError",
|
||||
"InvalidSessionDescriptionError",
|
||||
@ -1221,7 +1221,7 @@ PeerConnectionObserver.prototype = {
|
||||
{
|
||||
candidate: candidate,
|
||||
sdpMid: mid,
|
||||
sdpMLineIndex: level - 1
|
||||
sdpMLineIndex: level
|
||||
}
|
||||
));
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
component {00e0e20d-1494-4776-8e0e-0f0acbea3c79} PeerConnection.js
|
||||
component {bdc2e533-b308-4708-ac8e-a8bfade6d851} PeerConnection.js
|
||||
component {d1748d4c-7f6a-4dc5-add6-d55b7678537e} PeerConnection.js
|
||||
component {02b9970c-433d-4cc2-923d-f7028ac66073} PeerConnection.js
|
||||
component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
|
||||
@ -9,7 +9,7 @@ component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
|
||||
component {4fff5d46-d827-4cd4-a970-8fd53977440e} PeerConnection.js
|
||||
component {d974b814-8fde-411c-8c45-b86791b81030} PeerConnection.js
|
||||
|
||||
contract @mozilla.org/dom/peerconnection;1 {00e0e20d-1494-4776-8e0e-0f0acbea3c79}
|
||||
contract @mozilla.org/dom/peerconnection;1 {bdc2e533-b308-4708-ac8e-a8bfade6d851}
|
||||
contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
|
||||
contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac66073}
|
||||
contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
|
||||
|
@ -59,6 +59,7 @@ interface IPeerConnection : nsISupports
|
||||
|
||||
/* Constants for 'name' in error callbacks */
|
||||
const unsigned long kNoError = 0; // Test driver only
|
||||
const unsigned long kInvalidCandidate = 2;
|
||||
const unsigned long kInvalidMediastreamTrack = 3;
|
||||
const unsigned long kInvalidState = 4;
|
||||
const unsigned long kInvalidSessionDescription = 5;
|
||||
|
@ -21,9 +21,9 @@ NS_DEFINE_NAMED_CID(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CID)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStunUDPSocketFilterHandler)
|
||||
|
||||
|
||||
namespace sipcc
|
||||
namespace mozilla
|
||||
{
|
||||
// Factory defined in sipcc::, defines sipcc::PeerConnectionImplConstructor
|
||||
// Factory defined in mozilla::, defines mozilla::PeerConnectionImplConstructor
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(PeerConnectionImpl)
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(PeerConnectionImpl)
|
||||
NS_DEFINE_NAMED_CID(PEERCONNECTION_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kCIDs[] = {
|
||||
{ &kPEERCONNECTION_CID, false, nullptr, sipcc::PeerConnectionImplConstructor },
|
||||
{ &kPEERCONNECTION_CID, false, nullptr, mozilla::PeerConnectionImplConstructor },
|
||||
{ &kNS_STUN_UDP_SOCKET_FILTER_HANDLER_CID, false, nullptr, nsStunUDPSocketFilterHandlerConstructor },
|
||||
{ nullptr }
|
||||
};
|
||||
|
@ -67,6 +67,7 @@ interface PeerConnectionImpl {
|
||||
boolean pluginCrash(unsigned long long pluginId, DOMString name, DOMString pluginDumpID);
|
||||
|
||||
/* Attributes */
|
||||
[Constant]
|
||||
readonly attribute DOMString fingerprint;
|
||||
readonly attribute DOMString localDescription;
|
||||
readonly attribute DOMString remoteDescription;
|
||||
@ -74,7 +75,6 @@ interface PeerConnectionImpl {
|
||||
readonly attribute PCImplIceConnectionState iceConnectionState;
|
||||
readonly attribute PCImplIceGatheringState iceGatheringState;
|
||||
readonly attribute PCImplSignalingState signalingState;
|
||||
readonly attribute PCImplSipccState sipccState;
|
||||
attribute DOMString id;
|
||||
|
||||
attribute DOMString peerIdentity;
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
DtlsIdentity::~DtlsIdentity() {
|
||||
// XXX: make cert_ a smart pointer to avoid this, after we figure
|
||||
// out the linking problem.
|
||||
@ -27,7 +25,6 @@ DtlsIdentity::~DtlsIdentity() {
|
||||
}
|
||||
|
||||
const std::string DtlsIdentity::DEFAULT_HASH_ALGORITHM = "sha-256";
|
||||
const size_t DtlsIdentity::HASH_ALGORITHM_MAX_LENGTH = 64;
|
||||
|
||||
TemporaryRef<DtlsIdentity> DtlsIdentity::Generate() {
|
||||
|
||||
@ -210,89 +207,4 @@ nsresult DtlsIdentity::ComputeFingerprint(const CERTCertificate *cert,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Format the fingerprint in RFC 4572 Section 5 attribute format, including both
|
||||
// the hash name and the fingerprint, colons and all.
|
||||
// returns an empty string if there is a problem
|
||||
std::string DtlsIdentity::GetFormattedFingerprint(const std::string &algorithm) {
|
||||
unsigned char digest[HASH_ALGORITHM_MAX_LENGTH];
|
||||
size_t digest_length;
|
||||
|
||||
nsresult res = this->ComputeFingerprint(algorithm,
|
||||
digest,
|
||||
sizeof(digest),
|
||||
&digest_length);
|
||||
if (NS_FAILED(res)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Unable to compute " << algorithm
|
||||
<< " hash for identity: nsresult = 0x"
|
||||
<< std::hex << std::uppercase
|
||||
<< static_cast<uint32_t>(res)
|
||||
<< std::nouppercase << std::dec);
|
||||
return "";
|
||||
}
|
||||
|
||||
return algorithm + " " + this->FormatFingerprint(digest, digest_length);
|
||||
}
|
||||
|
||||
std::string DtlsIdentity::FormatFingerprint(const unsigned char *digest,
|
||||
std::size_t size) {
|
||||
std::string str("");
|
||||
char group[3];
|
||||
|
||||
for (std::size_t i=0; i < size; i++) {
|
||||
PR_snprintf(group, sizeof(group), "%.2X", digest[i]);
|
||||
if (i != 0) {
|
||||
str += ":";
|
||||
}
|
||||
str += group;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(str.size() == (size * 3 - 1)); // Check result length
|
||||
return str;
|
||||
}
|
||||
|
||||
// Parse a fingerprint in RFC 4572 format.
|
||||
// Note that this tolerates some badly formatted data, in particular:
|
||||
// (a) arbitrary runs of colons
|
||||
// (b) colons at the beginning or end.
|
||||
nsresult DtlsIdentity::ParseFingerprint(const std::string fp,
|
||||
unsigned char *digest,
|
||||
size_t size,
|
||||
size_t *length) {
|
||||
size_t offset = 0;
|
||||
bool top_half = true;
|
||||
uint8_t val = 0;
|
||||
|
||||
for (size_t i=0; i<fp.length(); i++) {
|
||||
if (offset >= size) {
|
||||
// Note: no known way for offset to get > size
|
||||
MOZ_MTLOG(ML_ERROR, "Fingerprint too long for buffer");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (top_half && (fp[i] == ':')) {
|
||||
continue;
|
||||
} else if ((fp[i] >= '0') && (fp[i] <= '9')) {
|
||||
val |= fp[i] - '0';
|
||||
} else if ((fp[i] >= 'A') && (fp[i] <= 'F')) {
|
||||
val |= fp[i] - 'A' + 10;
|
||||
} else {
|
||||
MOZ_MTLOG(ML_ERROR, "Invalid fingerprint value " << fp[i]);
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
if (top_half) {
|
||||
val <<= 4;
|
||||
top_half = false;
|
||||
} else {
|
||||
digest[offset++] = val;
|
||||
top_half = true;
|
||||
val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
*length = offset;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // close namespace
|
||||
|
@ -33,8 +33,6 @@ class DtlsIdentity {
|
||||
CERTCertificate *cert() { return cert_; }
|
||||
SECKEYPrivateKey *privkey() { return privkey_; }
|
||||
|
||||
std::string GetFormattedFingerprint(const std::string &algorithm = DEFAULT_HASH_ALGORITHM);
|
||||
|
||||
nsresult ComputeFingerprint(const std::string algorithm,
|
||||
unsigned char *digest,
|
||||
std::size_t size,
|
||||
@ -45,24 +43,18 @@ class DtlsIdentity {
|
||||
unsigned char *digest,
|
||||
std::size_t size,
|
||||
std::size_t *digest_length);
|
||||
|
||||
static nsresult ParseFingerprint(const std::string fp,
|
||||
unsigned char *digest,
|
||||
size_t size, size_t *length);
|
||||
static const std::string DEFAULT_HASH_ALGORITHM;
|
||||
enum {
|
||||
HASH_ALGORITHM_MAX_LENGTH = 64
|
||||
};
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DtlsIdentity)
|
||||
|
||||
private:
|
||||
private:
|
||||
DtlsIdentity(SECKEYPrivateKey *privkey, CERTCertificate *cert)
|
||||
: privkey_(privkey), cert_(cert) {}
|
||||
DISALLOW_COPY_ASSIGN(DtlsIdentity);
|
||||
|
||||
static const std::string DEFAULT_HASH_ALGORITHM;
|
||||
static const size_t HASH_ALGORITHM_MAX_LENGTH;
|
||||
|
||||
std::string FormatFingerprint(const unsigned char *digest,
|
||||
std::size_t size);
|
||||
|
||||
ScopedSECKEYPrivateKey privkey_;
|
||||
CERTCertificate *cert_; // TODO: Using a smart pointer here causes link
|
||||
// errors.
|
||||
|
@ -40,7 +40,6 @@
|
||||
// PR_LOGGING is off --> make no-op MTLOG macros
|
||||
#define MOZ_MTLOG_MODULE(n)
|
||||
#define MOZ_MTLOG(level, b)
|
||||
|
||||
#endif // defined(PR_LOGGING)
|
||||
|
||||
#endif // logging_h__
|
||||
|
@ -533,11 +533,21 @@ NrIceCtx::CreateStream(const std::string& name, int components) {
|
||||
RefPtr<NrIceMediaStream> stream =
|
||||
NrIceMediaStream::Create(this, name, components);
|
||||
|
||||
streams_.push_back(stream);
|
||||
if (stream) {
|
||||
streams_.push_back(stream);
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
std::string NrIceCtx::ufrag() const {
|
||||
return ctx_->ufrag;
|
||||
}
|
||||
|
||||
std::string NrIceCtx::pwd() const {
|
||||
return ctx_->pwd;
|
||||
}
|
||||
|
||||
void NrIceCtx::destroy_peer_ctx() {
|
||||
nr_ice_peer_ctx_destroy(&peer_);
|
||||
}
|
||||
|
@ -207,9 +207,20 @@ class NrIceCtx {
|
||||
RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
|
||||
int components);
|
||||
|
||||
RefPtr<NrIceMediaStream> GetStream(size_t index) {
|
||||
if (index < streams_.size()) {
|
||||
return streams_[index];
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// The name of the ctx
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
// Get ufrag and password.
|
||||
std::string ufrag() const;
|
||||
std::string pwd() const;
|
||||
|
||||
// Current state
|
||||
ConnectionState connection_state() const {
|
||||
return connection_state_;
|
||||
|
@ -338,6 +338,27 @@ nsresult NrIceMediaStream::GetCandidatePairs(std::vector<NrIceCandidatePair>*
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NrIceMediaStream::GetDefaultCandidate(
|
||||
NrIceCandidate* candidate) const {
|
||||
|
||||
nr_ice_candidate *cand;
|
||||
|
||||
int r = nr_ice_media_stream_get_default_candidate(stream_, 1, &cand);
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't get default ICE candidate for '"
|
||||
<< name_ << "'");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!ToNrIceCandidate(*cand, candidate)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to convert default ICE candidate for '"
|
||||
<< name_ << "'");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
std::vector<std::string> NrIceMediaStream::GetCandidates() const {
|
||||
char **attrs = 0;
|
||||
int attrct;
|
||||
|
@ -136,6 +136,10 @@ class NrIceMediaStream {
|
||||
// queue, in priority order. |out_pairs| is cleared before being filled.
|
||||
nsresult GetCandidatePairs(std::vector<NrIceCandidatePair>* out_pairs) const;
|
||||
|
||||
// TODO(bug 1096795): This needs to take a component number, so we can get
|
||||
// default candidates for rtcp.
|
||||
nsresult GetDefaultCandidate(NrIceCandidate* candidate) const;
|
||||
|
||||
// Parse remote attributes
|
||||
nsresult ParseAttributes(std::vector<std::string>& candidates);
|
||||
|
||||
@ -151,7 +155,7 @@ class NrIceMediaStream {
|
||||
NrIceCandidate** local, NrIceCandidate** remote);
|
||||
|
||||
// The number of components
|
||||
int components() const { return components_; }
|
||||
size_t components() const { return components_; }
|
||||
|
||||
// The underlying nICEr stream
|
||||
nr_ice_media_stream *stream() { return stream_; }
|
||||
@ -188,7 +192,7 @@ class NrIceMediaStream {
|
||||
|
||||
private:
|
||||
NrIceMediaStream(NrIceCtx *ctx, const std::string& name,
|
||||
int components) :
|
||||
size_t components) :
|
||||
state_(ICE_CONNECTING),
|
||||
ctx_(ctx),
|
||||
name_(name),
|
||||
@ -203,7 +207,7 @@ class NrIceMediaStream {
|
||||
State state_;
|
||||
NrIceCtx *ctx_;
|
||||
const std::string name_;
|
||||
const int components_;
|
||||
const size_t components_;
|
||||
nr_ice_media_stream *stream_;
|
||||
uint16_t level_;
|
||||
};
|
||||
|
@ -545,7 +545,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||
void DumpAndCheckActiveCandidates_s() {
|
||||
std::cerr << "Active candidates:" << std::endl;
|
||||
for (size_t i=0; i < streams_.size(); ++i) {
|
||||
for (int j=0; j < streams_[i]->components(); ++j) {
|
||||
for (size_t j=0; j < streams_[i]->components(); ++j) {
|
||||
std::cerr << "Stream " << i << " component " << j+1 << std::endl;
|
||||
|
||||
NrIceCandidate *local;
|
||||
|
@ -607,7 +607,8 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
||||
connect(this, &TransportTestPeer::GotCandidate);
|
||||
|
||||
// Create the transport layer
|
||||
ice_ = new TransportLayerIce(name, ice_ctx_, stream, 1);
|
||||
ice_ = new TransportLayerIce(name);
|
||||
ice_->SetParameters(ice_ctx_, stream, 1);
|
||||
|
||||
// Assemble the stack
|
||||
nsAutoPtr<std::queue<mozilla::TransportLayer *> > layers(
|
||||
|
@ -463,7 +463,9 @@ int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, vo
|
||||
if(r=nr_socket_getaddr(cand->isock->sock,&cand->addr))
|
||||
ABORT(r);
|
||||
cand->osock=cand->isock->sock;
|
||||
cand->state=NR_ICE_CAND_STATE_INITIALIZED;
|
||||
// This is actually ready, but we set this anyway to prevent it from
|
||||
// being paired twice.
|
||||
cand->state=NR_ICE_CAND_STATE_INITIALIZING;
|
||||
// Post this so that it doesn't happen in-line
|
||||
cand->ready_cb = ready_cb;
|
||||
cand->ready_cb_arg = cb_arg;
|
||||
|
@ -793,10 +793,11 @@ int nr_ice_component_pair_candidate(nr_ice_peer_ctx *pctx, nr_ice_component *pco
|
||||
trickle candidates).
|
||||
*/
|
||||
if (pair_all_remote || (pcand->state == NR_ICE_CAND_PEER_CANDIDATE_UNPAIRED)) {
|
||||
/* If we are pairing our own trickle candidates, the remote candidate should
|
||||
all be paired */
|
||||
if (pair_all_remote)
|
||||
assert (pcand->state == NR_ICE_CAND_PEER_CANDIDATE_PAIRED);
|
||||
if (pair_all_remote) {
|
||||
/* When a remote candidate arrives after the start of checking, but
|
||||
* before the gathering of local candidates, it can be in UNPAIRED */
|
||||
pcand->state = NR_ICE_CAND_PEER_CANDIDATE_PAIRED;
|
||||
}
|
||||
|
||||
nr_ice_compute_codeword(pcand->label,strlen(pcand->label),codeword);
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/CAND(%s): Pairing with peer candidate %s", pctx->label, codeword, pcand->label);
|
||||
@ -1101,10 +1102,12 @@ int nr_ice_component_insert_pair(nr_ice_component *pcomp, nr_ice_cand_pair *pair
|
||||
ABORT(r);
|
||||
|
||||
/* Make sure the check timer is running, if the stream was previously
|
||||
* started. We will not start streams just because a pair was created. */
|
||||
* started. We will not start streams just because a pair was created,
|
||||
* unless it is the first pair to be created across all streams. */
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/CAND-PAIR(%s): Ensure that check timer is running for new pair %s.",pair->remote->stream->pctx->label, pair->codeword, pair->as_string);
|
||||
|
||||
if(pair->remote->stream->ice_state == NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE){
|
||||
if(pair->remote->stream->ice_state == NR_ICE_MEDIA_STREAM_CHECKS_ACTIVE ||
|
||||
!pair->remote->stream->pctx->checks_started){
|
||||
if(nr_ice_media_stream_start_checks(pair->remote->stream->pctx, pair->remote->stream)) {
|
||||
r_log(LOG_ICE,LOG_WARNING,"ICE-PEER(%s)/CAND-PAIR(%s): Could not restart checks for new pair %s.",pair->remote->stream->pctx->label, pair->codeword, pair->as_string);
|
||||
ABORT(R_INTERNAL);
|
||||
|
@ -455,6 +455,10 @@ void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
|
||||
|
||||
ctx->uninitialized_candidates--;
|
||||
|
||||
// Avoid the need for yet another initialization function
|
||||
if (cand->state == NR_ICE_CAND_STATE_INITIALIZING && cand->type == HOST)
|
||||
cand->state = NR_ICE_CAND_STATE_INITIALIZED;
|
||||
|
||||
if (cand->state == NR_ICE_CAND_STATE_INITIALIZED) {
|
||||
int was_pruned = 0;
|
||||
|
||||
@ -468,7 +472,7 @@ void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
|
||||
if (ctx->trickle_cb && !was_pruned) {
|
||||
ctx->trickle_cb(ctx->trickle_cb_arg, ctx, cand->stream, cand->component_id, cand);
|
||||
|
||||
if (r=nr_ice_ctx_pair_new_trickle_candidates(ctx, cand)) {
|
||||
if (nr_ice_ctx_pair_new_trickle_candidates(ctx, cand)) {
|
||||
r_log(LOG_ICE,LOG_ERR, "ICE(%s): All could not pair new trickle candidate",ctx->label);
|
||||
/* But continue */
|
||||
}
|
||||
|
@ -137,6 +137,10 @@ nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_str
|
||||
cand->stream=stream;
|
||||
skip_whitespace(&str);
|
||||
|
||||
/* Skip a= if present */
|
||||
if (!strncmp(str, "a=", 2))
|
||||
str += 2;
|
||||
|
||||
/* Candidate attr */
|
||||
if (strncasecmp(str, "candidate:", 10))
|
||||
ABORT(R_BAD_DATA);
|
||||
|
@ -171,7 +171,7 @@ static int nr_ice_peer_ctx_parse_stream_attributes_int(nr_ice_peer_ctx *pctx, nr
|
||||
}
|
||||
}
|
||||
else {
|
||||
r_log(LOG_ICE,LOG_WARNING,"ICE(%s): peer (%s) specified bogus attribute",pctx->ctx->label,pctx->label);
|
||||
r_log(LOG_ICE,LOG_WARNING,"ICE(%s): peer (%s) specified bogus attribute: %s",pctx->ctx->label,pctx->label,attrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,6 +220,9 @@ static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream
|
||||
|
||||
TAILQ_INSERT_TAIL(&comp->candidates,cand,entry_comp);
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/CAND(%s): creating peer candidate",
|
||||
pctx->label,cand->label);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if (_status) {
|
||||
@ -291,25 +294,25 @@ int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s), stream(%s) failed to pair trickle ICE candidates",pctx->ctx->label,pctx->label,stream->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start checks if this stream is not checking yet or if it has checked
|
||||
all the available candidates but not had a completed check for all
|
||||
components.
|
||||
/* Start checks if this stream is not checking yet or if it has checked
|
||||
all the available candidates but not had a completed check for all
|
||||
components.
|
||||
|
||||
Note that this is not compliant with RFC 5245, but consistent with
|
||||
the libjingle trickle ICE behavior. Note that we will not restart
|
||||
checks if either (a) the stream has failed or (b) all components
|
||||
have a successful pair because the switch statement above jumps
|
||||
will in both states.
|
||||
Note that this is not compliant with RFC 5245, but consistent with
|
||||
the libjingle trickle ICE behavior. Note that we will not restart
|
||||
checks if either (a) the stream has failed or (b) all components
|
||||
have a successful pair because the switch statement above jumps
|
||||
will in both states.
|
||||
|
||||
TODO(ekr@rtfm.com): restart checks.
|
||||
TODO(ekr@rtfm.com): update when the trickle ICE RFC is published
|
||||
*/
|
||||
if (!pstream->timer) {
|
||||
if(r=nr_ice_media_stream_start_checks(pctx, pstream)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s), stream(%s) failed to start checks",pctx->ctx->label,pctx->label,stream->label);
|
||||
ABORT(r);
|
||||
TODO(ekr@rtfm.com): restart checks.
|
||||
TODO(ekr@rtfm.com): update when the trickle ICE RFC is published
|
||||
*/
|
||||
if (!pstream->timer) {
|
||||
if(r=nr_ice_media_stream_start_checks(pctx, pstream)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s), stream(%s) failed to start checks",pctx->ctx->label,pctx->label,stream->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,11 +84,25 @@ namespace mozilla {
|
||||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
TransportLayerIce::TransportLayerIce(const std::string& name,
|
||||
RefPtr<NrIceCtx> ctx, RefPtr<NrIceMediaStream> stream,
|
||||
int component)
|
||||
: name_(name), ctx_(ctx), stream_(stream), component_(component) {
|
||||
target_ = ctx->thread();
|
||||
TransportLayerIce::TransportLayerIce(const std::string& name)
|
||||
: name_(name), ctx_(nullptr), stream_(nullptr), component_(0) {}
|
||||
|
||||
TransportLayerIce::~TransportLayerIce() {
|
||||
// No need to do anything here, since we use smart pointers
|
||||
}
|
||||
|
||||
void TransportLayerIce::SetParameters(RefPtr<NrIceCtx> ctx,
|
||||
RefPtr<NrIceMediaStream> stream,
|
||||
int component) {
|
||||
ctx_ = ctx;
|
||||
stream_ = stream;
|
||||
component_ = component;
|
||||
|
||||
PostSetup();
|
||||
}
|
||||
|
||||
void TransportLayerIce::PostSetup() {
|
||||
target_ = ctx_->thread();
|
||||
|
||||
stream_->SignalReady.connect(this, &TransportLayerIce::IceReady);
|
||||
stream_->SignalFailed.connect(this, &TransportLayerIce::IceFailed);
|
||||
@ -99,10 +113,6 @@ TransportLayerIce::TransportLayerIce(const std::string& name,
|
||||
}
|
||||
}
|
||||
|
||||
TransportLayerIce::~TransportLayerIce() {
|
||||
// No need to do anything here, since we use smart pointers
|
||||
}
|
||||
|
||||
TransportResult TransportLayerIce::SendPacket(const unsigned char *data,
|
||||
size_t len) {
|
||||
CheckThread();
|
||||
|
@ -31,12 +31,14 @@ namespace mozilla {
|
||||
|
||||
class TransportLayerIce : public TransportLayer {
|
||||
public:
|
||||
TransportLayerIce(const std::string& name,
|
||||
RefPtr<NrIceCtx> ctx,
|
||||
RefPtr<NrIceMediaStream> stream,
|
||||
int component);
|
||||
explicit TransportLayerIce(const std::string& name);
|
||||
|
||||
virtual ~TransportLayerIce();
|
||||
|
||||
void SetParameters(RefPtr<NrIceCtx> ctx,
|
||||
RefPtr<NrIceMediaStream> stream,
|
||||
int component);
|
||||
|
||||
// Transport layer overrides.
|
||||
virtual TransportResult SendPacket(const unsigned char *data, size_t len);
|
||||
|
||||
@ -51,6 +53,7 @@ class TransportLayerIce : public TransportLayer {
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_ASSIGN(TransportLayerIce);
|
||||
void PostSetup();
|
||||
|
||||
const std::string name_;
|
||||
RefPtr<NrIceCtx> ctx_;
|
||||
|
@ -1,314 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "ECC_Types.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
#include "fsmdef_states.h"
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
typedef struct Timecard Timecard;
|
||||
#else
|
||||
#include "timecard.h"
|
||||
#endif
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_Call
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_Call)
|
||||
|
||||
protected:
|
||||
CC_Call () { }
|
||||
|
||||
virtual ~CC_Call () {}
|
||||
|
||||
public:
|
||||
virtual void setRemoteWindow (VideoWindowHandle window) = 0;
|
||||
|
||||
virtual int setExternalRenderer(VideoFormat videoFormat, ExternalRendererHandle renderer) = 0;
|
||||
|
||||
virtual void sendIFrame () = 0;
|
||||
|
||||
virtual void getLocalSdp(std::string *sdp) const = 0;
|
||||
virtual void getRemoteSdp(std::string *sdp) const = 0;
|
||||
virtual fsmdef_states_t getFsmState () const = 0;
|
||||
virtual std::string fsmStateToString (fsmdef_states_t state) const = 0;
|
||||
|
||||
virtual void getErrorString(std::string *error) const = 0;
|
||||
virtual pc_error getError() const = 0;
|
||||
|
||||
virtual CC_CallInfoPtr getCallInfo () = 0;
|
||||
|
||||
virtual std::string toString() = 0;
|
||||
|
||||
/**
|
||||
Originate call - API to go offhook and dial specified digits on a given call
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
@param [in] digits - digits to be dialed. can be empty then this API simply goes offhook
|
||||
|
||||
@return true or false.
|
||||
*/
|
||||
virtual bool originateCall (cc_sdp_direction_t video_pref, const std::string & digits) = 0;
|
||||
|
||||
/**
|
||||
Use this function to answer an incoming call.
|
||||
|
||||
@param[in] video_pref - video direction desired on call
|
||||
|
||||
@return true or false.
|
||||
*/
|
||||
virtual bool answerCall (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
Use this function to put an active call on hold.
|
||||
|
||||
@param[in] reason - If the user chooses to put the call on hold then
|
||||
CC_HOLD_REASON_NONE should be the value passed in here.
|
||||
|
||||
@return true or false. If it's not appropriate to put this call on
|
||||
hold at the moment then this function will return false.
|
||||
*/
|
||||
virtual bool hold (cc_hold_reason_t reason) = 0;
|
||||
|
||||
/**
|
||||
Use this function to resume a call that is currently on hold.
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool resume (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
Use this function to end an active call.
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool endCall() = 0;
|
||||
|
||||
/**
|
||||
Send digits on the call - can be invoked either to dial additional digits or send DTMF
|
||||
|
||||
@param [in] digit - digit to be dialed
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool sendDigit (cc_digit_t digit) = 0;
|
||||
|
||||
/**
|
||||
Send Backspace - Delete last digit dialed.
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool backspace() = 0;
|
||||
|
||||
/**
|
||||
Redial
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool redial (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
Initiate Call Forward All
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool initiateCallForwardAll() = 0;
|
||||
|
||||
/**
|
||||
end Consult leg - used to end consult leg when the user picks active calls list for xfer/conf
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool endConsultativeCall() = 0;
|
||||
|
||||
/**
|
||||
Initiate a conference
|
||||
|
||||
@param [in] video_pref - video direction desired on consult call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool conferenceStart (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
complete conference
|
||||
|
||||
@param [in] otherCall - CC_CallPtr of the other leg
|
||||
@param [in] video_pref - video direction desired on consult call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool conferenceComplete (CC_CallPtr otherLog, cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
start transfer
|
||||
|
||||
@param [in] video_pref - video direction desired on consult call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool transferStart (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
complete transfer
|
||||
|
||||
@param [in] otherLeg - CC_CallPtr of the other leg
|
||||
@param [in] video_pref - video direction desired on consult call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool transferComplete (CC_CallPtr otherLeg,
|
||||
cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
cancel conference or transfer
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool cancelTransferOrConferenceFeature() = 0;
|
||||
|
||||
/**
|
||||
direct Transfer
|
||||
|
||||
@param [in] target - call handle for transfer target call
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool directTransfer (CC_CallPtr target) = 0;
|
||||
|
||||
/**
|
||||
Join Across line
|
||||
|
||||
@param [in] target - join target
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool joinAcrossLine (CC_CallPtr target) = 0;
|
||||
|
||||
/**
|
||||
BLF Call Pickup
|
||||
|
||||
@param [in] video_pref - video direction preference
|
||||
@param [in] speed - speedDial Number
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool blfCallPickup (cc_sdp_direction_t video_pref, const std::string & speed) = 0;
|
||||
|
||||
/**
|
||||
Select a call
|
||||
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool select() = 0;
|
||||
|
||||
/**
|
||||
Update Video Media Cap for the call
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool updateVideoMediaCap (cc_sdp_direction_t video_pref) = 0;
|
||||
|
||||
/**
|
||||
send INFO method for the call
|
||||
@param [in] handle - call handle
|
||||
@param [in] infopackage - Info-Package header value
|
||||
@param [in] infotype - Content-Type header val
|
||||
@param [in] infobody - Body of the INFO message
|
||||
@return true or false
|
||||
*/
|
||||
virtual bool sendInfo (const std::string & infopackage, const std::string & infotype, const std::string & infobody) = 0;
|
||||
|
||||
/**
|
||||
API to mute audio
|
||||
|
||||
@return true if the operation succeeded
|
||||
|
||||
NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume.
|
||||
*/
|
||||
virtual bool muteAudio(void) = 0;
|
||||
|
||||
|
||||
/**
|
||||
API to unmute audio
|
||||
|
||||
@return true if the operation succeeded
|
||||
|
||||
NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume.
|
||||
*/
|
||||
virtual bool unmuteAudio(void) = 0;
|
||||
/**
|
||||
API to mute video
|
||||
|
||||
@return true if the operation succeeded
|
||||
|
||||
NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume.
|
||||
*/
|
||||
virtual bool muteVideo(void) = 0;
|
||||
|
||||
|
||||
/**
|
||||
API to unmute video
|
||||
|
||||
@return true if the operation succeeded
|
||||
|
||||
NOTE: The mute state is persisted within the stack and shall be remembered across hold/resume.
|
||||
*/
|
||||
virtual bool unmuteVideo(void) = 0;
|
||||
|
||||
|
||||
/**
|
||||
API to set the call volume, acceptable values are 0 - 100
|
||||
@return true if volume set successfully, false if value out of range or change failed
|
||||
*/
|
||||
virtual bool setVolume(int volume) = 0;
|
||||
|
||||
|
||||
/**
|
||||
Originate P2P call - API to go offhook and dial specified digits\user on a given call
|
||||
|
||||
@param [in] video_pref - video direction desired on call
|
||||
@param [in] digits - digits to be dialed. can be empty then this API simply goes offhook
|
||||
@param [in] ip address - the ip address of the peer to call
|
||||
|
||||
@return void
|
||||
*/
|
||||
virtual void originateP2PCall (cc_sdp_direction_t video_pref, const std::string & digits, const std::string & ip) = 0;
|
||||
|
||||
virtual pc_error createOffer (cc_media_options_t* options, Timecard *) = 0;
|
||||
|
||||
virtual pc_error createAnswer(Timecard *) = 0;
|
||||
|
||||
virtual pc_error setLocalDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *) = 0;
|
||||
|
||||
virtual pc_error setRemoteDescription(cc_jsep_action_t action, const std::string & sdp, Timecard *) = 0;
|
||||
|
||||
virtual pc_error setPeerConnection(const std::string& handle) = 0;
|
||||
|
||||
virtual pc_error addStream(cc_media_stream_id_t stream_id,
|
||||
cc_media_track_id_t track_id,
|
||||
cc_media_type_t media_type) = 0;
|
||||
|
||||
virtual pc_error removeStream(cc_media_stream_id_t stream_id, cc_media_track_id_t track_id, cc_media_type_t media_type) = 0;
|
||||
|
||||
virtual const std::string& getPeerConnection() const = 0;
|
||||
|
||||
virtual pc_error addICECandidate(const std::string & candidate, const std::string & mid, unsigned short level, Timecard *) = 0;
|
||||
|
||||
virtual pc_error foundICECandidate(const std::string & candidate, const std::string & mid, unsigned short level, Timecard *) = 0;
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -1,339 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
#include "fsmdef_states.h"
|
||||
}
|
||||
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "CC_CallTypes.h"
|
||||
#include "peer_connection_types.h"
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
typedef struct Timecard Timecard;
|
||||
#else
|
||||
#include "timecard.h"
|
||||
#endif
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
|
||||
class ECC_API CC_CallInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_CallInfo)
|
||||
protected:
|
||||
CC_CallInfo() { }
|
||||
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_CallInfo() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the line object associated with this call.
|
||||
|
||||
@return CC_LinePtr - line ID
|
||||
*/
|
||||
virtual CC_LinePtr getline () = 0;
|
||||
|
||||
/**
|
||||
get Call state
|
||||
@param [in] handle - call info handle
|
||||
@return call state
|
||||
*/
|
||||
virtual cc_call_state_t getCallState () = 0;
|
||||
|
||||
/**
|
||||
get FSM state
|
||||
@param [in] handle - call info handle
|
||||
@return FSM state
|
||||
*/
|
||||
virtual fsmdef_states_t getFsmState () const = 0;
|
||||
|
||||
/**
|
||||
print Call state
|
||||
@param [in] handle - call info handle
|
||||
@return call state as string
|
||||
*/
|
||||
virtual std::string callStateToString (cc_call_state_t state) = 0;
|
||||
|
||||
/**
|
||||
print FSM state
|
||||
@param [in] handle - call info handle
|
||||
@return call state as string
|
||||
*/
|
||||
virtual std::string fsmStateToString (fsmdef_states_t state) const = 0;
|
||||
|
||||
/**
|
||||
print Call event
|
||||
@param [in] call event
|
||||
@return call event as string
|
||||
*/
|
||||
virtual std::string callEventToString (ccapi_call_event_e callEvent) = 0;
|
||||
|
||||
/**
|
||||
Get ringer state.
|
||||
|
||||
@return bool ringer state.
|
||||
*/
|
||||
virtual bool getRingerState() = 0;
|
||||
|
||||
/**
|
||||
Get call attributes
|
||||
|
||||
@return cc_call_attr_t.
|
||||
*/
|
||||
virtual cc_call_attr_t getCallAttr() = 0;
|
||||
|
||||
/**
|
||||
Get the call type
|
||||
|
||||
@return cc_call_type_t for this call. Supported values inlude:
|
||||
CC_CALL_TYPE_INCOMING, CC_CALL_TYPE_OUTGOING and CC_CALL_TYPE_FORWARDED.
|
||||
*/
|
||||
virtual cc_call_type_t getCallType() = 0;
|
||||
|
||||
/**
|
||||
Get called party name
|
||||
|
||||
@return called party name
|
||||
*/
|
||||
virtual std::string getCalledPartyName() = 0;
|
||||
|
||||
/**
|
||||
Get called party number
|
||||
|
||||
@return called party number as a string.
|
||||
*/
|
||||
virtual std::string getCalledPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
Get calling party name
|
||||
|
||||
@return calling party name
|
||||
*/
|
||||
virtual std::string getCallingPartyName() = 0;
|
||||
|
||||
/**
|
||||
Get calling party number
|
||||
@return calling party number as a string
|
||||
Note: this is a const reference to a string that's owned by the
|
||||
*/
|
||||
virtual std::string getCallingPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
Get alternate number
|
||||
|
||||
@return calling party number as a string.
|
||||
*/
|
||||
virtual std::string getAlternateNumber() = 0;
|
||||
|
||||
/**
|
||||
This function is used to check if a given capability is supported
|
||||
based on the information in this CC_CallInfo object.
|
||||
|
||||
@param [in] capability - the capability that is to be checked for availability.
|
||||
@return boolean - returns true if the given capability is available, false otherwise.
|
||||
*/
|
||||
virtual bool hasCapability (CC_CallCapabilityEnum::CC_CallCapability capability) = 0;
|
||||
|
||||
/**
|
||||
If you need the complete set of capabilities
|
||||
|
||||
@return cc_return_t - set of Call Capabilities.
|
||||
*/
|
||||
virtual std::set<CC_CallCapabilityEnum::CC_CallCapability> getCapabilitySet() = 0;
|
||||
|
||||
/**
|
||||
get Original Called party name
|
||||
@param [in] handle - call info handle
|
||||
@return original called party name
|
||||
*/
|
||||
virtual std::string getOriginalCalledPartyName() = 0;
|
||||
|
||||
/**
|
||||
get Original Called party number
|
||||
@param [in] handle - call info handle
|
||||
@return original called party number
|
||||
*/
|
||||
virtual std::string getOriginalCalledPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
get last redirecting party name
|
||||
@param [in] handle - call info handle
|
||||
@return last redirecting party name
|
||||
*/
|
||||
virtual std::string getLastRedirectingPartyName() = 0;
|
||||
|
||||
/**
|
||||
get past redirecting party number
|
||||
@param [in] handle - call info handle
|
||||
@return last redirecting party number
|
||||
*/
|
||||
virtual std::string getLastRedirectingPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
get placed call party name
|
||||
@param [in] handle - call info handle
|
||||
@return placed party name
|
||||
*/
|
||||
virtual std::string getPlacedCallPartyName() = 0;
|
||||
|
||||
/**
|
||||
get placed call party number
|
||||
@param [in] handle - call info handle
|
||||
@return placed party number
|
||||
*/
|
||||
virtual std::string getPlacedCallPartyNumber() = 0;
|
||||
|
||||
/**
|
||||
get call instance number
|
||||
@param [in] handle - call info handle
|
||||
@return
|
||||
*/
|
||||
virtual cc_int32_t getCallInstance() = 0;
|
||||
|
||||
/**
|
||||
get call status prompt
|
||||
@param [in] handle - call info handle
|
||||
@return call status
|
||||
*/
|
||||
virtual std::string getStatus() = 0;
|
||||
|
||||
/**
|
||||
get call security // TODO XLS has callagent security and endtoend security on call?
|
||||
@param [in] handle - call info handle
|
||||
@return call security status
|
||||
*/
|
||||
virtual cc_call_security_t getSecurity() = 0;
|
||||
|
||||
/**
|
||||
get Call Selection Status
|
||||
@param [in] handle - call info handle
|
||||
@return bool - TRUE => selected
|
||||
*/
|
||||
virtual cc_int32_t getSelectionStatus() = 0;
|
||||
|
||||
/**
|
||||
get GCID
|
||||
@param [in] handle - call info handle
|
||||
@return GCID
|
||||
*/
|
||||
virtual std::string getGCID() = 0;
|
||||
|
||||
/**
|
||||
get ringer loop count
|
||||
@param handle - call handle
|
||||
@return once Vs continuous
|
||||
*/
|
||||
virtual bool getIsRingOnce() = 0;
|
||||
|
||||
/**
|
||||
get ringer mode
|
||||
@param handle - call handle
|
||||
@return ringer mode
|
||||
*/
|
||||
virtual int getRingerMode() = 0;
|
||||
|
||||
/**
|
||||
get onhook reason
|
||||
@param [in] handle - call info handle
|
||||
@return onhook reason
|
||||
*/
|
||||
virtual cc_int32_t getOnhookReason() = 0;
|
||||
|
||||
/**
|
||||
is Conference Call?
|
||||
@param [in] handle - call info handle
|
||||
@return boolean - is Conference
|
||||
*/
|
||||
virtual bool getIsConference() = 0;
|
||||
|
||||
/**
|
||||
getStream Statistics
|
||||
@param [in] handle - call info handle
|
||||
@param [in,out] stats - Array to get the stats
|
||||
@param [in,out] count - in len of stats arraysize of stats / out stats copied
|
||||
@return cc_return_t - CC_SUCCESS or CC_FAILURE
|
||||
*/
|
||||
virtual std::set<cc_int32_t> getStreamStatistics() = 0;
|
||||
|
||||
/**
|
||||
Call selection status
|
||||
@param [in] handle - call info handle
|
||||
@return bool - selection status
|
||||
*/
|
||||
virtual bool isCallSelected() = 0;
|
||||
|
||||
/**
|
||||
INFO Package for RECEIVED_INFO event
|
||||
@param [in] handle - call info handle
|
||||
@return string - Info package header
|
||||
*/
|
||||
virtual std::string getINFOPack() = 0;
|
||||
|
||||
/**
|
||||
INFO type for RECEIVED_INFO event
|
||||
|
||||
@return string - content-type header
|
||||
*/
|
||||
virtual std::string getINFOType() = 0;
|
||||
|
||||
/**
|
||||
INFO body for RECEIVED_INFO event
|
||||
|
||||
@return string - INFO body
|
||||
*/
|
||||
virtual std::string getINFOBody() = 0;
|
||||
|
||||
/**
|
||||
Get the call log reference
|
||||
|
||||
//TODO NEED TO DO SOMETHING WRAP CALL LOG REF.
|
||||
@return string - INFO body
|
||||
NOTE: Memory associated with the call log is tied to the
|
||||
this would be freed when the callinfo ref is freed.
|
||||
*/
|
||||
virtual cc_calllog_ref_t getCallLogRef() = 0;
|
||||
|
||||
/**
|
||||
returns the negotiated video direction for this call
|
||||
|
||||
@return cc_sdp_direction_t - video direction
|
||||
*/
|
||||
virtual cc_sdp_direction_t getVideoDirection() = 0;
|
||||
|
||||
/**
|
||||
Find out if this call is capable of querying the media state, which includes mute state and video direction
|
||||
@return bool
|
||||
*/
|
||||
virtual bool isMediaStateAvailable() = 0;
|
||||
|
||||
/**
|
||||
Get the audio mute state if available (check availability with isMediaStateAvailable())
|
||||
@return bool - the current audio state of the call
|
||||
*/
|
||||
virtual bool isAudioMuted(void) = 0;
|
||||
|
||||
/**
|
||||
Get the video mute state if available (check availability with isMediaStateAvailable())
|
||||
@return bool - the current video state of the call
|
||||
*/
|
||||
virtual bool isVideoMuted(void) = 0;
|
||||
|
||||
/**
|
||||
Get the current call volume level
|
||||
@return int - the current call volume level, or -1 if it cannot be determined
|
||||
*/
|
||||
virtual int getVolume() = 0;
|
||||
|
||||
};
|
||||
};
|
@ -1,50 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_CallServerInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_CallServerInfo)
|
||||
|
||||
protected:
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_CallServerInfo() { }
|
||||
CC_CallServerInfo() { }
|
||||
|
||||
public:
|
||||
/**
|
||||
gets call server name
|
||||
|
||||
@returns name of the call server
|
||||
*/
|
||||
virtual std::string getCallServerName() = 0;
|
||||
|
||||
/**
|
||||
gets call server mode
|
||||
|
||||
@returns - mode of the call server
|
||||
*/
|
||||
virtual cc_cucm_mode_t getCallServerMode() = 0;
|
||||
|
||||
/**
|
||||
gets calls erver name
|
||||
|
||||
@returns status of the call server
|
||||
*/
|
||||
virtual cc_ccm_status_t getCallServerStatus() = 0;
|
||||
};
|
||||
};
|
@ -1,50 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
namespace CC_CallCapabilityEnum
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
canSetRemoteWindow,
|
||||
canSetLocalWindow,
|
||||
canSendIFrame,
|
||||
canOriginateCall,
|
||||
canAnswerCall,
|
||||
canHold,
|
||||
canResume,
|
||||
canEndCall,
|
||||
canSendDigit,
|
||||
canBackspace,
|
||||
canRedial,
|
||||
canInitiateCallForwardAll,
|
||||
canEndConsultativeCall,
|
||||
canConferenceStart,
|
||||
canConferenceComplete,
|
||||
canTransferStart,
|
||||
canTransferComplete,
|
||||
canCancelTransferOrConferenceFeature,
|
||||
canDirectTransfer,
|
||||
canJoinAcrossLine,
|
||||
canBlfCallPickup,
|
||||
canSelect,
|
||||
canUpdateVideoMediaCap,
|
||||
canSendInfo,
|
||||
canMuteAudio,
|
||||
canUnmuteAudio,
|
||||
canMuteVideo,
|
||||
canUnmuteVideo,
|
||||
canSetVolume
|
||||
} CC_CallCapability;
|
||||
std::string ECC_API toString(CC_CallCapability cap);
|
||||
std::string ECC_API toString(std::set<CC_CallCapability>& caps);
|
||||
};
|
||||
};
|
@ -1,34 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SharedPtr.h"
|
||||
|
||||
#ifndef ECC_API
|
||||
#ifdef ECC_EXPORT
|
||||
#define ECC_API _declspec(dllexport)
|
||||
#elif ECC_IMPORT
|
||||
#define ECC_API _declspec(dllimport)
|
||||
#else
|
||||
#define ECC_API
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(CallControlManager)
|
||||
DECLARE_NS_PTR_VECTOR(PhoneDetails)
|
||||
DECLARE_NS_PTR(CC_Service)
|
||||
DECLARE_NS_PTR(VideoControl)
|
||||
DECLARE_NS_PTR(AudioControl)
|
||||
DECLARE_NS_PTR_VECTOR(CC_Device)
|
||||
DECLARE_NS_PTR(CC_DeviceInfo)
|
||||
DECLARE_NS_PTR(CC_CallServerInfo)
|
||||
DECLARE_NS_PTR(CC_FeatureInfo)
|
||||
DECLARE_NS_PTR_VECTOR(CC_Line)
|
||||
DECLARE_NS_PTR(CC_LineInfo)
|
||||
DECLARE_NS_PTR_VECTOR(CC_Call)
|
||||
DECLARE_NS_PTR(CC_CallInfo)
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
|
||||
class ECC_API CC_Device
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_Device)
|
||||
protected:
|
||||
CC_Device() {}
|
||||
|
||||
virtual ~CC_Device() {}
|
||||
|
||||
public:
|
||||
virtual std::string toString() = 0;
|
||||
|
||||
virtual CC_DeviceInfoPtr getDeviceInfo () = 0;
|
||||
|
||||
/**
|
||||
Create a call on the device. Line selection is on the first available line.
|
||||
Lines that have their MNC reached will be skipped. If you have a specific line
|
||||
you want to make a call on (assuming the device has more than available) then
|
||||
you should use CC_Line::createCall() to do that.
|
||||
|
||||
@return CC_CallPtr - the created call object wrapped in a smart_ptr.
|
||||
*/
|
||||
virtual CC_CallPtr createCall() = 0;
|
||||
|
||||
virtual void enableVideo(bool enable) = 0;
|
||||
virtual void enableCamera(bool enable) = 0;
|
||||
virtual void setDigestNamePasswd (char *name, char *pw) = 0;
|
||||
|
||||
private:
|
||||
// Cannot copy - clients should be passing the pointer not the object.
|
||||
CC_Device& operator=(const CC_Device& rhs);
|
||||
CC_Device(const CC_Device&);
|
||||
};
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_DeviceInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_DeviceInfo)
|
||||
protected:
|
||||
CC_DeviceInfo() { }
|
||||
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_DeviceInfo() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
gets the device name
|
||||
@returns - the device name as an std::string
|
||||
*/
|
||||
virtual std::string getDeviceName() = 0;
|
||||
|
||||
/**
|
||||
gets the service state
|
||||
@param [in] handle - reference to device info
|
||||
@returns cc_service_state_t - INS/OOS
|
||||
*/
|
||||
virtual cc_service_state_t getServiceState() = 0;
|
||||
|
||||
/**
|
||||
gets the service cause
|
||||
@param [in] handle - reference to device info
|
||||
@returns cc_service_cause_t - reason for service state
|
||||
*/
|
||||
virtual cc_service_cause_t getServiceCause() = 0;
|
||||
|
||||
/**
|
||||
gets vector of CC_CallPtr from this CC_DeviceInfo
|
||||
|
||||
@returns vector<CC_CallPtr> containing the CC_CallPtrs
|
||||
*/
|
||||
virtual std::vector<CC_CallPtr> getCalls () = 0;
|
||||
|
||||
/**
|
||||
gets list of handles to calls on the device by state
|
||||
@param [in] handle - reference to device info
|
||||
@param [in] state - call state for which the calls are requested
|
||||
@param [out] handles - array of call handle to be returned
|
||||
@param [in,out] count number allocated in array/elements returned
|
||||
@returns
|
||||
*/
|
||||
// void getCallsByState (cc_call_state_t state,
|
||||
// cc_call_handle_t handles[], cc_uint16_t *count);
|
||||
|
||||
/**
|
||||
gets vector of CC_LinePtr from this CC_DeviceInfo
|
||||
|
||||
@returns vector<CC_LinePtr> containing the CC_LinePtrs
|
||||
*/
|
||||
virtual std::vector<CC_LinePtr> getLines () = 0;
|
||||
|
||||
/**
|
||||
gets vector of features on the device
|
||||
|
||||
@returns
|
||||
*/
|
||||
virtual std::vector<CC_FeatureInfoPtr> getFeatures () = 0;
|
||||
|
||||
/**
|
||||
gets handles of call agent servers
|
||||
|
||||
@returns
|
||||
*/
|
||||
virtual std::vector<CC_CallServerInfoPtr> getCallServers () = 0;
|
||||
|
||||
/**
|
||||
gets call server name
|
||||
@param [in] handle - handle of call server
|
||||
@returns name of the call server
|
||||
NOTE: The memory for return string doesn't need to be freed it will be freed when the info reference is freed
|
||||
*/
|
||||
// cc_string_t getCallServerName (cc_callserver_ref_t handle);
|
||||
|
||||
/**
|
||||
gets call server mode
|
||||
@param [in] handle - handle of call server
|
||||
@returns - mode of the call server
|
||||
*/
|
||||
// cc_cucm_mode_t getCallServerMode (cc_callserver_ref_t handle);
|
||||
|
||||
/**
|
||||
gets calls erver name
|
||||
@param [in] handle - handle of call server
|
||||
@returns status of the call server
|
||||
*/
|
||||
// cc_ccm_status_t getCallServerStatus (cc_callserver_ref_t handle);
|
||||
|
||||
/**
|
||||
get the NOTIFICATION PROMPT
|
||||
@param [in] handle - reference to device info
|
||||
@returns
|
||||
*/
|
||||
// cc_string_t getNotifyPrompt ();
|
||||
|
||||
/**
|
||||
get the NOTIFICATION PROMPT PRIORITY
|
||||
@param [in] handle - reference to device info
|
||||
@returns
|
||||
*/
|
||||
// cc_uint32_t getNotifyPromptPriority ();
|
||||
|
||||
/**
|
||||
get the NOTIFICATION PROMPT Progress
|
||||
@param [in] handle - reference to device info
|
||||
@returns
|
||||
*/
|
||||
// cc_uint32_t getNotifyPromptProgress ();
|
||||
|
||||
private:
|
||||
// Cannot copy - clients should be passing the pointer not the object.
|
||||
CC_DeviceInfo& operator=(const CC_DeviceInfo& rhs);
|
||||
CC_DeviceInfo(const CC_DeviceInfo&);
|
||||
};
|
||||
};
|
@ -1,76 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_FeatureInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_FeatureInfo)
|
||||
protected:
|
||||
CC_FeatureInfo() { }
|
||||
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_FeatureInfo() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the physical button number on which this feature is configured
|
||||
|
||||
@return cc_int32_t - button assgn to the feature
|
||||
*/
|
||||
virtual cc_int32_t getButton() = 0;
|
||||
|
||||
/**
|
||||
Get the featureID
|
||||
|
||||
@return cc_int32_t - button assgn to the feature
|
||||
*/
|
||||
virtual cc_int32_t getFeatureID() = 0;
|
||||
|
||||
/**
|
||||
Get the feature Name
|
||||
|
||||
@return string - handle of the feature created
|
||||
*/
|
||||
virtual std::string getDisplayName() = 0;
|
||||
|
||||
/**
|
||||
Get the speeddial Number
|
||||
|
||||
@return string - handle of the feature created
|
||||
*/
|
||||
virtual std::string getSpeedDialNumber() = 0;
|
||||
|
||||
/**
|
||||
Get the contact
|
||||
|
||||
@return string - handle of the feature created
|
||||
*/
|
||||
virtual std::string getContact() = 0;
|
||||
|
||||
/**
|
||||
Get the retrieval prefix
|
||||
|
||||
@return string - handle of the feature created
|
||||
*/
|
||||
virtual std::string getRetrievalPrefix() = 0;
|
||||
|
||||
/**
|
||||
Get the feature option mask
|
||||
|
||||
@return cc_int32_t - button assgn to the feature
|
||||
*/
|
||||
virtual cc_int32_t getFeatureOptionMask() = 0;
|
||||
};
|
||||
};
|
@ -1,32 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_Line
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_Line)
|
||||
protected:
|
||||
CC_Line () { }
|
||||
|
||||
virtual ~CC_Line () {};
|
||||
|
||||
public:
|
||||
virtual std::string toString() = 0;
|
||||
|
||||
virtual cc_lineid_t getID() = 0;
|
||||
virtual CC_LineInfoPtr getLineInfo () = 0;
|
||||
virtual CC_CallPtr createCall () = 0;
|
||||
};
|
||||
};
|
@ -1,152 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include <bitset>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_LineInfo
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_LineInfo)
|
||||
protected:
|
||||
CC_LineInfo() { }
|
||||
|
||||
//Base class needs dtor to be declared as virtual
|
||||
virtual ~CC_LineInfo() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the line Name
|
||||
|
||||
@return string - line Name
|
||||
*/
|
||||
virtual std::string getName() = 0;
|
||||
|
||||
/**
|
||||
Get the line DN Number
|
||||
@return string - line DN
|
||||
*/
|
||||
virtual std::string getNumber() = 0;
|
||||
|
||||
/**
|
||||
Get the physical button number on which this line is configured
|
||||
|
||||
@return cc_uint32_t - button number
|
||||
*/
|
||||
virtual cc_uint32_t getButton() = 0;
|
||||
|
||||
/**
|
||||
Get the Line Type
|
||||
|
||||
@return cc_line_feature_t - line featureID ( Line )
|
||||
*/
|
||||
virtual cc_line_feature_t getLineType() = 0;
|
||||
|
||||
/**
|
||||
|
||||
@return bool - true if phone is currently registered with CM.
|
||||
*/
|
||||
virtual bool getRegState() = 0;
|
||||
|
||||
/**
|
||||
Get the CFWDAll status for the line
|
||||
|
||||
@return bool - isForwarded
|
||||
*/
|
||||
virtual bool isCFWDActive() = 0;
|
||||
|
||||
/**
|
||||
Get the CFWDAll destination
|
||||
|
||||
@return string - cfwd target
|
||||
*/
|
||||
virtual std::string getCFWDName() = 0;
|
||||
|
||||
/**
|
||||
Get calls on line
|
||||
|
||||
@param [in] line - line
|
||||
@return vector<CC_CallPtr>
|
||||
*/
|
||||
virtual std::vector<CC_CallPtr> getCalls (CC_LinePtr linePtr) = 0;
|
||||
|
||||
/**
|
||||
Get calls on line by state
|
||||
|
||||
@param [in] line - line
|
||||
@param [in] state - state
|
||||
|
||||
@return vector<CC_CallPtr>
|
||||
*/
|
||||
virtual std::vector<CC_CallPtr> getCallsByState (CC_LinePtr linePtr, cc_call_state_t state) = 0;
|
||||
|
||||
/**
|
||||
Get the MWI Status
|
||||
|
||||
@return cc_uint32_t - MWI status (boolean 0 => no MWI)
|
||||
*/
|
||||
virtual bool getMWIStatus() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI Type
|
||||
|
||||
@return cc_uint32_t - MWI Type
|
||||
*/
|
||||
virtual cc_uint32_t getMWIType() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI new msg count
|
||||
|
||||
@return cc_uint32_t - MWI new msg count
|
||||
*/
|
||||
virtual cc_uint32_t getMWINewMsgCount() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI old msg count
|
||||
|
||||
@return cc_uint32_t - MWI old msg count
|
||||
*/
|
||||
virtual cc_uint32_t getMWIOldMsgCount() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI high priority new msg count
|
||||
|
||||
@return cc_uint32_t - MWI new msg count
|
||||
*/
|
||||
virtual cc_uint32_t getMWIPrioNewMsgCount() = 0;
|
||||
|
||||
/**
|
||||
Get the MWI high priority old msg count
|
||||
|
||||
@return cc_uint32_t - MWI old msg count
|
||||
*/
|
||||
virtual cc_uint32_t getMWIPrioOldMsgCount() = 0;
|
||||
|
||||
/**
|
||||
has capability - is the feature allowed
|
||||
|
||||
@param [in] capability - capability being queried to see if it's available
|
||||
@return bool - is Allowed
|
||||
*/
|
||||
virtual bool hasCapability(ccapi_call_capability_e capability) = 0;
|
||||
|
||||
/**
|
||||
get Allowed Feature set
|
||||
|
||||
@return cc_return_t - bitset of Line Capabilities.
|
||||
*/
|
||||
virtual std::bitset<CCAPI_CALL_CAP_MAX> getCapabilitySet() = 0;
|
||||
};
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
/**
|
||||
* These callbacks relate to the "core" Call Control API objects CC_Device, CC_Line and CC_Call.
|
||||
*/
|
||||
class ECC_API CC_Observer
|
||||
{
|
||||
public:
|
||||
virtual void onDeviceEvent ( ccapi_device_event_e deviceEvent, CC_DevicePtr device, CC_DeviceInfoPtr info ) = 0;
|
||||
virtual void onFeatureEvent ( ccapi_device_event_e deviceEvent, CC_DevicePtr device, CC_FeatureInfoPtr feature_info) = 0;
|
||||
virtual void onLineEvent ( ccapi_line_event_e lineEvent, CC_LinePtr line, CC_LineInfoPtr info ) = 0;
|
||||
virtual void onCallEvent ( ccapi_call_event_e callEvent, CC_CallPtr call, CC_CallInfoPtr infog ) = 0;
|
||||
};
|
||||
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "CC_Observer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
#include "ccapi_service.h"
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class ECC_API CC_Service
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CC_Service)
|
||||
protected:
|
||||
CC_Service() {}
|
||||
virtual ~CC_Service() {};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Clients use CC_Observer to receive CCAPI events (Device, Line, Call) from the service.
|
||||
*/
|
||||
virtual void addCCObserver ( CC_Observer * observer ) = 0;
|
||||
virtual void removeCCObserver ( CC_Observer * observer ) = 0;
|
||||
|
||||
/**
|
||||
* Use init() immediately on creating the service, and destroy() when finished with it.
|
||||
* password is required for Asterisk not CUCM.
|
||||
* deviceName is required for CUCM not Asterisk.
|
||||
*/
|
||||
virtual bool init(const std::string& user, const std::string& password, const std::string& domain, const std::string& deviceName) = 0;
|
||||
virtual void destroy() = 0;
|
||||
|
||||
/**
|
||||
* TODO: Set config parameters prior to starting the service.
|
||||
* Need to design a nice abstraction for this accommodating SIPCC and CTI.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Use start() to attempt to register for a device and stop() to cancel a current
|
||||
* registration (or registration attempt).
|
||||
*/
|
||||
virtual bool startService() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Check on the current status/health of the service.
|
||||
*/
|
||||
virtual bool isStarted() = 0;
|
||||
|
||||
/**
|
||||
* Obtain the currently selected Device.
|
||||
* If multiple devices are discoverable (i.e. in CTI), all known devices will appear
|
||||
* in getDevices(), but only the ActiveDevice will be controllable at any given time.
|
||||
*/
|
||||
virtual CC_DevicePtr getActiveDevice() = 0;
|
||||
virtual std::vector<CC_DevicePtr> getDevices() = 0;
|
||||
|
||||
/**
|
||||
* Global settings for audio and video control. Return nullptr if Media control is not
|
||||
* available in this implementation. Return nullptr in any case if media is not yet
|
||||
* initialized.
|
||||
* TODO: Assuming for now that media init aligns with init/destroy.
|
||||
*/
|
||||
virtual AudioControlPtr getAudioControl() = 0;
|
||||
virtual VideoControlPtr getVideoControl() = 0;
|
||||
|
||||
virtual bool setLocalVoipPort(int port) = 0;
|
||||
virtual bool setRemoteVoipPort(int port) = 0;
|
||||
virtual bool setP2PMode(bool mode) = 0;
|
||||
virtual bool setSDPMode(bool mode) = 0;
|
||||
|
||||
private:
|
||||
CC_Service(const CC_Service& rhs);
|
||||
CC_Service& operator=(const CC_Service& rhs);
|
||||
};
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(AudioControl)
|
||||
class ECC_API AudioControl
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AudioControl)
|
||||
// device names are in UTF-8 encoding
|
||||
|
||||
virtual std::vector<std::string> getRecordingDevices() = 0;
|
||||
virtual std::vector<std::string> getPlayoutDevices() = 0;
|
||||
|
||||
virtual std::string getRecordingDevice() = 0;
|
||||
virtual std::string getPlayoutDevice() = 0;
|
||||
|
||||
virtual bool setRecordingDevice( const std::string& name ) = 0;
|
||||
virtual bool setPlayoutDevice( const std::string& name ) = 0;
|
||||
|
||||
virtual bool setDefaultVolume( int ) = 0;
|
||||
virtual int getDefaultVolume() = 0;
|
||||
|
||||
virtual bool setRingerVolume( int ) = 0;
|
||||
virtual int getRingerVolume() = 0;
|
||||
|
||||
protected:
|
||||
virtual ~AudioControl(){};
|
||||
};
|
||||
};
|
@ -1,36 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "ECC_Types.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(VideoControl)
|
||||
class ECC_API VideoControl
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoControl)
|
||||
|
||||
virtual void setVideoMode( bool enable ) = 0;
|
||||
|
||||
// window type is platform-specific
|
||||
virtual void setPreviewWindow( VideoWindowHandle window, int top, int left, int bottom, int right, RenderScaling style ) = 0;
|
||||
virtual void showPreviewWindow( bool show ) = 0;
|
||||
|
||||
// device names are in UTF-8 encoding
|
||||
virtual std::vector<std::string> getCaptureDevices() = 0;
|
||||
|
||||
virtual std::string getCaptureDevice() = 0;
|
||||
virtual bool setCaptureDevice( const std::string& name ) = 0;
|
||||
protected:
|
||||
virtual ~VideoControl() {};
|
||||
};
|
||||
|
||||
}; // namespace
|
@ -1,130 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
#include "CC_Observer.h"
|
||||
#include "ECC_Observer.h"
|
||||
#include "ECC_Types.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @mainpage Enhanced Call Control
|
||||
*
|
||||
* @section intro_sec Introduction
|
||||
* This wraps and aggregates the SIPCC and CTI call control stacks, media stacks, and various additional
|
||||
* components and glue necessary to start, configure and run them, and presents a high-level C++ API
|
||||
* for connection, device selection and status, and call control.
|
||||
*
|
||||
* @section main_outline Outline
|
||||
* @li The main entry point is CSF::CallControlManager, which is used to configure and start a
|
||||
* call control stack.
|
||||
* @li Configuration and events are raised to the CSF::ECC_Observer interface.
|
||||
* @li Call Control is performed via CSF::CC_Device, CSF::CC_Line and CSF::CC_Call.
|
||||
* @li Call Control events are raised to the CSF::CC_Observer interface.
|
||||
* @li Audio/Video device selection and global media configuration is performed via CSF::AudioControl
|
||||
* and CSF::VideoControl. Per-call media operations (mute, volume, etc) are integrated onto
|
||||
* the CSF::CC_Call and CSF::CC_CallInfo interfaces.
|
||||
*/
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR(CallControlManager)
|
||||
/**
|
||||
* CallControlManager
|
||||
*
|
||||
* The class is partitioned into several blocks of functionality:
|
||||
* - Create/Destroy - Initialisation and clean shutdown.
|
||||
* Destroy is optional if the destructor is used properly.
|
||||
* - Observer - Register for events when any state changes. Optional but strongly advised.
|
||||
*
|
||||
* Methods are generally synchronous (at present).
|
||||
*/
|
||||
class ECC_API CallControlManager
|
||||
{
|
||||
protected:
|
||||
virtual ~CallControlManager();
|
||||
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CallControlManager)
|
||||
/**
|
||||
* Use create() to create a CallControlManager instance.
|
||||
*
|
||||
* CallControlManager cleans up its resources in its destructor, implicitly disconnect()in if required.
|
||||
* Use the destroy() method if you need to force a cleanup earlier. It is a bad idea to continue using
|
||||
* CallControlManager or any of its related objects after destroy().
|
||||
*/
|
||||
static CallControlManagerPtr create();
|
||||
virtual bool destroy() = 0;
|
||||
|
||||
/**
|
||||
CC_Observer is for core call control events (on CC_Device, CC_Line and CC_Call).
|
||||
ECC_Observer is for "value add" features of CallControlManager.
|
||||
|
||||
Client can add multiple observers if they have different Observer objects that handle
|
||||
different event scenarios, but generally it's probably sufficient to only register one observer.
|
||||
|
||||
@param[in] observer - This is a pointer to a CC_Observer-derived class that the client
|
||||
must instantiate to receive notifications on this client object.
|
||||
*/
|
||||
virtual void addCCObserver ( CC_Observer * observer ) = 0;
|
||||
virtual void removeCCObserver ( CC_Observer * observer ) = 0;
|
||||
|
||||
virtual void addECCObserver ( ECC_Observer * observer ) = 0;
|
||||
virtual void removeECCObserver ( ECC_Observer * observer ) = 0;
|
||||
|
||||
virtual void setMultiClusterMode(bool allowMultipleClusters) = 0;
|
||||
virtual void setSIPCCLoggingMask(const cc_int32_t mask) = 0;
|
||||
virtual void setAuthenticationString(const std::string &authString) = 0;
|
||||
virtual void setSecureCachePath(const std::string &secureCachePath) = 0;
|
||||
|
||||
// Add local codecs
|
||||
virtual void setAudioCodecs(int codecMask) = 0;
|
||||
virtual void setVideoCodecs(int codecMask) = 0;
|
||||
|
||||
virtual bool registerUser(const std::string& deviceName, const std::string& user, const std::string& password, const std::string& domain) = 0;
|
||||
virtual bool disconnect() = 0;
|
||||
virtual std::string getPreferredDeviceName() = 0;
|
||||
virtual std::string getPreferredLineDN() = 0;
|
||||
virtual ConnectionStatusEnum::ConnectionStatus getConnectionStatus() = 0;
|
||||
virtual std::string getCurrentServer() = 0;
|
||||
|
||||
/* P2P MODE */
|
||||
virtual bool startP2PMode(const std::string& user) = 0;
|
||||
|
||||
/* SDP MODE */
|
||||
virtual bool startSDPMode() = 0;
|
||||
|
||||
/**
|
||||
* Obtain the device object, from which call control can be done.
|
||||
* getAvailablePhoneDetails lists all known devices which the user is likely to be able to control.
|
||||
*/
|
||||
virtual CC_DevicePtr getActiveDevice() = 0;
|
||||
virtual PhoneDetailsVtrPtr getAvailablePhoneDetails() = 0;
|
||||
virtual PhoneDetailsPtr getAvailablePhoneDetails(const std::string& deviceName) = 0;
|
||||
|
||||
/**
|
||||
* Obtain the audio/video object, from which video setup can be done.
|
||||
* This relates to global tuning, device selection, preview window positioning, etc, not to
|
||||
* per-call settings or control.
|
||||
*
|
||||
* These objects are unavailable except while in softphone mode.
|
||||
*/
|
||||
virtual VideoControlPtr getVideoControl() = 0;
|
||||
virtual AudioControlPtr getAudioControl() = 0;
|
||||
|
||||
virtual bool setProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key, std::string& value) = 0;
|
||||
virtual std::string getProperty(ConfigPropertyKeysEnum::ConfigPropertyKeys key) = 0;
|
||||
|
||||
protected:
|
||||
CallControlManager() {}
|
||||
private:
|
||||
CallControlManager(const CallControlManager&);
|
||||
CallControlManager& operator=(const CallControlManager&);
|
||||
};
|
||||
} //end namespace CSF
|
@ -1,27 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "ECC_Types.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
/**
|
||||
* These callbacks relate to CallControlManager's "value add" features relating to authentication,
|
||||
* configuration, setup, service health and management of SIP.
|
||||
*
|
||||
* They do not relate to call control - see also CC_Observer.
|
||||
*/
|
||||
class ECC_API ECC_Observer
|
||||
{
|
||||
public:
|
||||
virtual void onAvailablePhoneEvent (AvailablePhoneEventType::AvailablePhoneEvent event,
|
||||
const PhoneDetailsPtr availablePhoneDetails) = 0;
|
||||
|
||||
virtual void onAuthenticationStatusChange (AuthenticationStatusEnum::AuthenticationStatus) = 0;
|
||||
virtual void onConnectionStatusChange(ConnectionStatusEnum::ConnectionStatus status) = 0;
|
||||
};
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
/*
|
||||
These #defines are for use with CallControlManager::createSoftphone(..., const cc_int32_t mask) parameter as follows:
|
||||
|
||||
CallControlManager::createSoftphone(..., GSM_DEBUG_BIT | FIM_DEBUG_BIT | LSM_DEBUG_BIT );
|
||||
|
||||
This turns on debugging for the three areas (and disables logging in all other areas) of pSIPCC logging specified.
|
||||
|
||||
*/
|
||||
|
||||
#define SIP_DEBUG_MSG_BIT (1 << 0) // Bit 0
|
||||
#define SIP_DEBUG_STATE_BIT (1 << 1) // Bit 1
|
||||
#define SIP_DEBUG_TASK_BIT (1 << 2) // Bit 2
|
||||
#define SIP_DEBUG_REG_STATE_BIT (1 << 3) // Bit 3
|
||||
#define GSM_DEBUG_BIT (1 << 4) // Bit 4
|
||||
#define FIM_DEBUG_BIT (1 << 5) // Bit 5
|
||||
#define LSM_DEBUG_BIT (1 << 6) // Bit 6
|
||||
#define FSM_DEBUG_SM_BIT (1 << 7) // Bit 7
|
||||
#define CSM_DEBUG_SM_BIT (1 << 8) // Bit 8
|
||||
#define CC_DEBUG_BIT (1 << 9) // Bit 9
|
||||
#define CC_DEBUG_MSG_BIT (1 << 10) // Bit 10
|
||||
#define AUTH_DEBUG_BIT (1 << 11) // Bit 11
|
||||
#define CONFIG_DEBUG_BIT (1 << 12) // Bit 12
|
||||
#define DPINT_DEBUG_BIT (1 << 13) // Bit 13
|
||||
#define KPML_DEBUG_BIT (1 << 15) // Bit 15
|
||||
#define VCM_DEBUG_BIT (1 << 17) // Bit 17
|
||||
#define CC_APP_DEBUG_BIT (1 << 18) // Bit 18
|
||||
#define CC_LOG_DEBUG_BIT (1 << 19) // Bit 19
|
||||
#define TNP_DEBUG_BIT (1 << 20) // Bit 20
|
||||
|
||||
namespace CSFUnified
|
||||
{
|
||||
DECLARE_PTR(DeviceInfo)
|
||||
}
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
namespace AuthenticationFailureCodeType
|
||||
{
|
||||
typedef enum {
|
||||
eNoError,
|
||||
eNoServersConfigured,
|
||||
eNoCredentialsConfigured,
|
||||
eCouldNotConnect,
|
||||
eServerCertificateRejected,
|
||||
eCredentialsRejected,
|
||||
eResponseEmpty,
|
||||
eResponseInvalid
|
||||
} AuthenticationFailureCode;
|
||||
std::string ECC_API toString(AuthenticationFailureCode value);
|
||||
}
|
||||
|
||||
namespace AuthenticationStatusEnum
|
||||
{
|
||||
typedef enum {
|
||||
eNotAuthenticated,
|
||||
eInProgress,
|
||||
eAuthenticated,
|
||||
eFailed
|
||||
} AuthenticationStatus;
|
||||
std::string ECC_API toString(AuthenticationStatus value);
|
||||
}
|
||||
|
||||
namespace DeviceRetrievalFailureCodeType
|
||||
{
|
||||
typedef enum {
|
||||
eNoError,
|
||||
eNoServersConfigured,
|
||||
eNoDeviceNameConfigured,
|
||||
eCouldNotConnect,
|
||||
eFileNotFound,
|
||||
eFileEmpty,
|
||||
eFileInvalid
|
||||
} DeviceRetrievalFailureCode;
|
||||
std::string ECC_API toString(DeviceRetrievalFailureCode value);
|
||||
}
|
||||
|
||||
namespace ConnectionStatusEnum
|
||||
{
|
||||
typedef enum {
|
||||
eIdle,
|
||||
eNone,
|
||||
eFetchingDeviceConfig,
|
||||
eRegistering,
|
||||
eReady,
|
||||
eConnectedButNoDeviceReady,
|
||||
eRetrying,
|
||||
eFailed
|
||||
} ConnectionStatus;
|
||||
std::string ECC_API toString(ConnectionStatus value);
|
||||
}
|
||||
|
||||
namespace ServiceStateType {
|
||||
typedef enum
|
||||
{
|
||||
eUnknown,
|
||||
eInService,
|
||||
eOutOfService
|
||||
} ServiceState;
|
||||
std::string ECC_API toString(ServiceState value);
|
||||
}
|
||||
|
||||
namespace AvailablePhoneEventType
|
||||
{
|
||||
typedef enum {
|
||||
eFound, // New Phone device discovered and added to the Available list.
|
||||
eUpdated, // Change to an existing Phone details record in the Available list.
|
||||
eLost // Phone device removed from the Available list.
|
||||
} AvailablePhoneEvent;
|
||||
std::string ECC_API toString(AvailablePhoneEvent value);
|
||||
}
|
||||
|
||||
namespace ConfigPropertyKeysEnum
|
||||
{
|
||||
typedef enum {
|
||||
eLocalVoipPort,
|
||||
eRemoteVoipPort,
|
||||
eVersion,
|
||||
eTransport
|
||||
} ConfigPropertyKeys;
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
VideoEnableMode_DISABLED,
|
||||
VideoEnableMode_SENDONLY,
|
||||
VideoEnableMode_RECVONLY,
|
||||
VideoEnableMode_SENDRECV
|
||||
|
||||
} VideoEnableMode;
|
||||
|
||||
typedef enum // scaling from codec size to render window size
|
||||
{
|
||||
RenderScaling_NONE, // 1:1 actual pixels, crop and/or fill
|
||||
RenderScaling_TO_FIT, // scale to fit, without preserving aspect ratio
|
||||
RenderScaling_BORDER, // scale to fit, fill without cropping
|
||||
RenderScaling_CROP // scale to fit, crop without filling
|
||||
|
||||
} RenderScaling;
|
||||
|
||||
typedef void *VideoWindowHandle;
|
||||
typedef void* ExternalRendererHandle;
|
||||
typedef unsigned int VideoFormat;
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "CC_Common.h"
|
||||
#include "ECC_Types.h"
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
DECLARE_NS_PTR_VECTOR(PhoneDetails);
|
||||
class ECC_API PhoneDetails
|
||||
{
|
||||
protected:
|
||||
virtual ~PhoneDetails() {}
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PhoneDetails)
|
||||
/**
|
||||
* Get the device name (the CUCM device name) and the free text description.
|
||||
*/
|
||||
virtual std::string getName() const = 0;
|
||||
virtual std::string getDescription() const = 0;
|
||||
|
||||
/**
|
||||
* Get the model number (the internal CUCM number, not the number printed on the phone)
|
||||
* and the corresponding description (which normally does include the number printed on the phone).
|
||||
* Returns -1, "" if unknown
|
||||
*/
|
||||
virtual int getModel() const = 0;
|
||||
virtual std::string getModelDescription() const = 0;
|
||||
|
||||
virtual bool isSoftPhone() = 0;
|
||||
|
||||
/**
|
||||
* List the known directory numbers of lines associated with the device.
|
||||
* Empty list if unknown.
|
||||
*/
|
||||
virtual std::vector<std::string> getLineDNs() const = 0;
|
||||
|
||||
/**
|
||||
* Current status of the device, if known.
|
||||
*/
|
||||
virtual ServiceStateType::ServiceState getServiceState() const = 0;
|
||||
|
||||
/**
|
||||
* TFTP config of device, and freshness of the config.
|
||||
*/
|
||||
virtual std::string getConfig() const = 0;
|
||||
|
||||
protected:
|
||||
PhoneDetails() {}
|
||||
|
||||
private:
|
||||
PhoneDetails(const PhoneDetails&);
|
||||
PhoneDetails& operator=(const PhoneDetails&);
|
||||
};
|
||||
};
|
@ -1,44 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "base/linked_ptr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#ifndef DECLARE_PTR
|
||||
#define DECLARE_PTR(className)\
|
||||
class className;\
|
||||
typedef linked_ptr<className> className##Ptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DECLARE_PTR_VECTOR
|
||||
#define DECLARE_PTR_VECTOR(className)\
|
||||
DECLARE_PTR(className)\
|
||||
typedef std::vector<className##Ptr> className##Vtr;\
|
||||
typedef linked_ptr<className##Vtr> className##Vtr##Ptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef NULL_PTR
|
||||
#define NULL_PTR(className) linked_ptr<className>()
|
||||
#endif
|
||||
|
||||
// NSPR Variations of the above, to help with migration
|
||||
// from linked_ptr to nsRefPtr
|
||||
#ifndef DECLARE_NS_PTR
|
||||
#define DECLARE_NS_PTR(className)\
|
||||
class className;\
|
||||
typedef nsRefPtr<className> className##Ptr;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DECLARE_NS_PTR_VECTOR
|
||||
#define DECLARE_NS_PTR_VECTOR(className)\
|
||||
DECLARE_NS_PTR(className)\
|
||||
typedef std::vector<className##Ptr> className##Vtr;\
|
||||
typedef linked_ptr<className##Vtr> className##Vtr##Ptr;
|
||||
#endif
|
@ -1,53 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef T1_DEBUG_H
|
||||
#define T1_DEBUG_H
|
||||
|
||||
#include "CC_Common.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <ccapi_service.h>
|
||||
#include "ccapi_types.h"
|
||||
|
||||
ECC_API cc_string_t device_event_getname(ccapi_device_event_e);
|
||||
ECC_API cc_string_t call_event_getname(ccapi_call_event_e);
|
||||
ECC_API cc_string_t line_event_getname(ccapi_line_event_e);
|
||||
|
||||
ECC_API cc_string_t digit_getname(cc_digit_t);
|
||||
ECC_API cc_string_t cucm_mode_getname(cc_cucm_mode_t);
|
||||
ECC_API cc_string_t line_feature_getname(cc_line_feature_t);
|
||||
ECC_API cc_string_t feature_option_mask_getname(cc_feature_option_mask_t);
|
||||
ECC_API cc_string_t service_cause_getname(cc_service_cause_t);
|
||||
ECC_API cc_string_t service_state_getname(cc_service_state_t);
|
||||
ECC_API cc_string_t ccm_status_getname(cc_ccm_status_t);
|
||||
ECC_API cc_string_t line_reg_state_getname(cc_line_reg_state_t);
|
||||
ECC_API cc_string_t shutdown_reason_getname(cc_shutdown_reason_t);
|
||||
ECC_API cc_string_t kpml_config_getname(cc_kpml_config_t);
|
||||
ECC_API cc_string_t upgrade_getname(cc_upgrade_t);
|
||||
ECC_API cc_string_t sdp_direction_getname(cc_sdp_direction_t);
|
||||
ECC_API cc_string_t blf_state_getname(cc_blf_state_t);
|
||||
ECC_API cc_string_t blf_feature_mask_getname(cc_blf_feature_mask_t);
|
||||
ECC_API cc_string_t call_state_getname(cc_call_state_t);
|
||||
ECC_API cc_string_t call_attr_getname(cc_call_attr_t);
|
||||
ECC_API cc_string_t hold_reason_getname(cc_hold_reason_t);
|
||||
ECC_API cc_string_t call_type_getname(cc_call_type_t);
|
||||
ECC_API cc_string_t call_security_getname(cc_call_security_t);
|
||||
ECC_API cc_string_t call_policy_getname(cc_call_policy_t);
|
||||
ECC_API cc_string_t log_disposition_getname(cc_log_disposition_t);
|
||||
ECC_API cc_string_t call_priority_getname(cc_call_priority_t);
|
||||
ECC_API cc_string_t call_selection_getname(cc_call_selection_t);
|
||||
ECC_API cc_string_t call_capability_getname(ccapi_call_capability_e);
|
||||
ECC_API cc_string_t srv_ctrl_req_getname(cc_srv_ctrl_req_t);
|
||||
ECC_API cc_string_t srv_ctrl_cmd_getname(cc_srv_ctrl_cmd_t);
|
||||
ECC_API cc_string_t message_type_getname(cc_message_type_t);
|
||||
ECC_API cc_string_t lamp_state_getname(cc_lamp_state_t);
|
||||
ECC_API cc_string_t cause_getname(cc_cause_t);
|
||||
ECC_API cc_string_t subscriptions_ext_getname(cc_subscriptions_ext_t);
|
||||
ECC_API cc_string_t apply_config_result_getname(cc_apply_config_result_t);
|
||||
|
||||
}
|
||||
|
||||
#endif /* T1_DEBUG_H */
|
@ -10,19 +10,9 @@
|
||||
#include "base/basictypes.h"
|
||||
|
||||
#include <map>
|
||||
#include "cpr_threads.h"
|
||||
#include "prrwlock.h"
|
||||
#include "prthread.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#ifndef WIN32
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#ifdef OS_MACOSX
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#ifdef OS_LINUX
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
|
||||
static PRLogModuleInfo *gLogModuleInfo = nullptr;
|
||||
|
||||
@ -44,81 +34,6 @@ PRLogModuleInfo *GetWebRTCLogInfo()
|
||||
return gWebRTCLogModuleInfo;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
void CSFLogRegisterThread(const cprThread_t thread);
|
||||
void CSFLogUnregisterThread(const cprThread_t thread);
|
||||
#ifndef WIN32
|
||||
pthread_t cprGetThreadId(cprThread_t thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
typedef unsigned int thread_key_t;
|
||||
#else
|
||||
typedef pthread_t thread_key_t;
|
||||
#endif
|
||||
static PRRWLock *maplock = PR_NewRWLock(0,"thread map");
|
||||
typedef std::map<thread_key_t,const cpr_thread_t*> threadMap_t;
|
||||
static threadMap_t threadMap;
|
||||
|
||||
void CSFLogRegisterThread(const cprThread_t thread) {
|
||||
const cpr_thread_t *t = reinterpret_cast<cpr_thread_t *>(thread);
|
||||
thread_key_t key;
|
||||
#ifdef WIN32
|
||||
key = t->threadId;
|
||||
#else
|
||||
key = cprGetThreadId(thread);
|
||||
#endif
|
||||
|
||||
CSFLog(CSF_LOG_DEBUG, __FILE__, __LINE__, "log",
|
||||
"Registering new thread with logging system: %s", t->name);
|
||||
PR_RWLock_Wlock(maplock);
|
||||
threadMap[key] = t;
|
||||
PR_RWLock_Unlock(maplock);
|
||||
}
|
||||
|
||||
void CSFLogUnregisterThread(const cprThread_t thread) {
|
||||
const cpr_thread_t *t = reinterpret_cast<cpr_thread_t *>(thread);
|
||||
thread_key_t key;
|
||||
#ifdef WIN32
|
||||
key = t->threadId;
|
||||
#else
|
||||
key = cprGetThreadId(thread);
|
||||
#endif
|
||||
CSFLog(CSF_LOG_DEBUG, __FILE__, __LINE__, "log",
|
||||
"Unregistering thread from logging system: %s", t->name);
|
||||
PR_RWLock_Wlock(maplock);
|
||||
threadMap.erase(key);
|
||||
PR_RWLock_Unlock(maplock);
|
||||
}
|
||||
|
||||
const char *CSFCurrentThreadName() {
|
||||
const char *name = nullptr;
|
||||
#ifdef WIN32
|
||||
thread_key_t key = GetCurrentThreadId();
|
||||
#else
|
||||
thread_key_t key = pthread_self();
|
||||
#endif
|
||||
PR_RWLock_Rlock(maplock);
|
||||
threadMap_t::iterator i = threadMap.find(key);
|
||||
if (i != threadMap.end()) {
|
||||
name = i->second->name;
|
||||
}
|
||||
PR_RWLock_Unlock(maplock);
|
||||
return name;
|
||||
}
|
||||
|
||||
#ifdef OS_MACOSX
|
||||
// pthread_getname_np isn't available on all versions of OS X, so
|
||||
// we need to load it in dynamically and check for its presence
|
||||
static int (*dynamic_pthread_getname_np)(pthread_t,char*,size_t);
|
||||
bool init_pthread_getname() {
|
||||
*reinterpret_cast<void**>(&dynamic_pthread_getname_np) =
|
||||
dlsym(RTLD_DEFAULT, "pthread_getname_np");
|
||||
return dynamic_pthread_getname_np;
|
||||
}
|
||||
static bool have_pthread_getname_np = init_pthread_getname();
|
||||
#endif
|
||||
|
||||
void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const char* tag , const char* format, va_list args)
|
||||
{
|
||||
@ -151,40 +66,16 @@ void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const
|
||||
|
||||
#define MAX_MESSAGE_LENGTH 1024
|
||||
char message[MAX_MESSAGE_LENGTH];
|
||||
char buffer[64] = "";
|
||||
|
||||
const char *threadName = CSFCurrentThreadName();
|
||||
const char *threadName = NULL;
|
||||
|
||||
// Check if we're the main thread...
|
||||
if (!threadName && NS_IsMainThread()) {
|
||||
if (NS_IsMainThread()) {
|
||||
threadName = "main";
|
||||
}
|
||||
|
||||
// If null, the name wasn't set up by CPR -- try NSPR
|
||||
if (!threadName) {
|
||||
} else {
|
||||
threadName = PR_GetThreadName(PR_GetCurrentThread());
|
||||
}
|
||||
|
||||
// If not NSPR, it might be from some other imported library that uses
|
||||
// one of the variety of non-portable means of naming threads.
|
||||
#ifdef OS_LINUX
|
||||
if (!threadName &&
|
||||
!prctl(PR_GET_NAME,reinterpret_cast<uintptr_t>(buffer),0,0,0)) {
|
||||
buffer[16]='\0';
|
||||
if (buffer[0] != '\0') {
|
||||
threadName = buffer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef OS_MACOSX
|
||||
if (!threadName && have_pthread_getname_np) {
|
||||
dynamic_pthread_getname_np(pthread_self(), buffer, sizeof(buffer));
|
||||
if (buffer[0] != '\0') {
|
||||
threadName = buffer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If we can't find it anywhere, use a blank string
|
||||
if (!threadName) {
|
||||
threadName = "";
|
||||
|
@ -88,8 +88,9 @@ print_timecard(Timecard *tc)
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nTimecard created %4lld.%6.6lld\n\n",
|
||||
tc->start_time / PR_USEC_PER_SEC, tc->start_time % PR_USEC_PER_SEC);
|
||||
printf("\nTimecard created %4ld.%6.6ld\n\n",
|
||||
(long)(tc->start_time / PR_USEC_PER_SEC),
|
||||
(long)(tc->start_time % PR_USEC_PER_SEC));
|
||||
|
||||
line_width = 1 + 11 + 11 + event_width + file_width + 6 +
|
||||
function_width + (4 * 3);
|
||||
@ -113,9 +114,9 @@ print_timecard(Timecard *tc)
|
||||
} else {
|
||||
delta = entry->timestamp - tc->start_time;
|
||||
}
|
||||
printf(" %4lld.%6.6lld | %4lld.%6.6lld | %-*s | %*s:%-5d | %-*s\n",
|
||||
offset / PR_USEC_PER_SEC, offset % PR_USEC_PER_SEC,
|
||||
delta / PR_USEC_PER_SEC, delta % PR_USEC_PER_SEC,
|
||||
printf(" %4ld.%6.6ld | %4ld.%6.6ld | %-*s | %*s:%-5d | %-*s\n",
|
||||
(long)(offset / PR_USEC_PER_SEC), (long)(offset % PR_USEC_PER_SEC),
|
||||
(long)(delta / PR_USEC_PER_SEC), (long)(delta % PR_USEC_PER_SEC),
|
||||
(int)event_width, entry->event,
|
||||
(int)file_width, entry->file, entry->line,
|
||||
(int)function_width, entry->function);
|
||||
|
@ -861,6 +861,10 @@ WebrtcAudioConduit::CodecConfigToWebRTCCodec(const AudioCodecConfig* codecInfo,
|
||||
cinst.rate = codecInfo->mRate;
|
||||
cinst.pacsize = codecInfo->mPacSize;
|
||||
cinst.plfreq = codecInfo->mFreq;
|
||||
if (codecInfo->mName == "G722") {
|
||||
// Compensate for G.722 spec error in RFC 1890
|
||||
cinst.plfreq = 16000;
|
||||
}
|
||||
cinst.channels = codecInfo->mChannels;
|
||||
return true;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#define CODEC_CONFIG_H_
|
||||
|
||||
#include <string>
|
||||
#include "ccsdp_rtcp_fb.h"
|
||||
#include <vector>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -76,7 +76,11 @@ public:
|
||||
*/
|
||||
int mType; // payload type
|
||||
std::string mName;
|
||||
uint32_t mRtcpFbTypes;
|
||||
|
||||
std::vector<std::string> mAckFbTypes;
|
||||
std::vector<std::string> mNackFbTypes;
|
||||
std::vector<std::string> mCcmFbTypes;
|
||||
|
||||
unsigned int mMaxFrameSize;
|
||||
unsigned int mMaxFrameRate;
|
||||
unsigned int mMaxMBPS; // in macroblocks-per-second
|
||||
@ -91,13 +95,11 @@ public:
|
||||
|
||||
VideoCodecConfig(int type,
|
||||
std::string name,
|
||||
int rtcpFbTypes,
|
||||
unsigned int max_fs = 0,
|
||||
unsigned int max_fr = 0,
|
||||
const struct VideoCodecConfigH264 *h264 = nullptr) :
|
||||
mType(type),
|
||||
mName(name),
|
||||
mRtcpFbTypes(rtcpFbTypes),
|
||||
mMaxFrameSize(max_fs), // may be overridden
|
||||
mMaxFrameRate(max_fr),
|
||||
mMaxMBPS(0),
|
||||
@ -121,19 +123,36 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool RtcpFbIsSet(sdp_rtcp_fb_nack_type_e type) const
|
||||
// Nothing seems to use this right now. Do we intend to support this
|
||||
// someday?
|
||||
bool RtcpFbAckIsSet(const std::string& type) const
|
||||
{
|
||||
return mRtcpFbTypes & sdp_rtcp_fb_nack_to_bitmap(type);
|
||||
for (auto i = mAckFbTypes.begin(); i != mAckFbTypes.end(); ++i) {
|
||||
if (*i == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RtcpFbIsSet(sdp_rtcp_fb_ack_type_e type) const
|
||||
bool RtcpFbNackIsSet(const std::string& type) const
|
||||
{
|
||||
return mRtcpFbTypes & sdp_rtcp_fb_ack_to_bitmap(type);
|
||||
for (auto i = mNackFbTypes.begin(); i != mNackFbTypes.end(); ++i) {
|
||||
if (*i == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RtcpFbIsSet(sdp_rtcp_fb_ccm_type_e type) const
|
||||
bool RtcpFbCcmIsSet(const std::string& type) const
|
||||
{
|
||||
return mRtcpFbTypes & sdp_rtcp_fb_ccm_to_bitmap(type);
|
||||
for (auto i = mCcmFbTypes.begin(); i != mCcmFbTypes.end(); ++i) {
|
||||
if (*i == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -288,21 +288,21 @@ MediaConduitErrorCode WebrtcVideoConduit::Init(WebrtcVideoConduit *other)
|
||||
if (branch)
|
||||
{
|
||||
int32_t temp;
|
||||
NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.video.test_latency", &mVideoLatencyTestEnable)));
|
||||
NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.min_bitrate", &temp)));
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.video.test_latency", &mVideoLatencyTestEnable)));
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.min_bitrate", &temp)));
|
||||
if (temp >= 0) {
|
||||
mMinBitrate = temp;
|
||||
}
|
||||
NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.start_bitrate", &temp)));
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.start_bitrate", &temp)));
|
||||
if (temp >= 0) {
|
||||
mStartBitrate = temp;
|
||||
}
|
||||
NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.max_bitrate", &temp)));
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetIntPref("media.peerconnection.video.max_bitrate", &temp)));
|
||||
if (temp >= 0) {
|
||||
mMaxBitrate = temp;
|
||||
}
|
||||
bool use_loadmanager = false;
|
||||
NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.navigator.load_adapt", &use_loadmanager)));
|
||||
(void) NS_WARN_IF(NS_FAILED(branch->GetBoolPref("media.navigator.load_adapt", &use_loadmanager)));
|
||||
if (use_loadmanager) {
|
||||
mLoadManager = LoadManagerBuild();
|
||||
}
|
||||
@ -657,7 +657,7 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
|
||||
mSendingWidth = 0;
|
||||
mSendingHeight = 0;
|
||||
|
||||
if(codecConfig->RtcpFbIsSet(SDP_RTCP_FB_NACK_BASIC)) {
|
||||
if(codecConfig->RtcpFbNackIsSet("")) {
|
||||
CSFLogDebug(logTag, "Enabling NACK (send) for video stream\n");
|
||||
if (mPtrRTP->SetNACKStatus(mChannel, true) != 0)
|
||||
{
|
||||
@ -740,17 +740,17 @@ WebrtcVideoConduit::ConfigureRecvMediaCodecs(
|
||||
|
||||
// Check for the keyframe request type: PLI is preferred
|
||||
// over FIR, and FIR is preferred over none.
|
||||
if (codecConfigList[i]->RtcpFbIsSet(SDP_RTCP_FB_NACK_PLI))
|
||||
if (codecConfigList[i]->RtcpFbNackIsSet("pli"))
|
||||
{
|
||||
kf_request = webrtc::kViEKeyFrameRequestPliRtcp;
|
||||
} else if(kf_request == webrtc::kViEKeyFrameRequestNone &&
|
||||
codecConfigList[i]->RtcpFbIsSet(SDP_RTCP_FB_CCM_FIR))
|
||||
codecConfigList[i]->RtcpFbCcmIsSet("fir"))
|
||||
{
|
||||
kf_request = webrtc::kViEKeyFrameRequestFirRtcp;
|
||||
}
|
||||
|
||||
// Check whether NACK is requested
|
||||
if(codecConfigList[i]->RtcpFbIsSet(SDP_RTCP_FB_NACK_BASIC))
|
||||
if(codecConfigList[i]->RtcpFbNackIsSet(""))
|
||||
{
|
||||
use_nack_basic = true;
|
||||
}
|
||||
@ -1278,7 +1278,7 @@ WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo,
|
||||
// hand or from a config fetched with GetConfig(); this modifies the config
|
||||
// to match parameters from VideoCodecConfig
|
||||
cinst.plType = codecInfo->mType;
|
||||
if (codecInfo->mName == "H264_P0" || codecInfo->mName == "H264_P1") {
|
||||
if (codecInfo->mName == "H264") {
|
||||
cinst.codecType = webrtc::kVideoCodecH264;
|
||||
PL_strncpyz(cinst.plName, "H264", sizeof(cinst.plName));
|
||||
} else if (codecInfo->mName == "VP8") {
|
||||
|
@ -1,94 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "CSFLog.h"
|
||||
#include "CSFVideoControlWrapper.h"
|
||||
|
||||
static const char* logTag = "VcmSipccBinding";
|
||||
|
||||
namespace CSF {
|
||||
|
||||
void VideoControlWrapper::setVideoMode( bool enable )
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
_realVideoControl->setVideoMode(enable);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to setVideoMode to %s for expired video control",
|
||||
enable ? "TRUE" : "FALSE");
|
||||
}
|
||||
}
|
||||
|
||||
void VideoControlWrapper::setPreviewWindow( VideoWindowHandle window, int top, int left, int bottom, int right, RenderScaling style )
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
_realVideoControl->setPreviewWindow(window, top, left, bottom, right, style);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to setPreviewWindow for expired video control");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void VideoControlWrapper::showPreviewWindow( bool show )
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
_realVideoControl->showPreviewWindow(show);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to showPreviewWindow( %s ) for expired video control",
|
||||
show ? "TRUE" : "FALSE");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> VideoControlWrapper::getCaptureDevices()
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
return _realVideoControl->getCaptureDevices();
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to getCaptureDevices for expired video control");
|
||||
std::vector<std::string> vec;
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string VideoControlWrapper::getCaptureDevice()
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
return _realVideoControl->getCaptureDevice();
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to getCaptureDevice for expired video control");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
bool VideoControlWrapper::setCaptureDevice( const std::string& name )
|
||||
{
|
||||
if (_realVideoControl != nullptr)
|
||||
{
|
||||
return _realVideoControl->setCaptureDevice(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSFLogWarn( logTag, "Attempt to setCaptureDevice to %s for expired video control",
|
||||
name.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,90 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _CSF_VCM_SIPCC_BINDING_H_
|
||||
#define _CSF_VCM_SIPCC_BINDING_H_
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "ccapi_types.h"
|
||||
}
|
||||
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
|
||||
class nsIThread;
|
||||
class nsIEventTarget;
|
||||
class nsIPrefBranch;
|
||||
|
||||
namespace mozilla {
|
||||
class NrIceMediaStream;
|
||||
};
|
||||
|
||||
namespace CSF
|
||||
{
|
||||
class AudioTermination;
|
||||
class VideoTermination;
|
||||
class AudioControl;
|
||||
class VideoControl;
|
||||
class MediaProvider;
|
||||
class MediaProviderObserver;
|
||||
|
||||
class StreamObserver
|
||||
{
|
||||
public:
|
||||
virtual void registerStream(cc_call_handle_t call, int streamId, bool isVideo) = 0;
|
||||
virtual void deregisterStream(cc_call_handle_t call, int streamId) = 0;
|
||||
virtual void dtmfBurst(int digit, int direction, int duration) = 0;
|
||||
virtual void sendIFrame(cc_call_handle_t call) = 0;
|
||||
};
|
||||
|
||||
class VcmSIPCCBinding
|
||||
{
|
||||
public:
|
||||
VcmSIPCCBinding ();
|
||||
virtual ~VcmSIPCCBinding();
|
||||
|
||||
// The getter is only for use by the vcm_* impl functions.
|
||||
void setStreamObserver(StreamObserver*);
|
||||
static StreamObserver* getStreamObserver();
|
||||
|
||||
static AudioTermination * getAudioTermination();
|
||||
static VideoTermination * getVideoTermination();
|
||||
|
||||
static AudioControl * getAudioControl();
|
||||
static VideoControl * getVideoControl();
|
||||
|
||||
void setMediaProviderObserver(MediaProviderObserver* obs);
|
||||
static MediaProviderObserver * getMediaProviderObserver();
|
||||
|
||||
static void setAudioCodecs(int codecMask);
|
||||
static void setVideoCodecs(int codecMask);
|
||||
|
||||
static int getAudioCodecs();
|
||||
static int getVideoCodecs();
|
||||
static int getVideoCodecsGmp();
|
||||
static int getVideoCodecsHw();
|
||||
|
||||
static void setMainThread(nsIThread *thread);
|
||||
static nsIThread *getMainThread();
|
||||
|
||||
static nsCOMPtr<nsIPrefBranch> getPrefBranch();
|
||||
|
||||
static int gVideoCodecGmpMask;
|
||||
private:
|
||||
nsCOMPtr<mozIGeckoMediaPluginService> mGMPService;
|
||||
static VcmSIPCCBinding * gSelf;
|
||||
StreamObserver* streamObserver;
|
||||
MediaProviderObserver *mediaProviderObserver;
|
||||
static bool gInitGmpCodecs;
|
||||
static int gAudioCodecMask;
|
||||
static int gVideoCodecMask;
|
||||
static nsIThread *gMainThread;
|
||||
static nsIEventTarget *gSTSThread;
|
||||
static nsCOMPtr<nsIPrefBranch> gBranch;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,35 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _Included_cip_sipcc_CodecMask
|
||||
#define _Included_cip_sipcc_CodecMask
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_G711
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_G711 1L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_G729A
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_G729A 2L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_G729B
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_G729B 4L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_LINEAR
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_LINEAR 8L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_G722
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_G722 16L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_iLBC
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_iLBC 32L
|
||||
#undef cip_sipcc_CodecMask_DSP_RESOURCE_iSAC
|
||||
#define cip_sipcc_CodecMask_DSP_RESOURCE_iSAC 64L
|
||||
#undef cip_sipcc_CodecMask_DSP_DECODEONLY
|
||||
#define cip_sipcc_CodecMask_DSP_DECODEONLY 0L
|
||||
#undef cip_sipcc_CodecMask_DSP_ENCODEONLY
|
||||
#define cip_sipcc_CodecMask_DSP_ENCODEONLY 1L
|
||||
#undef cip_sipcc_CodecMask_DSP_FULLDUPLEX
|
||||
#define cip_sipcc_CodecMask_DSP_FULLDUPLEX 2L
|
||||
#undef cip_sipcc_CodecMask_DSP_IGNORE
|
||||
#define cip_sipcc_CodecMask_DSP_IGNORE 3L
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -366,7 +366,6 @@ public:
|
||||
nsCOMPtr<nsIEventTarget> main_thread,
|
||||
nsCOMPtr<nsIEventTarget> sts_thread,
|
||||
DOMMediaStream *domstream,
|
||||
int pipeline_index, // For PeerConnectionMedia/mPipelines
|
||||
int level,
|
||||
bool is_video,
|
||||
RefPtr<MediaSessionConduit> conduit,
|
||||
@ -377,7 +376,6 @@ public:
|
||||
conduit, rtp_transport, rtcp_transport),
|
||||
listener_(new PipelineListener(conduit)),
|
||||
domstream_(domstream),
|
||||
pipeline_index_(pipeline_index),
|
||||
is_video_(is_video)
|
||||
{}
|
||||
|
||||
@ -387,7 +385,6 @@ public:
|
||||
virtual void AttachToTrack(TrackID track_id);
|
||||
|
||||
// Index used to refer to this before we know the TrackID
|
||||
virtual TrackID pipeline_index() const { return pipeline_index_; }
|
||||
// Note: unlike MediaPipeline::trackid(), this is threadsafe
|
||||
// Not set until first media is received
|
||||
virtual TrackID const trackid_locked() { return listener_->trackid(); }
|
||||
@ -521,7 +518,6 @@ public:
|
||||
private:
|
||||
RefPtr<PipelineListener> listener_;
|
||||
DOMMediaStream *domstream_;
|
||||
int pipeline_index_; // for lookups in LocalSourceStreamInfo::mPipelines;
|
||||
bool is_video_;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,703 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "PeerConnectionMedia.h"
|
||||
#include "MediaPipelineFactory.h"
|
||||
#include "transportflow.h"
|
||||
#include "transportlayer.h"
|
||||
#include "transportlayerdtls.h"
|
||||
#include "transportlayerice.h"
|
||||
|
||||
#include "signaling/src/jsep/JsepTrack.h"
|
||||
#include "signaling/src/jsep/JsepTransport.h"
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#endif
|
||||
|
||||
#include "GmpVideoCodec.h"
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
#include "OMXVideoCodec.h"
|
||||
#include "OMXCodecWrapper.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MOZ_MTLOG_MODULE("MediaPipelineFactory")
|
||||
|
||||
// Trivial wrapper class around a vector of ptrs.
|
||||
template <class T> class PtrVector
|
||||
{
|
||||
public:
|
||||
~PtrVector()
|
||||
{
|
||||
for (auto it = values.begin(); it != values.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<T*> values;
|
||||
};
|
||||
|
||||
static nsresult
|
||||
JsepCodecDescToCodecConfig(const JsepCodecDescription& aCodec,
|
||||
AudioCodecConfig** aConfig)
|
||||
{
|
||||
MOZ_ASSERT(aCodec.mType == SdpMediaSection::kAudio);
|
||||
if (aCodec.mType != SdpMediaSection::kAudio)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
const JsepAudioCodecDescription& desc =
|
||||
static_cast<const JsepAudioCodecDescription&>(aCodec);
|
||||
|
||||
uint16_t pt;
|
||||
|
||||
if (!desc.GetPtAsInt(&pt)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Invalid payload type: " << desc.mDefaultPt);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*aConfig = new AudioCodecConfig(pt,
|
||||
desc.mName,
|
||||
desc.mClock,
|
||||
desc.mPacketSize,
|
||||
desc.mChannels,
|
||||
desc.mBitrate);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
JsepCodecDescToCodecConfig(const JsepCodecDescription& aCodec,
|
||||
VideoCodecConfig** aConfig)
|
||||
{
|
||||
MOZ_ASSERT(aCodec.mType == SdpMediaSection::kVideo);
|
||||
if (aCodec.mType != SdpMediaSection::kVideo) {
|
||||
MOZ_ASSERT(false, "JsepCodecDescription has wrong type");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const JsepVideoCodecDescription& desc =
|
||||
static_cast<const JsepVideoCodecDescription&>(aCodec);
|
||||
|
||||
uint16_t pt;
|
||||
|
||||
if (!desc.GetPtAsInt(&pt)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Invalid payload type: " << desc.mDefaultPt);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ScopedDeletePtr<VideoCodecConfigH264> h264Config;
|
||||
|
||||
if (desc.mName == "H264") {
|
||||
h264Config = new VideoCodecConfigH264;
|
||||
size_t spropSize = sizeof(h264Config->sprop_parameter_sets);
|
||||
strncpy(h264Config->sprop_parameter_sets,
|
||||
desc.mSpropParameterSets.c_str(),
|
||||
spropSize);
|
||||
h264Config->sprop_parameter_sets[spropSize - 1] = '\0';
|
||||
h264Config->packetization_mode = desc.mPacketizationMode;
|
||||
h264Config->profile_level_id = desc.mProfileLevelId;
|
||||
h264Config->max_mbps = desc.mMaxMbps;
|
||||
h264Config->max_fs = desc.mMaxFs;
|
||||
h264Config->max_cpb = desc.mMaxCpb;
|
||||
h264Config->max_dpb = desc.mMaxDpb;
|
||||
h264Config->max_br = desc.mMaxBr;
|
||||
h264Config->tias_bw = 0; // TODO. Issue 165.
|
||||
}
|
||||
|
||||
VideoCodecConfig* configRaw;
|
||||
configRaw = new VideoCodecConfig(
|
||||
pt, desc.mName, desc.mMaxFs, desc.mMaxFr, h264Config);
|
||||
|
||||
configRaw->mAckFbTypes = desc.mAckFbTypes;
|
||||
configRaw->mNackFbTypes = desc.mNackFbTypes;
|
||||
configRaw->mCcmFbTypes = desc.mCcmFbTypes;
|
||||
|
||||
*aConfig = configRaw;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Accessing the PCMedia should be safe here because we shouldn't
|
||||
// have enqueued this function unless it was still active and
|
||||
// the ICE data is destroyed on the STS.
|
||||
static void
|
||||
FinalizeTransportFlow_s(RefPtr<PeerConnectionMedia> aPCMedia,
|
||||
RefPtr<TransportFlow> aFlow, size_t aLevel,
|
||||
bool aIsRtcp,
|
||||
nsAutoPtr<PtrVector<TransportLayer> > aLayerList)
|
||||
{
|
||||
TransportLayerIce* ice =
|
||||
static_cast<TransportLayerIce*>(aLayerList->values.front());
|
||||
ice->SetParameters(
|
||||
aPCMedia->ice_ctx(), aPCMedia->ice_media_stream(aLevel), aIsRtcp ? 2 : 1);
|
||||
nsAutoPtr<std::queue<TransportLayer*> > layerQueue(
|
||||
new std::queue<TransportLayer*>);
|
||||
for (auto i = aLayerList->values.begin(); i != aLayerList->values.end();
|
||||
++i) {
|
||||
layerQueue->push(*i);
|
||||
}
|
||||
aLayerList->values.clear();
|
||||
(void)aFlow->PushLayers(layerQueue); // TODO(bug 854518): Process errors.
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateOrGetTransportFlow(
|
||||
size_t aLevel,
|
||||
bool aIsRtcp,
|
||||
const JsepTransport& aTransport,
|
||||
RefPtr<TransportFlow>* aFlowOutparam)
|
||||
{
|
||||
nsresult rv;
|
||||
RefPtr<TransportFlow> flow;
|
||||
|
||||
flow = mPCMedia->GetTransportFlow(aLevel, aIsRtcp);
|
||||
if (flow) {
|
||||
*aFlowOutparam = flow;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
std::ostringstream osId;
|
||||
osId << mPC->GetHandle() << ":" << aLevel << ","
|
||||
<< (aIsRtcp ? "rtcp" : "rtp");
|
||||
flow = new TransportFlow(osId.str());
|
||||
|
||||
// The media streams are made on STS so we need to defer setup.
|
||||
auto ice = MakeUnique<TransportLayerIce>(mPC->GetHandle());
|
||||
auto dtls = MakeUnique<TransportLayerDtls>();
|
||||
dtls->SetRole(aTransport.mDtls->GetRole() ==
|
||||
JsepDtlsTransport::kJsepDtlsClient
|
||||
? TransportLayerDtls::CLIENT
|
||||
: TransportLayerDtls::SERVER);
|
||||
|
||||
RefPtr<DtlsIdentity> pcid = mPC->GetIdentity();
|
||||
if (!pcid) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get DTLS identity.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
dtls->SetIdentity(pcid);
|
||||
|
||||
const SdpFingerprintAttributeList& fingerprints =
|
||||
aTransport.mDtls->GetFingerprints();
|
||||
for (auto fp = fingerprints.mFingerprints.begin();
|
||||
fp != fingerprints.mFingerprints.end();
|
||||
++fp) {
|
||||
std::ostringstream ss;
|
||||
ss << fp->hashFunc;
|
||||
rv = dtls->SetVerificationDigest(ss.str(), &fp->fingerprint[0],
|
||||
fp->fingerprint.size());
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Could not set fingerprint");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint16_t> srtpCiphers;
|
||||
srtpCiphers.push_back(SRTP_AES128_CM_HMAC_SHA1_80);
|
||||
srtpCiphers.push_back(SRTP_AES128_CM_HMAC_SHA1_32);
|
||||
|
||||
rv = dtls->SetSrtpCiphers(srtpCiphers);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't set SRTP ciphers");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsAutoPtr<PtrVector<TransportLayer> > layers(new PtrVector<TransportLayer>);
|
||||
layers->values.push_back(ice.release());
|
||||
layers->values.push_back(dtls.release());
|
||||
|
||||
rv = mPCMedia->GetSTSThread()->Dispatch(
|
||||
WrapRunnableNM(FinalizeTransportFlow_s, mPCMedia, flow, aLevel, aIsRtcp,
|
||||
layers),
|
||||
NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to dispatch FinalizeTransportFlow_s");
|
||||
return rv;
|
||||
}
|
||||
|
||||
mPCMedia->AddTransportFlow(aLevel, aIsRtcp, flow);
|
||||
|
||||
*aFlowOutparam = flow;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateMediaPipeline(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack)
|
||||
{
|
||||
MOZ_MTLOG(ML_DEBUG,
|
||||
"Creating media pipeline"
|
||||
<< " m-line index=" << aTrackPair.mLevel
|
||||
<< " type=" << aTrack.GetMediaType()
|
||||
<< " direction=" << aTrack.GetDirection());
|
||||
|
||||
MOZ_ASSERT(aTrackPair.mRtpTransport);
|
||||
|
||||
// First make sure the transport flow exists.
|
||||
RefPtr<TransportFlow> rtpFlow;
|
||||
nsresult rv = CreateOrGetTransportFlow(
|
||||
aTrackPair.mLevel, false, *aTrackPair.mRtpTransport, &rtpFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
MOZ_ASSERT(rtpFlow);
|
||||
|
||||
RefPtr<TransportFlow> rtcpFlow;
|
||||
if (aTrackPair.mRtcpTransport) {
|
||||
rv = CreateOrGetTransportFlow(
|
||||
aTrackPair.mLevel, true, *aTrackPair.mRtcpTransport, &rtcpFlow);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
MOZ_ASSERT(rtcpFlow);
|
||||
}
|
||||
|
||||
// TODO(bug 1016476): If bundle is in play, grab the TransportFlows for the
|
||||
// bundle level too.
|
||||
|
||||
bool receiving =
|
||||
aTrack.GetDirection() == JsepTrack::Direction::kJsepTrackReceiving;
|
||||
|
||||
RefPtr<MediaSessionConduit> conduit;
|
||||
if (aTrack.GetMediaType() == SdpMediaSection::kAudio) {
|
||||
rv = CreateAudioConduit(aTrackPair, aTrack, &conduit);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
} else if (aTrack.GetMediaType() == SdpMediaSection::kVideo) {
|
||||
rv = CreateVideoConduit(aTrackPair, aTrack, &conduit);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
} else {
|
||||
// We've created the TransportFlow, nothing else to do here.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (receiving) {
|
||||
rv = CreateMediaPipelineReceiving(rtpFlow, rtcpFlow, nullptr, nullptr,
|
||||
aTrackPair, aTrack, conduit);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
} else {
|
||||
rv = CreateMediaPipelineSending(rtpFlow, rtcpFlow, nullptr, nullptr,
|
||||
aTrackPair, aTrack, conduit);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateMediaPipelineReceiving(
|
||||
RefPtr<TransportFlow> aRtpFlow,
|
||||
RefPtr<TransportFlow> aRtcpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtcpFlow,
|
||||
const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
const RefPtr<MediaSessionConduit>& aConduit)
|
||||
{
|
||||
|
||||
// Find the stream we need
|
||||
nsRefPtr<RemoteSourceStreamInfo> stream =
|
||||
mPCMedia->GetRemoteStreamById(aTrack.GetStreamId());
|
||||
MOZ_ASSERT(stream);
|
||||
if (!stream) {
|
||||
// This should never happen
|
||||
MOZ_ASSERT(false);
|
||||
MOZ_MTLOG(ML_ERROR, "Stream not found: " << aTrack.GetStreamId());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
RefPtr<MediaPipelineReceive> pipeline;
|
||||
|
||||
// TODO(bug 1016476): Need bundle filter.
|
||||
nsAutoPtr<MediaPipelineFilter> filter(nullptr);
|
||||
|
||||
if (aTrack.GetMediaType() == SdpMediaSection::kAudio) {
|
||||
pipeline = new MediaPipelineReceiveAudio(
|
||||
mPC->GetHandle(),
|
||||
mPC->GetMainThread().get(),
|
||||
mPC->GetSTSThread(),
|
||||
stream->GetMediaStream()->GetStream(),
|
||||
// Use the level + 1 as the track id. 0 is forbidden
|
||||
aTrackPair.mLevel + 1,
|
||||
aTrackPair.mLevel,
|
||||
static_cast<AudioSessionConduit*>(aConduit.get()), // Ugly downcast.
|
||||
aRtpFlow,
|
||||
aRtcpFlow,
|
||||
aBundleRtpFlow,
|
||||
aBundleRtcpFlow,
|
||||
filter);
|
||||
|
||||
} else if (aTrack.GetMediaType() == SdpMediaSection::kVideo) {
|
||||
pipeline = new MediaPipelineReceiveVideo(
|
||||
mPC->GetHandle(),
|
||||
mPC->GetMainThread().get(),
|
||||
mPC->GetSTSThread(),
|
||||
stream->GetMediaStream()->GetStream(),
|
||||
// Use the level + 1 as the track id. 0 is forbidden
|
||||
aTrackPair.mLevel + 1,
|
||||
aTrackPair.mLevel,
|
||||
static_cast<VideoSessionConduit*>(aConduit.get()), // Ugly downcast.
|
||||
aRtpFlow,
|
||||
aRtcpFlow,
|
||||
aBundleRtpFlow,
|
||||
aBundleRtcpFlow,
|
||||
filter);
|
||||
} else {
|
||||
MOZ_ASSERT(false);
|
||||
MOZ_MTLOG(ML_ERROR, "Invalid media type in CreateMediaPipelineReceiving");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = pipeline->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't initialize receiving pipeline");
|
||||
return rv;
|
||||
}
|
||||
|
||||
stream->StorePipeline(aTrackPair.mLevel, SdpMediaSection::kVideo, pipeline);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateMediaPipelineSending(
|
||||
RefPtr<TransportFlow> aRtpFlow,
|
||||
RefPtr<TransportFlow> aRtcpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtcpFlow,
|
||||
const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
const RefPtr<MediaSessionConduit>& aConduit)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsRefPtr<LocalSourceStreamInfo> stream =
|
||||
mPCMedia->GetLocalStreamById(aTrack.GetStreamId());
|
||||
MOZ_ASSERT(stream);
|
||||
if (!stream) {
|
||||
// This should never happen
|
||||
MOZ_MTLOG(ML_ERROR, "Stream not found: " << aTrack.GetStreamId());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Now we have all the pieces, create the pipeline
|
||||
RefPtr<MediaPipelineTransmit> pipeline = new MediaPipelineTransmit(
|
||||
mPC->GetHandle(), mPC->GetMainThread().get(), mPC->GetSTSThread(),
|
||||
stream->GetMediaStream(), aTrackPair.mLevel,
|
||||
aTrack.GetMediaType() == SdpMediaSection::kVideo, aConduit, aRtpFlow,
|
||||
aRtcpFlow);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// implement checking for peerIdentity (where failure == black/silence)
|
||||
nsIDocument* doc = mPC->GetWindow()->GetExtantDoc();
|
||||
if (doc) {
|
||||
pipeline->UpdateSinkIdentity_m(doc->NodePrincipal(),
|
||||
mPC->GetPeerIdentity());
|
||||
} else {
|
||||
MOZ_MTLOG(ML_ERROR, "Cannot initialize pipeline without attached doc");
|
||||
return NS_ERROR_FAILURE; // Don't remove this till we know it's safe.
|
||||
}
|
||||
#endif
|
||||
|
||||
rv = pipeline->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't initialize sending pipeline");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// TODO(bug 1016476): Copied from vcmSIPCCBinding. Need to unifdef and port in.
|
||||
#if 0
|
||||
// This tells the receive MediaPipeline (if there is one) whether we are
|
||||
// doing bundle, and if so, updates the filter. Once the filter is finalized,
|
||||
// it is then copied to the transmit pipeline so it can filter RTCP.
|
||||
if (attrs->bundle_level) {
|
||||
nsAutoPtr<MediaPipelineFilter> filter (new MediaPipelineFilter);
|
||||
for (int s = 0; s < attrs->num_ssrcs; ++s) {
|
||||
filter->AddRemoteSSRC(attrs->ssrcs[s]);
|
||||
}
|
||||
pc.impl()->media()->SetUsingBundle_m(level, true);
|
||||
pc.impl()->media()->UpdateFilterFromRemoteDescription_m(level, filter);
|
||||
} else {
|
||||
// This will also clear the filter.
|
||||
pc.impl()->media()->SetUsingBundle_m(level, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
stream->StorePipeline(aTrackPair.mLevel, pipeline);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateAudioConduit(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
RefPtr<MediaSessionConduit>* aConduitp)
|
||||
{
|
||||
|
||||
if (!aTrack.GetNegotiatedDetails()) {
|
||||
MOZ_ASSERT(false, "Track is missing negotiated details");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
bool receiving =
|
||||
aTrack.GetDirection() == JsepTrack::Direction::kJsepTrackReceiving;
|
||||
|
||||
RefPtr<MediaSessionConduit> otherConduit =
|
||||
mPCMedia->GetConduit(aTrackPair.mLevel, !receiving);
|
||||
MOZ_ASSERT_IF(otherConduit,
|
||||
otherConduit->type() == MediaSessionConduit::AUDIO);
|
||||
// The two sides of a send/receive pair of conduits each keep a raw pointer
|
||||
// to the other, and are responsible for cleanly shutting down.
|
||||
RefPtr<AudioSessionConduit> conduit = AudioSessionConduit::Create(
|
||||
static_cast<AudioSessionConduit*>(otherConduit.get()));
|
||||
|
||||
if (!conduit) {
|
||||
MOZ_MTLOG(ML_ERROR, "Could not create audio conduit");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPCMedia->AddConduit(aTrackPair.mLevel, receiving, conduit);
|
||||
|
||||
size_t numCodecs = aTrack.GetNegotiatedDetails()->GetCodecCount();
|
||||
if (numCodecs == 0) {
|
||||
MOZ_MTLOG(ML_ERROR, "Can't set up a conduit with 0 codecs");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (receiving) {
|
||||
PtrVector<AudioCodecConfig> configs;
|
||||
|
||||
for (size_t i = 0; i < numCodecs; i++) {
|
||||
const JsepCodecDescription* cdesc;
|
||||
nsresult rv = aTrack.GetNegotiatedDetails()->GetCodec(i, &cdesc);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get codec from jsep track, rv="
|
||||
<< static_cast<uint32_t>(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
AudioCodecConfig* configRaw;
|
||||
rv = JsepCodecDescToCodecConfig(*cdesc, &configRaw);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
configs.values.push_back(configRaw);
|
||||
}
|
||||
|
||||
auto error = conduit->ConfigureRecvMediaCodecs(configs.values);
|
||||
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "ConfigureRecvMediaCodecs failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
const JsepCodecDescription* cdesc;
|
||||
// Best codec.
|
||||
nsresult rv = aTrack.GetNegotiatedDetails()->GetCodec(0, &cdesc);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get codec from jsep track, rv="
|
||||
<< static_cast<uint32_t>(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
AudioCodecConfig* configRaw;
|
||||
rv = JsepCodecDescToCodecConfig(*cdesc, &configRaw);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
ScopedDeletePtr<AudioCodecConfig> config(configRaw);
|
||||
auto error = conduit->ConfigureSendMediaCodec(config.get());
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "ConfigureSendMediaCodec failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const SdpExtmapAttributeList::Extmap* audioLevelExt =
|
||||
aTrack.GetNegotiatedDetails()->GetExt(
|
||||
"urn:ietf:params:rtp-hdrext:ssrc-audio-level");
|
||||
|
||||
if (audioLevelExt) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Calling EnableAudioLevelExtension");
|
||||
error = conduit->EnableAudioLevelExtension(true, audioLevelExt->entry);
|
||||
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "EnableAudioLevelExtension failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aConduitp = conduit;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MediaPipelineFactory::CreateVideoConduit(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
RefPtr<MediaSessionConduit>* aConduitp)
|
||||
{
|
||||
|
||||
if (!aTrack.GetNegotiatedDetails()) {
|
||||
MOZ_ASSERT(false, "Track is missing negotiated details");
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
bool receiving =
|
||||
aTrack.GetDirection() == JsepTrack::Direction::kJsepTrackReceiving;
|
||||
|
||||
// Instantiate an appropriate conduit
|
||||
RefPtr<MediaSessionConduit> peerConduit =
|
||||
mPCMedia->GetConduit(aTrackPair.mLevel, !receiving);
|
||||
MOZ_ASSERT_IF(peerConduit, peerConduit->type() == MediaSessionConduit::VIDEO);
|
||||
|
||||
// The two sides of a send/receive pair of conduits each keep a raw
|
||||
// pointer to the other, and are responsible for cleanly shutting down.
|
||||
RefPtr<VideoSessionConduit> conduit = VideoSessionConduit::Create(
|
||||
static_cast<VideoSessionConduit*>(peerConduit.get()));
|
||||
|
||||
if (!conduit) {
|
||||
MOZ_MTLOG(ML_ERROR, "Could not create video conduit");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPCMedia->AddConduit(aTrackPair.mLevel, receiving, conduit);
|
||||
|
||||
size_t numCodecs = aTrack.GetNegotiatedDetails()->GetCodecCount();
|
||||
if (numCodecs == 0) {
|
||||
MOZ_MTLOG(ML_ERROR, "Can't set up a conduit with 0 codecs");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (receiving) {
|
||||
PtrVector<VideoCodecConfig> configs;
|
||||
|
||||
for (size_t i = 0; i < numCodecs; i++) {
|
||||
const JsepCodecDescription* cdesc;
|
||||
|
||||
nsresult rv = aTrack.GetNegotiatedDetails()->GetCodec(i, &cdesc);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get codec from jsep track, rv="
|
||||
<< static_cast<uint32_t>(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
VideoCodecConfig* configRaw;
|
||||
rv = JsepCodecDescToCodecConfig(*cdesc, &configRaw);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
UniquePtr<VideoCodecConfig> config(configRaw);
|
||||
if (EnsureExternalCodec(*conduit, config.get(), false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
configs.values.push_back(config.release());
|
||||
}
|
||||
|
||||
auto error = conduit->ConfigureRecvMediaCodecs(configs.values);
|
||||
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "ConfigureRecvMediaCodecs failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
const JsepCodecDescription* cdesc;
|
||||
// Best codec.
|
||||
nsresult rv = aTrack.GetNegotiatedDetails()->GetCodec(0, &cdesc);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to get codec from jsep track, rv="
|
||||
<< static_cast<uint32_t>(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
VideoCodecConfig* configRaw;
|
||||
rv = JsepCodecDescToCodecConfig(*cdesc, &configRaw);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// Take possession of this pointer
|
||||
ScopedDeletePtr<VideoCodecConfig> config(configRaw);
|
||||
|
||||
if (EnsureExternalCodec(*conduit, config, true)) {
|
||||
MOZ_MTLOG(ML_ERROR, "External codec not available");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
auto error = conduit->ConfigureSendMediaCodec(config);
|
||||
|
||||
if (error) {
|
||||
MOZ_MTLOG(ML_ERROR, "ConfigureSendMediaCodec failed: " << error);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
*aConduitp = conduit;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add external H.264 video codec.
|
||||
*/
|
||||
MediaConduitErrorCode
|
||||
MediaPipelineFactory::EnsureExternalCodec(VideoSessionConduit& aConduit,
|
||||
VideoCodecConfig* aConfig,
|
||||
bool aIsSend)
|
||||
{
|
||||
if (aConfig->mName == "VP8") {
|
||||
return kMediaConduitNoError;
|
||||
} else if (aConfig->mName == "H264") {
|
||||
// Register H.264 codec.
|
||||
if (aIsSend) {
|
||||
VideoEncoder* encoder = nullptr;
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
encoder =
|
||||
OMXVideoCodec::CreateEncoder(OMXVideoCodec::CodecType::CODEC_H264);
|
||||
#else
|
||||
encoder = GmpVideoCodec::CreateEncoder();
|
||||
#endif
|
||||
if (encoder) {
|
||||
return aConduit.SetExternalSendCodec(aConfig, encoder);
|
||||
} else {
|
||||
return kMediaConduitInvalidSendCodec;
|
||||
}
|
||||
} else {
|
||||
VideoDecoder* decoder;
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
decoder =
|
||||
OMXVideoCodec::CreateDecoder(OMXVideoCodec::CodecType::CODEC_H264);
|
||||
#else
|
||||
decoder = GmpVideoCodec::CreateDecoder();
|
||||
#endif
|
||||
if (decoder) {
|
||||
return aConduit.SetExternalRecvCodec(aConfig, decoder);
|
||||
} else {
|
||||
return kMediaConduitInvalidReceiveCodec;
|
||||
}
|
||||
}
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
} else {
|
||||
MOZ_MTLOG(ML_ERROR,
|
||||
"Invalid video codec configured: " << aConfig->mName.c_str());
|
||||
return aIsSend ? kMediaConduitInvalidSendCodec
|
||||
: kMediaConduitInvalidReceiveCodec;
|
||||
}
|
||||
|
||||
NS_NOTREACHED("Shouldn't get here!");
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
@ -0,0 +1,72 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef _MEDIAPIPELINEFACTORY_H_
|
||||
#define _MEDIAPIPELINEFACTORY_H_
|
||||
|
||||
#include "MediaConduitInterface.h"
|
||||
#include "PeerConnectionMedia.h"
|
||||
#include "transportflow.h"
|
||||
|
||||
#include "signaling/src/jsep/JsepTrack.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class MediaPipelineFactory
|
||||
{
|
||||
public:
|
||||
explicit MediaPipelineFactory(PeerConnectionMedia* aPCMedia)
|
||||
: mPCMedia(aPCMedia), mPC(aPCMedia->GetPC())
|
||||
{
|
||||
}
|
||||
|
||||
nsresult CreateMediaPipeline(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack);
|
||||
|
||||
private:
|
||||
nsresult CreateMediaPipelineReceiving(
|
||||
RefPtr<TransportFlow> aRtpFlow,
|
||||
RefPtr<TransportFlow> aRtcpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtcpFlow,
|
||||
const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
const RefPtr<MediaSessionConduit>& aConduit);
|
||||
|
||||
nsresult CreateMediaPipelineSending(
|
||||
RefPtr<TransportFlow> aRtpFlow,
|
||||
RefPtr<TransportFlow> aRtcpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtpFlow,
|
||||
RefPtr<TransportFlow> aBundleRtcpFlow,
|
||||
const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
const RefPtr<MediaSessionConduit>& aConduit);
|
||||
|
||||
nsresult CreateAudioConduit(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
RefPtr<MediaSessionConduit>* aConduitp);
|
||||
|
||||
nsresult CreateVideoConduit(const JsepTrackPair& aTrackPair,
|
||||
const JsepTrack& aTrack,
|
||||
RefPtr<MediaSessionConduit>* aConduitp);
|
||||
|
||||
MediaConduitErrorCode EnsureExternalCodec(VideoSessionConduit& aConduit,
|
||||
VideoCodecConfig* aConfig,
|
||||
bool aIsSend);
|
||||
|
||||
nsresult CreateOrGetTransportFlow(size_t aLevel, bool aIsRtcp,
|
||||
const JsepTransport& transport,
|
||||
RefPtr<TransportFlow>* out);
|
||||
|
||||
private:
|
||||
// Not owned, and assumed to exist as long as the factory.
|
||||
// The factory is a transient object, so this is fairly easy.
|
||||
PeerConnectionMedia* mPCMedia;
|
||||
PeerConnectionImpl* mPC;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -15,7 +15,7 @@
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
MediaStreamList::MediaStreamList(sipcc::PeerConnectionImpl* peerConnection,
|
||||
MediaStreamList::MediaStreamList(PeerConnectionImpl* peerConnection,
|
||||
StreamType type)
|
||||
: mPeerConnection(peerConnection),
|
||||
mType(type)
|
||||
@ -83,11 +83,11 @@ MediaStreamList::IndexedGetter(uint32_t index, bool& found)
|
||||
}
|
||||
if (mType == Local) {
|
||||
return GetStreamFromInfo(mPeerConnection->media()->
|
||||
GetLocalStream(index), found);
|
||||
GetLocalStreamByIndex(index), found);
|
||||
}
|
||||
|
||||
return GetStreamFromInfo(mPeerConnection->media()->
|
||||
GetRemoteStream(index), found);
|
||||
GetRemoteStreamByIndex(index), found);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -16,11 +16,8 @@
|
||||
#include "DOMMediaStream.h"
|
||||
#endif
|
||||
|
||||
namespace sipcc {
|
||||
class PeerConnectionImpl;
|
||||
} // namespace sipcc
|
||||
|
||||
namespace mozilla {
|
||||
class PeerConnectionImpl;
|
||||
namespace dom {
|
||||
|
||||
class MediaStreamList : public nsISupports,
|
||||
@ -32,7 +29,7 @@ public:
|
||||
Remote
|
||||
};
|
||||
|
||||
MediaStreamList(sipcc::PeerConnectionImpl* peerConnection, StreamType type);
|
||||
MediaStreamList(PeerConnectionImpl* peerConnection, StreamType type);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaStreamList)
|
||||
@ -47,7 +44,7 @@ public:
|
||||
private:
|
||||
virtual ~MediaStreamList();
|
||||
|
||||
nsRefPtr<sipcc::PeerConnectionImpl> mPeerConnection;
|
||||
nsRefPtr<PeerConnectionImpl> mPeerConnection;
|
||||
StreamType mType;
|
||||
};
|
||||
|
||||
|
@ -5,20 +5,9 @@
|
||||
#include "CSFLog.h"
|
||||
|
||||
#include "base/histogram.h"
|
||||
#include "CallControlManager.h"
|
||||
#include "CC_Device.h"
|
||||
#include "CC_Call.h"
|
||||
#include "CC_Observer.h"
|
||||
#include "ccapi_call_info.h"
|
||||
#include "CC_SIPCCCallInfo.h"
|
||||
#include "ccapi_device_info.h"
|
||||
#include "CC_SIPCCDeviceInfo.h"
|
||||
#include "vcm.h"
|
||||
#include "VcmSIPCCBinding.h"
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "PeerConnectionCtx.h"
|
||||
#include "runnable_utils.h"
|
||||
#include "debug-psipcc-types.h"
|
||||
#include "prcvar.h"
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
@ -42,56 +31,6 @@ namespace mozilla {
|
||||
|
||||
using namespace dom;
|
||||
|
||||
// Convert constraints to C structures
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
static void
|
||||
Apply(const Optional<bool> &aSrc, cc_boolean_option_t *aDst) {
|
||||
if (aSrc.WasPassed()) {
|
||||
aDst->was_passed = true;
|
||||
aDst->value = aSrc.Value();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
Apply(const Optional<int32_t> &aSrc, cc_int32_option_t *aDst) {
|
||||
if (aSrc.WasPassed()) {
|
||||
aDst->was_passed = true;
|
||||
aDst->value = aSrc.Value();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SipccOfferOptions::SipccOfferOptions() {
|
||||
memset(&mOptions, 0, sizeof(mOptions));
|
||||
}
|
||||
|
||||
SipccOfferOptions::SipccOfferOptions(
|
||||
const RTCOfferOptions &aSrc) {
|
||||
cc_media_options_t* c = &mOptions;
|
||||
memset(c, 0, sizeof(*c));
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
Apply(aSrc.mOfferToReceiveAudio, &c->offer_to_receive_audio);
|
||||
Apply(aSrc.mOfferToReceiveVideo, &c->offer_to_receive_video);
|
||||
if (!Preferences::GetBool("media.peerconnection.video.enabled", true)) {
|
||||
c->offer_to_receive_video.was_passed = true;
|
||||
c->offer_to_receive_video.value = false;
|
||||
}
|
||||
Apply(aSrc.mMozDontOfferDataChannel, &c->moz_dont_offer_datachannel);
|
||||
Apply(aSrc.mMozBundleOnly, &c->moz_bundle_only);
|
||||
#endif
|
||||
}
|
||||
|
||||
cc_media_options_t*
|
||||
SipccOfferOptions::build() const {
|
||||
cc_media_options_t* cc = (cc_media_options_t*)
|
||||
cpr_malloc(sizeof(cc_media_options_t));
|
||||
if (cc) {
|
||||
*cc = mOptions;
|
||||
}
|
||||
return cc;
|
||||
}
|
||||
|
||||
class PeerConnectionCtxShutdown : public nsIObserver
|
||||
{
|
||||
public:
|
||||
@ -121,7 +60,7 @@ public:
|
||||
const char16_t* aData) {
|
||||
if (strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
|
||||
CSFLogDebug(logTag, "Shutting down PeerConnectionCtx");
|
||||
sipcc::PeerConnectionCtx::Destroy();
|
||||
PeerConnectionCtx::Destroy();
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
services::GetObserverService();
|
||||
@ -134,7 +73,7 @@ public:
|
||||
|
||||
// Make sure we're not deleted while still inside ::Observe()
|
||||
nsRefPtr<PeerConnectionCtxShutdown> kungFuDeathGrip(this);
|
||||
sipcc::PeerConnectionCtx::gPeerConnectionCtxShutdown = nullptr;
|
||||
PeerConnectionCtx::gPeerConnectionCtxShutdown = nullptr;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -152,8 +91,7 @@ private:
|
||||
NS_IMPL_ISUPPORTS(PeerConnectionCtxShutdown, nsIObserver);
|
||||
}
|
||||
|
||||
using namespace mozilla;
|
||||
namespace sipcc {
|
||||
namespace mozilla {
|
||||
|
||||
PeerConnectionCtx* PeerConnectionCtx::gInstance;
|
||||
nsIThread* PeerConnectionCtx::gMainThread;
|
||||
@ -163,7 +101,6 @@ nsresult PeerConnectionCtx::InitializeGlobal(nsIThread *mainThread,
|
||||
nsIEventTarget* stsThread) {
|
||||
if (!gMainThread) {
|
||||
gMainThread = mainThread;
|
||||
CSF::VcmSIPCCBinding::setMainThread(gMainThread);
|
||||
} else {
|
||||
MOZ_ASSERT(gMainThread == mainThread);
|
||||
}
|
||||
@ -183,9 +120,9 @@ nsresult PeerConnectionCtx::InitializeGlobal(nsIThread *mainThread,
|
||||
|
||||
gInstance = ctx;
|
||||
|
||||
if (!sipcc::PeerConnectionCtx::gPeerConnectionCtxShutdown) {
|
||||
sipcc::PeerConnectionCtx::gPeerConnectionCtxShutdown = new PeerConnectionCtxShutdown();
|
||||
sipcc::PeerConnectionCtx::gPeerConnectionCtxShutdown->Init();
|
||||
if (!PeerConnectionCtx::gPeerConnectionCtxShutdown) {
|
||||
PeerConnectionCtx::gPeerConnectionCtxShutdown = new PeerConnectionCtxShutdown();
|
||||
PeerConnectionCtx::gPeerConnectionCtxShutdown->Init();
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,51 +300,6 @@ PeerConnectionCtx::EverySecondTelemetryCallback_m(nsITimer* timer, void *closure
|
||||
nsresult PeerConnectionCtx::Initialize() {
|
||||
initGMP();
|
||||
|
||||
mCCM = CSF::CallControlManager::create();
|
||||
|
||||
NS_ENSURE_TRUE(mCCM.get(), NS_ERROR_FAILURE);
|
||||
|
||||
// Add the local audio codecs
|
||||
// FIX - Get this list from MediaEngine instead
|
||||
int codecMask = 0;
|
||||
codecMask |= VCM_CODEC_RESOURCE_G711;
|
||||
codecMask |= VCM_CODEC_RESOURCE_OPUS;
|
||||
//codecMask |= VCM_CODEC_RESOURCE_LINEAR;
|
||||
codecMask |= VCM_CODEC_RESOURCE_G722;
|
||||
//codecMask |= VCM_CODEC_RESOURCE_iLBC;
|
||||
//codecMask |= VCM_CODEC_RESOURCE_iSAC;
|
||||
mCCM->setAudioCodecs(codecMask);
|
||||
|
||||
//Add the local video codecs
|
||||
// FIX - Get this list from MediaEngine instead
|
||||
// Turning them all on for now
|
||||
codecMask = 0;
|
||||
// Only adding codecs supported
|
||||
//codecMask |= VCM_CODEC_RESOURCE_H263;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
if (Preferences::GetBool("media.peerconnection.video.h264_enabled")) {
|
||||
codecMask |= VCM_CODEC_RESOURCE_H264;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
// Outside MOZILLA_INTERNAL_API ensures H.264 available in unit tests
|
||||
codecMask |= VCM_CODEC_RESOURCE_H264;
|
||||
#endif
|
||||
|
||||
codecMask |= VCM_CODEC_RESOURCE_VP8;
|
||||
//codecMask |= VCM_CODEC_RESOURCE_I420;
|
||||
mCCM->setVideoCodecs(codecMask);
|
||||
mCCM->addCCObserver(this);
|
||||
ChangeSipccState(dom::PCImplSipccState::Starting);
|
||||
|
||||
if (!mCCM->startSDPMode())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
mDevice = mCCM->getActiveDevice();
|
||||
NS_ENSURE_TRUE(mDevice.get(), NS_ERROR_FAILURE);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
mConnectionCounter = 0;
|
||||
Telemetry::GetHistogramById(Telemetry::WEBRTC_CALL_COUNT)->Add(0);
|
||||
@ -418,7 +310,8 @@ nsresult PeerConnectionCtx::Initialize() {
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mTelemetryTimer->InitWithFuncCallback(EverySecondTelemetryCallback_m, this, 1000,
|
||||
nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP);
|
||||
#endif
|
||||
#endif // MOZILLA_INTERNAL_API
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -464,9 +357,6 @@ nsresult PeerConnectionCtx::Cleanup() {
|
||||
|
||||
mQueuedJSEPOperations.Clear();
|
||||
mGMPService = nullptr;
|
||||
|
||||
mCCM->destroy();
|
||||
mCCM->removeCCObserver(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -480,10 +370,6 @@ PeerConnectionCtx::~PeerConnectionCtx() {
|
||||
#endif
|
||||
};
|
||||
|
||||
CSF::CC_CallPtr PeerConnectionCtx::createCall() {
|
||||
return mDevice->createCall();
|
||||
}
|
||||
|
||||
void PeerConnectionCtx::queueJSEPOperation(nsRefPtr<nsIRunnable> aOperation) {
|
||||
mQueuedJSEPOperations.AppendElement(aOperation);
|
||||
}
|
||||
@ -496,35 +382,33 @@ void PeerConnectionCtx::onGMPReady() {
|
||||
mQueuedJSEPOperations.Clear();
|
||||
}
|
||||
|
||||
void PeerConnectionCtx::onDeviceEvent(ccapi_device_event_e aDeviceEvent,
|
||||
CSF::CC_DevicePtr aDevice,
|
||||
CSF::CC_DeviceInfoPtr aInfo ) {
|
||||
cc_service_state_t state = aInfo->getServiceState();
|
||||
// We are keeping this in a local var to avoid a data race
|
||||
// with ChangeSipccState in the debug message and compound if below
|
||||
dom::PCImplSipccState currentSipccState = mSipccState;
|
||||
|
||||
switch (aDeviceEvent) {
|
||||
case CCAPI_DEVICE_EV_STATE:
|
||||
CSFLogDebug(logTag, "%s - %d : %d", __FUNCTION__, state,
|
||||
static_cast<uint32_t>(currentSipccState));
|
||||
|
||||
if (CC_STATE_INS == state) {
|
||||
// SIPCC is up
|
||||
if (dom::PCImplSipccState::Starting == currentSipccState ||
|
||||
dom::PCImplSipccState::Idle == currentSipccState) {
|
||||
ChangeSipccState(dom::PCImplSipccState::Started);
|
||||
} else {
|
||||
CSFLogError(logTag, "%s PeerConnection already started", __FUNCTION__);
|
||||
}
|
||||
} else {
|
||||
NS_NOTREACHED("Unsupported Signaling State Transition");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CSFLogDebug(logTag, "%s: Ignoring event: %s\n",__FUNCTION__,
|
||||
device_event_getname(aDeviceEvent));
|
||||
bool PeerConnectionCtx::gmpHasH264() {
|
||||
if (!mGMPService) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX I'd prefer if this was all known ahead of time...
|
||||
|
||||
nsTArray<nsCString> tags;
|
||||
tags.AppendElement(NS_LITERAL_CSTRING("h264"));
|
||||
|
||||
bool has_gmp;
|
||||
nsresult rv;
|
||||
rv = mGMPService->HasPluginForAPI(NS_LITERAL_CSTRING("encode-video"),
|
||||
&tags,
|
||||
&has_gmp);
|
||||
if (NS_FAILED(rv) || !has_gmp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
rv = mGMPService->HasPluginForAPI(NS_LITERAL_CSTRING("decode-video"),
|
||||
&tags,
|
||||
&has_gmp);
|
||||
if (NS_FAILED(rv) || !has_gmp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace sipcc
|
||||
} // namespace mozilla
|
||||
|
@ -8,17 +8,6 @@
|
||||
#include <string>
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "CallControlManager.h"
|
||||
#include "CC_Device.h"
|
||||
#include "CC_DeviceInfo.h"
|
||||
#include "CC_Call.h"
|
||||
#include "CC_CallInfo.h"
|
||||
#include "CC_Line.h"
|
||||
#include "CC_LineInfo.h"
|
||||
#include "CC_Observer.h"
|
||||
#include "CC_FeatureInfo.h"
|
||||
#include "cpr_stdlib.h"
|
||||
|
||||
#include "StaticPtr.h"
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "mozIGeckoMediaPluginService.h"
|
||||
@ -31,52 +20,17 @@ namespace dom {
|
||||
class WebrtcGlobalInformation;
|
||||
}
|
||||
|
||||
// Unit-test helper, because cc_media_options_t is hard to forward-declare
|
||||
|
||||
class SipccOfferOptions {
|
||||
public:
|
||||
SipccOfferOptions();
|
||||
explicit SipccOfferOptions(const dom::RTCOfferOptions &aOther);
|
||||
cc_media_options_t* build() const;
|
||||
protected:
|
||||
cc_media_options_t mOptions;
|
||||
};
|
||||
}
|
||||
|
||||
namespace sipcc {
|
||||
|
||||
class OnCallEventArgs {
|
||||
public:
|
||||
OnCallEventArgs(ccapi_call_event_e aCallEvent, CSF::CC_CallInfoPtr aInfo)
|
||||
: mCallEvent(aCallEvent), mInfo(aInfo) {}
|
||||
|
||||
ccapi_call_event_e mCallEvent;
|
||||
CSF::CC_CallInfoPtr mInfo;
|
||||
};
|
||||
|
||||
// A class to hold some of the singleton objects we need:
|
||||
// * The global PeerConnectionImpl table and its associated lock.
|
||||
// * Currently SIPCC only allows a single stack instance to exist in a process
|
||||
// at once. This class implements a singleton object that wraps that.
|
||||
// * The observer class that demuxes events onto individual PCs.
|
||||
class PeerConnectionCtx : public CSF::CC_Observer {
|
||||
// * Stats report objects for PCs that are gone
|
||||
// * GMP related state
|
||||
class PeerConnectionCtx {
|
||||
public:
|
||||
static nsresult InitializeGlobal(nsIThread *mainThread, nsIEventTarget *stsThread);
|
||||
static PeerConnectionCtx* GetInstance();
|
||||
static bool isActive();
|
||||
static void Destroy();
|
||||
|
||||
// Implementations of CC_Observer methods
|
||||
virtual void onDeviceEvent(ccapi_device_event_e deviceEvent, CSF::CC_DevicePtr device, CSF::CC_DeviceInfoPtr info);
|
||||
virtual void onFeatureEvent(ccapi_device_event_e deviceEvent, CSF::CC_DevicePtr device, CSF::CC_FeatureInfoPtr feature_info) {}
|
||||
virtual void onLineEvent(ccapi_line_event_e lineEvent, CSF::CC_LinePtr line, CSF::CC_LineInfoPtr info) {}
|
||||
virtual void onCallEvent(ccapi_call_event_e callEvent, CSF::CC_CallPtr call, CSF::CC_CallInfoPtr info) {}
|
||||
|
||||
// Create a SIPCC Call
|
||||
CSF::CC_CallPtr createCall();
|
||||
|
||||
mozilla::dom::PCImplSipccState sipcc_state() { return mSipccState; }
|
||||
|
||||
bool isReady() {
|
||||
// If mGMPService is not set, we aren't using GMP.
|
||||
if (mGMPService) {
|
||||
@ -88,6 +42,8 @@ class PeerConnectionCtx : public CSF::CC_Observer {
|
||||
void queueJSEPOperation(nsRefPtr<nsIRunnable> aJSEPOperation);
|
||||
void onGMPReady();
|
||||
|
||||
bool gmpHasH264();
|
||||
|
||||
// Make these classes friend so that they can access mPeerconnections.
|
||||
friend class PeerConnectionImpl;
|
||||
friend class PeerConnectionWrapper;
|
||||
@ -104,8 +60,7 @@ class PeerConnectionCtx : public CSF::CC_Observer {
|
||||
// We could make these available only via accessors but it's too much trouble.
|
||||
std::map<const std::string, PeerConnectionImpl *> mPeerConnections;
|
||||
|
||||
PeerConnectionCtx() : mSipccState(mozilla::dom::PCImplSipccState::Idle),
|
||||
mCCM(nullptr), mDevice(nullptr), mGMPReady(false) {}
|
||||
PeerConnectionCtx() : mGMPReady(false) {}
|
||||
// This is a singleton, so don't copy construct it, etc.
|
||||
PeerConnectionCtx(const PeerConnectionCtx& other) MOZ_DELETE;
|
||||
void operator=(const PeerConnectionCtx& other) MOZ_DELETE;
|
||||
@ -114,10 +69,6 @@ class PeerConnectionCtx : public CSF::CC_Observer {
|
||||
nsresult Initialize();
|
||||
nsresult Cleanup();
|
||||
|
||||
void ChangeSipccState(mozilla::dom::PCImplSipccState aState) {
|
||||
mSipccState = aState;
|
||||
}
|
||||
|
||||
void initGMP();
|
||||
|
||||
static void
|
||||
@ -136,11 +87,6 @@ public:
|
||||
private:
|
||||
#endif
|
||||
|
||||
// SIPCC objects
|
||||
mozilla::dom::PCImplSipccState mSipccState; // TODO(ekr@rtfm.com): refactor this out? What does it do?
|
||||
CSF::CallControlManagerPtr mCCM;
|
||||
CSF::CC_DevicePtr mDevice;
|
||||
|
||||
// We cannot form offers/answers properly until the Gecko Media Plugin stuff
|
||||
// has been initted, which is a complicated mess of thread dispatches,
|
||||
// including sync dispatches to main. So, we need to be able to queue up
|
||||
@ -156,6 +102,6 @@ public:
|
||||
static mozilla::StaticRefPtr<mozilla::PeerConnectionCtxShutdown> gPeerConnectionCtxShutdown;
|
||||
};
|
||||
|
||||
} // namespace sipcc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,8 +22,13 @@
|
||||
#include "nricemediastream.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsIThread.h"
|
||||
|
||||
#include "signaling/src/jsep/JsepSession.h"
|
||||
#include "signaling/src/jsep/JsepSessionImpl.h"
|
||||
#include "signaling/src/sdp/SdpMediaSection.h"
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/PeerConnectionImplEnumsBinding.h"
|
||||
#include "StreamBuffer.h"
|
||||
@ -88,7 +93,6 @@ class PeerConnectionObserver;
|
||||
typedef NS_ConvertUTF8toUTF16 PCObserverString;
|
||||
#endif
|
||||
}
|
||||
class SipccOfferOptions;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) && __cplusplus >= 201103L
|
||||
@ -110,7 +114,7 @@ already_AddRefed<resulttype> func (__VA_ARGS__, rv)
|
||||
|
||||
struct MediaStreamTable;
|
||||
|
||||
namespace sipcc {
|
||||
namespace mozilla {
|
||||
|
||||
using mozilla::dom::PeerConnectionObserver;
|
||||
using mozilla::dom::RTCConfiguration;
|
||||
@ -130,6 +134,15 @@ class PeerConnectionWrapper;
|
||||
class PeerConnectionMedia;
|
||||
class RemoteSourceStreamInfo;
|
||||
|
||||
// Uuid Generator
|
||||
class PCUuidGenerator : public mozilla::JsepUuidGenerator {
|
||||
public:
|
||||
virtual bool Generate(std::string* idp) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIUUIDGenerator> mGenerator;
|
||||
};
|
||||
|
||||
class IceConfiguration
|
||||
{
|
||||
public:
|
||||
@ -226,6 +239,7 @@ public:
|
||||
|
||||
enum Error {
|
||||
kNoError = 0,
|
||||
kInvalidCandidate = 2,
|
||||
kInvalidMediastreamTrack = 3,
|
||||
kInvalidState = 4,
|
||||
kInvalidSessionDescription = 5,
|
||||
@ -247,7 +261,8 @@ public:
|
||||
IceConfiguration *aDst);
|
||||
already_AddRefed<DOMMediaStream> MakeMediaStream(uint32_t aHint);
|
||||
|
||||
nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo);
|
||||
nsresult CreateRemoteSourceStreamInfo(nsRefPtr<RemoteSourceStreamInfo>* aInfo,
|
||||
const std::string& aId);
|
||||
|
||||
// DataConnection observers
|
||||
void NotifyDataChannel(already_AddRefed<mozilla::DataChannel> aChannel);
|
||||
@ -272,6 +287,10 @@ public:
|
||||
NrIceCtx::ConnectionState state);
|
||||
void IceGatheringStateChange(NrIceCtx* ctx,
|
||||
NrIceCtx::GatheringState state);
|
||||
// TODO(bug 1096795): Need a |component| id here for rtcp.
|
||||
void EndOfLocalCandidates(const std::string& defaultAddr,
|
||||
uint16_t defaultPort,
|
||||
uint16_t level);
|
||||
void IceStreamReady(NrIceMediaStream *aStream);
|
||||
|
||||
static void ListenThread(void *aData);
|
||||
@ -291,9 +310,6 @@ public:
|
||||
|
||||
// Get the DTLS identity (local side)
|
||||
mozilla::RefPtr<DtlsIdentity> const GetIdentity() const;
|
||||
std::string GetFingerprint() const;
|
||||
std::string GetFingerprintAlgorithm() const;
|
||||
std::string GetFingerprintHexValue() const;
|
||||
|
||||
// Create a fake media stream
|
||||
nsresult CreateFakeMediaStream(uint32_t hint, mozilla::DOMMediaStream** retval);
|
||||
@ -336,7 +352,8 @@ public:
|
||||
rv = CreateAnswer();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP CreateOffer(const mozilla::SipccOfferOptions& aConstraints);
|
||||
NS_IMETHODIMP CreateOffer(
|
||||
const mozilla::JsepOfferOptions& aConstraints);
|
||||
|
||||
NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP);
|
||||
|
||||
@ -368,8 +385,6 @@ public:
|
||||
NS_ConvertUTF16toUTF8(aMid).get(), aLevel);
|
||||
}
|
||||
|
||||
void OnRemoteStreamAdded(const MediaStreamTable& aStream);
|
||||
|
||||
NS_IMETHODIMP CloseStreams();
|
||||
|
||||
void CloseStreams(ErrorResult &rv)
|
||||
@ -477,15 +492,6 @@ public:
|
||||
return state;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP SipccState(mozilla::dom::PCImplSipccState* aState);
|
||||
|
||||
mozilla::dom::PCImplSipccState SipccState()
|
||||
{
|
||||
mozilla::dom::PCImplSipccState state;
|
||||
SipccState(&state);
|
||||
return state;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP IceConnectionState(
|
||||
mozilla::dom::PCImplIceConnectionState* aState);
|
||||
|
||||
@ -517,8 +523,7 @@ public:
|
||||
const nsAString& aPluginName,
|
||||
const nsAString& aPluginDumpID);
|
||||
|
||||
nsresult InitializeDataChannel(int track_id, uint16_t aLocalport,
|
||||
uint16_t aRemoteport, uint16_t aNumstreams);
|
||||
nsresult InitializeDataChannel();
|
||||
|
||||
NS_IMETHODIMP_TO_ERRORRESULT(ConnectDataConnection, ErrorResult &rv,
|
||||
uint16_t aLocalport,
|
||||
@ -560,16 +565,6 @@ public:
|
||||
// is called to start the list over.
|
||||
void ClearSdpParseErrorMessages();
|
||||
|
||||
void StartTrickle();
|
||||
|
||||
// Called by VcmSIPCCBinding::vcmRxAllocICE; this is how sipcc tells us about
|
||||
// each m-line it has put in the sdp.
|
||||
void OnNewMline(uint16_t level) {
|
||||
if (level > mNumMlines) {
|
||||
mNumMlines = level;
|
||||
}
|
||||
}
|
||||
|
||||
void OnAddIceCandidateError() {
|
||||
++mAddCandidateErrorCount;
|
||||
}
|
||||
@ -580,7 +575,7 @@ public:
|
||||
// Sets the RTC Signaling State
|
||||
void SetSignalingState_m(mozilla::dom::PCImplSignalingState aSignalingState);
|
||||
|
||||
// Updates the RTC signaling state based on the sipcc state
|
||||
// Updates the RTC signaling state based on the JsepSession state
|
||||
void UpdateSignalingState();
|
||||
|
||||
bool IsClosed() const;
|
||||
@ -613,6 +608,9 @@ private:
|
||||
const IceConfiguration* aConfiguration,
|
||||
const RTCConfiguration* aRTCConfiguration,
|
||||
nsISupports* aThread);
|
||||
nsresult CalculateFingerprint(const std::string& algorithm,
|
||||
std::vector<uint8_t>& fingerprint) const;
|
||||
nsresult ConfigureJsepSessionCodecs();
|
||||
|
||||
NS_IMETHODIMP EnsureDataConnection(uint16_t aNumstreams);
|
||||
|
||||
@ -646,11 +644,10 @@ private:
|
||||
void SendLocalIceCandidateToContent(uint16_t level,
|
||||
const std::string& mid,
|
||||
const std::string& candidate);
|
||||
void FoundIceCandidate(const std::string& candidate, uint16_t level);
|
||||
|
||||
NS_IMETHOD FingerprintSplitHelper(
|
||||
std::string& fingerprint, size_t& spaceIdx) const;
|
||||
|
||||
nsresult GetDatachannelParameters(
|
||||
const mozilla::JsepApplicationCodecDescription** codec,
|
||||
uint16_t* level) const;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
static void GetStatsForPCObserver_s(
|
||||
@ -676,8 +673,6 @@ private:
|
||||
// any other attributes of this class.
|
||||
Timecard *mTimeCard;
|
||||
|
||||
// The call
|
||||
mozilla::ScopedDeletePtr<Internal> mInternal;
|
||||
mozilla::dom::PCImplSignalingState mSignalingState;
|
||||
|
||||
// ICE State
|
||||
@ -697,12 +692,6 @@ private:
|
||||
// The SDP sent in from JS - here for debugging.
|
||||
std::string mLocalRequestedSDP;
|
||||
std::string mRemoteRequestedSDP;
|
||||
// The SDP we are using.
|
||||
std::string mLocalSDP;
|
||||
std::string mRemoteSDP;
|
||||
|
||||
// Holding tank for trickle candidates that arrive before setLocal is done.
|
||||
std::vector<std::pair<std::string, uint16_t>> mCandidateBuffer;
|
||||
|
||||
// DTLS fingerprint
|
||||
std::string mFingerprint;
|
||||
@ -740,6 +729,10 @@ private:
|
||||
bool mAllowIceLoopback;
|
||||
nsRefPtr<PeerConnectionMedia> mMedia;
|
||||
|
||||
// The JSEP negotiation session.
|
||||
mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
|
||||
mozilla::UniquePtr<mozilla::JsepSession> mJsepSession;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// Start time of ICE, used for telemetry
|
||||
mozilla::TimeStamp mIceStartTime;
|
||||
@ -756,10 +749,6 @@ private:
|
||||
|
||||
bool mHaveDataStream;
|
||||
|
||||
uint16_t mNumMlines;
|
||||
|
||||
// Holder for error messages from parsing SDP
|
||||
std::vector<std::string> mSDPParseErrorMessages;
|
||||
unsigned int mAddCandidateErrorCount;
|
||||
|
||||
bool mTrickle;
|
||||
@ -783,7 +772,7 @@ class PeerConnectionWrapper
|
||||
nsRefPtr<PeerConnectionImpl> impl_;
|
||||
};
|
||||
|
||||
} // end sipcc namespace
|
||||
} // end mozilla namespace
|
||||
|
||||
#undef NS_IMETHODIMP_TO_ERRORRESULT
|
||||
#undef NS_IMETHODIMP_TO_ERRORRESULT_RETREF
|
||||
|
@ -1,21 +1,27 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "CSFLog.h"
|
||||
|
||||
#include "nspr.h"
|
||||
#include "cc_constants.h"
|
||||
|
||||
#include "nricectx.h"
|
||||
#include "nricemediastream.h"
|
||||
#include "MediaPipelineFactory.h"
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "PeerConnectionMedia.h"
|
||||
#include "AudioConduit.h"
|
||||
#include "VideoConduit.h"
|
||||
#include "runnable_utils.h"
|
||||
#include "transportlayerice.h"
|
||||
#include "transportlayerdtls.h"
|
||||
#include "signaling/src/jsep/JsepSession.h"
|
||||
#include "signaling/src/jsep/JsepTransport.h"
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#include "MediaStreamList.h"
|
||||
@ -24,10 +30,10 @@
|
||||
#include "mozilla/dom/RTCStatsReportBinding.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace sipcc {
|
||||
namespace mozilla {
|
||||
|
||||
static const char* logTag = "PeerConnectionMedia";
|
||||
static const mozilla::TrackID TRACK_AUDIO = 0;
|
||||
@ -134,12 +140,12 @@ int LocalSourceStreamInfo::HasTrackType(DOMMediaStream* aStream, bool aIsVideo)
|
||||
}
|
||||
|
||||
// XXX revisit once we support multiple tracks of a type - bug 1056650
|
||||
nsresult LocalSourceStreamInfo::ReplaceTrack(int aIndex,
|
||||
nsresult LocalSourceStreamInfo::ReplaceTrack(int aMLine,
|
||||
DOMMediaStream* aNewStream,
|
||||
TrackID aNewTrack)
|
||||
{
|
||||
// Note aIndex != aOldTrack!
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> pipeline = mPipelines[aIndex];
|
||||
// Note aMLine != aOldTrack!
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> pipeline = mPipelines[aMLine];
|
||||
MOZ_ASSERT(pipeline);
|
||||
if (NS_SUCCEEDED(static_cast<mozilla::MediaPipelineTransmit*>(pipeline.get())->ReplaceTrack(aNewStream, aNewTrack))) {
|
||||
return NS_OK;
|
||||
@ -166,7 +172,7 @@ void RemoteSourceStreamInfo::DetachMedia_m()
|
||||
// walk through all the MediaPipelines and call the shutdown
|
||||
// media functions. Must be on the main thread.
|
||||
for (std::map<int, mozilla::RefPtr<mozilla::MediaPipeline> >::iterator it =
|
||||
mPipelines.begin(); it != mPipelines.end();
|
||||
mPipelines.begin(); it != mPipelines.end();
|
||||
++it) {
|
||||
it->second->ShutdownMedia_m();
|
||||
}
|
||||
@ -196,15 +202,13 @@ PeerConnectionImpl* PeerConnectionImpl::CreatePeerConnection()
|
||||
PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
||||
: mParent(parent),
|
||||
mParentHandle(parent->GetHandle()),
|
||||
mParentName(parent->GetName()),
|
||||
mAllowIceLoopback(false),
|
||||
mIceCtx(nullptr),
|
||||
mDNSResolver(new mozilla::NrIceResolver()),
|
||||
mUuidGen(MakeUnique<PCUuidGenerator>()),
|
||||
mMainThread(mParent->GetMainThread()),
|
||||
mSTSThread(mParent->GetSTSThread()) {
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
mAllowIceLoopback = Preferences::GetBool(
|
||||
"media.peerconnection.ice.loopback", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_servers,
|
||||
@ -212,7 +216,7 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
||||
{
|
||||
// TODO(ekr@rtfm.com): need some way to set not offerer later
|
||||
// Looks like a bug in the NrIceCtx API.
|
||||
mIceCtx = NrIceCtx::Create("PC:" + mParent->GetName(),
|
||||
mIceCtx = NrIceCtx::Create("PC:" + mParentName,
|
||||
true, // Offerer
|
||||
true, // Trickle
|
||||
mAllowIceLoopback);
|
||||
@ -254,59 +258,274 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
||||
this,
|
||||
&PeerConnectionMedia::IceConnectionStateChange_s);
|
||||
|
||||
// Create three streams to start with.
|
||||
// One each for audio, video and DataChannel
|
||||
// TODO: this will be re-visited
|
||||
RefPtr<NrIceMediaStream> audioStream =
|
||||
mIceCtx->CreateStream((mParent->GetName()+": stream1/audio").c_str(), 2);
|
||||
RefPtr<NrIceMediaStream> videoStream =
|
||||
mIceCtx->CreateStream((mParent->GetName()+": stream2/video").c_str(), 2);
|
||||
RefPtr<NrIceMediaStream> dcStream =
|
||||
mIceCtx->CreateStream((mParent->GetName()+": stream3/data").c_str(), 2);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!audioStream) {
|
||||
CSFLogError(logTag, "%s: audio stream is NULL", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
mIceStreams.push_back(audioStream);
|
||||
void
|
||||
PeerConnectionMedia::UpdateTransports(const mozilla::JsepSession& session) {
|
||||
|
||||
size_t numTransports = session.GetTransportCount();
|
||||
for (size_t i = 0; i < numTransports; ++i) {
|
||||
RefPtr<JsepTransport> transport;
|
||||
|
||||
nsresult rv = session.GetTransport(i, &transport);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
std::string ufrag;
|
||||
std::string pwd;
|
||||
std::vector<std::string> candidates;
|
||||
|
||||
bool hasAttrs = false;
|
||||
if (transport->mIce) {
|
||||
hasAttrs = true;
|
||||
ufrag = transport->mIce->GetUfrag();
|
||||
pwd = transport->mIce->GetPassword();
|
||||
candidates = transport->mIce->GetCandidates();
|
||||
}
|
||||
|
||||
// Update the transport.
|
||||
// TODO(bug 1017888): don't repeat candidates on renegotiation. Perhaps
|
||||
// suppress inside nICEr?
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::UpdateIceMediaStream_s,
|
||||
i,
|
||||
transport->mComponents,
|
||||
hasAttrs,
|
||||
ufrag,
|
||||
pwd,
|
||||
candidates),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
if (!videoStream) {
|
||||
CSFLogError(logTag, "%s: video stream is NULL", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
mIceStreams.push_back(videoStream);
|
||||
}
|
||||
|
||||
if (!dcStream) {
|
||||
CSFLogError(logTag, "%s: datachannel stream is NULL", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
} else {
|
||||
mIceStreams.push_back(dcStream);
|
||||
}
|
||||
// TODO(bug 1017888): Need to deal properly with renegotatiation.
|
||||
// For now just start gathering.
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::EnsureIceGathering_s),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
// TODO(ekr@rtfm.com): This is not connected to the PCCimpl.
|
||||
// Will need to do that later.
|
||||
for (std::size_t i=0; i<mIceStreams.size(); i++) {
|
||||
mIceStreams[i]->SetLevel(i + 1);
|
||||
mIceStreams[i]->SignalReady.connect(this, &PeerConnectionMedia::IceStreamReady);
|
||||
mIceStreams[i]->SignalCandidate.connect(
|
||||
this,
|
||||
&PeerConnectionMedia::OnCandidateFound_s);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(ekr@rtfm.com): When we have a generic error reporting mechanism,
|
||||
// figure out how to report that StartGathering failed. Bug 827982.
|
||||
RUN_ON_THREAD(mIceCtx->thread(),
|
||||
WrapRunnable(mIceCtx, &NrIceCtx::StartGathering), NS_DISPATCH_NORMAL);
|
||||
nsresult PeerConnectionMedia::UpdateMediaPipelines(
|
||||
const mozilla::JsepSession& session) {
|
||||
size_t numPairs = session.GetNegotiatedTrackPairCount();
|
||||
mozilla::MediaPipelineFactory factory(this);
|
||||
const mozilla::JsepTrackPair* pair;
|
||||
|
||||
for (size_t i = 0; i < numPairs; ++i) {
|
||||
nsresult rv = session.GetNegotiatedTrackPair(i, &pair);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_ASSERT(false);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// TODO(bug 1099318): We are forced to do receive then transmit, because of
|
||||
// a bug in the VideoConduit code. This will need to be fixed for
|
||||
// renegotiation.
|
||||
if (pair->mReceiving) {
|
||||
rv = factory.CreateMediaPipeline(*pair, *pair->mReceiving);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "Failed to create receiving pipeline, rv=%u",
|
||||
static_cast<unsigned>(rv));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (pair->mSending) {
|
||||
rv = factory.CreateMediaPipeline(*pair, *pair->mSending);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "Failed to create sending pipeline, rv=%u",
|
||||
static_cast<unsigned>(rv));
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::StartIceChecks(const mozilla::JsepSession& session) {
|
||||
|
||||
std::vector<size_t> numComponentsByLevel;
|
||||
for (size_t i = 0; i < session.GetTransportCount(); ++i) {
|
||||
RefPtr<JsepTransport> transport;
|
||||
nsresult rv = session.GetTransport(i, &transport);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "JsepSession::GetTransport() failed: %u",
|
||||
static_cast<unsigned>(rv));
|
||||
MOZ_ASSERT(false, "JsepSession::GetTransport() failed!");
|
||||
break;
|
||||
}
|
||||
|
||||
if (transport->mState == JsepTransport::kJsepTransportClosed) {
|
||||
numComponentsByLevel.push_back(0);
|
||||
} else {
|
||||
numComponentsByLevel.push_back(transport->mComponents);
|
||||
}
|
||||
}
|
||||
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::StartIceChecks_s,
|
||||
session.IsIceControlling(),
|
||||
session.RemoteIsIceLite(),
|
||||
// Copy, just in case API changes to return a ref
|
||||
std::vector<std::string>(session.GetIceOptions()),
|
||||
numComponentsByLevel),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::StartIceChecks_s(
|
||||
bool aIsControlling,
|
||||
bool aIsIceLite,
|
||||
const std::vector<std::string>& aIceOptionsList,
|
||||
const std::vector<size_t>& aComponentCountByLevel) {
|
||||
|
||||
CSFLogDebug(logTag, "Starting ICE Checking");
|
||||
|
||||
std::vector<std::string> attributes;
|
||||
if (aIsIceLite) {
|
||||
attributes.push_back("ice-lite");
|
||||
}
|
||||
|
||||
if (!aIceOptionsList.empty()) {
|
||||
attributes.push_back("ice-options:");
|
||||
for (auto i = aIceOptionsList.begin(); i != aIceOptionsList.end(); ++i) {
|
||||
attributes.back() += *i + ' ';
|
||||
}
|
||||
}
|
||||
|
||||
nsresult rv = mIceCtx->ParseGlobalAttributes(attributes);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "%s: couldn't parse global parameters", __FUNCTION__ );
|
||||
}
|
||||
|
||||
mIceCtx->SetControlling(aIsControlling ?
|
||||
NrIceCtx::ICE_CONTROLLING :
|
||||
NrIceCtx::ICE_CONTROLLED);
|
||||
|
||||
for (size_t i = 0; i < aComponentCountByLevel.size(); ++i) {
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtx->GetStream(i));
|
||||
if (!stream) {
|
||||
MOZ_ASSERT(false, "JsepSession has more streams than the ICE ctx");
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t c = aComponentCountByLevel[i]; c < stream->components(); ++c) {
|
||||
// components are 1-indexed
|
||||
stream->DisableComponent(c + 1);
|
||||
}
|
||||
}
|
||||
|
||||
mIceCtx->StartChecks();
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::AddIceCandidate(const std::string& candidate,
|
||||
const std::string& mid,
|
||||
uint32_t aMLine) {
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::AddIceCandidate_s,
|
||||
std::string(candidate), // Make copies.
|
||||
std::string(mid),
|
||||
aMLine),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
void
|
||||
PeerConnectionMedia::AddIceCandidate_s(const std::string& aCandidate,
|
||||
const std::string& aMid,
|
||||
uint32_t aMLine) {
|
||||
if (aMLine >= mIceStreams.size()) {
|
||||
CSFLogError(logTag, "Couldn't process ICE candidate for bogus level %u",
|
||||
aMLine);
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv = mIceStreams[aMLine]->ParseTrickleCandidate(aCandidate);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "Couldn't process ICE candidate at level %u",
|
||||
aMLine);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::EnsureIceGathering_s() {
|
||||
if (mIceCtx->gathering_state() == NrIceCtx::ICE_CTX_GATHER_INIT) {
|
||||
mIceCtx->StartGathering();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::UpdateIceMediaStream_s(size_t aMLine,
|
||||
size_t aComponentCount,
|
||||
bool aHasAttrs,
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPassword,
|
||||
const std::vector<std::string>&
|
||||
aCandidateList) {
|
||||
if (aMLine > mIceStreams.size()) {
|
||||
CSFLogError(logTag, "Missing stream for previous m-line %u, this can "
|
||||
"happen if we failed to create a stream earlier.",
|
||||
static_cast<unsigned>(aMLine - 1));
|
||||
return;
|
||||
}
|
||||
|
||||
CSFLogDebug(logTag, "%s: Creating ICE media stream=%u components=%u",
|
||||
mParentHandle.c_str(),
|
||||
static_cast<unsigned>(aMLine),
|
||||
static_cast<unsigned>(aComponentCount));
|
||||
RefPtr<NrIceMediaStream> stream;
|
||||
|
||||
if (mIceStreams.size() == aMLine) {
|
||||
std::ostringstream os;
|
||||
os << mParentName << " level=" << aMLine;
|
||||
stream = mIceCtx->CreateStream(os.str().c_str(), aComponentCount);
|
||||
|
||||
if (!stream) {
|
||||
CSFLogError(logTag, "Failed to create ICE stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
stream->SetLevel(aMLine);
|
||||
stream->SignalReady.connect(this, &PeerConnectionMedia::IceStreamReady_s);
|
||||
stream->SignalCandidate.connect(this,
|
||||
&PeerConnectionMedia::OnCandidateFound_s);
|
||||
|
||||
mIceStreams.push_back(stream);
|
||||
} else {
|
||||
stream = mIceStreams[aMLine];
|
||||
}
|
||||
|
||||
if (aHasAttrs) {
|
||||
std::vector<std::string> attrs;
|
||||
for (auto i = aCandidateList.begin(); i != aCandidateList.end(); ++i) {
|
||||
attrs.push_back("candidate:" + *i);
|
||||
}
|
||||
attrs.push_back("ice-ufrag:" + aUfrag);
|
||||
attrs.push_back("ice-pwd:" + aPassword);
|
||||
|
||||
nsresult rv = stream->ParseAttributes(attrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(logTag, "Couldn't parse ICE attributes, rv=%u",
|
||||
static_cast<unsigned>(rv));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
|
||||
uint32_t hints,
|
||||
uint32_t *stream_id)
|
||||
std::string *stream_id)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
@ -345,14 +564,20 @@ PeerConnectionMedia::AddStream(DOMMediaStream* aMediaStream,
|
||||
}
|
||||
if (aMediaStream == lss->GetMediaStream()) {
|
||||
localSourceStream = lss;
|
||||
*stream_id = u;
|
||||
*stream_id = lss->GetId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!localSourceStream) {
|
||||
localSourceStream = new LocalSourceStreamInfo(aMediaStream, this);
|
||||
std::string id;
|
||||
if (!mUuidGen->Generate(&id)) {
|
||||
CSFLogError(logTag, "Failed to generate UUID for stream");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
localSourceStream = new LocalSourceStreamInfo(aMediaStream, this, id);
|
||||
mLocalSourceStreams.AppendElement(localSourceStream);
|
||||
*stream_id = mLocalSourceStreams.Length() - 1;
|
||||
*stream_id = id;
|
||||
}
|
||||
|
||||
if (hints & DOMMediaStream::HINT_CONTENTS_AUDIO) {
|
||||
@ -465,7 +690,7 @@ PeerConnectionMedia::ShutdownMediaTransport_s()
|
||||
}
|
||||
|
||||
LocalSourceStreamInfo*
|
||||
PeerConnectionMedia::GetLocalStream(int aIndex)
|
||||
PeerConnectionMedia::GetLocalStreamByIndex(int aIndex)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
if(aIndex < 0 || aIndex >= (int) mLocalSourceStreams.Length()) {
|
||||
@ -476,30 +701,57 @@ PeerConnectionMedia::GetLocalStream(int aIndex)
|
||||
return mLocalSourceStreams[aIndex];
|
||||
}
|
||||
|
||||
RemoteSourceStreamInfo*
|
||||
PeerConnectionMedia::GetRemoteStream(int aIndex)
|
||||
LocalSourceStreamInfo*
|
||||
PeerConnectionMedia::GetLocalStreamById(const std::string& id)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
if(aIndex < 0 || aIndex >= (int) mRemoteSourceStreams.Length()) {
|
||||
return nullptr;
|
||||
for (size_t i = 0; i < mLocalSourceStreams.Length(); ++i) {
|
||||
if (id == mLocalSourceStreams[i]->GetId()) {
|
||||
return mLocalSourceStreams[i];
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mRemoteSourceStreams[aIndex]);
|
||||
return mRemoteSourceStreams[aIndex];
|
||||
MOZ_ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
PeerConnectionMedia::SetUsingBundle_m(int level, bool decision)
|
||||
RemoteSourceStreamInfo*
|
||||
PeerConnectionMedia::GetRemoteStreamByIndex(size_t aIndex)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
MOZ_ASSERT(mRemoteSourceStreams.SafeElementAt(aIndex));
|
||||
return mRemoteSourceStreams.SafeElementAt(aIndex);
|
||||
}
|
||||
|
||||
RemoteSourceStreamInfo*
|
||||
PeerConnectionMedia::GetRemoteStreamById(const std::string& id)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
for (size_t i = 0; i < mRemoteSourceStreams.Length(); ++i) {
|
||||
if (mRemoteSourceStreams[i]->SetUsingBundle_m(level, decision)) {
|
||||
// Found the MediaPipeline for |level|
|
||||
if (id == mRemoteSourceStreams[i]->GetId()) {
|
||||
return mRemoteSourceStreams[i];
|
||||
}
|
||||
}
|
||||
|
||||
// This does not have a MOZ_ASSERT like GetLocalStreamById because in the
|
||||
// case of local streams, the stream id and stream info are created
|
||||
// simultaneously, whereas in the remote case the stream id exists first,
|
||||
// meaning we have to be able to check.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
PeerConnectionMedia::SetUsingBundle_m(int aMLine, bool decision)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
for (size_t i = 0; i < mRemoteSourceStreams.Length(); ++i) {
|
||||
if (mRemoteSourceStreams[i]->SetUsingBundle_m(aMLine, decision)) {
|
||||
// Found the MediaPipeline for |aMLine|
|
||||
return true;
|
||||
}
|
||||
}
|
||||
CSFLogWarn(logTag, "Could not locate level %d to set bundle flag to %s",
|
||||
static_cast<int>(level),
|
||||
static_cast<int>(aMLine),
|
||||
decision ? "true" : "false");
|
||||
return false;
|
||||
}
|
||||
@ -524,19 +776,19 @@ UpdateFilterFromRemoteDescription_s(
|
||||
|
||||
bool
|
||||
PeerConnectionMedia::UpdateFilterFromRemoteDescription_m(
|
||||
int level,
|
||||
int aMLine,
|
||||
nsAutoPtr<mozilla::MediaPipelineFilter> filter)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
RefPtr<mozilla::MediaPipeline> receive;
|
||||
for (size_t i = 0; !receive && i < mRemoteSourceStreams.Length(); ++i) {
|
||||
receive = mRemoteSourceStreams[i]->GetPipelineByLevel_m(level);
|
||||
receive = mRemoteSourceStreams[i]->GetPipelineByLevel_m(aMLine);
|
||||
}
|
||||
|
||||
RefPtr<mozilla::MediaPipeline> transmit;
|
||||
for (size_t i = 0; !transmit && i < mLocalSourceStreams.Length(); ++i) {
|
||||
transmit = mLocalSourceStreams[i]->GetPipelineByLevel_m(level);
|
||||
transmit = mLocalSourceStreams[i]->GetPipelineByLevel_m(aMLine);
|
||||
}
|
||||
|
||||
if (receive && transmit) {
|
||||
@ -555,19 +807,15 @@ PeerConnectionMedia::UpdateFilterFromRemoteDescription_m(
|
||||
return true;
|
||||
} else {
|
||||
CSFLogWarn(logTag, "Could not locate level %d to update filter",
|
||||
static_cast<int>(level));
|
||||
static_cast<int>(aMLine));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionMedia::AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo,
|
||||
int *aIndex)
|
||||
PeerConnectionMedia::AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
MOZ_ASSERT(aIndex);
|
||||
|
||||
*aIndex = mRemoteSourceStreams.Length();
|
||||
|
||||
mRemoteSourceStreams.AppendElement(aInfo);
|
||||
|
||||
@ -600,6 +848,31 @@ PeerConnectionMedia::IceGatheringStateChange_s(NrIceCtx* ctx,
|
||||
NrIceCtx::GatheringState state)
|
||||
{
|
||||
ASSERT_ON_THREAD(mSTSThread);
|
||||
|
||||
if (state == NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
|
||||
// Fire off EndOfLocalCandidates for each stream
|
||||
for (size_t i = 0; ; ++i) {
|
||||
RefPtr<NrIceMediaStream> stream(ctx->GetStream(i));
|
||||
if (!stream) {
|
||||
break;
|
||||
}
|
||||
|
||||
NrIceCandidate candidate;
|
||||
nsresult res = stream->GetDefaultCandidate(&candidate);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
EndOfLocalCandidates(candidate.cand_addr.host,
|
||||
candidate.cand_addr.port,
|
||||
i);
|
||||
} else {
|
||||
CSFLogError(logTag, "%s: GetDefaultCandidate failed for level %u, "
|
||||
"res=%u",
|
||||
__FUNCTION__,
|
||||
static_cast<unsigned>(i),
|
||||
static_cast<unsigned>(res));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ShutdownMediaTransport_s has not run yet because it unhooks this function
|
||||
// from its signal, which means that SelfDestruct_m has not been dispatched
|
||||
// yet either, so this PCMedia will still be around when this dispatch reaches
|
||||
@ -650,6 +923,18 @@ PeerConnectionMedia::OnCandidateFound_s(NrIceMediaStream *aStream,
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::EndOfLocalCandidates(const std::string& aDefaultAddr,
|
||||
uint16_t aDefaultPort,
|
||||
uint16_t aMLine) {
|
||||
// We will still be around because we have not started teardown yet
|
||||
GetMainThread()->Dispatch(
|
||||
WrapRunnable(this,
|
||||
&PeerConnectionMedia::EndOfLocalCandidates_m,
|
||||
aDefaultAddr, aDefaultPort, aMLine),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::IceGatheringStateChange_m(NrIceCtx* ctx,
|
||||
NrIceCtx::GatheringState state)
|
||||
@ -667,7 +952,7 @@ PeerConnectionMedia::IceConnectionStateChange_m(NrIceCtx* ctx,
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::IceStreamReady(NrIceMediaStream *aStream)
|
||||
PeerConnectionMedia::IceStreamReady_s(NrIceMediaStream *aStream)
|
||||
{
|
||||
MOZ_ASSERT(aStream);
|
||||
|
||||
@ -676,13 +961,18 @@ PeerConnectionMedia::IceStreamReady(NrIceMediaStream *aStream)
|
||||
|
||||
void
|
||||
PeerConnectionMedia::OnCandidateFound_m(const std::string &candidate,
|
||||
uint16_t level)
|
||||
uint16_t aMLine)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
SignalCandidate(candidate, level);
|
||||
SignalCandidate(candidate, aMLine);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PeerConnectionMedia::EndOfLocalCandidates_m(const std::string& aDefaultAddr,
|
||||
uint16_t aDefaultPort,
|
||||
uint16_t aMLine) {
|
||||
SignalEndOfLocalCandidates(aDefaultAddr, aDefaultPort, aMLine);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::DtlsConnected_s(TransportLayer *dtlsLayer,
|
||||
@ -841,29 +1131,29 @@ RemoteSourceStreamInfo::AnyCodecHasPluginID(uint64_t aPluginID)
|
||||
|
||||
void
|
||||
LocalSourceStreamInfo::StorePipeline(
|
||||
int aTrack, mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline)
|
||||
int aMLine, mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline)
|
||||
{
|
||||
MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end());
|
||||
if (mPipelines.find(aTrack) != mPipelines.end()) {
|
||||
MOZ_ASSERT(mPipelines.find(aMLine) == mPipelines.end());
|
||||
if (mPipelines.find(aMLine) != mPipelines.end()) {
|
||||
CSFLogError(logTag, "%s: Storing duplicate track", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
//TODO: Revisit once we start supporting multiple streams or multiple tracks
|
||||
// of same type bug 1056650
|
||||
mPipelines[aTrack] = aPipeline;
|
||||
mPipelines[aMLine] = aPipeline;
|
||||
}
|
||||
|
||||
void
|
||||
RemoteSourceStreamInfo::StorePipeline(
|
||||
int aTrack, bool aIsVideo,
|
||||
int aMLine, bool aIsVideo,
|
||||
mozilla::RefPtr<mozilla::MediaPipelineReceive> aPipeline)
|
||||
{
|
||||
MOZ_ASSERT(mPipelines.find(aTrack) == mPipelines.end());
|
||||
if (mPipelines.find(aTrack) != mPipelines.end()) {
|
||||
CSFLogError(logTag, "%s: Request to store duplicate track %d", __FUNCTION__, aTrack);
|
||||
MOZ_ASSERT(mPipelines.find(aMLine) == mPipelines.end());
|
||||
if (mPipelines.find(aMLine) != mPipelines.end()) {
|
||||
CSFLogError(logTag, "%s: Request to store duplicate track %d", __FUNCTION__, aMLine);
|
||||
return;
|
||||
}
|
||||
CSFLogDebug(logTag, "%s track %d %s = %p", __FUNCTION__, aTrack, aIsVideo ? "video" : "audio",
|
||||
CSFLogDebug(logTag, "%s track %d %s = %p", __FUNCTION__, aMLine, aIsVideo ? "video" : "audio",
|
||||
aPipeline.get());
|
||||
// See if we have both audio and video here, and if so cross the streams and sync them
|
||||
// XXX Needs to be adjusted when we support multiple streams of the same type bug 1056650
|
||||
@ -880,17 +1170,17 @@ RemoteSourceStreamInfo::StorePipeline(
|
||||
mPipelines[it->first]->Conduit());
|
||||
video_conduit->SyncTo(audio_conduit);
|
||||
CSFLogDebug(logTag, "Syncing %p to %p, %d to %d", video_conduit, audio_conduit,
|
||||
aTrack, it->first);
|
||||
aMLine, it->first);
|
||||
}
|
||||
}
|
||||
//TODO: Revisit once we start supporting multiple streams or multiple tracks
|
||||
// of same type bug 1056650
|
||||
mPipelines[aTrack] = aPipeline;
|
||||
mPipelines[aMLine] = aPipeline;
|
||||
//TODO: move to attribute on Pipeline
|
||||
mTypes[aTrack] = aIsVideo;
|
||||
mTypes[aMLine] = aIsVideo;
|
||||
}
|
||||
|
||||
RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int level) {
|
||||
RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int aMLine) {
|
||||
ASSERT_ON_THREAD(mParent->GetMainThread());
|
||||
|
||||
// Refuse to hand out references if we're tearing down.
|
||||
@ -900,7 +1190,7 @@ RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int level) {
|
||||
// standing)
|
||||
if (mMediaStream) {
|
||||
for (auto p = mPipelines.begin(); p != mPipelines.end(); ++p) {
|
||||
if (p->second->level() == level) {
|
||||
if (p->second->level() == aMLine) {
|
||||
return p->second;
|
||||
}
|
||||
}
|
||||
@ -909,11 +1199,11 @@ RefPtr<MediaPipeline> SourceStreamInfo::GetPipelineByLevel_m(int level) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool RemoteSourceStreamInfo::SetUsingBundle_m(int aLevel, bool decision) {
|
||||
bool RemoteSourceStreamInfo::SetUsingBundle_m(int aMLine, bool decision) {
|
||||
ASSERT_ON_THREAD(mParent->GetMainThread());
|
||||
|
||||
// Avoid adding and dropping an extra ref
|
||||
MediaPipeline *pipeline = GetPipelineByLevel_m(aLevel);
|
||||
MediaPipeline *pipeline = GetPipelineByLevel_m(aMLine);
|
||||
|
||||
if (pipeline) {
|
||||
RUN_ON_THREAD(mParent->GetSTSThread(),
|
||||
@ -928,4 +1218,4 @@ bool RemoteSourceStreamInfo::SetUsingBundle_m(int aLevel, bool decision) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace sipcc
|
||||
} // namespace mozilla
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "MediaSegment.h"
|
||||
#endif
|
||||
|
||||
#include "signaling/src/jsep/JsepSession.h"
|
||||
#include "AudioSegment.h"
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
@ -36,6 +37,7 @@ class nsIPrincipal;
|
||||
namespace mozilla {
|
||||
class DataChannel;
|
||||
class PeerIdentity;
|
||||
class MediaPipelineFactory;
|
||||
namespace dom {
|
||||
struct RTCInboundRTPStreamStats;
|
||||
struct RTCOutboundRTPStreamStats;
|
||||
@ -47,16 +49,15 @@ struct RTCOutboundRTPStreamStats;
|
||||
#include "nricemediastream.h"
|
||||
#include "MediaPipeline.h"
|
||||
|
||||
namespace sipcc {
|
||||
namespace mozilla {
|
||||
|
||||
class PeerConnectionImpl;
|
||||
class PeerConnectionMedia;
|
||||
class PCUuidGenerator;
|
||||
|
||||
/* Temporary for providing audio data */
|
||||
class Fake_AudioGenerator {
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
explicit Fake_AudioGenerator(DOMMediaStream* aStream) : mStream(aStream), mCount(0) {
|
||||
mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
MOZ_ASSERT(mTimer);
|
||||
@ -96,7 +97,6 @@ class Fake_AudioGenerator {
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
class Fake_VideoGenerator {
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
typedef mozilla::gfx::IntSize IntSize;
|
||||
|
||||
explicit Fake_VideoGenerator(DOMMediaStream* aStream) {
|
||||
@ -174,19 +174,21 @@ class Fake_VideoGenerator {
|
||||
|
||||
class SourceStreamInfo {
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
SourceStreamInfo(DOMMediaStream* aMediaStream,
|
||||
PeerConnectionMedia *aParent)
|
||||
PeerConnectionMedia *aParent,
|
||||
const std::string& aId)
|
||||
: mMediaStream(aMediaStream),
|
||||
mParent(aParent) {
|
||||
mParent(aParent),
|
||||
mId(aId) {
|
||||
MOZ_ASSERT(mMediaStream);
|
||||
}
|
||||
|
||||
SourceStreamInfo(already_AddRefed<DOMMediaStream>& aMediaStream,
|
||||
PeerConnectionMedia *aParent)
|
||||
PeerConnectionMedia *aParent,
|
||||
const std::string& aId)
|
||||
: mMediaStream(aMediaStream),
|
||||
mParent(aParent) {
|
||||
mParent(aParent),
|
||||
mId(aId) {
|
||||
MOZ_ASSERT(mMediaStream);
|
||||
}
|
||||
|
||||
@ -198,12 +200,14 @@ public:
|
||||
// It allows visibility into the pipelines and flows.
|
||||
const std::map<mozilla::TrackID, mozilla::RefPtr<mozilla::MediaPipeline>>&
|
||||
GetPipelines() const { return mPipelines; }
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> GetPipelineByLevel_m(int level);
|
||||
mozilla::RefPtr<mozilla::MediaPipeline> GetPipelineByLevel_m(int aMLine);
|
||||
const std::string& GetId() const { return mId; }
|
||||
|
||||
protected:
|
||||
std::map<mozilla::TrackID, mozilla::RefPtr<mozilla::MediaPipeline>> mPipelines;
|
||||
nsRefPtr<DOMMediaStream> mMediaStream;
|
||||
PeerConnectionMedia *mParent;
|
||||
const std::string mId;
|
||||
};
|
||||
|
||||
// TODO(ekr@rtfm.com): Refactor {Local,Remote}SourceStreamInfo
|
||||
@ -213,28 +217,28 @@ class LocalSourceStreamInfo : public SourceStreamInfo {
|
||||
mMediaStream = nullptr;
|
||||
}
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
LocalSourceStreamInfo(DOMMediaStream *aMediaStream,
|
||||
PeerConnectionMedia *aParent)
|
||||
: SourceStreamInfo(aMediaStream, aParent) {}
|
||||
PeerConnectionMedia *aParent,
|
||||
const std::string& aId)
|
||||
: SourceStreamInfo(aMediaStream, aParent, aId) {}
|
||||
|
||||
// Returns the mPipelines index for the track or -1.
|
||||
#if 0
|
||||
int HasTrack(DOMMediaStream* aStream, mozilla::TrackID aTrack);
|
||||
int HasTrack(DOMMediaStream* aStream, mozilla::TrackID aMLine);
|
||||
#endif
|
||||
int HasTrackType(DOMMediaStream* aStream, bool aIsVideo);
|
||||
// XXX NOTE: does not change mMediaStream, even if it replaces the last track
|
||||
// in a LocalSourceStreamInfo. Revise when we have support for multiple tracks
|
||||
// of a type.
|
||||
// Note aIndex != aOldTrack! It's the result of HasTrackType()
|
||||
nsresult ReplaceTrack(int aIndex, DOMMediaStream* aNewStream, mozilla::TrackID aNewTrack);
|
||||
// Note aMLine != aOldTrack! It's the result of HasTrackType()
|
||||
nsresult ReplaceTrack(int aMLine, DOMMediaStream* aNewStream, mozilla::TrackID aNewTrack);
|
||||
|
||||
void StorePipeline(int aTrack,
|
||||
void StorePipeline(int aMLine,
|
||||
mozilla::RefPtr<mozilla::MediaPipelineTransmit> aPipeline);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal, const PeerIdentity* aSinkIdentity);
|
||||
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal,
|
||||
const mozilla::PeerIdentity* aSinkIdentity);
|
||||
#endif
|
||||
|
||||
void ExpectAudio(const mozilla::TrackID);
|
||||
@ -257,17 +261,17 @@ private:
|
||||
class RemoteSourceStreamInfo : public SourceStreamInfo {
|
||||
~RemoteSourceStreamInfo() {}
|
||||
public:
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
RemoteSourceStreamInfo(already_AddRefed<DOMMediaStream> aMediaStream,
|
||||
PeerConnectionMedia *aParent)
|
||||
: SourceStreamInfo(aMediaStream, aParent),
|
||||
mTrackTypeHints(0) {}
|
||||
PeerConnectionMedia *aParent,
|
||||
const std::string& aId)
|
||||
: SourceStreamInfo(aMediaStream, aParent, aId),
|
||||
mTrackTypeHints(0) {
|
||||
}
|
||||
|
||||
void StorePipeline(int aTrack, bool aIsVideo,
|
||||
void StorePipeline(int aMLine, bool aIsVideo,
|
||||
mozilla::RefPtr<mozilla::MediaPipelineReceive> aPipeline);
|
||||
|
||||
bool SetUsingBundle_m(int aLevel, bool decision);
|
||||
bool SetUsingBundle_m(int aMLine, bool decision);
|
||||
|
||||
void DetachTransport_s();
|
||||
void DetachMedia_m();
|
||||
@ -292,6 +296,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
public:
|
||||
explicit PeerConnectionMedia(PeerConnectionImpl *parent);
|
||||
|
||||
PeerConnectionImpl* GetPC() { return mParent; }
|
||||
nsresult Init(const std::vector<mozilla::NrIceStunServer>& stun_servers,
|
||||
const std::vector<mozilla::NrIceTurnServer>& turn_servers);
|
||||
// WARNING: This destroys the object!
|
||||
@ -315,9 +320,22 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
return mIceStreams.size();
|
||||
}
|
||||
|
||||
// Create and modify transports in response to negotiation events.
|
||||
void UpdateTransports(const mozilla::JsepSession& session);
|
||||
|
||||
// Start ICE checks.
|
||||
void StartIceChecks(const mozilla::JsepSession& session);
|
||||
|
||||
// Process a trickle ICE candidate.
|
||||
void AddIceCandidate(const std::string& candidate, const std::string& mid,
|
||||
uint32_t aMLine);
|
||||
|
||||
// Handle complete media pipelines.
|
||||
nsresult UpdateMediaPipelines(const mozilla::JsepSession& session);
|
||||
|
||||
// Add a stream (main thread only)
|
||||
nsresult AddStream(DOMMediaStream* aMediaStream, uint32_t hints,
|
||||
uint32_t *stream_id);
|
||||
std::string* stream_id);
|
||||
|
||||
// Remove a stream (main thread only)
|
||||
nsresult RemoveStream(DOMMediaStream* aMediaStream,
|
||||
@ -329,29 +347,33 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
{
|
||||
return mLocalSourceStreams.Length();
|
||||
}
|
||||
LocalSourceStreamInfo* GetLocalStream(int index);
|
||||
LocalSourceStreamInfo* GetLocalStreamByIndex(int index);
|
||||
LocalSourceStreamInfo* GetLocalStreamById(const std::string& id);
|
||||
|
||||
// Get a specific remote stream
|
||||
uint32_t RemoteStreamsLength()
|
||||
{
|
||||
return mRemoteSourceStreams.Length();
|
||||
}
|
||||
RemoteSourceStreamInfo* GetRemoteStream(int index);
|
||||
|
||||
bool SetUsingBundle_m(int level, bool decision);
|
||||
RemoteSourceStreamInfo* GetRemoteStreamByIndex(size_t index);
|
||||
RemoteSourceStreamInfo* GetRemoteStreamById(const std::string& id);
|
||||
|
||||
bool SetUsingBundle_m(int aMLine, bool decision);
|
||||
bool UpdateFilterFromRemoteDescription_m(
|
||||
int level,
|
||||
int aMLine,
|
||||
nsAutoPtr<mozilla::MediaPipelineFilter> filter);
|
||||
|
||||
// Add a remote stream. Returns the index in index
|
||||
nsresult AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo, int *aIndex);
|
||||
// Add a remote stream.
|
||||
nsresult AddRemoteStream(nsRefPtr<RemoteSourceStreamInfo> aInfo);
|
||||
nsresult AddRemoteStreamHint(int aIndex, bool aIsVideo);
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// In cases where the peer isn't yet identified, we disable the pipeline (not
|
||||
// the stream, that would potentially affect others), so that it sends
|
||||
// black/silence. Once the peer is identified, re-enable those streams.
|
||||
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal, const PeerIdentity* aSinkIdentity);
|
||||
void UpdateSinkIdentity_m(nsIPrincipal* aPrincipal,
|
||||
const mozilla::PeerIdentity* aSinkIdentity);
|
||||
// this determines if any stream is peerIdentity constrained
|
||||
bool AnyLocalStreamHasPeerIdentity() const;
|
||||
// When we finally learn who is on the other end, we need to change the ownership
|
||||
@ -408,7 +430,11 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
SignalIceGatheringStateChange;
|
||||
sigslot::signal2<mozilla::NrIceCtx*, mozilla::NrIceCtx::ConnectionState>
|
||||
SignalIceConnectionStateChange;
|
||||
// This passes a candidate:... attribute and level
|
||||
sigslot::signal2<const std::string&, uint16_t> SignalCandidate;
|
||||
// This passes address, port, level of the default candidate.
|
||||
sigslot::signal3<const std::string&, uint16_t, uint16_t>
|
||||
SignalEndOfLocalCandidates;
|
||||
|
||||
private:
|
||||
// Shutdown media transport. Must be called on STS thread.
|
||||
@ -418,26 +444,50 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
// thread.
|
||||
void SelfDestruct_m();
|
||||
|
||||
// Manage ICE transports.
|
||||
void UpdateIceMediaStream_s(size_t aMLine, size_t aComponentCount,
|
||||
bool aHasAttrs,
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPassword,
|
||||
const std::vector<std::string>& aCandidateList);
|
||||
void EnsureIceGathering_s();
|
||||
void StartIceChecks_s(bool aIsControlling,
|
||||
bool aIsIceLite,
|
||||
const std::vector<std::string>& aIceOptionsList,
|
||||
const std::vector<size_t>& aComponentCountByLevel);
|
||||
|
||||
// Process a trickle ICE candidate.
|
||||
void AddIceCandidate_s(const std::string& aCandidate, const std::string& aMid,
|
||||
uint32_t aMLine);
|
||||
|
||||
|
||||
// ICE events
|
||||
void IceGatheringStateChange_s(mozilla::NrIceCtx* ctx,
|
||||
mozilla::NrIceCtx::GatheringState state);
|
||||
void IceConnectionStateChange_s(mozilla::NrIceCtx* ctx,
|
||||
mozilla::NrIceCtx::ConnectionState state);
|
||||
void IceStreamReady(mozilla::NrIceMediaStream *aStream);
|
||||
void IceStreamReady_s(mozilla::NrIceMediaStream *aStream);
|
||||
void OnCandidateFound_s(mozilla::NrIceMediaStream *aStream,
|
||||
const std::string &candidate);
|
||||
void EndOfLocalCandidates(const std::string& aDefaultAddr,
|
||||
uint16_t aDefaultPort,
|
||||
uint16_t aMLine);
|
||||
|
||||
void IceGatheringStateChange_m(mozilla::NrIceCtx* ctx,
|
||||
mozilla::NrIceCtx::GatheringState state);
|
||||
void IceConnectionStateChange_m(mozilla::NrIceCtx* ctx,
|
||||
mozilla::NrIceCtx::ConnectionState state);
|
||||
void OnCandidateFound_m(const std::string &candidate, uint16_t level);
|
||||
void OnCandidateFound_m(const std::string &candidate, uint16_t aMLine);
|
||||
void EndOfLocalCandidates_m(const std::string& aDefaultAddr,
|
||||
uint16_t aDefaultPort,
|
||||
uint16_t aMLine);
|
||||
|
||||
|
||||
// The parent PC
|
||||
PeerConnectionImpl *mParent;
|
||||
// and a loose handle on it for event driven stuff
|
||||
std::string mParentHandle;
|
||||
std::string mParentName;
|
||||
|
||||
// A list of streams returned from GetUserMedia
|
||||
// This is only accessed on the main thread (with one special exception)
|
||||
@ -464,6 +514,9 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
// flows)
|
||||
std::map<int, mozilla::RefPtr<mozilla::MediaSessionConduit> > mConduits;
|
||||
|
||||
// UUID Generator
|
||||
mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
|
||||
|
||||
// The main thread.
|
||||
nsCOMPtr<nsIThread> mMainThread;
|
||||
|
||||
@ -473,5 +526,5 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
|
||||
};
|
||||
|
||||
} // namespace sipcc
|
||||
} // namespace mozilla
|
||||
#endif
|
||||
|
@ -25,18 +25,15 @@
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "webrtc/system_wrappers/interface/trace.h"
|
||||
|
||||
using sipcc::PeerConnectionImpl;
|
||||
using sipcc::PeerConnectionCtx;
|
||||
using sipcc::RTCStatsQuery;
|
||||
|
||||
static const char* logTag = "WebrtcGlobalInformation";
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
|
||||
typedef Vector<nsAutoPtr<RTCStatsQuery>> RTCStatsQueries;
|
||||
|
||||
static sipcc::PeerConnectionCtx* GetPeerConnectionCtx()
|
||||
static PeerConnectionCtx* GetPeerConnectionCtx()
|
||||
{
|
||||
if(PeerConnectionCtx::isActive()) {
|
||||
MOZ_ASSERT(PeerConnectionCtx::GetInstance());
|
||||
@ -500,7 +497,7 @@ static void GetStatsForLongTermStorage_s(
|
||||
}
|
||||
|
||||
void WebrtcGlobalInformation::StoreLongTermICEStatistics(
|
||||
sipcc::PeerConnectionImpl& aPc) {
|
||||
PeerConnectionImpl& aPc) {
|
||||
Telemetry::Accumulate(Telemetry::WEBRTC_ICE_FINAL_CONNECTION_STATE,
|
||||
static_cast<uint32_t>(aPc.IceConnectionState()));
|
||||
|
||||
|
@ -8,11 +8,8 @@
|
||||
#include "nsString.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h" // for Optional
|
||||
|
||||
namespace sipcc {
|
||||
class PeerConnectionImpl;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
class PeerConnectionImpl;
|
||||
class ErrorResult;
|
||||
|
||||
namespace dom {
|
||||
@ -39,7 +36,7 @@ public:
|
||||
static void SetAecDebug(const GlobalObject& aGlobal, bool aEnable);
|
||||
static bool AecDebug(const GlobalObject& aGlobal);
|
||||
|
||||
static void StoreLongTermICEStatistics(sipcc::PeerConnectionImpl& aPc);
|
||||
static void StoreLongTermICEStatistics(PeerConnectionImpl& aPc);
|
||||
|
||||
private:
|
||||
WebrtcGlobalInformation() MOZ_DELETE;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "PeerConnectionImpl.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
namespace sipcc {
|
||||
namespace mozilla {
|
||||
class PeerConnectionImpl;
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ public:
|
||||
stateError
|
||||
};
|
||||
|
||||
AFakePCObserver(sipcc::PeerConnectionImpl *peerConnection,
|
||||
AFakePCObserver(mozilla::PeerConnectionImpl *peerConnection,
|
||||
const std::string &aName) :
|
||||
state(stateNoResponse), addIceSuccessCount(0),
|
||||
onAddStreamCalled(false),
|
||||
@ -61,7 +61,7 @@ public:
|
||||
|
||||
ResponseState state;
|
||||
std::string lastString;
|
||||
sipcc::PeerConnectionImpl::Error lastStatusCode;
|
||||
mozilla::PeerConnectionImpl::Error lastStatusCode;
|
||||
mozilla::dom::PCObserverStateType lastStateType;
|
||||
int addIceSuccessCount;
|
||||
bool onAddStreamCalled;
|
||||
@ -90,7 +90,7 @@ public:
|
||||
virtual NS_IMETHODIMP OnIceCandidate(uint16_t level, const char *mid,
|
||||
const char *candidate, ER&) = 0;
|
||||
protected:
|
||||
sipcc::PeerConnectionImpl *pc;
|
||||
mozilla::PeerConnectionImpl *pc;
|
||||
std::vector<mozilla::DOMMediaStream *> streams;
|
||||
};
|
||||
}
|
||||
|
@ -629,8 +629,8 @@ class TransportConduitTest : public ::testing::Test
|
||||
ASSERT_EQ(mozilla::kMediaConduitNoError, err);
|
||||
|
||||
//configure send and recv codecs on theconduit
|
||||
mozilla::VideoCodecConfig cinst1(120, "VP8", 0);
|
||||
mozilla::VideoCodecConfig cinst2(124, "I420", 0);
|
||||
mozilla::VideoCodecConfig cinst1(120, "VP8");
|
||||
mozilla::VideoCodecConfig cinst2(124, "I420");
|
||||
|
||||
|
||||
std::vector<mozilla::VideoCodecConfig* > rcvCodecList;
|
||||
@ -711,8 +711,8 @@ class TransportConduitTest : public ::testing::Test
|
||||
cerr << " 1. Same Codec (VP8) Repeated Twice " << endl;
|
||||
cerr << " *************************************************" << endl;
|
||||
|
||||
mozilla::VideoCodecConfig cinst1(120, "VP8", 0);
|
||||
mozilla::VideoCodecConfig cinst2(120, "VP8", 0);
|
||||
mozilla::VideoCodecConfig cinst1(120, "VP8");
|
||||
mozilla::VideoCodecConfig cinst2(120, "VP8");
|
||||
rcvCodecList.push_back(&cinst1);
|
||||
rcvCodecList.push_back(&cinst2);
|
||||
err = videoSession->ConfigureRecvMediaCodecs(rcvCodecList);
|
||||
@ -728,8 +728,8 @@ class TransportConduitTest : public ::testing::Test
|
||||
cerr << " Setting payload 1 with name: I4201234tttttthhhyyyy89087987y76t567r7756765rr6u6676" << endl;
|
||||
cerr << " Setting payload 2 with name of zero length" << endl;
|
||||
|
||||
mozilla::VideoCodecConfig cinst3(124, "I4201234tttttthhhyyyy89087987y76t567r7756765rr6u6676", 0);
|
||||
mozilla::VideoCodecConfig cinst4(124, "", 0);
|
||||
mozilla::VideoCodecConfig cinst3(124, "I4201234tttttthhhyyyy89087987y76t567r7756765rr6u6676");
|
||||
mozilla::VideoCodecConfig cinst4(124, "");
|
||||
|
||||
rcvCodecList.push_back(&cinst3);
|
||||
rcvCodecList.push_back(&cinst4);
|
||||
@ -812,7 +812,7 @@ class TransportConduitTest : public ::testing::Test
|
||||
ASSERT_NE(mVideoSession, (void*)nullptr);
|
||||
|
||||
// Configure send codecs on the conduit.
|
||||
mozilla::VideoCodecConfig cinst1(120, "VP8", 0, max_fs);
|
||||
mozilla::VideoCodecConfig cinst1(120, "VP8", max_fs);
|
||||
|
||||
err = mVideoSession->ConfigureSendMediaCodec(&cinst1);
|
||||
ASSERT_EQ(mozilla::kMediaConduitNoError, err);
|
||||
@ -947,7 +947,7 @@ class TransportConduitTest : public ::testing::Test
|
||||
void SetGmpCodecs() {
|
||||
mExternalEncoder = mozilla::GmpVideoCodec::CreateEncoder();
|
||||
mExternalDecoder = mozilla::GmpVideoCodec::CreateDecoder();
|
||||
mozilla::VideoCodecConfig config(124, "H264", 0);
|
||||
mozilla::VideoCodecConfig config(124, "H264");
|
||||
mVideoSession->SetExternalSendCodec(&config, mExternalEncoder);
|
||||
mVideoSession2->SetExternalRecvCodec(&config, mExternalDecoder);
|
||||
}
|
||||
|
@ -271,7 +271,6 @@ class TestAgentSend : public TestAgent {
|
||||
test_utils->sts_target(),
|
||||
audio_,
|
||||
1,
|
||||
1,
|
||||
false,
|
||||
audio_conduit_,
|
||||
rtp,
|
||||
|
@ -56,7 +56,7 @@ static bool SetupGlobalThread() {
|
||||
return false;
|
||||
|
||||
gThread = thread;
|
||||
sipcc::PeerConnectionCtx::InitializeGlobal(gThread,
|
||||
PeerConnectionCtx::InitializeGlobal(gThread,
|
||||
test_utils->sts_target());
|
||||
}
|
||||
return true;
|
||||
@ -2444,7 +2444,7 @@ int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
int result = RUN_ALL_TESTS();
|
||||
|
||||
sipcc::PeerConnectionCtx::Destroy();
|
||||
PeerConnectionCtx::Destroy();
|
||||
delete test_utils;
|
||||
|
||||
return result;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -335,8 +335,8 @@ pref("media.navigator.video.default_width",0); // adaptive default
|
||||
pref("media.navigator.video.default_height",0); // adaptive default
|
||||
pref("media.peerconnection.enabled", true);
|
||||
pref("media.peerconnection.video.enabled", true);
|
||||
pref("media.navigator.video.max_fs", 0); // unrestricted
|
||||
pref("media.navigator.video.max_fr", 0); // unrestricted
|
||||
pref("media.navigator.video.max_fs", 12288); // Enough for 2048x1536
|
||||
pref("media.navigator.video.max_fr", 60);
|
||||
pref("media.navigator.video.h264.level", 31); // 0x42E01f - level 3.1
|
||||
pref("media.navigator.video.h264.max_br", 0);
|
||||
pref("media.navigator.video.h264.max_mbps", 0);
|
||||
@ -359,6 +359,7 @@ pref("media.peerconnection.use_document_iceservers", true);
|
||||
// Do not enable identity before fixing origin spoofing: see Bug 968335
|
||||
pref("media.peerconnection.identity.enabled", false);
|
||||
pref("media.peerconnection.identity.timeout", 10000);
|
||||
pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments.
|
||||
// These values (aec, agc, and noice) are from media/webrtc/trunk/webrtc/common_types.h
|
||||
// kXxxUnchanged = 0, kXxxDefault = 1, and higher values are specific to each
|
||||
// setting (for Xxx = Ec, Agc, or Ns). Defaults are all set to kXxxDefault here.
|
||||
|
@ -25,7 +25,7 @@ class DeviceRunner(BaseRunner):
|
||||
'MOZ_CRASHREPORTER_NO_REPORT': '1',
|
||||
'MOZ_CRASHREPORTER_SHUTDOWN': '1',
|
||||
'MOZ_HIDE_RESULTS_TABLE': '1',
|
||||
'NSPR_LOG_MODULES': 'signaling:5,mtransport:5,datachannel:5',
|
||||
'NSPR_LOG_MODULES': 'signaling:5,mtransport:5,datachannel:5,jsep:5,MediaPipelineFactory:5',
|
||||
'R_LOG_LEVEL': '6',
|
||||
'R_LOG_DESTINATION': 'stderr',
|
||||
'R_LOG_VERBOSE': '1',
|
||||
|
Loading…
Reference in New Issue
Block a user