Bug 906990: Part 12. Report statistics from all components when the MediaStreamTrack is not specified. r=ekr, r=jib

This commit is contained in:
Byron Campen [:bwc] 2014-01-14 08:48:27 -08:00
parent cd38456723
commit b5354c4365
9 changed files with 306 additions and 163 deletions

View File

@ -119,13 +119,17 @@ GlobalPCList.prototype = {
},
getStatsForEachPC: function(callback, errorCallback) {
function getStatsFromPC(pcref) {
if (pcref.get()) {
pcref.get().getStatsInternal(null, callback, errorCallback);
}
}
for (let winId in this._list) {
if (this._list.hasOwnProperty(winId)) {
this.removeNullRefs(winId);
if (this._list[winId]) {
this._list[winId].forEach(function(pcref) {
pcref.get().getStatsInternal(null, callback, errorCallback);
});
this._list[winId].forEach(getStatsFromPC);
}
}
}

View File

@ -1488,8 +1488,17 @@ PeerConnectionWrapper.prototype = {
ok(toNum(counters["inboundrtp"]) >= nin, "Have at least " + nin + " inboundrtp stat(s) *");
is(toNum(counters["outboundrtp"]), nout, "Have " + nout + " outboundrtp stat(s)");
ok(toNum(counters["localcandidate"]), "Have localcandidate stat(s)");
ok(toNum(counters["remotecandidate"]), "Have remotecandidate stat(s)");
var numLocalCandidates = toNum(counters["localcandidate"]);
var numRemoteCandidates = toNum(counters["remotecandidate"]);
// If there are no tracks, there will be no stats either.
if (nin + nout > 0) {
ok(numLocalCandidates, "Have localcandidate stat(s)");
ok(numRemoteCandidates, "Have remotecandidate stat(s)");
} else {
is(numLocalCandidates, 0, "Have no localcandidate stats");
is(numRemoteCandidates, 0, "Have no remotecandidate stats");
}
},
/**

View File

@ -104,6 +104,7 @@ enum RTCStatsIceCandidateType {
};
dictionary RTCIceCandidateStats : RTCStats {
DOMString componentId;
DOMString candidateId;
DOMString ipAddress;
long portNumber;

View File

@ -1589,6 +1589,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
pc.impl()->GetSTSThread(),
stream->GetMediaStream()->GetStream(),
pc_track_id,
level,
conduit, rtp_flow, rtcp_flow);
nsresult res = pipeline->Init();
@ -1640,6 +1641,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
pc.impl()->GetSTSThread(),
stream->GetMediaStream()->GetStream(),
pc_track_id,
level,
conduit, rtp_flow, rtcp_flow);
nsresult res = pipeline->Init();
@ -2241,6 +2243,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
pc.impl()->GetSTSThread(),
stream->GetMediaStream(),
pc_track_id,
level,
conduit, rtp_flow, rtcp_flow);
nsresult res = pipeline->Init();
@ -2291,6 +2294,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
pc.impl()->GetSTSThread(),
stream->GetMediaStream(),
pc_track_id,
level,
conduit, rtp_flow, rtcp_flow);
nsresult res = pipeline->Init();

View File

@ -71,12 +71,14 @@ class MediaPipeline : public sigslot::has_slots<> {
nsCOMPtr<nsIEventTarget> sts_thread,
MediaStream *stream,
TrackID track_id,
int level,
RefPtr<MediaSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
RefPtr<TransportFlow> rtcp_transport)
: direction_(direction),
stream_(stream),
track_id_(track_id),
level_(level),
conduit_(conduit),
rtp_transport_(rtp_transport),
rtp_state_(MP_CONNECTING),
@ -126,6 +128,7 @@ class MediaPipeline : public sigslot::has_slots<> {
virtual Direction direction() const { return direction_; }
virtual TrackID trackid() const { return track_id_; }
virtual int level() const { return level_; }
bool IsDoingRtcpMux() const {
return (rtp_transport_ == rtcp_transport_);
@ -194,6 +197,7 @@ class MediaPipeline : public sigslot::has_slots<> {
// Used on STS and MediaStreamGraph threads.
TrackID track_id_; // The track on the stream.
// Written and used as the stream_;
int level_; // The m-line index (starting at 1, to match convention)
RefPtr<MediaSessionConduit> conduit_; // Our conduit. Written on the main
// thread. Read on STS thread.
@ -315,12 +319,13 @@ class MediaPipelineTransmit : public MediaPipeline {
nsCOMPtr<nsIEventTarget> sts_thread,
DOMMediaStream *domstream,
TrackID track_id,
int level,
RefPtr<MediaSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
RefPtr<TransportFlow> rtcp_transport) :
MediaPipeline(pc, TRANSMIT, main_thread, sts_thread,
domstream->GetStream(), track_id, conduit, rtp_transport,
rtcp_transport),
domstream->GetStream(), track_id, level,
conduit, rtp_transport, rtcp_transport),
listener_(new PipelineListener(conduit)),
domstream_(domstream)
{}
@ -437,11 +442,12 @@ class MediaPipelineReceive : public MediaPipeline {
nsCOMPtr<nsIEventTarget> sts_thread,
MediaStream *stream,
TrackID track_id,
int level,
RefPtr<MediaSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
RefPtr<TransportFlow> rtcp_transport) :
MediaPipeline(pc, RECEIVE, main_thread, sts_thread,
stream, track_id, conduit, rtp_transport,
stream, track_id, level, conduit, rtp_transport,
rtcp_transport),
segments_added_(0) {
}
@ -464,11 +470,12 @@ class MediaPipelineReceiveAudio : public MediaPipelineReceive {
nsCOMPtr<nsIEventTarget> sts_thread,
MediaStream *stream,
TrackID track_id,
int level,
RefPtr<AudioSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
RefPtr<TransportFlow> rtcp_transport) :
MediaPipelineReceive(pc, main_thread, sts_thread,
stream, track_id, conduit, rtp_transport,
stream, track_id, level, conduit, rtp_transport,
rtcp_transport),
listener_(new PipelineListener(stream->AsSourceStream(),
track_id, conduit)) {
@ -526,11 +533,12 @@ class MediaPipelineReceiveVideo : public MediaPipelineReceive {
nsCOMPtr<nsIEventTarget> sts_thread,
MediaStream *stream,
TrackID track_id,
int level,
RefPtr<VideoSessionConduit> conduit,
RefPtr<TransportFlow> rtp_transport,
RefPtr<TransportFlow> rtcp_transport) :
MediaPipelineReceive(pc, main_thread, sts_thread,
stream, track_id, conduit, rtp_transport,
stream, track_id, level, conduit, rtp_transport,
rtcp_transport),
renderer_(new PipelineRenderer(MOZ_THIS_IN_INITIALIZER_LIST())),
listener_(new PipelineListener(stream->AsSourceStream(), track_id)) {

View File

@ -5,6 +5,7 @@
#include <cstdlib>
#include <cerrno>
#include <deque>
#include <sstream>
#include "base/histogram.h"
#include "vcm.h"
@ -32,6 +33,7 @@
#include "nsIConsoleService.h"
#include "nsThreadUtils.h"
#include "nsProxyRelease.h"
#include "prtime.h"
#include "runnable_utils.h"
#include "PeerConnectionCtx.h"
@ -56,6 +58,7 @@
#include "nsURLHelper.h"
#include "nsNetUtil.h"
#include "nsIDOMDataChannel.h"
#include "nsIDOMLocation.h"
#include "mozilla/dom/RTCConfigurationBinding.h"
#include "mozilla/dom/RTCStatsReportBinding.h"
#include "mozilla/dom/RTCPeerConnectionBinding.h"
@ -715,8 +718,36 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
MOZ_ASSERT(aWindow);
mWindow = aWindow;
NS_ENSURE_STATE(mWindow);
#endif // MOZILLA_INTERNAL_API
PRTime timestamp = PR_Now();
// Ok if we truncate this.
char temp[128];
#ifdef MOZILLA_INTERNAL_API
nsIDOMLocation* location = nullptr;
mWindow->GetLocation(&location);
MOZ_ASSERT(location);
nsString locationAStr;
location->ToString(locationAStr);
location->Release();
nsCString locationCStr;
CopyUTF16toUTF8(locationAStr, locationCStr);
MOZ_ASSERT(mWindow);
PR_snprintf(temp,
sizeof(temp),
"%llu (id=%u url=%s)",
(unsigned long long)timestamp,
(unsigned)mWindow->WindowID(),
locationCStr.get() ? locationCStr.get() : "NULL");
#else
PR_snprintf(temp, sizeof(temp), "%llu", (unsigned long long)timestamp);
#endif // MOZILLA_INTERNAL_API
mName = temp;
// Generate a random handle
unsigned char handle_bin[8];
SECStatus rv;
@ -1265,29 +1296,49 @@ PeerConnectionImpl::GetStats(MediaStreamTrack *aSelector, bool internalStats) {
// Gather up pipelines from mMedia and dispatch them to STS for inspection
nsAutoPtr<std::vector<RefPtr<MediaPipeline>>> pipelines(
new std::vector<RefPtr<MediaPipeline>>());
std::vector<RefPtr<MediaPipeline>> pipelines;
TrackID trackId = aSelector ? aSelector->GetTrackID() : 0;
for (int i = 0, len = mMedia->LocalStreamsLength(); i < len; i++) {
PushBackSelect(*pipelines, mMedia->GetLocalStream(i)->GetPipelines(), trackId);
PushBackSelect(pipelines, mMedia->GetLocalStream(i)->GetPipelines(), trackId);
}
for (int i = 0, len = mMedia->RemoteStreamsLength(); i < len; i++) {
PushBackSelect(*pipelines, mMedia->GetRemoteStream(i)->GetPipelines(), trackId);
PushBackSelect(pipelines, mMedia->GetRemoteStream(i)->GetPipelines(), trackId);
}
// From the list of MediaPipelines, determine the set of NrIceMediaStreams
// we are interested in.
std::vector<RefPtr<NrIceMediaStream> > streams;
RefPtr<NrIceCtx> iceCtx(mMedia->ice_ctx());
for (auto p = pipelines.begin(); p != pipelines.end(); ++p) {
size_t level = p->get()->level();
// TODO(bcampen@mozilla.com): I may need to revisit this for bundle.
// (Bug 786234)
RefPtr<NrIceMediaStream> temp(mMedia->ice_media_stream(level-1));
if (temp.get()) {
streams.push_back(temp);
} else {
CSFLogError(logTag, "Failed to get NrIceMediaStream for level %u "
"in %s: %s",
level, __FUNCTION__, mHandle.c_str());
MOZ_CRASH();
}
}
DOMHighResTimeStamp now;
nsresult rv = GetTimeSinceEpoch(&now);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<PeerConnectionImpl> pc(this);
RUN_ON_THREAD(mSTSThread,
WrapRunnable(pc,
&PeerConnectionImpl::GetStats_s,
trackId,
internalStats,
pipelines,
now),
WrapRunnableNM(&PeerConnectionImpl::GetStats_s,
mHandle,
mName,
mThread,
internalStats,
pipelines,
iceCtx,
streams,
now),
NS_DISPATCH_NORMAL);
#endif
return NS_OK;
@ -1299,11 +1350,11 @@ PeerConnectionImpl::GetLogging(const nsAString& aPattern) {
#ifdef MOZILLA_INTERNAL_API
std::string pattern(NS_ConvertUTF16toUTF8(aPattern).get());
nsRefPtr<PeerConnectionImpl> pc(this);
RUN_ON_THREAD(mSTSThread,
WrapRunnable(pc,
&PeerConnectionImpl::GetLogging_s,
pattern),
WrapRunnableNM(&PeerConnectionImpl::GetLogging_s,
mHandle,
mThread,
pattern),
NS_DISPATCH_NORMAL);
#endif
@ -1749,6 +1800,13 @@ PeerConnectionImpl::GetHandle()
return mHandle;
}
const std::string&
PeerConnectionImpl::GetName()
{
PC_AUTO_ENTER_API_CALL_NO_CHECK();
return mName;
}
static mozilla::dom::PCImplIceConnectionState
toDomIceConnectionState(NrIceCtx::ConnectionState state) {
switch (state) {
@ -1896,15 +1954,16 @@ PeerConnectionImpl::IceGatheringStateChange_m(PCImplIceGatheringState aState)
#ifdef MOZILLA_INTERNAL_API
nsresult
PeerConnectionImpl::GetStatsImpl_s(
TrackID trackId,
bool internalStats,
nsAutoPtr<std::vector<RefPtr<MediaPipeline>>> pipelines,
const std::vector<RefPtr<MediaPipeline>>& pipelines,
const RefPtr<NrIceCtx>& iceCtx,
const std::vector<RefPtr<NrIceMediaStream>>& streams,
DOMHighResTimeStamp now,
RTCStatsReportInternal *report) {
RTCStatsReportInternal* report) {
// Gather stats from pipelines provided (can't touch mMedia + stream on STS)
for (auto it = pipelines->begin(); it != pipelines->end(); ++it) {
for (auto it = pipelines.begin(); it != pipelines.end(); ++it) {
const MediaPipeline& mp = **it;
nsString idstr = (mp.Conduit()->type() == MediaSessionConduit::AUDIO) ?
NS_LITERAL_STRING("audio_") : NS_LITERAL_STRING("video_");
@ -1938,152 +1997,184 @@ PeerConnectionImpl::GetStatsImpl_s(
}
}
if (mMedia) {
// Gather stats from ICE
RefPtr<NrIceMediaStream> mediaStream(mMedia->ice_media_stream(trackId));
if (mediaStream) {
std::vector<NrIceCandidatePair> candPairs;
mediaStream->GetCandidatePairs(&candPairs);
NS_ConvertASCIItoUTF16 componentId(mediaStream->name().c_str());
for (auto p = candPairs.begin(); p != candPairs.end(); ++p) {
NS_ConvertASCIItoUTF16 codeword(p->codeword.c_str());
NS_ConvertASCIItoUTF16 localCodeword(p->local.codeword.c_str());
NS_ConvertASCIItoUTF16 remoteCodeword(p->remote.codeword.c_str());
// Only expose candidate-pair statistics to chrome, until we've thought
// through the implications of exposing it to content.
if (internalStats) {
RTCIceCandidatePairStats s;
s.mId.Construct(codeword);
s.mComponentId.Construct(componentId);
s.mTimestamp.Construct(now);
s.mType.Construct(RTCStatsType::Candidatepair);
// Not quite right; we end up with duplicate candidates. Will fix.
s.mLocalCandidateId.Construct(localCodeword);
s.mRemoteCandidateId.Construct(remoteCodeword);
s.mNominated.Construct(p->nominated);
s.mMozPriority.Construct(p->priority);
s.mSelected.Construct(p->selected);
s.mState.Construct(RTCStatsIceCandidatePairState(p->state));
report->mIceCandidatePairStats.Value().AppendElement(s);
}
{
RTCIceCandidateStats local;
local.mId.Construct(localCodeword);
local.mTimestamp.Construct(now);
local.mType.Construct(RTCStatsType::Localcandidate);
local.mCandidateType.Construct(
RTCStatsIceCandidateType(p->local.type));
local.mIpAddress.Construct(
NS_ConvertASCIItoUTF16(p->local.cand_addr.host.c_str()));
local.mPortNumber.Construct(p->local.cand_addr.port);
report->mIceCandidateStats.Value().AppendElement(local);
}
{
RTCIceCandidateStats remote;
remote.mId.Construct(remoteCodeword);
remote.mTimestamp.Construct(now);
remote.mType.Construct(RTCStatsType::Remotecandidate);
remote.mCandidateType.Construct(
RTCStatsIceCandidateType(p->remote.type));
remote.mIpAddress.Construct(
NS_ConvertASCIItoUTF16(p->remote.cand_addr.host.c_str()));
remote.mPortNumber.Construct(p->remote.cand_addr.port);
report->mIceCandidateStats.Value().AppendElement(remote);
}
}
}
// Gather stats from ICE
for (auto s = streams.begin(); s != streams.end(); ++s) {
FillStatsReport_s(**s, internalStats, now, report);
}
return NS_OK;
}
void PeerConnectionImpl::GetStats_s(
TrackID trackId,
void PeerConnectionImpl::FillStatsReport_s(
NrIceMediaStream& mediaStream,
bool internalStats,
nsAutoPtr<std::vector<RefPtr<MediaPipeline>>> pipelines,
DOMHighResTimeStamp now,
RTCStatsReportInternal* report) {
std::vector<NrIceCandidatePair> candPairs;
nsresult res = mediaStream.GetCandidatePairs(&candPairs);
if (NS_FAILED(res)) {
CSFLogError(logTag, "%s: Error getting candidate pairs", __FUNCTION__);
return;
}
NS_ConvertASCIItoUTF16 componentId(mediaStream.name().c_str());
for (auto p = candPairs.begin(); p != candPairs.end(); ++p) {
NS_ConvertASCIItoUTF16 codeword(p->codeword.c_str());
NS_ConvertASCIItoUTF16 localCodeword(p->local.codeword.c_str());
NS_ConvertASCIItoUTF16 remoteCodeword(p->remote.codeword.c_str());
// Only expose candidate-pair statistics to chrome, until we've thought
// through the implications of exposing it to content.
if (internalStats) {
RTCIceCandidatePairStats s;
s.mId.Construct(codeword);
s.mComponentId.Construct(componentId);
s.mTimestamp.Construct(now);
s.mType.Construct(RTCStatsType::Candidatepair);
s.mLocalCandidateId.Construct(localCodeword);
s.mRemoteCandidateId.Construct(remoteCodeword);
s.mNominated.Construct(p->nominated);
s.mMozPriority.Construct(p->priority);
s.mSelected.Construct(p->selected);
s.mState.Construct(RTCStatsIceCandidatePairState(p->state));
report->mIceCandidatePairStats.Value().AppendElement(s);
}
{
RTCIceCandidateStats local;
local.mComponentId.Construct(componentId);
local.mId.Construct(localCodeword);
local.mTimestamp.Construct(now);
local.mType.Construct(RTCStatsType::Localcandidate);
local.mCandidateType.Construct(
RTCStatsIceCandidateType(p->local.type));
local.mIpAddress.Construct(
NS_ConvertASCIItoUTF16(p->local.cand_addr.host.c_str()));
local.mPortNumber.Construct(p->local.cand_addr.port);
report->mIceCandidateStats.Value().AppendElement(local);
}
{
RTCIceCandidateStats remote;
remote.mComponentId.Construct(componentId);
remote.mId.Construct(remoteCodeword);
remote.mTimestamp.Construct(now);
remote.mType.Construct(RTCStatsType::Remotecandidate);
remote.mCandidateType.Construct(
RTCStatsIceCandidateType(p->remote.type));
remote.mIpAddress.Construct(
NS_ConvertASCIItoUTF16(p->remote.cand_addr.host.c_str()));
remote.mPortNumber.Construct(p->remote.cand_addr.port);
report->mIceCandidateStats.Value().AppendElement(remote);
}
}
}
void PeerConnectionImpl::GetStats_s(
const std::string& pcHandle, // The Runnable holds the memory
const std::string& pcName, // The Runnable holds the memory
nsCOMPtr<nsIThread> callbackThread,
bool internalStats,
const std::vector<RefPtr<MediaPipeline>>& pipelines,
const RefPtr<NrIceCtx>& iceCtx,
const std::vector<RefPtr<NrIceMediaStream>>& streams,
DOMHighResTimeStamp now) {
nsAutoPtr<RTCStatsReportInternal> report(new RTCStatsReportInternalConstruct(
NS_ConvertASCIItoUTF16(mHandle.c_str()), now));
// We do not use the pcHandle here, since that's risky to expose to content.
nsAutoPtr<RTCStatsReportInternal> report(
new RTCStatsReportInternalConstruct(
NS_ConvertASCIItoUTF16(pcName.c_str()),
now));
nsresult rv = report ? GetStatsImpl_s(trackId, internalStats, pipelines, now,
report)
: NS_ERROR_UNEXPECTED;
nsresult rv = GetStatsImpl_s(internalStats,
pipelines,
iceCtx,
streams,
now,
report);
nsRefPtr<PeerConnectionImpl> pc(this);
RUN_ON_THREAD(mThread,
WrapRunnable(pc,
&PeerConnectionImpl::OnStatsReport_m,
rv,
pipelines, // return for release on main thread
report),
RUN_ON_THREAD(callbackThread,
WrapRunnableNM(&PeerConnectionImpl::OnStatsReport_m,
pcHandle,
rv,
pipelines, // return for release on main thread
report),
NS_DISPATCH_NORMAL);
}
void PeerConnectionImpl::OnStatsReport_m(
const std::string& pcHandle,
nsresult result,
nsAutoPtr<std::vector<RefPtr<MediaPipeline>>> pipelines, //returned for release
const std::vector<RefPtr<MediaPipeline>>& pipelines, //returned for release
nsAutoPtr<RTCStatsReportInternal> report) {
nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
if (pco) {
JSErrorResult rv;
if (NS_SUCCEEDED(result)) {
pco->OnGetStatsSuccess(*report, rv);
} else {
pco->OnGetStatsError(kInternalError,
ObString("Failed to fetch statistics"),
rv);
}
if (rv.Failed()) {
CSFLogError(logTag, "Error firing stats observer callback");
// Is the PeerConnectionImpl still around?
PeerConnectionWrapper pcw(pcHandle);
if (pcw.impl()) {
nsRefPtr<PeerConnectionObserver> pco =
do_QueryObjectReferent(pcw.impl()->mPCObserver);
if (pco) {
JSErrorResult rv;
if (NS_SUCCEEDED(result)) {
pco->OnGetStatsSuccess(*report, rv);
} else {
pco->OnGetStatsError(kInternalError,
ObString("Failed to fetch statistics"),
rv);
}
if (rv.Failed()) {
CSFLogError(logTag, "Error firing stats observer callback");
}
}
}
}
void PeerConnectionImpl::GetLogging_s(const std::string& pattern) {
void PeerConnectionImpl::GetLogging_s(const std::string& pcHandle,
nsCOMPtr<nsIThread> callbackThread,
const std::string& pattern) {
RLogRingBuffer* logs = RLogRingBuffer::GetInstance();
std::deque<std::string> result;
logs->Filter(pattern, 0, &result);
nsRefPtr<PeerConnectionImpl> pc(this);
RUN_ON_THREAD(mThread,
WrapRunnable(pc,
&PeerConnectionImpl::OnGetLogging_m,
pattern,
result),
nsAutoPtr<std::deque<std::string>> result(new std::deque<std::string>);
logs->Filter(pattern, 0, result);
RUN_ON_THREAD(callbackThread,
WrapRunnableNM(&PeerConnectionImpl::OnGetLogging_m,
pcHandle,
pattern,
result),
NS_DISPATCH_NORMAL);
}
void PeerConnectionImpl::OnGetLogging_m(const std::string& pattern,
const std::deque<std::string>& logging) {
nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
if (!pco) {
return;
}
void PeerConnectionImpl::OnGetLogging_m(
const std::string& pcHandle,
const std::string& pattern,
nsAutoPtr<std::deque<std::string>> logging) {
JSErrorResult rv;
if (!logging.empty()) {
Sequence<nsString> nsLogs;
for (auto l = logging.begin(); l != logging.end(); ++l) {
nsLogs.AppendElement(ObString(l->c_str()));
// Is the PeerConnectionImpl still around?
PeerConnectionWrapper pcw(pcHandle);
if (pcw.impl()) {
nsRefPtr<PeerConnectionObserver> pco =
do_QueryObjectReferent(pcw.impl()->mPCObserver);
if (pco) {
JSErrorResult rv;
if (!logging->empty()) {
Sequence<nsString> nsLogs;
for (auto l = logging->begin(); l != logging->end(); ++l) {
nsLogs.AppendElement(ObString(l->c_str()));
}
pco->OnGetLoggingSuccess(nsLogs, rv);
} else {
pco->OnGetLoggingError(kInternalError,
ObString(("No logging matching pattern " + pattern).c_str()), rv);
}
if (rv.Failed()) {
CSFLogError(logTag, "Error firing stats observer callback");
}
}
pco->OnGetLoggingSuccess(nsLogs, rv);
} else {
pco->OnGetLoggingError(kInternalError,
ObString(("No logging matching pattern " + pattern).c_str()), rv);
}
if (rv.Failed()) {
CSFLogError(logTag, "Error firing stats observer callback");
}
}
#endif
void

View File

@ -223,6 +223,9 @@ public:
// Handle system to allow weak references to be passed through C code
virtual const std::string& GetHandle();
// Name suitable for exposing to content
virtual const std::string& GetName();
// ICE events
void IceConnectionStateChange(NrIceCtx* ctx,
NrIceCtx::ConnectionState state);
@ -541,32 +544,51 @@ private:
#ifdef MOZILLA_INTERNAL_API
// TODO(bcampen@mozilla.com): Once the dust settles on this stuff, it
// probably makes sense to make these static in PeerConnectionImpl.cpp
// (ie; stop exporting them)
// Fills in an RTCStatsReportInternal. Must be run on STS.
void GetStats_s(
mozilla::TrackID trackId,
static void GetStats_s(
const std::string& pcHandle,
const std::string& pcName,
nsCOMPtr<nsIThread> callbackThread,
bool internalStats,
nsAutoPtr<std::vector<mozilla::RefPtr<mozilla::MediaPipeline>>> pipelines,
const std::vector<mozilla::RefPtr<mozilla::MediaPipeline>> &pipelines,
const mozilla::RefPtr<NrIceCtx> &iceCtx,
const std::vector<mozilla::RefPtr<NrIceMediaStream>> &streams,
DOMHighResTimeStamp now);
nsresult GetStatsImpl_s(
mozilla::TrackID trackId,
static nsresult GetStatsImpl_s(
bool internalStats,
nsAutoPtr<std::vector<mozilla::RefPtr<mozilla::MediaPipeline>>> pipelines,
const std::vector<mozilla::RefPtr<mozilla::MediaPipeline>> &pipelines,
const mozilla::RefPtr<NrIceCtx> &iceCtx,
const std::vector<mozilla::RefPtr<NrIceMediaStream>> &streams,
DOMHighResTimeStamp now,
mozilla::dom::RTCStatsReportInternal *report);
static void FillStatsReport_s(
NrIceMediaStream& stream,
bool internalStats,
DOMHighResTimeStamp now,
mozilla::dom::RTCStatsReportInternal* stats);
// Sends an RTCStatsReport to JS. Must run on main thread.
void OnStatsReport_m(
static void OnStatsReport_m(
const std::string& pcHandle,
nsresult result,
nsAutoPtr<std::vector<mozilla::RefPtr<mozilla::MediaPipeline>>> pipelines,
const std::vector<mozilla::RefPtr<mozilla::MediaPipeline>> &pipelines,
nsAutoPtr<mozilla::dom::RTCStatsReportInternal> report);
// Fetches logs matching pattern from RLogRingBuffer. Must be run on STS.
void GetLogging_s(const std::string& pattern);
static void GetLogging_s(const std::string& pcHandle,
nsCOMPtr<nsIThread> callbackThread,
const std::string& pattern);
// Sends logging to JS. Must run on main thread.
void OnGetLogging_m(const std::string& pattern,
const std::deque<std::string>& logging);
static void OnGetLogging_m(const std::string& pcHandle,
const std::string& pattern,
nsAutoPtr<std::deque<std::string>> logging);
#endif
// Timecard used to measure processing time. This should be the first class
@ -606,6 +628,9 @@ private:
// A handle to refer to this PC with
std::string mHandle;
// A name for this PC that we are willing to expose to content.
std::string mName;
// The target to run stuff on
nsCOMPtr<nsIEventTarget> mSTSThread;

View File

@ -148,7 +148,7 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
{
// TODO(ekr@rtfm.com): need some way to set not offerer later
// Looks like a bug in the NrIceCtx API.
mIceCtx = NrIceCtx::Create("PC:" + mParent->GetHandle(), true);
mIceCtx = NrIceCtx::Create("PC:" + mParent->GetName(), true);
if(!mIceCtx) {
CSFLogError(logTag, "%s: Failed to create Ice Context", __FUNCTION__);
return NS_ERROR_FAILURE;
@ -191,11 +191,11 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
// One each for audio, video and DataChannel
// TODO: this will be re-visited
RefPtr<NrIceMediaStream> audioStream =
mIceCtx->CreateStream((mParent->GetHandle()+"/stream1/audio").c_str(), 2);
mIceCtx->CreateStream((mParent->GetName()+": stream1/audio").c_str(), 2);
RefPtr<NrIceMediaStream> videoStream =
mIceCtx->CreateStream((mParent->GetHandle()+"/stream2/video").c_str(), 2);
mIceCtx->CreateStream((mParent->GetName()+": stream2/video").c_str(), 2);
RefPtr<NrIceMediaStream> dcStream =
mIceCtx->CreateStream((mParent->GetHandle()+"/stream3/data").c_str(), 2);
mIceCtx->CreateStream((mParent->GetName()+": stream3/data").c_str(), 2);
if (!audioStream) {
CSFLogError(logTag, "%s: audio stream is NULL", __FUNCTION__);

View File

@ -197,6 +197,7 @@ class TestAgentSend : public TestAgent {
test_utils->sts_target(),
audio_,
1,
1,
audio_conduit_,
audio_rtp_transport_.flow_,
audio_rtcp_transport_.flow_);
@ -246,7 +247,7 @@ class TestAgentReceive : public TestAgent {
test_pc,
nullptr,
test_utils->sts_target(),
audio_->GetStream(), 1,
audio_->GetStream(), 1, 1,
static_cast<mozilla::AudioSessionConduit *>(audio_conduit_.get()),
audio_rtp_transport_.flow_, audio_rtcp_transport_.flow_);