Bug 792175 - Move PeerConnection operations onto main thread. r=jesup,derf,ehugg

This commit is contained in:
EKR 2012-09-26 10:14:23 -07:00
parent 004403a545
commit fe254a31df
13 changed files with 1691 additions and 477 deletions

View File

@ -107,7 +107,7 @@ nsresult NrIceMediaStream::ParseAttributes(std::vector<std::string>&
for (size_t i=0; i<attributes.size(); ++i) {
attributes_in.push_back(const_cast<char *>(attributes[i].c_str()));
}
// Still need to call nr_ice_ctx_parse_stream_attributes.
int r = nr_ice_peer_ctx_parse_stream_attributes(ctx_->peer(),
stream_,
@ -127,7 +127,8 @@ nsresult NrIceMediaStream::ParseAttributes(std::vector<std::string>&
nsresult NrIceMediaStream::ParseTrickleCandidate(const std::string& candidate) {
int r;
MOZ_MTLOG(PR_LOG_DEBUG, "NrIceCtx(" << ctx_->name() << "): parsing trickle candidate " << candidate);
MOZ_MTLOG(PR_LOG_DEBUG, "NrIceCtx(" << ctx_->name() << ")/STREAM(" <<
name() << ") : parsing trickle candidate " << candidate);
r = nr_ice_peer_ctx_parse_trickle_candidate(ctx_->peer(),
stream_,

View File

@ -1,7 +1,7 @@
# 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/.
MAX_ARGS = 10
MAX_ARGS = 15
boilerplate = "/* This Source Code Form is subject to the terms of the Mozilla Public\n\
* License, v. 2.0. If a copy of the MPL was not distributed with this\n\

View File

@ -903,6 +903,606 @@ template<typename C, typename M, typename A0, typename A1, typename A2, typename
// 10 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> class runnable_args_nm_10 : public runnable_args_base {
public:
runnable_args_nm_10(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9) {}
NS_IMETHOD Run() {
m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
return NS_OK;
}
private:
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
};
// 10 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R> class runnable_args_nm_10_ret : public runnable_args_base {
public:
runnable_args_nm_10_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R *r) :
m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9) {}
NS_IMETHOD Run() {
*r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
return NS_OK;
}
private:
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
};
// 10 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9> class runnable_args_m_10 : public runnable_args_base {
public:
runnable_args_m_10(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) :
o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9) {}
NS_IMETHOD Run() {
((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
return NS_OK;
}
private:
C o_;
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
};
// 10 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R> class runnable_args_m_10_ret : public runnable_args_base {
public:
runnable_args_m_10_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R *r) :
o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9) {}
NS_IMETHOD Run() {
*r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_);
return NS_OK;
}
private:
C o_;
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
};
// 11 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> class runnable_args_nm_11 : public runnable_args_base {
public:
runnable_args_nm_11(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10) {}
NS_IMETHOD Run() {
m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
return NS_OK;
}
private:
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
};
// 11 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R> class runnable_args_nm_11_ret : public runnable_args_base {
public:
runnable_args_nm_11_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R *r) :
m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10) {}
NS_IMETHOD Run() {
*r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
return NS_OK;
}
private:
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
};
// 11 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10> class runnable_args_m_11 : public runnable_args_base {
public:
runnable_args_m_11(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) :
o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10) {}
NS_IMETHOD Run() {
((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
return NS_OK;
}
private:
C o_;
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
};
// 11 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R> class runnable_args_m_11_ret : public runnable_args_base {
public:
runnable_args_m_11_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R *r) :
o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10) {}
NS_IMETHOD Run() {
*r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_);
return NS_OK;
}
private:
C o_;
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
};
// 12 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11> class runnable_args_nm_12 : public runnable_args_base {
public:
runnable_args_nm_12(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) :
m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11) {}
NS_IMETHOD Run() {
m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
return NS_OK;
}
private:
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
};
// 12 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R> class runnable_args_nm_12_ret : public runnable_args_base {
public:
runnable_args_nm_12_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R *r) :
m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11) {}
NS_IMETHOD Run() {
*r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
return NS_OK;
}
private:
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
};
// 12 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11> class runnable_args_m_12 : public runnable_args_base {
public:
runnable_args_m_12(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) :
o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11) {}
NS_IMETHOD Run() {
((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
return NS_OK;
}
private:
C o_;
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
};
// 12 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R> class runnable_args_m_12_ret : public runnable_args_base {
public:
runnable_args_m_12_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R *r) :
o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11) {}
NS_IMETHOD Run() {
*r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_);
return NS_OK;
}
private:
C o_;
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
};
// 13 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12> class runnable_args_nm_13 : public runnable_args_base {
public:
runnable_args_nm_13(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) :
m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12) {}
NS_IMETHOD Run() {
m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
return NS_OK;
}
private:
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
A12 a12_;
};
// 13 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R> class runnable_args_nm_13_ret : public runnable_args_base {
public:
runnable_args_nm_13_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R *r) :
m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12) {}
NS_IMETHOD Run() {
*r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
return NS_OK;
}
private:
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
A12 a12_;
};
// 13 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12> class runnable_args_m_13 : public runnable_args_base {
public:
runnable_args_m_13(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) :
o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12) {}
NS_IMETHOD Run() {
((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
return NS_OK;
}
private:
C o_;
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
A12 a12_;
};
// 13 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R> class runnable_args_m_13_ret : public runnable_args_base {
public:
runnable_args_m_13_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R *r) :
o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12) {}
NS_IMETHOD Run() {
*r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_);
return NS_OK;
}
private:
C o_;
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
A12 a12_;
};
// 14 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13> class runnable_args_nm_14 : public runnable_args_base {
public:
runnable_args_nm_14(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) :
m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13) {}
NS_IMETHOD Run() {
m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
return NS_OK;
}
private:
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
A12 a12_;
A13 a13_;
};
// 14 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R> class runnable_args_nm_14_ret : public runnable_args_base {
public:
runnable_args_nm_14_ret(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R *r) :
m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13) {}
NS_IMETHOD Run() {
*r_ = m_(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
return NS_OK;
}
private:
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
A12 a12_;
A13 a13_;
};
// 14 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13> class runnable_args_m_14 : public runnable_args_base {
public:
runnable_args_m_14(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) :
o_(o), m_(m), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13) {}
NS_IMETHOD Run() {
((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
return NS_OK;
}
private:
C o_;
M m_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
A12 a12_;
A13 a13_;
};
// 14 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R> class runnable_args_m_14_ret : public runnable_args_base {
public:
runnable_args_m_14_ret(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R *r) :
o_(o), m_(m), r_(r), a0_(a0), a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9), a10_(a10), a11_(a11), a12_(a12), a13_(a13) {}
NS_IMETHOD Run() {
*r_ = ((*o_).*m_)(a0_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_, a10_, a11_, a12_, a13_);
return NS_OK;
}
private:
C o_;
M m_;
R* r_;
A0 a0_;
A1 a1_;
A2 a2_;
A3 a3_;
A4 a4_;
A5 a5_;
A6 a6_;
A7 a7_;
A8 a8_;
A9 a9_;
A10 a10_;
A11 a11_;
A12 a12_;
A13 a13_;
};
@ -1186,3 +1786,143 @@ runnable_args_m_9_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, R>* WrapRunnable
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, r);
}
// 10 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
runnable_args_nm_10<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
return new runnable_args_nm_10<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
// 10 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R>
runnable_args_nm_10_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R* r) {
return new runnable_args_nm_10_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, R>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, r);
}
// 10 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
runnable_args_m_10<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) {
return new runnable_args_m_10<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
// 10 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename R>
runnable_args_m_10_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, R* r) {
return new runnable_args_m_10_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, R>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, r);
}
// 11 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
runnable_args_nm_11<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) {
return new runnable_args_nm_11<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
// 11 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R>
runnable_args_nm_11_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R* r) {
return new runnable_args_nm_11_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, r);
}
// 11 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10>
runnable_args_m_11<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) {
return new runnable_args_m_11<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
// 11 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename R>
runnable_args_m_11_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, R* r) {
return new runnable_args_m_11_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, R>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, r);
}
// 12 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11>
runnable_args_nm_12<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) {
return new runnable_args_nm_12<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
}
// 12 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R>
runnable_args_nm_12_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R* r) {
return new runnable_args_nm_12_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, r);
}
// 12 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11>
runnable_args_m_12<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11) {
return new runnable_args_m_12<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
}
// 12 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename R>
runnable_args_m_12_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, R* r) {
return new runnable_args_m_12_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, R>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, r);
}
// 13 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12>
runnable_args_nm_13<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) {
return new runnable_args_nm_13<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
}
// 13 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R>
runnable_args_nm_13_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R* r) {
return new runnable_args_nm_13_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, r);
}
// 13 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12>
runnable_args_m_13<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12) {
return new runnable_args_m_13<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12);
}
// 13 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename R>
runnable_args_m_13_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, R* r) {
return new runnable_args_m_13_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, R>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, r);
}
// 14 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13>
runnable_args_nm_14<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>* WrapRunnableNM(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) {
return new runnable_args_nm_14<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
}
// 14 arguments --
template<typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R>
runnable_args_nm_14_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>* WrapRunnableNMRet(M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R* r) {
return new runnable_args_nm_14_ret<M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>
(m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, r);
}
// 14 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13>
runnable_args_m_14<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>* WrapRunnable(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13) {
return new runnable_args_m_14<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13);
}
// 14 arguments --
template<typename C, typename M, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9, typename A10, typename A11, typename A12, typename A13, typename R>
runnable_args_m_14_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>* WrapRunnableRet(C o, M m, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10, A11 a11, A12 a12, A13 a13, R* r) {
return new runnable_args_m_14_ret<C, M, A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, R>
(o, m, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, r);
}

View File

@ -60,9 +60,10 @@ typedef enum {
using namespace CSF;
VcmSIPCCBinding * VcmSIPCCBinding::_pSelf = NULL;
int VcmSIPCCBinding::mAudioCodecMask = 0;
int VcmSIPCCBinding::mVideoCodecMask = 0;
VcmSIPCCBinding * VcmSIPCCBinding::gSelf = NULL;
int VcmSIPCCBinding::gAudioCodecMask = 0;
int VcmSIPCCBinding::gVideoCodecMask = 0;
nsIThread *VcmSIPCCBinding::gMainThread = NULL;
static mozilla::RefPtr<TransportFlow> vcmCreateTransportFlow(sipcc::PeerConnectionImpl *pc,
int level, bool rtcp,
@ -70,17 +71,27 @@ static mozilla::RefPtr<TransportFlow> vcmCreateTransportFlow(sipcc::PeerConnecti
const char *fingerprint
);
// Convenience macro to acquire PC
#define ENSURE_PC(pc, errval) \
do { \
if (!pc.impl()) { \
CSFLogDebug(logTag, "%s: couldn't acquire peerconnection %s", __FUNCTION__, peerconnection); \
return errval; \
} \
} while(0)
VcmSIPCCBinding::VcmSIPCCBinding ()
: streamObserver(NULL)
{
delete _pSelf;//delete is NULL safe, so I don't need to check if it's NULL
_pSelf = this;
delete gSelf;//delete is NULL safe, so I don't need to check if it's NULL
gSelf = this;
}
VcmSIPCCBinding::~VcmSIPCCBinding ()
{
assert(_pSelf != NULL);
_pSelf = NULL;
assert(gSelf);
gSelf = NULL;
}
void VcmSIPCCBinding::setStreamObserver(StreamObserver* obs)
@ -91,8 +102,8 @@ void VcmSIPCCBinding::setStreamObserver(StreamObserver* obs)
/* static */
StreamObserver * VcmSIPCCBinding::getStreamObserver()
{
if (_pSelf != NULL)
return _pSelf->streamObserver;
if (gSelf != NULL)
return gSelf->streamObserver;
return NULL;
}
@ -105,8 +116,8 @@ void VcmSIPCCBinding::setMediaProviderObserver(MediaProviderObserver* obs)
MediaProviderObserver * VcmSIPCCBinding::getMediaProviderObserver()
{
if (_pSelf != NULL)
return _pSelf->mediaProviderObserver;
if (gSelf != NULL)
return gSelf->mediaProviderObserver;
return NULL;
}
@ -114,25 +125,34 @@ MediaProviderObserver * VcmSIPCCBinding::getMediaProviderObserver()
void VcmSIPCCBinding::setAudioCodecs(int codecMask)
{
CSFLogDebugS(logTag, "SETTING AUDIO: " << codecMask);
VcmSIPCCBinding::mAudioCodecMask = codecMask;
VcmSIPCCBinding::gAudioCodecMask = codecMask;
}
void VcmSIPCCBinding::setVideoCodecs(int codecMask)
{
CSFLogDebugS(logTag, "SETTING VIDEO: " << codecMask);
VcmSIPCCBinding::mVideoCodecMask = codecMask;
VcmSIPCCBinding::gVideoCodecMask = codecMask;
}
int VcmSIPCCBinding::getAudioCodecs()
{
return VcmSIPCCBinding::mAudioCodecMask;
return VcmSIPCCBinding::gAudioCodecMask;
}
int VcmSIPCCBinding::getVideoCodecs()
{
return VcmSIPCCBinding::mVideoCodecMask;
return VcmSIPCCBinding::gVideoCodecMask;
}
void VcmSIPCCBinding::setMainThread(nsIThread *thread)
{
gMainThread = thread;
}
nsIThread* VcmSIPCCBinding::getMainThread()
{
return gMainThread;
}
/* static */
AudioTermination * VcmSIPCCBinding::getAudioTermination()
@ -393,16 +413,16 @@ void vcmRxAllocPort(cc_mcapid_t mcap_id,
* @return void
*
*/
void vcmRxAllocICE(cc_mcapid_t mcap_id,
cc_groupid_t group_id,
cc_streamid_t stream_id,
cc_call_handle_t call_handle,
const char *peerconnection,
uint16_t level,
char **default_addrp, /* Out */
int *default_portp, /* Out */
char ***candidatesp, /* Out */
int *candidate_ctp /* Out */
static void vcmRxAllocICE_m(cc_mcapid_t mcap_id,
cc_groupid_t group_id,
cc_streamid_t stream_id,
cc_call_handle_t call_handle,
const char *peerconnection,
uint16_t level,
char **default_addrp, /* Out */
int *default_portp, /* Out */
char ***candidatesp, /* Out */
int *candidate_ctp /* Out */
)
{
*default_portp = -1;
@ -413,17 +433,11 @@ void vcmRxAllocICE(cc_mcapid_t mcap_id,
// Note: we don't acquire any media resources here, and we assume that the
// ICE streams already exist, so we're just acquiring them. Any logic
// to make them on demand is elsewhere.
CSFLogDebug( logTag, "%s: acquiring peerconnection %s", __FUNCTION__, peerconnection);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
MOZ_ASSERT(pc);
if (!pc) {
CSFLogError(logTag, "%s: AcquireInstance returned NULL", __FUNCTION__);
return;
}
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, /**/);
CSFLogDebug( logTag, "%s: Getting stream %d", __FUNCTION__, level);
mozilla::RefPtr<NrIceMediaStream> stream = pc->impl()->media()->
mozilla::RefPtr<NrIceMediaStream> stream = pc.impl()->media()->
ice_media_stream(level-1);
MOZ_ASSERT(stream);
if (!stream) {
@ -465,6 +479,50 @@ void vcmRxAllocICE(cc_mcapid_t mcap_id,
}
/**
* Gets the ICE parameters for a stream. Called "alloc" for style consistency
*
* This is a thunk to vcmRxAllocICE_m
*
* @param[in] group_id - group identifier to which stream belongs.
* @param[in] stream_id - stream identifier
* @param[in] call_handle - call identifier
* @param[in] peerconnection - the peerconnection in use
* @param[out] default_addrp - the ICE default addr
* @param[out] port_allocatedp - the ICE default port
* @param[out] candidatesp - the ICE candidate array
* @param[out] candidate_ctp length of the array
*
* @return void
*
*/
void vcmRxAllocICE(cc_mcapid_t mcap_id,
cc_groupid_t group_id,
cc_streamid_t stream_id,
cc_call_handle_t call_handle,
const char *peerconnection,
uint16_t level,
char **default_addrp, /* Out */
int *default_portp, /* Out */
char ***candidatesp, /* Out */
int *candidate_ctp /* Out */
)
{
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNM(&vcmRxAllocICE_m,
mcap_id,
group_id,
stream_id,
call_handle,
peerconnection,
level,
default_addrp,
default_portp,
candidatesp,
candidate_ctp),
NS_DISPATCH_SYNC);
}
/* Get ICE global parameters (ufrag and pwd)
* @param[in] peerconnection - the peerconnection in use
* @param[out] ufragp - where to put the ufrag
@ -472,7 +530,9 @@ void vcmRxAllocICE(cc_mcapid_t mcap_id,
*
* @return void
*/
void vcmGetIceParams(const char *peerconnection, char **ufragp, char **pwdp)
static void vcmGetIceParams_m(const char *peerconnection,
char **ufragp,
char **pwdp)
{
CSFLogDebug( logTag, "%s: PC = %s", __FUNCTION__, peerconnection);
@ -481,15 +541,10 @@ void vcmGetIceParams(const char *peerconnection, char **ufragp, char **pwdp)
// Note: we don't acquire any media resources here, and we assume that the
// ICE streams already exist, so we're just acquiring them. Any logic
// to make them on demand is elsewhere.
CSFLogDebug( logTag, "%s: acquiring peerconnection %s", __FUNCTION__, peerconnection);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
MOZ_ASSERT(pc);
if (!pc) {
return;
}
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, /**/);
std::vector<std::string> attrs = pc->impl()->media()->
std::vector<std::string> attrs = pc.impl()->media()->
ice_ctx()->GetGlobalAttributes();
// Now fish through these looking for a ufrag and passwd
@ -530,6 +585,27 @@ void vcmGetIceParams(const char *peerconnection, char **ufragp, char **pwdp)
return;
}
/* Get ICE global parameters (ufrag and pwd)
*
* This is a thunk to vcmGetIceParams_m.
*
* @param[in] peerconnection - the peerconnection in use
* @param[out] ufragp - where to put the ufrag
* @param[out] pwdp - where to put the pwd
*
* @return void
*/
void vcmGetIceParams(const char *peerconnection,
char **ufragp,
char **pwdp)
{
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNM(&vcmGetIceParams_m,
peerconnection,
ufragp,
pwdp),
NS_DISPATCH_SYNC);
}
/* Set remote ICE global parameters.
@ -540,17 +616,14 @@ void vcmGetIceParams(const char *peerconnection, char **ufragp, char **pwdp)
*
* @return 0 success, error failure
*/
short vcmSetIceSessionParams(const char *peerconnection, char *ufrag, char *pwd)
static short vcmSetIceSessionParams_m(const char *peerconnection,
char *ufrag,
char *pwd)
{
CSFLogDebug( logTag, "%s: PC = %s", __FUNCTION__, peerconnection);
CSFLogDebug( logTag, "%s: acquiring peerconnection %s", __FUNCTION__, peerconnection);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
MOZ_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, VCM_ERROR);
std::vector<std::string> attributes;
@ -559,7 +632,7 @@ short vcmSetIceSessionParams(const char *peerconnection, char *ufrag, char *pwd)
if (pwd)
attributes.push_back(pwd);
nsresult res = pc->impl()->media()->ice_ctx()->
nsresult res = pc.impl()->media()->ice_ctx()->
ParseGlobalAttributes(attributes);
if (!NS_SUCCEEDED(res)) {
@ -570,6 +643,33 @@ short vcmSetIceSessionParams(const char *peerconnection, char *ufrag, char *pwd)
return 0;
}
/* Set remote ICE global parameters.
*
* This is a thunk to vcmSetIceSessionParams_m.
*
* @param[in] peerconnection - the peerconnection in use
* @param[in] ufrag - the ufrag
* @param[in] pwd - the pwd
*
* @return 0 success, error failure
*/
short vcmSetIceSessionParams(const char *peerconnection,
char *ufrag,
char *pwd)
{
short ret;
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNMRet(&vcmSetIceSessionParams_m,
peerconnection,
ufrag,
pwd,
&ret),
NS_DISPATCH_SYNC);
return ret;
}
/* Set ice candidate for trickle ICE.
*
* @param[in] peerconnection - the peerconnection in use
@ -578,26 +678,23 @@ short vcmSetIceSessionParams(const char *peerconnection, char *ufrag, char *pwd)
*
* @return 0 success, error failure
*/
short vcmSetIceCandidate(const char *peerconnection, const char *icecandidate, uint16_t level)
static short vcmSetIceCandidate_m(const char *peerconnection,
const char *icecandidate,
uint16_t level)
{
CSFLogDebug( logTag, "%s: PC = %s", __FUNCTION__, peerconnection);
CSFLogDebug( logTag, "%s: acquiring peerconnection %s", __FUNCTION__, peerconnection);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
MOZ_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, VCM_ERROR);
CSFLogDebug( logTag, "%s(): Getting stream %d", __FUNCTION__, level);
mozilla::RefPtr<NrIceMediaStream> stream = pc->impl()->media()->
mozilla::RefPtr<NrIceMediaStream> stream = pc.impl()->media()->
ice_media_stream(level-1);
if (!stream)
return VCM_ERROR;
nsresult res;
nsresult rv = pc->impl()->media()->ice_ctx()->thread()->Dispatch(
nsresult rv = pc.impl()->media()->ice_ctx()->thread()->Dispatch(
WrapRunnableRet(stream, &NrIceMediaStream::ParseTrickleCandidate, icecandidate, &res),
NS_DISPATCH_SYNC);
@ -614,25 +711,48 @@ short vcmSetIceCandidate(const char *peerconnection, const char *icecandidate, u
return 0;
}
/* Set ice candidate for trickle ICE.
*
* This is a thunk to vcmSetIceCandidate_m
*
* @param[in] peerconnection - the peerconnection in use
* @param[in] icecandidate - the icecandidate
* @param[in] level - the m line level
*
* @return 0 success, error failure
*/
short vcmSetIceCandidate(const char *peerconnection,
const char *icecandidate,
uint16_t level)
{
short ret;
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNMRet(&vcmSetIceCandidate_m,
peerconnection,
icecandidate,
level,
&ret),
NS_DISPATCH_SYNC);
return ret;
}
/* Start ICE checks
* @param[in] peerconnection - the peerconnection in use
* @return 0 success, error failure
*/
short vcmStartIceChecks(const char *peerconnection)
static short vcmStartIceChecks_m(const char *peerconnection)
{
CSFLogDebug( logTag, "%s: PC = %s", __FUNCTION__, peerconnection);
CSFLogDebug( logTag, "%s: acquiring peerconnection %s", __FUNCTION__, peerconnection);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
MOZ_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, VCM_ERROR);
nsresult res;
nsresult rv = pc->impl()->media()->ice_ctx()->thread()->Dispatch(
WrapRunnableRet(pc->impl()->media()->ice_ctx(), &NrIceCtx::StartChecks, &res),
nsresult rv = pc.impl()->media()->ice_ctx()->thread()->Dispatch(
WrapRunnableRet(pc.impl()->media()->ice_ctx(), &NrIceCtx::StartChecks, &res),
NS_DISPATCH_SYNC);
if (!NS_SUCCEEDED(rv)) {
@ -649,6 +769,26 @@ short vcmStartIceChecks(const char *peerconnection)
}
/* Start ICE checks
*
* This is a thunk to vcmStartIceChecks_m
*
* @param[in] peerconnection - the peerconnection in use
* @return 0 success, error failure
*/
short vcmStartIceChecks(const char *peerconnection)
{
short ret;
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNMRet(&vcmStartIceChecks_m,
peerconnection,
&ret),
NS_DISPATCH_SYNC);
return ret;
}
/* Set remote ICE media-level parameters.
*
* @param[in] peerconnection - the peerconnection in use
@ -659,21 +799,20 @@ short vcmStartIceChecks(const char *peerconnection)
* @param[i] candidate_ct - the number of candidates
* @return 0 success, error failure
*/
short vcmSetIceMediaParams(const char *peerconnection, int level, char *ufrag, char *pwd,
char **candidates, int candidate_ct)
static short vcmSetIceMediaParams_m(const char *peerconnection,
int level,
char *ufrag,
char *pwd,
char **candidates,
int candidate_ct)
{
CSFLogDebug( logTag, "%s: PC = %s", __FUNCTION__, peerconnection);
CSFLogDebug( logTag, "%s: acquiring peerconnection %s", __FUNCTION__, peerconnection);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
MOZ_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, VCM_ERROR);
CSFLogDebug( logTag, "%s(): Getting stream %d", __FUNCTION__, level);
mozilla::RefPtr<NrIceMediaStream> stream = pc->impl()->media()->
mozilla::RefPtr<NrIceMediaStream> stream = pc.impl()->media()->
ice_media_stream(level-1);
if (!stream)
return VCM_ERROR;
@ -699,6 +838,42 @@ short vcmSetIceMediaParams(const char *peerconnection, int level, char *ufrag, c
return 0;
}
/* Set remote ICE media-level parameters.
*
* This is a thunk to vcmSetIceMediaParams_w
*
* @param[in] peerconnection - the peerconnection in use
* @param[in] level - the m-line
* @param[in] ufrag - the ufrag
* @param[in] pwd - the pwd
* @param[in] candidates - the candidates
* @param[i] candidate_ct - the number of candidates
* @return 0 success, error failure
*/
short vcmSetIceMediaParams(const char *peerconnection,
int level,
char *ufrag,
char *pwd,
char **candidates,
int candidate_ct)
{
short ret;
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNMRet(&vcmSetIceMediaParams_m,
peerconnection,
level,
ufrag,
pwd,
candidates,
candidate_ct,
&ret),
NS_DISPATCH_SYNC);
return ret;
}
/*
* Create a remote stream
*
@ -711,7 +886,7 @@ short vcmSetIceMediaParams(const char *peerconnection, int level, char *ufrag, c
*
* Returns: zero(0) for success; otherwise, ERROR for failure
*/
short vcmCreateRemoteStream(
static short vcmCreateRemoteStream_m(
cc_mcapid_t mcap_id,
const char *peerconnection,
int *pc_stream_id) {
@ -719,13 +894,8 @@ short vcmCreateRemoteStream(
nsresult res;
CSFLogDebug( logTag, "%s", __FUNCTION__);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
MOZ_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, VCM_ERROR);
if (CC_IS_AUDIO(mcap_id)) {
hints |= nsDOMMediaStream::HINT_CONTENTS_AUDIO;
@ -735,12 +905,12 @@ short vcmCreateRemoteStream(
}
sipcc::RemoteSourceStreamInfo* info;
res = pc->impl()->CreateRemoteSourceStreamInfo(hints, &info);
res = pc.impl()->CreateRemoteSourceStreamInfo(hints, &info);
if (NS_FAILED(res)) {
return VCM_ERROR;
}
res = pc->impl()->media()->AddRemoteStream(info, pc_stream_id);
res = pc.impl()->media()->AddRemoteStream(info, pc_stream_id);
if (NS_FAILED(res)) {
return VCM_ERROR;
}
@ -765,6 +935,37 @@ short vcmCreateRemoteStream(
return 0;
}
/*
* Create a remote stream
*
* This is a thunk to vcmCreateRemoteStream_m
*
* @param[in] mcap_id - group identifier to which stream belongs.
* @param[in] peerconnection - the peerconnection in use
* @param[out] pc_stream_id - the id of the allocated stream
*
* TODO(ekr@rtfm.com): Revise along with everything else for the
* new stream model.
*
* Returns: zero(0) for success; otherwise, ERROR for failure
*/
short vcmCreateRemoteStream(cc_mcapid_t mcap_id,
const char *peerconnection,
int *pc_stream_id)
{
short ret;
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNMRet(&vcmCreateRemoteStream_m,
mcap_id,
peerconnection,
pc_stream_id,
&ret),
NS_DISPATCH_SYNC);
return ret;
}
/*
* Get DTLS key data
@ -777,23 +978,18 @@ short vcmCreateRemoteStream(
*
* Returns: zero(0) for success; otherwise, ERROR for failure
*/
short vcmGetDtlsIdentity(const char *peerconnection,
char *digest_algp,
size_t max_digest_alg_len,
char *digestp,
size_t max_digest_len) {
CSFLogDebug( logTag, "%s: acquiring peerconnection %s", __FUNCTION__, peerconnection);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
MOZ_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
static short vcmGetDtlsIdentity_m(const char *peerconnection,
char *digest_algp,
size_t max_digest_alg_len,
char *digestp,
size_t max_digest_len) {
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, VCM_ERROR);
unsigned char digest[TransportLayerDtls::kMaxDigestLength];
size_t digest_len;
nsresult res = pc->impl()->GetIdentity()->ComputeFingerprint("sha-256", digest,
nsresult res = pc.impl()->GetIdentity()->ComputeFingerprint("sha-256", digest,
sizeof(digest),
&digest_len);
if (!NS_SUCCEEDED(res)) {
@ -816,6 +1012,39 @@ short vcmGetDtlsIdentity(const char *peerconnection,
return 0;
}
/*
* Get DTLS key data
*
* This is a thunk to vcmGetDtlsIdentity_m
*
* @param[in] peerconnection - the peerconnection in use
* @param[out] digest_algp - the digest algorithm e.g. 'SHA-1'
* @param[in] max_digest_alg_len - length of string
* @param[out] digestp - the digest string
* @param[in] max_digest_len - length of string
*
* Returns: zero(0) for success; otherwise, ERROR for failure
*/
short vcmGetDtlsIdentity(const char *peerconnection,
char *digest_algp,
size_t max_digest_alg_len,
char *digestp,
size_t max_digest_len) {
short ret;
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNMRet(&vcmGetDtlsIdentity_m,
peerconnection,
digest_algp,
max_digest_alg_len,
digestp,
max_digest_len,
&ret),
NS_DISPATCH_SYNC);
return ret;
}
/* Set negotiated DataChannel parameters.
*
* @param[in] peerconnection - the peerconnection in use
@ -829,15 +1058,6 @@ short vcmSetDataChannelParameters(const char *peerconnection, cc_uint16_t stream
{
CSFLogDebug( logTag, "%s: PC = %s", __FUNCTION__, peerconnection);
CSFLogDebug( logTag, "%s: acquiring peerconnection %s", __FUNCTION__, peerconnection);
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
PR_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
return 0;
}
@ -1030,7 +1250,7 @@ int vcmRxStart(cc_mcapid_t mcap_id,
* Returns: zero(0) for success; otherwise, ERROR for failure
*/
int vcmRxStartICE(cc_mcapid_t mcap_id,
static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
cc_groupid_t group_id,
cc_streamid_t stream_id,
int level,
@ -1046,13 +1266,9 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
{
CSFLogDebug( logTag, "%s(%s)", __FUNCTION__, peerconnection);
// Find the PC and get the stream
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
PR_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
// Find the PC.
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, VCM_ERROR);
if(!payloads) {
CSFLogError( logTag, "Unitialized payload list");
@ -1061,7 +1277,7 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
// Find the stream we need
nsRefPtr<sipcc::RemoteSourceStreamInfo> stream =
pc->impl()->media()->GetRemoteStream(pc_stream_id);
pc.impl()->media()->GetRemoteStream(pc_stream_id);
if (!stream) {
// This should never happen
PR_ASSERT(PR_FALSE);
@ -1069,14 +1285,14 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
}
// Create the transport flows
mozilla::RefPtr<TransportFlow> rtp_flow =
vcmCreateTransportFlow(pc->impl(), level, false,
vcmCreateTransportFlow(pc.impl(), level, false,
fingerprint_alg, fingerprint);
if (!rtp_flow) {
CSFLogError( logTag, "Could not create RTP flow");
return VCM_ERROR;
}
mozilla::RefPtr<TransportFlow> rtcp_flow =
vcmCreateTransportFlow(pc->impl(), level, true,
vcmCreateTransportFlow(pc.impl(), level, true,
fingerprint_alg, fingerprint);
if (!rtcp_flow) {
CSFLogError( logTag, "Could not create RTCP flow");
@ -1111,8 +1327,8 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
// Now we have all the pieces, create the pipeline
stream->StorePipeline(pc_track_id,
new mozilla::MediaPipelineReceiveAudio(
pc->impl()->GetMainThread().get(),
pc->impl()->GetSTSThread(),
pc.impl()->GetMainThread().get(),
pc.impl()->GetSTSThread(),
stream->GetMediaStream(),
conduit, rtp_flow, rtcp_flow));
@ -1143,8 +1359,8 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
// Now we have all the pieces, create the pipeline
stream->StorePipeline(pc_track_id,
new mozilla::MediaPipelineReceiveVideo(
pc->impl()->GetMainThread().get(),
pc->impl()->GetSTSThread(),
pc.impl()->GetMainThread().get(),
pc.impl()->GetSTSThread(),
stream->GetMediaStream(),
conduit, rtp_flow, rtcp_flow));
@ -1158,6 +1374,67 @@ int vcmRxStartICE(cc_mcapid_t mcap_id,
}
/**
* start rx stream
* Same concept as vcmRxStart but for ICE/PeerConnection-based flows
*
* This is a thunk to vcmRxStartICE_m
*
* @param[in] mcap_id - media cap id
* @param[in] group_id - group identifier to which the stream belongs
* @param[in] stream_id - stream id of the given media type.
* @param[in] level - the m-line index
* @param[in] pc_stream_id - the media stream index (from PC.addStream())
* @param[i]n pc_track_id - the track within the media stream
* @param[in] call_handle - call handle
* @param[in] peerconnection - the peerconnection in use
* @param[in] num_payloads - number of negotiated payloads
* @param[in] payloads - negotiated codec details list
* @param[in] fingerprint_alg - the DTLS fingerprint algorithm
* @param[in] fingerprint - the DTLS fingerprint
* @param[in] attrs - media attributes
*
* Returns: zero(0) for success; otherwise, ERROR for failure
*/
int vcmRxStartICE(cc_mcapid_t mcap_id,
cc_groupid_t group_id,
cc_streamid_t stream_id,
int level,
int pc_stream_id,
int pc_track_id,
cc_call_handle_t call_handle,
const char *peerconnection,
int num_payloads,
const vcm_payload_info_t* payloads,
const char *fingerprint_alg,
const char *fingerprint,
vcm_mediaAttrs_t *attrs)
{
int ret;
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNMRet(&vcmRxStartICE_m,
mcap_id,
group_id,
stream_id,
level,
pc_stream_id,
pc_track_id,
call_handle,
peerconnection,
num_payloads,
payloads,
fingerprint_alg,
fingerprint,
attrs,
&ret),
NS_DISPATCH_SYNC);
return ret;
}
/**
* Close the receive stream.
*
@ -1596,7 +1873,7 @@ int vcmTxStart(cc_mcapid_t mcap_id,
*/
#define EXTRACT_DYNAMIC_PAYLOAD_TYPE(PTYPE) ((PTYPE)>>16)
int vcmTxStartICE(cc_mcapid_t mcap_id,
static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
cc_groupid_t group_id,
cc_streamid_t stream_id,
int level,
@ -1613,25 +1890,21 @@ int vcmTxStartICE(cc_mcapid_t mcap_id,
CSFLogDebug( logTag, "%s(%s)", __FUNCTION__, peerconnection);
// Find the PC and get the stream
mozilla::ScopedDeletePtr<sipcc::PeerConnectionWrapper> pc(
sipcc::PeerConnectionImpl::AcquireInstance(peerconnection));
PR_ASSERT(pc);
if (!pc) {
return VCM_ERROR;
}
nsRefPtr<sipcc::LocalSourceStreamInfo> stream = pc->impl()->media()->
sipcc::PeerConnectionWrapper pc(peerconnection);
ENSURE_PC(pc, VCM_ERROR);
nsRefPtr<sipcc::LocalSourceStreamInfo> stream = pc.impl()->media()->
GetLocalStream(pc_stream_id);
// Create the transport flows
mozilla::RefPtr<TransportFlow> rtp_flow =
vcmCreateTransportFlow(pc->impl(), level, false,
vcmCreateTransportFlow(pc.impl(), level, false,
fingerprint_alg, fingerprint);
if (!rtp_flow) {
CSFLogError( logTag, "Could not create RTP flow");
return VCM_ERROR;
}
mozilla::RefPtr<TransportFlow> rtcp_flow =
vcmCreateTransportFlow(pc->impl(), level, true,
vcmCreateTransportFlow(pc.impl(), level, true,
fingerprint_alg, fingerprint);
if (!rtcp_flow) {
CSFLogError( logTag, "Could not create RTCP flow");
@ -1660,8 +1933,8 @@ int vcmTxStartICE(cc_mcapid_t mcap_id,
mozilla::RefPtr<mozilla::MediaPipelineTransmit> pipeline =
new mozilla::MediaPipelineTransmit(
pc->impl()->GetMainThread().get(),
pc->impl()->GetSTSThread(),
pc.impl()->GetMainThread().get(),
pc.impl()->GetSTSThread(),
stream->GetMediaStream(),
conduit, rtp_flow, rtcp_flow);
@ -1693,8 +1966,8 @@ int vcmTxStartICE(cc_mcapid_t mcap_id,
// Create the pipeline
mozilla::RefPtr<mozilla::MediaPipeline> pipeline =
new mozilla::MediaPipelineTransmit(
pc->impl()->GetMainThread().get(),
pc->impl()->GetSTSThread(),
pc.impl()->GetMainThread().get(),
pc.impl()->GetSTSThread(),
stream->GetMediaStream(),
conduit, rtp_flow, rtcp_flow);
@ -1712,6 +1985,68 @@ int vcmTxStartICE(cc_mcapid_t mcap_id,
return 0;
}
/**
* start tx stream
* Same concept as vcmTxStart but for ICE/PeerConnection-based flows
*
* This is a thunk to vcmTxStartICE_m
*
* @param[in] mcap_id - media cap id
* @param[in] group_id - group identifier to which the stream belongs
* @param[in] stream_id - stream id of the given media type.
* @param[in] level - the m-line index
* @param[in] pc_stream_id - the media stream index (from PC.addStream())
* @param[i]n pc_track_id - the track within the media stream
* @param[in] call_handle - call handle
* @param[in] peerconnection - the peerconnection in use
* @param[in] payload - payload type
* @param[in] tos - bit marking
* @param[in] fingerprint_alg - the DTLS fingerprint algorithm
* @param[in] fingerprint - the DTLS fingerprint
* @param[in] attrs - media attributes
*
* Returns: zero(0) for success; otherwise, ERROR for failure
*
*/
#define EXTRACT_DYNAMIC_PAYLOAD_TYPE(PTYPE) ((PTYPE)>>16)
int vcmTxStartICE(cc_mcapid_t mcap_id,
cc_groupid_t group_id,
cc_streamid_t stream_id,
int level,
int pc_stream_id,
int pc_track_id,
cc_call_handle_t call_handle,
const char *peerconnection,
const vcm_payload_info_t *payload,
short tos,
const char *fingerprint_alg,
const char *fingerprint,
vcm_mediaAttrs_t *attrs)
{
int ret;
VcmSIPCCBinding::getMainThread()->Dispatch(
WrapRunnableNMRet(&vcmTxStartICE_m,
mcap_id,
group_id,
stream_id,
level,
pc_stream_id,
pc_track_id,
call_handle,
peerconnection,
payload,
tos,
fingerprint_alg,
fingerprint,
attrs,
&ret),
NS_DISPATCH_SYNC);
return ret;
}
/**
* Close the transmit stream

View File

@ -10,6 +10,8 @@ extern "C"
#include "ccapi_types.h"
}
class nsIThread;
namespace CSF
{
class AudioTermination;
@ -53,12 +55,16 @@ namespace CSF
static int getAudioCodecs();
static int getVideoCodecs();
static void setMainThread(nsIThread *thread);
static nsIThread *getMainThread();
private:
static VcmSIPCCBinding * _pSelf;
static VcmSIPCCBinding * gSelf;
StreamObserver* streamObserver;
MediaProviderObserver *mediaProviderObserver;
static int mAudioCodecMask;
static int mVideoCodecMask;
static int gAudioCodecMask;
static int gVideoCodecMask;
static nsIThread *gMainThread;
};
}

View File

@ -442,10 +442,13 @@ nsresult MediaPipelineTransmit::Init() {
"audio" : "video") <<
" hints=" << stream_->GetHintContents());
return RUN_ON_THREAD(main_thread_, WrapRunnable(stream_->GetStream(),
// Force this to be a refptr so that we are holding a strong reference
// to the media stream.
nsRefPtr<MediaStream> stream (stream_->GetStream());
return RUN_ON_THREAD(main_thread_, WrapRunnable(stream,
&MediaStream::AddListener,
listener_),
NS_DISPATCH_SYNC);
NS_DISPATCH_NORMAL);
}
nsresult MediaPipeline::PipelineTransport::SendRtpPacket(
@ -665,10 +668,14 @@ void MediaPipelineTransmit::ProcessVideoChunk(VideoSessionConduit *conduit,
nsresult MediaPipelineReceiveAudio::Init() {
MOZ_MTLOG(PR_LOG_DEBUG, __FUNCTION__);
return RUN_ON_THREAD(main_thread_, WrapRunnable(stream_->GetStream(),
&MediaStream::AddListener,
listener_),
NS_DISPATCH_SYNC);
// Force this to be a refptr so that we are holding a strong reference
// to the media stream.
nsRefPtr<MediaStream> stream (stream_->GetStream());
return RUN_ON_THREAD(main_thread_, WrapRunnable(stream,
&MediaStream::AddListener,
listener_),
NS_DISPATCH_NORMAL);
}
void MediaPipelineReceiveAudio::PipelineListener::

View File

@ -13,39 +13,64 @@
#include "CC_SIPCCDeviceInfo.h"
#include "CSFLog.h"
#include "vcm.h"
#include "VcmSIPCCBinding.h"
#include "PeerConnectionImpl.h"
#include "PeerConnectionCtx.h"
#include "runnable_utils.h"
#include "cpr_socket.h"
static const char* logTag = "PeerConnectionCtx";
namespace sipcc {
PeerConnectionCtx* PeerConnectionCtx::instance;
PeerConnectionCtx* PeerConnectionCtx::gInstance;
nsIThread* PeerConnectionCtx::gMainThread;
nsresult PeerConnectionCtx::InitializeGlobal(nsIThread *mainThread) {
if (!gMainThread) {
gMainThread = mainThread;
CSF::VcmSIPCCBinding::setMainThread(gMainThread);
} else {
MOZ_ASSERT(gMainThread == mainThread);
}
bool on;
nsresult res;
#ifdef MOZILLA_INTERNAL_API
// This check fails on the unit tests because they do not
// have the right thread behavior.
res = gMainThread->IsOnCurrentThread(&on);
NS_ENSURE_SUCCESS(res, res);
MOZ_ASSERT(on);
#endif
if (!gInstance) {
CSFLogDebug(logTag, "Creating PeerConnectionCtx");
PeerConnectionCtx *ctx = new PeerConnectionCtx();
res = ctx->Initialize();
PR_ASSERT(NS_SUCCEEDED(res));
if (!NS_SUCCEEDED(res))
return res;
gInstance = ctx;
}
return NS_OK;
}
PeerConnectionCtx* PeerConnectionCtx::GetInstance() {
if (instance)
return instance;
CSFLogDebug(logTag, "Creating PeerConnectionCtx");
PeerConnectionCtx *ctx = new PeerConnectionCtx();
nsresult res = ctx->Initialize();
PR_ASSERT(NS_SUCCEEDED(res));
if (!NS_SUCCEEDED(res))
return NULL;
instance = ctx;
return instance;
MOZ_ASSERT(gInstance);
return gInstance;
}
void PeerConnectionCtx::Destroy() {
CSFLogDebug(logTag, "%s", __FUNCTION__);
instance->Cleanup();
delete instance;
instance = NULL;
gInstance->Cleanup();
delete gInstance;
gInstance = NULL;
}
nsresult PeerConnectionCtx::Initialize() {
@ -118,20 +143,34 @@ void PeerConnectionCtx::onDeviceEvent(ccapi_device_event_e aDeviceEvent,
}
}
// Demux the call event to the right PeerConnection
void PeerConnectionCtx::onCallEvent(ccapi_call_event_e aCallEvent,
CSF::CC_CallPtr aCall,
CSF::CC_CallInfoPtr aInfo) {
CSFLogDebug(logTag, "onCallEvent()");
mozilla::ScopedDeletePtr<PeerConnectionWrapper> pc(
PeerConnectionImpl::AcquireInstance(
aCall->getPeerConnection()));
CSF::CC_CallPtr aCall,
CSF::CC_CallInfoPtr aInfo) {
// This is called on a SIPCC thread.
// WARNING: Do not make this NS_DISPATCH_NORMAL.
// CC_*Ptr is not thread-safe so we must not manipulate
// the ref count on multiple threads at once.
// NS_DISPATCH_SYNC enforces this and because this is
// not a real nsThread, we don't have to worry about
// reentrancy.
RUN_ON_THREAD(gMainThread,
WrapRunnable(this,
&PeerConnectionCtx::onCallEvent_m,
aCallEvent, aCall, aInfo),
NS_DISPATCH_SYNC);
}
if (!pc) // This must be an event on a dead PC. Ignore
// Demux the call event to the right PeerConnection
void PeerConnectionCtx::onCallEvent_m(ccapi_call_event_e aCallEvent,
CSF::CC_CallPtr aCall,
CSF::CC_CallInfoPtr aInfo) {
CSFLogDebug(logTag, "onCallEvent()");
PeerConnectionWrapper pc(aCall->getPeerConnection());
if (!pc.impl()) // This must be an event on a dead PC. Ignore
return;
CSFLogDebug(logTag, "Calling PC");
pc->impl()->onCallEvent(aCallEvent, aCall, aInfo);
pc.impl()->onCallEvent(aCallEvent, aCall, aInfo);
}
} // namespace sipcc

View File

@ -17,12 +17,14 @@
namespace sipcc {
// Currently SIPCC only allows a single stack instance to exist in a process
// at once. This class implements a singleton object that wraps that
// instance. It also hosts the observer class that demuxes events onto
// individual PCs.
// 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 {
public:
static nsresult InitializeGlobal(nsIThread *mainThread);
static PeerConnectionCtx* GetInstance();
static void Destroy();
@ -37,7 +39,14 @@ class PeerConnectionCtx : public CSF::CC_Observer {
PeerConnectionImpl::SipccState sipcc_state() { return mSipccState; }
// Make these classes friend so that they can access mPeerconnections.
friend class PeerConnectionImpl;
friend class PeerConnectionWrapper;
private:
// We could make these available only via accessors but it's too much trouble.
std::map<const std::string, PeerConnectionImpl *> mPeerConnections;
PeerConnectionCtx() : mSipccState(PeerConnectionImpl::kIdle),
mCCM(NULL), mDevice(NULL) {}
// This is a singleton, so don't copy construct it, etc.
@ -52,12 +61,17 @@ class PeerConnectionCtx : public CSF::CC_Observer {
mSipccState = aState;
}
virtual void onCallEvent_m(ccapi_call_event_e callEvent,
CSF::CC_CallPtr call,
CSF::CC_CallInfoPtr info);
// SIPCC objects
PeerConnectionImpl::SipccState mSipccState; // TODO(ekr@rtfm.com): refactor this out? What does it do?
CSF::CallControlManagerPtr mCCM;
CSF::CC_DevicePtr mDevice;
static PeerConnectionCtx *instance;
static PeerConnectionCtx *gInstance;
static nsIThread *gMainThread;
};
} // namespace sipcc

View File

@ -106,162 +106,104 @@ void MediaConstraints::buildArray(cc_media_constraints_t** constraintarray) {
(*constraintarray)->constraint_count = i;
}
typedef enum {
PC_OBSERVER_CALLBACK,
PC_OBSERVER_CONNECTION,
PC_OBSERVER_CLOSEDCONNECTION,
PC_OBSERVER_DATACHANNEL,
PC_OBSERVER_ICE,
PC_OBSERVER_READYSTATE
} PeerConnectionObserverType;
// TODO: Refactor this.
class PeerConnectionObserverDispatch : public nsRunnable {
public:
PeerConnectionObserverDispatch(CSF::CC_CallInfoPtr aInfo,
nsRefPtr<PeerConnectionImpl> aPC,
IPeerConnectionObserver* aObserver) :
mType(PC_OBSERVER_CALLBACK), mInfo(aInfo), mChannel(nullptr), mPC(aPC), mObserver(aObserver) {}
PeerConnectionObserverDispatch(PeerConnectionObserverType aType,
nsRefPtr<nsIDOMDataChannel> aChannel,
nsRefPtr<PeerConnectionImpl> aPC,
IPeerConnectionObserver* aObserver) :
mType(aType), mInfo(nullptr), mChannel(aChannel), mPC(aPC), mObserver(aObserver) {}
PeerConnectionObserverDispatch(PeerConnectionObserverType aType,
nsRefPtr<PeerConnectionImpl> aPC,
IPeerConnectionObserver* aObserver) :
mType(aType), mInfo(nullptr), mPC(aPC), mObserver(aObserver) {}
IPeerConnectionObserver* aObserver)
: mPC(aPC),
mObserver(aObserver),
mCode(static_cast<StatusCode>(aInfo->getStatusCode())),
mSdpStr(),
mCallState(aInfo->getCallState()),
mStateStr(aInfo->callStateToString(mCallState)) {
if (mCallState == REMOTESTREAMADD) {
MediaStreamTable *streams = NULL;
streams = aInfo->getMediaStreams();
mRemoteStream = mPC->media()->GetRemoteStream(streams->media_stream_id);
MOZ_ASSERT(mRemoteStream);
}
if ((mCallState == CREATEOFFER) || (mCallState == CREATEANSWER)) {
mSdpStr = aInfo->getSDP();
}
}
~PeerConnectionObserverDispatch(){}
NS_IMETHOD Run()
{
switch (mType) {
case PC_OBSERVER_CALLBACK:
NS_IMETHOD Run() {
switch (mCallState) {
case CREATEOFFER:
mObserver->OnCreateOfferSuccess(mSdpStr.c_str());
break;
case CREATEANSWER:
mObserver->OnCreateAnswerSuccess(mSdpStr.c_str());
break;
case CREATEOFFERERROR:
mObserver->OnCreateOfferError(mCode);
break;
case CREATEANSWERERROR:
mObserver->OnCreateAnswerError(mCode);
break;
case SETLOCALDESC:
mObserver->OnSetLocalDescriptionSuccess(mCode);
break;
case SETREMOTEDESC:
mObserver->OnSetRemoteDescriptionSuccess(mCode);
break;
case SETLOCALDESCERROR:
mObserver->OnSetLocalDescriptionError(mCode);
break;
case SETREMOTEDESCERROR:
mObserver->OnSetRemoteDescriptionError(mCode);
break;
case REMOTESTREAMADD:
{
StatusCode code;
std::string s_sdpstr;
MediaStreamTable *streams = NULL;
cc_call_state_t state = mInfo->getCallState();
std::string statestr = mInfo->callStateToString(state);
nsDOMMediaStream* stream;
uint32_t hint;
switch (state) {
case CREATEOFFER:
s_sdpstr = mInfo->getSDP();
mObserver->OnCreateOfferSuccess(s_sdpstr.c_str());
break;
case CREATEANSWER:
s_sdpstr = mInfo->getSDP();
mObserver->OnCreateAnswerSuccess(s_sdpstr.c_str());
break;
case CREATEOFFERERROR:
code = (StatusCode)mInfo->getStatusCode();
mObserver->OnCreateOfferError(code);
break;
case CREATEANSWERERROR:
code = (StatusCode)mInfo->getStatusCode();
mObserver->OnCreateAnswerError(code);
break;
case SETLOCALDESC:
code = (StatusCode)mInfo->getStatusCode();
mObserver->OnSetLocalDescriptionSuccess(code);
break;
case SETREMOTEDESC:
code = (StatusCode)mInfo->getStatusCode();
mObserver->OnSetRemoteDescriptionSuccess(code);
break;
case SETLOCALDESCERROR:
code = (StatusCode)mInfo->getStatusCode();
mObserver->OnSetLocalDescriptionError(code);
break;
case SETREMOTEDESCERROR:
code = (StatusCode)mInfo->getStatusCode();
mObserver->OnSetRemoteDescriptionError(code);
break;
case REMOTESTREAMADD:
{
streams = mInfo->getMediaStreams();
nsRefPtr<RemoteSourceStreamInfo> remoteStream = mPC->media()->
GetRemoteStream(streams->media_stream_id);
MOZ_ASSERT(remoteStream);
if (!remoteStream)
{
CSFLogErrorS(logTag, __FUNCTION__ << " GetRemoteStream returned NULL");
}
else
{
stream = remoteStream->GetMediaStream();
hint = stream->GetHintContents();
if (hint == nsDOMMediaStream::HINT_CONTENTS_AUDIO) {
mObserver->OnAddStream(stream, "audio");
} else if (hint == nsDOMMediaStream::HINT_CONTENTS_VIDEO) {
mObserver->OnAddStream(stream, "video");
} else {
CSFLogErrorS(logTag, __FUNCTION__ << "Audio & Video not supported");
MOZ_ASSERT(PR_FALSE);
}
}
break;
if (!mRemoteStream) {
CSFLogErrorS(logTag, __FUNCTION__ << " GetRemoteStream returned NULL");
} else {
stream = mRemoteStream->GetMediaStream();
hint = stream->GetHintContents();
if (hint == nsDOMMediaStream::HINT_CONTENTS_AUDIO) {
mObserver->OnAddStream(stream, "audio");
} else if (hint == nsDOMMediaStream::HINT_CONTENTS_VIDEO) {
mObserver->OnAddStream(stream, "video");
} else {
CSFLogErrorS(logTag, __FUNCTION__ << "Audio & Video not supported");
MOZ_ASSERT(PR_FALSE);
}
default:
CSFLogDebugS(logTag, ": **** UNHANDLED CALL STATE : " << statestr);
break;
}
break;
}
case PC_OBSERVER_CONNECTION:
CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection onconnection");
mObserver->NotifyConnection();
default:
CSFLogDebugS(logTag, ": **** UNHANDLED CALL STATE : " << mStateStr);
break;
case PC_OBSERVER_CLOSEDCONNECTION:
CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection onclosedconnection");
mObserver->NotifyClosedConnection();
break;
case PC_OBSERVER_DATACHANNEL:
CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection ondatachannel");
mObserver->NotifyDataChannel(mChannel);
#ifdef MOZILLA_INTERNAL_API
NS_DataChannelAppReady(mChannel);
#endif
break;
case PC_OBSERVER_ICE:
CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection ICE callback ");
mObserver->OnStateChange(IPeerConnectionObserver::kIceState);
break;
case PC_OBSERVER_READYSTATE:
CSFLogDebugS(logTag, __FUNCTION__ << ": Delivering PeerConnection Ready State callback ");
mObserver->OnStateChange(IPeerConnectionObserver::kReadyState);
}
return NS_OK;
}
private:
PeerConnectionObserverType mType;
CSF::CC_CallInfoPtr mInfo;
nsRefPtr<nsIDOMDataChannel> mChannel;
nsRefPtr<PeerConnectionImpl> mPC;
nsCOMPtr<IPeerConnectionObserver> mObserver;
StatusCode mCode;
std::string mSdpStr;
cc_call_state_t mCallState;
std::string mStateStr;
nsRefPtr<RemoteSourceStreamInfo> mRemoteStream;
};
std::map<const std::string, PeerConnectionImpl *>
PeerConnectionImpl::peerconnections;
NS_IMPL_THREADSAFE_ISUPPORTS1(PeerConnectionImpl, IPeerConnection)
PeerConnectionImpl::PeerConnectionImpl()
@ -273,19 +215,27 @@ PeerConnectionImpl::PeerConnectionImpl()
, mWindow(NULL)
, mIdentity(NULL)
, mSTSThread(NULL)
, mMedia(new PeerConnectionMedia(this))
{}
, mMedia(new PeerConnectionMedia(this)) {
MOZ_ASSERT(NS_IsMainThread());
}
PeerConnectionImpl::~PeerConnectionImpl()
{
Close(false);
PC_AUTO_ENTER_API_CALL_NO_CHECK();
PeerConnectionCtx::GetInstance()->mPeerConnections.erase(mHandle);
CloseInt(false);
#if 0
// TODO(ekr@rtfm.com): figure out how to shut down PCCtx.
// bug 820011.
// Since this and Initialize() occur on MainThread, they can't both be
// running at once
// Might be more optimal to release off a timer (and XPCOM Shutdown)
// to avoid churn
peerconnections.erase(mHandle);
if (peerconnections.empty())
if (PeerConnectionCtx::GetInstance()->mPeerConnections.empty())
Shutdown();
#endif
/* We should release mPCObserver on the main thread, but also prevent a double free.
nsCOMPtr<nsIThread> mainThread;
@ -303,8 +253,7 @@ PeerConnectionImpl::MakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aRetval)
nsRefPtr<nsDOMMediaStream> stream = nsDOMMediaStream::CreateSourceStream(aHint);
NS_ADDREF(*aRetval = stream);
CSFLogDebugS(logTag, "PeerConnection " << static_cast<void*>(this)
<< ": Created media stream " << static_cast<void*>(stream)
CSFLogDebugS(logTag, "Created media stream " << static_cast<void*>(stream)
<< " inner: " << static_cast<void*>(stream->GetStream()));
return NS_OK;
@ -326,18 +275,11 @@ nsresult
PeerConnectionImpl::CreateRemoteSourceStreamInfo(uint32_t aHint, RemoteSourceStreamInfo** aInfo)
{
MOZ_ASSERT(aInfo);
PC_AUTO_ENTER_API_CALL_NO_CHECK();
nsIDOMMediaStream* stream;
nsresult res;
if (!mThread || NS_IsMainThread()) {
res = MakeMediaStream(aHint, &stream);
} else {
mThread->Dispatch(WrapRunnableRet(
this, &PeerConnectionImpl::MakeMediaStream, aHint, &stream, &res
), NS_DISPATCH_SYNC);
}
nsresult res = MakeMediaStream(aHint, &stream);
if (NS_FAILED(res)) {
return res;
}
@ -352,8 +294,8 @@ PeerConnectionImpl::CreateRemoteSourceStreamInfo(uint32_t aHint, RemoteSourceStr
return NS_OK;
}
mThread->Dispatch(WrapRunnableRet(
this, &PeerConnectionImpl::MakeRemoteSource, comstream, aInfo, &res
mThread->Dispatch(WrapRunnableNMRet(
&PeerConnectionImpl::MakeRemoteSource, comstream, aInfo, &res
), NS_DISPATCH_SYNC);
if (NS_FAILED(res)) {
@ -369,6 +311,7 @@ PeerConnectionImpl::Initialize(IPeerConnectionObserver* aObserver,
nsIThread* aThread) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aObserver);
MOZ_ASSERT(aThread);
mPCObserver = aObserver;
nsresult res;
@ -379,6 +322,8 @@ PeerConnectionImpl::Initialize(IPeerConnectionObserver* aObserver,
NS_ENSURE_SUCCESS(res, res);
#endif
mThread = aThread;
#ifdef MOZILLA_INTERNAL_API
// Currently no standalone unit tests for DataChannel,
// which is the user of mWindow
@ -387,8 +332,8 @@ PeerConnectionImpl::Initialize(IPeerConnectionObserver* aObserver,
NS_ENSURE_STATE(mWindow);
#endif
// The thread parameter can be passed in as NULL
mThread = aThread;
res = PeerConnectionCtx::InitializeGlobal(mThread);
NS_ENSURE_SUCCESS(res, res);
PeerConnectionCtx *pcctx = PeerConnectionCtx::GetInstance();
MOZ_ASSERT(pcctx);
@ -429,7 +374,7 @@ PeerConnectionImpl::Initialize(IPeerConnectionObserver* aObserver,
// Store under mHandle
mCall->setPeerConnection(mHandle);
peerconnections[mHandle] = this;
PeerConnectionCtx::GetInstance()->mPeerConnections[mHandle] = this;
// Create the DTLS Identity
mIdentity = DtlsIdentity::Generate();
@ -481,6 +426,7 @@ nsresult
PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aRetval)
{
MOZ_ASSERT(aRetval);
PC_AUTO_ENTER_API_CALL(false);
bool mute = false;
@ -494,8 +440,8 @@ PeerConnectionImpl::CreateFakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aR
if (!mThread || NS_IsMainThread()) {
res = MakeMediaStream(aHint, aRetval);
} else {
mThread->Dispatch(WrapRunnableRet(
this, &PeerConnectionImpl::MakeMediaStream, aHint, aRetval, &res
mThread->Dispatch(WrapRunnableNMRet(
&PeerConnectionImpl::MakeMediaStream, aHint, aRetval, &res
), NS_DISPATCH_SYNC);
}
@ -524,6 +470,8 @@ PeerConnectionImpl::ConnectDataConnection(uint16_t aLocalport,
uint16_t aRemoteport,
uint16_t aNumstreams)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
#ifdef MOZILLA_INTERNAL_API
mDataConnection = new mozilla::DataChannelConnection(this);
NS_ENSURE_TRUE(mDataConnection,NS_ERROR_FAILURE);
@ -551,6 +499,7 @@ PeerConnectionImpl::CreateDataChannel(const nsACString& aLabel,
uint16_t aMaxNum,
nsIDOMDataChannel** aRetval)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aRetval);
#ifdef MOZILLA_INTERNAL_API
@ -580,68 +529,65 @@ PeerConnectionImpl::CreateDataChannel(const nsACString& aLabel,
void
PeerConnectionImpl::NotifyConnection()
{
MOZ_ASSERT(NS_IsMainThread());
PC_AUTO_ENTER_API_CALL_NO_CHECK();
CSFLogDebugS(logTag, __FUNCTION__);
#ifdef MOZILLA_INTERNAL_API
if (mPCObserver) {
PeerConnectionObserverDispatch* runnable =
new PeerConnectionObserverDispatch(PC_OBSERVER_CONNECTION, nullptr,
this, mPCObserver);
if (mThread) {
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
return;
}
runnable->Run();
}
RUN_ON_THREAD(mThread,
WrapRunnable(mPCObserver,
&IPeerConnectionObserver::NotifyConnection),
NS_DISPATCH_NORMAL);
#endif
}
void
PeerConnectionImpl::NotifyClosedConnection()
{
MOZ_ASSERT(NS_IsMainThread());
PC_AUTO_ENTER_API_CALL_NO_CHECK();
CSFLogDebugS(logTag, __FUNCTION__);
#ifdef MOZILLA_INTERNAL_API
if (mPCObserver) {
PeerConnectionObserverDispatch* runnable =
new PeerConnectionObserverDispatch(PC_OBSERVER_CLOSEDCONNECTION, nullptr,
this, mPCObserver);
if (mThread) {
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
return;
}
runnable->Run();
}
RUN_ON_THREAD(mThread,
WrapRunnable(mPCObserver,
&IPeerConnectionObserver::NotifyClosedConnection),
NS_DISPATCH_NORMAL);
#endif
}
#ifdef MOZILLA_INTERNAL_API
// Not a member function so that we don't need to keep the PC live.
static void NotifyDataChannel_m(nsRefPtr<nsIDOMDataChannel> aChannel,
nsCOMPtr<IPeerConnectionObserver> aObserver)
{
MOZ_ASSERT(NS_IsMainThread());
aObserver->NotifyDataChannel(aChannel);
NS_DataChannelAppReady(aChannel);
}
#endif
void
PeerConnectionImpl::NotifyDataChannel(mozilla::DataChannel *aChannel)
{
MOZ_ASSERT(NS_IsMainThread());
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aChannel);
CSFLogDebugS(logTag, __FUNCTION__ << ": channel: " << static_cast<void*>(aChannel));
#ifdef MOZILLA_INTERNAL_API
nsCOMPtr<nsIDOMDataChannel> domchannel;
nsresult rv = NS_NewDOMDataChannel(aChannel, mWindow,
getter_AddRefs(domchannel));
nsCOMPtr<nsIDOMDataChannel> domchannel;
nsresult rv = NS_NewDOMDataChannel(aChannel, mWindow,
getter_AddRefs(domchannel));
NS_ENSURE_SUCCESS(rv,);
if (mPCObserver) {
PeerConnectionObserverDispatch* runnable =
new PeerConnectionObserverDispatch(PC_OBSERVER_DATACHANNEL, domchannel.get(),
this, mPCObserver);
if (mThread) {
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
return;
}
runnable->Run();
}
RUN_ON_THREAD(mThread,
WrapRunnableNM(NotifyDataChannel_m,
domchannel.get(),
mPCObserver),
NS_DISPATCH_NORMAL);
#endif
}
@ -714,21 +660,23 @@ PeerConnectionImpl::ConvertConstraints(
NS_IMETHODIMP
PeerConnectionImpl::CreateOffer(const JS::Value& aConstraints, JSContext* aCx)
{
CheckIceState();
PC_AUTO_ENTER_API_CALL(true);
MediaConstraints* cs = new MediaConstraints();
nsresult rv = ConvertConstraints(aConstraints, cs, aCx);
MediaConstraints cs;
nsresult rv = ConvertConstraints(aConstraints, &cs, aCx);
if (rv != NS_OK) {
return rv;
}
return CreateOffer(*cs);
return CreateOffer(cs);
}
// Used by unit tests and the IDL CreateOffer.
NS_IMETHODIMP
PeerConnectionImpl::CreateOffer(MediaConstraints& constraints)
{
PC_AUTO_ENTER_API_CALL(true);
mRole = kRoleOfferer; // TODO(ekr@rtfm.com): Interrogate SIPCC here?
cc_media_constraints_t* cc_constraints = nullptr;
@ -741,21 +689,22 @@ PeerConnectionImpl::CreateOffer(MediaConstraints& constraints)
NS_IMETHODIMP
PeerConnectionImpl::CreateAnswer(const JS::Value& aConstraints, JSContext* aCx)
{
CheckIceState();
PC_AUTO_ENTER_API_CALL(true);
MediaConstraints* cs = new MediaConstraints();
nsresult rv = ConvertConstraints(aConstraints, cs, aCx);
MediaConstraints cs;
nsresult rv = ConvertConstraints(aConstraints, &cs, aCx);
if (rv != NS_OK) {
return rv;
}
CreateAnswer(*cs);
return NS_OK;
return CreateAnswer(cs);
}
NS_IMETHODIMP
PeerConnectionImpl::CreateAnswer(MediaConstraints& constraints)
{
PC_AUTO_ENTER_API_CALL(true);
mRole = kRoleAnswerer; // TODO(ekr@rtfm.com): Interrogate SIPCC here?
cc_media_constraints_t* cc_constraints = nullptr;
@ -768,12 +717,13 @@ PeerConnectionImpl::CreateAnswer(MediaConstraints& constraints)
NS_IMETHODIMP
PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP)
{
PC_AUTO_ENTER_API_CALL(true);
if (!aSDP) {
CSFLogError(logTag, "%s - aSDP is NULL", __FUNCTION__);
return NS_ERROR_FAILURE;
}
CheckIceState();
mLocalRequestedSDP = aSDP;
mCall->setLocalDescription((cc_jsep_action_t)aAction, mLocalRequestedSDP);
return NS_OK;
@ -782,27 +732,30 @@ PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP)
NS_IMETHODIMP
PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP)
{
PC_AUTO_ENTER_API_CALL(true);
if (!aSDP) {
CSFLogError(logTag, "%s - aSDP is NULL", __FUNCTION__);
return NS_ERROR_FAILURE;
}
CheckIceState();
mRemoteRequestedSDP = aSDP;
mCall->setRemoteDescription((cc_jsep_action_t)action, mRemoteRequestedSDP);
return NS_OK;
}
NS_IMETHODIMP
PeerConnectionImpl::AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel) {
CheckIceState();
PC_AUTO_ENTER_API_CALL(true);
mCall->addICECandidate(aCandidate, aMid, aLevel);
return NS_OK;
}
NS_IMETHODIMP
PeerConnectionImpl::CloseStreams() {
PC_AUTO_ENTER_API_CALL(false);
if (mReadyState != PeerConnectionImpl::kClosed) {
ChangeReadyState(PeerConnectionImpl::kClosing);
}
@ -813,6 +766,8 @@ PeerConnectionImpl::CloseStreams() {
NS_IMETHODIMP
PeerConnectionImpl::AddStream(nsIDOMMediaStream* aMediaStream) {
PC_AUTO_ENTER_API_CALL(true);
uint32_t stream_id;
nsresult res = mMedia->AddStream(aMediaStream, &stream_id);
if (NS_FAILED(res))
@ -835,6 +790,8 @@ PeerConnectionImpl::AddStream(nsIDOMMediaStream* aMediaStream) {
NS_IMETHODIMP
PeerConnectionImpl::RemoveStream(nsIDOMMediaStream* aMediaStream) {
PC_AUTO_ENTER_API_CALL(true);
uint32_t stream_id;
nsresult res = mMedia->RemoveStream(aMediaStream, &stream_id);
@ -893,6 +850,7 @@ PeerConnectionImpl::GetFingerprint(char** fingerprint)
NS_IMETHODIMP
PeerConnectionImpl::GetLocalDescription(char** aSDP)
{
PC_AUTO_ENTER_API_CALL(true);
MOZ_ASSERT(aSDP);
char* tmp = new char[mLocalSDP.size() + 1];
@ -906,6 +864,7 @@ PeerConnectionImpl::GetLocalDescription(char** aSDP)
NS_IMETHODIMP
PeerConnectionImpl::GetRemoteDescription(char** aSDP)
{
PC_AUTO_ENTER_API_CALL(true);
MOZ_ASSERT(aSDP);
char* tmp = new char[mRemoteSDP.size() + 1];
@ -919,6 +878,7 @@ PeerConnectionImpl::GetRemoteDescription(char** aSDP)
NS_IMETHODIMP
PeerConnectionImpl::GetReadyState(uint32_t* aState)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aState);
*aState = mReadyState;
@ -928,6 +888,7 @@ PeerConnectionImpl::GetReadyState(uint32_t* aState)
NS_IMETHODIMP
PeerConnectionImpl::GetSipccState(uint32_t* aState)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aState);
PeerConnectionCtx* pcctx = PeerConnectionCtx::GetInstance();
@ -938,19 +899,42 @@ PeerConnectionImpl::GetSipccState(uint32_t* aState)
NS_IMETHODIMP
PeerConnectionImpl::GetIceState(uint32_t* aState)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aState);
*aState = mIceState;
return NS_OK;
}
nsresult
PeerConnectionImpl::CheckApiState(bool assert_ice_ready) const
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
PR_ASSERT(!assert_ice_ready || (mIceState != kIceGathering));
if (mReadyState == kClosed)
return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP
PeerConnectionImpl::Close(bool aIsSynchronous)
{
if (mCall != NULL)
PC_AUTO_ENTER_API_CALL(false);
return CloseInt(aIsSynchronous);
}
nsresult
PeerConnectionImpl::CloseInt(bool aIsSynchronous)
{
PC_AUTO_ENTER_API_CALL(true);
if (mCall != nullptr)
mCall->endCall();
#ifdef MOZILLA_INTERNAL_API
if (mDataConnection != NULL)
if (mDataConnection)
mDataConnection->CloseAll();
#endif
@ -964,13 +948,7 @@ PeerConnectionImpl::Close(bool aIsSynchronous)
void
PeerConnectionImpl::ShutdownMedia(bool aIsSynchronous)
{
// Check that we are on the main thread.
if (mThread) {
bool on;
MOZ_ASSERT(NS_SUCCEEDED(mThread->IsOnCurrentThread(&on)));
MOZ_ASSERT(on);
}
PC_AUTO_ENTER_API_CALL_NO_CHECK();
if (!mMedia)
return;
@ -1000,6 +978,7 @@ void
PeerConnectionImpl::onCallEvent(ccapi_call_event_e aCallEvent,
CSF::CC_CallPtr aCall, CSF::CC_CallInfoPtr aInfo)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aCall.get());
MOZ_ASSERT(aInfo.get());
@ -1042,47 +1021,50 @@ PeerConnectionImpl::onCallEvent(ccapi_call_event_e aCallEvent,
void
PeerConnectionImpl::ChangeReadyState(PeerConnectionImpl::ReadyState aReadyState)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
mReadyState = aReadyState;
// FIXME: Dispatch on main thread.
if (mPCObserver) {
PeerConnectionObserverDispatch* runnable =
new PeerConnectionObserverDispatch(PC_OBSERVER_READYSTATE, this, mPCObserver);
if (mThread) {
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
return;
}
runnable->Run();
}
// Note that we are passing an nsRefPtr<IPeerConnectionObserver> which
// keeps the observer live.
RUN_ON_THREAD(mThread, WrapRunnable(mPCObserver,
&IPeerConnectionObserver::OnStateChange,
IPeerConnectionObserver::kReadyState),
NS_DISPATCH_NORMAL);
}
PeerConnectionWrapper *PeerConnectionImpl::AcquireInstance(const std::string& aHandle)
{
if (peerconnections.find(aHandle) == peerconnections.end()) {
return NULL;
PeerConnectionWrapper::PeerConnectionWrapper(const std::string& handle)
: impl_(nullptr) {
if (PeerConnectionCtx::GetInstance()->mPeerConnections.find(handle) ==
PeerConnectionCtx::GetInstance()->mPeerConnections.end()) {
return;
}
PeerConnectionImpl *impl = peerconnections[aHandle];
impl->AddRef();
return new PeerConnectionWrapper(impl);
}
void
PeerConnectionImpl::ReleaseInstance()
{
Release();
impl_ = PeerConnectionCtx::GetInstance()->mPeerConnections[handle];
}
const std::string&
PeerConnectionImpl::GetHandle()
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mHandle;
}
// This is called from the STS thread and so we need to thunk
// to the main thread.
void
PeerConnectionImpl::IceGatheringCompleted(NrIceCtx *aCtx)
{
RUN_ON_THREAD(mThread,
WrapRunnable(this,
&PeerConnectionImpl::IceGatheringCompleted_m,
aCtx),
NS_DISPATCH_SYNC);
}
void
PeerConnectionImpl::IceGatheringCompleted_m(NrIceCtx *aCtx)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aCtx);
CSFLogDebugS(logTag, __FUNCTION__ << ": ctx: " << static_cast<void*>(aCtx));
@ -1091,13 +1073,11 @@ PeerConnectionImpl::IceGatheringCompleted(NrIceCtx *aCtx)
#ifdef MOZILLA_INTERNAL_API
if (mPCObserver) {
PeerConnectionObserverDispatch* runnable =
new PeerConnectionObserverDispatch(PC_OBSERVER_ICE, this, mPCObserver);
if (mThread) {
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
return;
}
runnable->Run();
RUN_ON_THREAD(mThread,
WrapRunnable(mPCObserver,
&IPeerConnectionObserver::OnStateChange,
IPeerConnectionObserver::kIceState),
NS_DISPATCH_NORMAL);
}
#endif
}
@ -1105,6 +1085,17 @@ PeerConnectionImpl::IceGatheringCompleted(NrIceCtx *aCtx)
void
PeerConnectionImpl::IceCompleted(NrIceCtx *aCtx)
{
RUN_ON_THREAD(mThread,
WrapRunnable(this,
&PeerConnectionImpl::IceCompleted_m,
aCtx),
NS_DISPATCH_SYNC);
}
void
PeerConnectionImpl::IceCompleted_m(NrIceCtx *aCtx)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aCtx);
CSFLogDebugS(logTag, __FUNCTION__ << ": ctx: " << static_cast<void*>(aCtx));
@ -1113,13 +1104,11 @@ PeerConnectionImpl::IceCompleted(NrIceCtx *aCtx)
#ifdef MOZILLA_INTERNAL_API
if (mPCObserver) {
PeerConnectionObserverDispatch* runnable =
new PeerConnectionObserverDispatch(PC_OBSERVER_ICE, this, mPCObserver);
if (mThread) {
mThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
return;
}
runnable->Run();
RUN_ON_THREAD(mThread,
WrapRunnable(mPCObserver,
&IPeerConnectionObserver::OnStateChange,
IPeerConnectionObserver::kIceState),
NS_DISPATCH_NORMAL);
}
#endif
}
@ -1127,6 +1116,7 @@ PeerConnectionImpl::IceCompleted(NrIceCtx *aCtx)
void
PeerConnectionImpl::IceStreamReady(NrIceMediaStream *aStream)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
MOZ_ASSERT(aStream);
CSFLogDebugS(logTag, __FUNCTION__ << ": " << aStream->name().c_str());
@ -1157,6 +1147,7 @@ GetStreams(JSContext* cx, PeerConnectionImpl* peerConnection,
NS_IMETHODIMP
PeerConnectionImpl::GetLocalStreams(JSContext* cx, JS::Value* streams)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
#ifdef MOZILLA_INTERNAL_API
return GetStreams(cx, this, MediaStreamList::Local, streams);
#else
@ -1167,6 +1158,7 @@ PeerConnectionImpl::GetLocalStreams(JSContext* cx, JS::Value* streams)
NS_IMETHODIMP
PeerConnectionImpl::GetRemoteStreams(JSContext* cx, JS::Value* streams)
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
#ifdef MOZILLA_INTERNAL_API
return GetStreams(cx, this, MediaStreamList::Remote, streams);
#else

View File

@ -42,6 +42,8 @@ using namespace mozilla;
namespace sipcc {
class PeerConnectionWrapper;
struct ConstraintInfo {
std::string value;
bool mandatory;
@ -60,6 +62,17 @@ private:
class PeerConnectionWrapper;
// Enter an API call and check that the state is OK,
// the PC isn't closed, etc.
#define PC_AUTO_ENTER_API_CALL(assert_ice_ready) \
do { \
/* do/while prevents res from conflicting with locals */ \
nsresult res = CheckApiState(assert_ice_ready); \
if (NS_FAILED(res)) return res; \
} while(0)
#define PC_AUTO_ENTER_API_CALL_NO_CHECK() CheckThread()
class PeerConnectionImpl MOZ_FINAL : public IPeerConnection,
#ifdef MOZILLA_INTERNAL_API
public mozilla::DataChannelConnection::DataConnectionListener,
@ -103,8 +116,16 @@ public:
static PeerConnectionImpl* CreatePeerConnection();
static void Shutdown();
static nsresult ConvertConstraints(
const JS::Value& aConstraints, MediaConstraints* aObj, JSContext* aCx);
static nsresult MakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aStream);
static nsresult MakeRemoteSource(nsDOMMediaStream* aStream, RemoteSourceStreamInfo** aInfo);
Role GetRole() const {
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mRole;
}
Role GetRole() const { return mRole; }
nsresult CreateRemoteSourceStreamInfo(uint32_t aHint, RemoteSourceStreamInfo** aInfo);
// Implementation of the only observer we need
@ -120,11 +141,12 @@ public:
void NotifyDataChannel(mozilla::DataChannel *aChannel);
// Get the media object
const nsRefPtr<PeerConnectionMedia>& media() const { return mMedia; }
const nsRefPtr<PeerConnectionMedia>& media() const {
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mMedia;
}
// Handle system to allow weak references to be passed through C code
static PeerConnectionWrapper *AcquireInstance(const std::string& aHandle);
virtual void ReleaseInstance();
virtual const std::string& GetHandle();
// ICE events
@ -136,23 +158,33 @@ public:
static void ConnectThread(void *aData);
// Get the main thread
nsCOMPtr<nsIThread> GetMainThread() { return mThread; }
nsCOMPtr<nsIThread> GetMainThread() {
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mThread;
}
// Get the STS thread
nsCOMPtr<nsIEventTarget> GetSTSThread() { return mSTSThread; }
nsCOMPtr<nsIEventTarget> GetSTSThread() {
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mSTSThread;
}
// Get the DTLS identity
mozilla::RefPtr<DtlsIdentity> const GetIdentity() { return mIdentity; }
mozilla::RefPtr<DtlsIdentity> const GetIdentity() {
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mIdentity;
}
// Create a fake media stream
nsresult CreateFakeMediaStream(uint32_t hint, nsIDOMMediaStream** retval);
nsPIDOMWindow* GetWindow() const { return mWindow; }
nsPIDOMWindow* GetWindow() const {
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mWindow;
}
// Validate constraints and construct a MediaConstraints object
// from a JS::Value.
nsresult ConvertConstraints(
const JS::Value& aConstraints, MediaConstraints* aObj, JSContext* aCx);
NS_IMETHODIMP CreateOffer(MediaConstraints& aConstraints);
NS_IMETHODIMP CreateAnswer(MediaConstraints& aConstraints);
@ -160,16 +192,33 @@ private:
PeerConnectionImpl(const PeerConnectionImpl&rhs);
PeerConnectionImpl& operator=(PeerConnectionImpl);
NS_IMETHODIMP CreateOfferInt(MediaConstraints& constraints);
NS_IMETHODIMP CreateAnswerInt(MediaConstraints& constraints);
nsresult CloseInt(bool aIsSynchronous);
void ChangeReadyState(ReadyState aReadyState);
void CheckIceState() {
PR_ASSERT(mIceState != kIceGathering);
nsresult CheckApiState(bool assert_ice_ready) const;
void CheckThread() const {
NS_ABORT_IF_FALSE(CheckThreadInt(), "Wrong thread");
}
bool CheckThreadInt() const {
#ifdef MOZILLA_INTERNAL_API
// Thread assertions are disabled in the C++ unit tests because those
// make API calls off the main thread.
// TODO(ekr@rtfm.com): Fix the unit tests so they don't do that.
bool on;
NS_ENSURE_SUCCESS(mThread->IsOnCurrentThread(&on), false);
NS_ENSURE_TRUE(on, false);
#endif
return true;
}
// Shut down media. Called on any thread.
void ShutdownMedia(bool isSynchronous);
nsresult MakeMediaStream(uint32_t aHint, nsIDOMMediaStream** aStream);
nsresult MakeRemoteSource(nsDOMMediaStream* aStream, RemoteSourceStreamInfo** aInfo);
// ICE callbacks run on the right thread.
void IceGatheringCompleted_m(NrIceCtx *aCtx);
void IceCompleted_m(NrIceCtx *aCtx);
// The role we are adopting
Role mRole;
@ -212,9 +261,6 @@ private:
nsRefPtr<PeerConnectionMedia> mMedia;
// Singleton list of all the PeerConnections
static std::map<const std::string, PeerConnectionImpl *> peerconnections;
public:
//these are temporary until the DataChannel Listen/Connect API is removed
unsigned short listenPort;
@ -225,17 +271,12 @@ public:
// This is what is returned when you acquire on a handle
class PeerConnectionWrapper {
public:
PeerConnectionWrapper(PeerConnectionImpl *impl) : impl_(impl) {}
~PeerConnectionWrapper() {
if (impl_)
impl_->ReleaseInstance();
}
PeerConnectionWrapper(const std::string& handle);
PeerConnectionImpl *impl() { return impl_; }
private:
PeerConnectionImpl *impl_;
nsRefPtr<PeerConnectionImpl> impl_;
};
} // end sipcc namespace

View File

@ -48,15 +48,17 @@ public:
// Note: only one listener supported
class Fake_MediaStream {
public:
Fake_MediaStream () : mListeners() {}
public:
Fake_MediaStream () : mListeners(), mMutex("Fake MediaStream") {}
virtual ~Fake_MediaStream() { Stop(); }
void AddListener(Fake_MediaStreamListener *aListener) {
mozilla::MutexAutoLock lock(mMutex);
mListeners.insert(aListener);
}
void RemoveListener(Fake_MediaStreamListener *aListener) {
mozilla::MutexAutoLock lock(mMutex);
mListeners.erase(aListener);
}
@ -67,8 +69,12 @@ public:
virtual void Periodic() {}
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Fake_MediaStream);
protected:
std::set<Fake_MediaStreamListener *> mListeners;
mozilla::Mutex mMutex; // Lock to prevent the listener list from being modified while
// executing Periodic().
};
class Fake_MediaPeriodic : public nsITimerCallback {
@ -205,7 +211,7 @@ public:
void SetHintContents(uint32_t aHintContents) { mHintContents = aHintContents; }
private:
Fake_MediaStream *mMediaStream;
nsRefPtr<Fake_MediaStream> mMediaStream;
// tells the SDP generator about whether this
// MediaStream probably has audio and/or video

View File

@ -38,6 +38,7 @@ nsresult Fake_SourceMediaStream::Start() {
}
nsresult Fake_SourceMediaStream::Stop() {
mozilla::MutexAutoLock lock(mMutex);
if (mTimer)
mTimer->Cancel();
mPeriodic->Detach();
@ -45,6 +46,7 @@ nsresult Fake_SourceMediaStream::Stop() {
}
void Fake_SourceMediaStream::Periodic() {
mozilla::MutexAutoLock lock(mMutex);
// Pull more audio-samples iff pulling is enabled
// and we are not asked by the signaling agent to stop
//pulling data.
@ -69,6 +71,10 @@ nsresult Fake_MediaStreamBase::Start() {
}
nsresult Fake_MediaStreamBase::Stop() {
// Lock the mutex so that we know that after this
// has returned, periodic will not be firing again
// and so it's safe to destruct.
mozilla::MutexAutoLock lock(mMutex);
mTimer->Cancel();
return NS_OK;
@ -76,6 +82,7 @@ nsresult Fake_MediaStreamBase::Stop() {
// Fake_AudioStreamSource
void Fake_AudioStreamSource::Periodic() {
mozilla::MutexAutoLock lock(mMutex);
//Are we asked to stop pumping audio samples ?
if(mStop) {
return;

View File

@ -297,20 +297,20 @@ TestObserver::OnAddStream(nsIDOMMediaStream *stream, const char *type)
nsDOMMediaStream *ms = static_cast<nsDOMMediaStream *>(stream);
cout << "OnAddStream called hints=" << ms->GetHintContents() << endl;
state = stateSuccess;
cout << "OnAddStream called hints=" << ms->GetHintContents() << " type=" << type << " thread=" <<
PR_GetCurrentThread() << endl ;
onAddStreamCalled = true;
streams.push_back(ms);
// We know that the media stream is secretly a Fake_SourceMediaStream,
// so now we can start it pulling from us
Fake_SourceMediaStream *fs = static_cast<Fake_SourceMediaStream *>(ms->GetStream());
nsresult ret;
test_utils->sts_target()->Dispatch(
WrapRunnableRet(fs, &Fake_SourceMediaStream::Start, &ret),
NS_DISPATCH_SYNC);
streams.push_back(ms);
WrapRunnable(fs, &Fake_SourceMediaStream::Start),
NS_DISPATCH_NORMAL);
return NS_OK;
}
@ -475,14 +475,15 @@ class ParsedSDP {
class SignalingAgent {
public:
SignalingAgent() {
Init();
}
SignalingAgent() : pc(nullptr) {}
~SignalingAgent() {
Close();
pc->GetMainThread()->Dispatch(
WrapRunnable(this, &SignalingAgent::Close),
NS_DISPATCH_SYNC);
}
void Init()
void Init(nsCOMPtr<nsIThread> thread)
{
size_t found = 2;
ASSERT_TRUE(found > 0);
@ -493,7 +494,7 @@ class SignalingAgent {
pObserver = new TestObserver(pc);
ASSERT_TRUE(pObserver);
ASSERT_EQ(pc->Initialize(pObserver, nullptr, nullptr), NS_OK);
ASSERT_EQ(pc->Initialize(pObserver, nullptr, thread), NS_OK);
ASSERT_TRUE_WAIT(sipcc_state() == sipcc::PeerConnectionImpl::kStarted,
kDefaultTimeout);
@ -520,7 +521,10 @@ class SignalingAgent {
void Close()
{
cout << "Close" << endl;
pc->Close(false);
pc = nullptr;
// Shutdown is synchronous evidently.
// ASSERT_TRUE(pObserver->WaitForObserverCall());
// ASSERT_EQ(pc->sipcc_state(), sipcc::PeerConnectionInterface::kIdle);
@ -794,6 +798,24 @@ class SignalingEnvironment : public ::testing::Environment {
class SignalingTest : public ::testing::Test {
public:
static void SetUpTestCase() {
nsIThread *thread;
nsresult rv = NS_NewThread(&thread);
ASSERT_TRUE(NS_SUCCEEDED(rv));
gThread = thread;
}
void SetUp() {
a1_.Init(gThread);
a2_.Init(gThread);
}
static void TearDownTestCase() {
gThread = nullptr;
}
void CreateOffer(sipcc::MediaConstraints& constraints,
uint32_t offerFlags, uint32_t sdpCheck) {
a1_.CreateOffer(constraints, offerFlags, sdpCheck);
@ -882,10 +904,13 @@ public:
}
protected:
static nsCOMPtr<nsIThread> gThread;
SignalingAgent a1_; // Canonically "caller"
SignalingAgent a2_; // Canonically "callee"
};
nsCOMPtr<nsIThread> SignalingTest::gThread;
TEST_F(SignalingTest, JustInit)
{
@ -1232,6 +1257,7 @@ TEST_F(SignalingTest, FullCallTrickle)
OfferAnswerTrickle(constraints, constraints,
SHOULD_SENDRECV_AV, SHOULD_SENDRECV_AV);
std::cerr << "ICE handshake completed" << std::endl;
PR_Sleep(kDefaultTimeout * 2); // Wait for some data to get written
a1_.CloseSendStreams();