mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 906990 - Part 12: Report statistics from all components when the MediaStreamTrack is not specified. r=ekr
This commit is contained in:
parent
d3401e83a9
commit
f0d2b96210
@ -119,13 +119,17 @@ GlobalPCList.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getStatsForEachPC: function(callback, errorCallback) {
|
getStatsForEachPC: function(callback, errorCallback) {
|
||||||
|
function getStatsFromPC(pcref) {
|
||||||
|
if (pcref.get()) {
|
||||||
|
pcref.get().getStatsInternal(null, callback, errorCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let winId in this._list) {
|
for (let winId in this._list) {
|
||||||
if (this._list.hasOwnProperty(winId)) {
|
if (this._list.hasOwnProperty(winId)) {
|
||||||
this.removeNullRefs(winId);
|
this.removeNullRefs(winId);
|
||||||
if (this._list[winId]) {
|
if (this._list[winId]) {
|
||||||
this._list[winId].forEach(function(pcref) {
|
this._list[winId].forEach(getStatsFromPC);
|
||||||
pcref.get().getStatsInternal(null, callback, errorCallback);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,7 @@ enum RTCStatsIceCandidateType {
|
|||||||
};
|
};
|
||||||
|
|
||||||
dictionary RTCIceCandidateStats : RTCStats {
|
dictionary RTCIceCandidateStats : RTCStats {
|
||||||
|
DOMString componentId;
|
||||||
DOMString candidateId;
|
DOMString candidateId;
|
||||||
DOMString ipAddress;
|
DOMString ipAddress;
|
||||||
long portNumber;
|
long portNumber;
|
||||||
|
@ -1589,6 +1589,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
|
|||||||
pc.impl()->GetSTSThread(),
|
pc.impl()->GetSTSThread(),
|
||||||
stream->GetMediaStream()->GetStream(),
|
stream->GetMediaStream()->GetStream(),
|
||||||
pc_track_id,
|
pc_track_id,
|
||||||
|
level,
|
||||||
conduit, rtp_flow, rtcp_flow);
|
conduit, rtp_flow, rtcp_flow);
|
||||||
|
|
||||||
nsresult res = pipeline->Init();
|
nsresult res = pipeline->Init();
|
||||||
@ -1640,6 +1641,7 @@ static int vcmRxStartICE_m(cc_mcapid_t mcap_id,
|
|||||||
pc.impl()->GetSTSThread(),
|
pc.impl()->GetSTSThread(),
|
||||||
stream->GetMediaStream()->GetStream(),
|
stream->GetMediaStream()->GetStream(),
|
||||||
pc_track_id,
|
pc_track_id,
|
||||||
|
level,
|
||||||
conduit, rtp_flow, rtcp_flow);
|
conduit, rtp_flow, rtcp_flow);
|
||||||
|
|
||||||
nsresult res = pipeline->Init();
|
nsresult res = pipeline->Init();
|
||||||
@ -2241,6 +2243,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
|||||||
pc.impl()->GetSTSThread(),
|
pc.impl()->GetSTSThread(),
|
||||||
stream->GetMediaStream(),
|
stream->GetMediaStream(),
|
||||||
pc_track_id,
|
pc_track_id,
|
||||||
|
level,
|
||||||
conduit, rtp_flow, rtcp_flow);
|
conduit, rtp_flow, rtcp_flow);
|
||||||
|
|
||||||
nsresult res = pipeline->Init();
|
nsresult res = pipeline->Init();
|
||||||
@ -2291,6 +2294,7 @@ static int vcmTxStartICE_m(cc_mcapid_t mcap_id,
|
|||||||
pc.impl()->GetSTSThread(),
|
pc.impl()->GetSTSThread(),
|
||||||
stream->GetMediaStream(),
|
stream->GetMediaStream(),
|
||||||
pc_track_id,
|
pc_track_id,
|
||||||
|
level,
|
||||||
conduit, rtp_flow, rtcp_flow);
|
conduit, rtp_flow, rtcp_flow);
|
||||||
|
|
||||||
nsresult res = pipeline->Init();
|
nsresult res = pipeline->Init();
|
||||||
|
@ -71,12 +71,14 @@ class MediaPipeline : public sigslot::has_slots<> {
|
|||||||
nsCOMPtr<nsIEventTarget> sts_thread,
|
nsCOMPtr<nsIEventTarget> sts_thread,
|
||||||
MediaStream *stream,
|
MediaStream *stream,
|
||||||
TrackID track_id,
|
TrackID track_id,
|
||||||
|
int level,
|
||||||
RefPtr<MediaSessionConduit> conduit,
|
RefPtr<MediaSessionConduit> conduit,
|
||||||
RefPtr<TransportFlow> rtp_transport,
|
RefPtr<TransportFlow> rtp_transport,
|
||||||
RefPtr<TransportFlow> rtcp_transport)
|
RefPtr<TransportFlow> rtcp_transport)
|
||||||
: direction_(direction),
|
: direction_(direction),
|
||||||
stream_(stream),
|
stream_(stream),
|
||||||
track_id_(track_id),
|
track_id_(track_id),
|
||||||
|
level_(level),
|
||||||
conduit_(conduit),
|
conduit_(conduit),
|
||||||
rtp_transport_(rtp_transport),
|
rtp_transport_(rtp_transport),
|
||||||
rtp_state_(MP_CONNECTING),
|
rtp_state_(MP_CONNECTING),
|
||||||
@ -126,6 +128,7 @@ class MediaPipeline : public sigslot::has_slots<> {
|
|||||||
|
|
||||||
virtual Direction direction() const { return direction_; }
|
virtual Direction direction() const { return direction_; }
|
||||||
virtual TrackID trackid() const { return track_id_; }
|
virtual TrackID trackid() const { return track_id_; }
|
||||||
|
virtual int level() const { return level_; }
|
||||||
|
|
||||||
bool IsDoingRtcpMux() const {
|
bool IsDoingRtcpMux() const {
|
||||||
return (rtp_transport_ == rtcp_transport_);
|
return (rtp_transport_ == rtcp_transport_);
|
||||||
@ -194,6 +197,7 @@ class MediaPipeline : public sigslot::has_slots<> {
|
|||||||
// Used on STS and MediaStreamGraph threads.
|
// Used on STS and MediaStreamGraph threads.
|
||||||
TrackID track_id_; // The track on the stream.
|
TrackID track_id_; // The track on the stream.
|
||||||
// Written and used as 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
|
RefPtr<MediaSessionConduit> conduit_; // Our conduit. Written on the main
|
||||||
// thread. Read on STS thread.
|
// thread. Read on STS thread.
|
||||||
|
|
||||||
@ -315,12 +319,13 @@ class MediaPipelineTransmit : public MediaPipeline {
|
|||||||
nsCOMPtr<nsIEventTarget> sts_thread,
|
nsCOMPtr<nsIEventTarget> sts_thread,
|
||||||
DOMMediaStream *domstream,
|
DOMMediaStream *domstream,
|
||||||
TrackID track_id,
|
TrackID track_id,
|
||||||
|
int level,
|
||||||
RefPtr<MediaSessionConduit> conduit,
|
RefPtr<MediaSessionConduit> conduit,
|
||||||
RefPtr<TransportFlow> rtp_transport,
|
RefPtr<TransportFlow> rtp_transport,
|
||||||
RefPtr<TransportFlow> rtcp_transport) :
|
RefPtr<TransportFlow> rtcp_transport) :
|
||||||
MediaPipeline(pc, TRANSMIT, main_thread, sts_thread,
|
MediaPipeline(pc, TRANSMIT, main_thread, sts_thread,
|
||||||
domstream->GetStream(), track_id, conduit, rtp_transport,
|
domstream->GetStream(), track_id, level,
|
||||||
rtcp_transport),
|
conduit, rtp_transport, rtcp_transport),
|
||||||
listener_(new PipelineListener(conduit)),
|
listener_(new PipelineListener(conduit)),
|
||||||
domstream_(domstream)
|
domstream_(domstream)
|
||||||
{}
|
{}
|
||||||
@ -437,11 +442,12 @@ class MediaPipelineReceive : public MediaPipeline {
|
|||||||
nsCOMPtr<nsIEventTarget> sts_thread,
|
nsCOMPtr<nsIEventTarget> sts_thread,
|
||||||
MediaStream *stream,
|
MediaStream *stream,
|
||||||
TrackID track_id,
|
TrackID track_id,
|
||||||
|
int level,
|
||||||
RefPtr<MediaSessionConduit> conduit,
|
RefPtr<MediaSessionConduit> conduit,
|
||||||
RefPtr<TransportFlow> rtp_transport,
|
RefPtr<TransportFlow> rtp_transport,
|
||||||
RefPtr<TransportFlow> rtcp_transport) :
|
RefPtr<TransportFlow> rtcp_transport) :
|
||||||
MediaPipeline(pc, RECEIVE, main_thread, sts_thread,
|
MediaPipeline(pc, RECEIVE, main_thread, sts_thread,
|
||||||
stream, track_id, conduit, rtp_transport,
|
stream, track_id, level, conduit, rtp_transport,
|
||||||
rtcp_transport),
|
rtcp_transport),
|
||||||
segments_added_(0) {
|
segments_added_(0) {
|
||||||
}
|
}
|
||||||
@ -464,11 +470,12 @@ class MediaPipelineReceiveAudio : public MediaPipelineReceive {
|
|||||||
nsCOMPtr<nsIEventTarget> sts_thread,
|
nsCOMPtr<nsIEventTarget> sts_thread,
|
||||||
MediaStream *stream,
|
MediaStream *stream,
|
||||||
TrackID track_id,
|
TrackID track_id,
|
||||||
|
int level,
|
||||||
RefPtr<AudioSessionConduit> conduit,
|
RefPtr<AudioSessionConduit> conduit,
|
||||||
RefPtr<TransportFlow> rtp_transport,
|
RefPtr<TransportFlow> rtp_transport,
|
||||||
RefPtr<TransportFlow> rtcp_transport) :
|
RefPtr<TransportFlow> rtcp_transport) :
|
||||||
MediaPipelineReceive(pc, main_thread, sts_thread,
|
MediaPipelineReceive(pc, main_thread, sts_thread,
|
||||||
stream, track_id, conduit, rtp_transport,
|
stream, track_id, level, conduit, rtp_transport,
|
||||||
rtcp_transport),
|
rtcp_transport),
|
||||||
listener_(new PipelineListener(stream->AsSourceStream(),
|
listener_(new PipelineListener(stream->AsSourceStream(),
|
||||||
track_id, conduit)) {
|
track_id, conduit)) {
|
||||||
@ -526,11 +533,12 @@ class MediaPipelineReceiveVideo : public MediaPipelineReceive {
|
|||||||
nsCOMPtr<nsIEventTarget> sts_thread,
|
nsCOMPtr<nsIEventTarget> sts_thread,
|
||||||
MediaStream *stream,
|
MediaStream *stream,
|
||||||
TrackID track_id,
|
TrackID track_id,
|
||||||
|
int level,
|
||||||
RefPtr<VideoSessionConduit> conduit,
|
RefPtr<VideoSessionConduit> conduit,
|
||||||
RefPtr<TransportFlow> rtp_transport,
|
RefPtr<TransportFlow> rtp_transport,
|
||||||
RefPtr<TransportFlow> rtcp_transport) :
|
RefPtr<TransportFlow> rtcp_transport) :
|
||||||
MediaPipelineReceive(pc, main_thread, sts_thread,
|
MediaPipelineReceive(pc, main_thread, sts_thread,
|
||||||
stream, track_id, conduit, rtp_transport,
|
stream, track_id, level, conduit, rtp_transport,
|
||||||
rtcp_transport),
|
rtcp_transport),
|
||||||
renderer_(new PipelineRenderer(MOZ_THIS_IN_INITIALIZER_LIST())),
|
renderer_(new PipelineRenderer(MOZ_THIS_IN_INITIALIZER_LIST())),
|
||||||
listener_(new PipelineListener(stream->AsSourceStream(), track_id)) {
|
listener_(new PipelineListener(stream->AsSourceStream(), track_id)) {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "base/histogram.h"
|
#include "base/histogram.h"
|
||||||
#include "vcm.h"
|
#include "vcm.h"
|
||||||
@ -32,6 +33,7 @@
|
|||||||
#include "nsIConsoleService.h"
|
#include "nsIConsoleService.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsProxyRelease.h"
|
#include "nsProxyRelease.h"
|
||||||
|
#include "prtime.h"
|
||||||
|
|
||||||
#include "runnable_utils.h"
|
#include "runnable_utils.h"
|
||||||
#include "PeerConnectionCtx.h"
|
#include "PeerConnectionCtx.h"
|
||||||
@ -56,6 +58,7 @@
|
|||||||
#include "nsURLHelper.h"
|
#include "nsURLHelper.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsIDOMDataChannel.h"
|
#include "nsIDOMDataChannel.h"
|
||||||
|
#include "nsIDOMLocation.h"
|
||||||
#include "mozilla/dom/RTCConfigurationBinding.h"
|
#include "mozilla/dom/RTCConfigurationBinding.h"
|
||||||
#include "mozilla/dom/RTCStatsReportBinding.h"
|
#include "mozilla/dom/RTCStatsReportBinding.h"
|
||||||
#include "mozilla/dom/RTCPeerConnectionBinding.h"
|
#include "mozilla/dom/RTCPeerConnectionBinding.h"
|
||||||
@ -709,8 +712,34 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
|
|||||||
MOZ_ASSERT(aWindow);
|
MOZ_ASSERT(aWindow);
|
||||||
mWindow = aWindow;
|
mWindow = aWindow;
|
||||||
NS_ENSURE_STATE(mWindow);
|
NS_ENSURE_STATE(mWindow);
|
||||||
|
|
||||||
#endif // MOZILLA_INTERNAL_API
|
#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);
|
||||||
|
|
||||||
|
nsCString locationCStr;
|
||||||
|
CopyUTF16toUTF8(locationAStr, locationCStr);
|
||||||
|
PR_snprintf(temp,
|
||||||
|
sizeof(temp),
|
||||||
|
"%ull (id=%u url=%s)",
|
||||||
|
timestamp,
|
||||||
|
mWindow->WindowID(),
|
||||||
|
locationCStr.get());
|
||||||
|
#else
|
||||||
|
PR_snprintf(temp, sizeof(temp), "%ull", timestamp);
|
||||||
|
#endif // MOZILLA_INTERNAL_API
|
||||||
|
|
||||||
|
mName = temp;
|
||||||
|
|
||||||
// Generate a random handle
|
// Generate a random handle
|
||||||
unsigned char handle_bin[8];
|
unsigned char handle_bin[8];
|
||||||
SECStatus rv;
|
SECStatus rv;
|
||||||
@ -1259,29 +1288,49 @@ PeerConnectionImpl::GetStats(MediaStreamTrack *aSelector, bool internalStats) {
|
|||||||
|
|
||||||
// Gather up pipelines from mMedia and dispatch them to STS for inspection
|
// Gather up pipelines from mMedia and dispatch them to STS for inspection
|
||||||
|
|
||||||
nsAutoPtr<std::vector<RefPtr<MediaPipeline>>> pipelines(
|
std::vector<RefPtr<MediaPipeline>> pipelines;
|
||||||
new std::vector<RefPtr<MediaPipeline>>());
|
|
||||||
TrackID trackId = aSelector ? aSelector->GetTrackID() : 0;
|
TrackID trackId = aSelector ? aSelector->GetTrackID() : 0;
|
||||||
|
|
||||||
for (int i = 0, len = mMedia->LocalStreamsLength(); i < len; i++) {
|
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++) {
|
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;
|
DOMHighResTimeStamp now;
|
||||||
nsresult rv = GetTimeSinceEpoch(&now);
|
nsresult rv = GetTimeSinceEpoch(&now);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsRefPtr<PeerConnectionImpl> pc(this);
|
|
||||||
RUN_ON_THREAD(mSTSThread,
|
RUN_ON_THREAD(mSTSThread,
|
||||||
WrapRunnable(pc,
|
WrapRunnableNM(&PeerConnectionImpl::GetStats_s,
|
||||||
&PeerConnectionImpl::GetStats_s,
|
mHandle,
|
||||||
trackId,
|
mName,
|
||||||
internalStats,
|
mThread,
|
||||||
pipelines,
|
internalStats,
|
||||||
now),
|
pipelines,
|
||||||
|
iceCtx,
|
||||||
|
streams,
|
||||||
|
now),
|
||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
#endif
|
#endif
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -1293,11 +1342,11 @@ PeerConnectionImpl::GetLogging(const nsAString& aPattern) {
|
|||||||
|
|
||||||
#ifdef MOZILLA_INTERNAL_API
|
#ifdef MOZILLA_INTERNAL_API
|
||||||
std::string pattern(NS_ConvertUTF16toUTF8(aPattern).get());
|
std::string pattern(NS_ConvertUTF16toUTF8(aPattern).get());
|
||||||
nsRefPtr<PeerConnectionImpl> pc(this);
|
|
||||||
RUN_ON_THREAD(mSTSThread,
|
RUN_ON_THREAD(mSTSThread,
|
||||||
WrapRunnable(pc,
|
WrapRunnableNM(&PeerConnectionImpl::GetLogging_s,
|
||||||
&PeerConnectionImpl::GetLogging_s,
|
mHandle,
|
||||||
pattern),
|
mThread,
|
||||||
|
pattern),
|
||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -1737,6 +1786,13 @@ PeerConnectionImpl::GetHandle()
|
|||||||
return mHandle;
|
return mHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string&
|
||||||
|
PeerConnectionImpl::GetName()
|
||||||
|
{
|
||||||
|
PC_AUTO_ENTER_API_CALL_NO_CHECK();
|
||||||
|
return mName;
|
||||||
|
}
|
||||||
|
|
||||||
static mozilla::dom::PCImplIceConnectionState
|
static mozilla::dom::PCImplIceConnectionState
|
||||||
toDomIceConnectionState(NrIceCtx::ConnectionState state) {
|
toDomIceConnectionState(NrIceCtx::ConnectionState state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@ -1884,15 +1940,16 @@ PeerConnectionImpl::IceGatheringStateChange_m(PCImplIceGatheringState aState)
|
|||||||
#ifdef MOZILLA_INTERNAL_API
|
#ifdef MOZILLA_INTERNAL_API
|
||||||
nsresult
|
nsresult
|
||||||
PeerConnectionImpl::GetStatsImpl_s(
|
PeerConnectionImpl::GetStatsImpl_s(
|
||||||
TrackID trackId,
|
|
||||||
bool internalStats,
|
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,
|
DOMHighResTimeStamp now,
|
||||||
RTCStatsReportInternal *report) {
|
RTCStatsReportInternal* report) {
|
||||||
|
|
||||||
// Gather stats from pipelines provided (can't touch mMedia + stream on STS)
|
// 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;
|
const MediaPipeline& mp = **it;
|
||||||
nsString idstr = (mp.Conduit()->type() == MediaSessionConduit::AUDIO) ?
|
nsString idstr = (mp.Conduit()->type() == MediaSessionConduit::AUDIO) ?
|
||||||
NS_LITERAL_STRING("audio_") : NS_LITERAL_STRING("video_");
|
NS_LITERAL_STRING("audio_") : NS_LITERAL_STRING("video_");
|
||||||
@ -1926,152 +1983,184 @@ PeerConnectionImpl::GetStatsImpl_s(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mMedia) {
|
// Gather stats from ICE
|
||||||
|
for (auto s = streams.begin(); s != streams.end(); ++s) {
|
||||||
// Gather stats from ICE
|
FillStatsReport_s(**s, internalStats, now, report);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerConnectionImpl::GetStats_s(
|
void PeerConnectionImpl::FillStatsReport_s(
|
||||||
TrackID trackId,
|
NrIceMediaStream& mediaStream,
|
||||||
bool internalStats,
|
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) {
|
DOMHighResTimeStamp now) {
|
||||||
|
|
||||||
nsAutoPtr<RTCStatsReportInternal> report(new RTCStatsReportInternalConstruct(
|
// We do not use the pcHandle here, since that's risky to expose to content.
|
||||||
NS_ConvertASCIItoUTF16(mHandle.c_str()), now));
|
nsAutoPtr<RTCStatsReportInternal> report(
|
||||||
|
new RTCStatsReportInternalConstruct(
|
||||||
|
NS_ConvertASCIItoUTF16(pcName.c_str()),
|
||||||
|
now));
|
||||||
|
|
||||||
nsresult rv = report ? GetStatsImpl_s(trackId, internalStats, pipelines, now,
|
nsresult rv = GetStatsImpl_s(internalStats,
|
||||||
report)
|
pipelines,
|
||||||
: NS_ERROR_UNEXPECTED;
|
iceCtx,
|
||||||
|
streams,
|
||||||
|
now,
|
||||||
|
report);
|
||||||
|
|
||||||
nsRefPtr<PeerConnectionImpl> pc(this);
|
RUN_ON_THREAD(callbackThread,
|
||||||
RUN_ON_THREAD(mThread,
|
WrapRunnableNM(&PeerConnectionImpl::OnStatsReport_m,
|
||||||
WrapRunnable(pc,
|
pcHandle,
|
||||||
&PeerConnectionImpl::OnStatsReport_m,
|
rv,
|
||||||
rv,
|
pipelines, // return for release on main thread
|
||||||
pipelines, // return for release on main thread
|
report),
|
||||||
report),
|
|
||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerConnectionImpl::OnStatsReport_m(
|
void PeerConnectionImpl::OnStatsReport_m(
|
||||||
|
const std::string& pcHandle,
|
||||||
nsresult result,
|
nsresult result,
|
||||||
nsAutoPtr<std::vector<RefPtr<MediaPipeline>>> pipelines, //returned for release
|
const std::vector<RefPtr<MediaPipeline>>& pipelines, //returned for release
|
||||||
nsAutoPtr<RTCStatsReportInternal> report) {
|
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()) {
|
// Is the PeerConnectionImpl still around?
|
||||||
CSFLogError(logTag, "Error firing stats observer callback");
|
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();
|
RLogRingBuffer* logs = RLogRingBuffer::GetInstance();
|
||||||
std::deque<std::string> result;
|
nsAutoPtr<std::deque<std::string>> result(new std::deque<std::string>);
|
||||||
logs->Filter(pattern, 0, &result);
|
logs->Filter(pattern, 0, result);
|
||||||
nsRefPtr<PeerConnectionImpl> pc(this);
|
RUN_ON_THREAD(callbackThread,
|
||||||
RUN_ON_THREAD(mThread,
|
WrapRunnableNM(&PeerConnectionImpl::OnGetLogging_m,
|
||||||
WrapRunnable(pc,
|
pcHandle,
|
||||||
&PeerConnectionImpl::OnGetLogging_m,
|
pattern,
|
||||||
pattern,
|
result),
|
||||||
result),
|
|
||||||
NS_DISPATCH_NORMAL);
|
NS_DISPATCH_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerConnectionImpl::OnGetLogging_m(const std::string& pattern,
|
void PeerConnectionImpl::OnGetLogging_m(
|
||||||
const std::deque<std::string>& logging) {
|
const std::string& pcHandle,
|
||||||
nsRefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
|
const std::string& pattern,
|
||||||
if (!pco) {
|
nsAutoPtr<std::deque<std::string>> logging) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JSErrorResult rv;
|
// Is the PeerConnectionImpl still around?
|
||||||
if (!logging.empty()) {
|
PeerConnectionWrapper pcw(pcHandle);
|
||||||
Sequence<nsString> nsLogs;
|
if (pcw.impl()) {
|
||||||
for (auto l = logging.begin(); l != logging.end(); ++l) {
|
nsRefPtr<PeerConnectionObserver> pco =
|
||||||
nsLogs.AppendElement(ObString(l->c_str()));
|
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
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -223,6 +223,9 @@ public:
|
|||||||
// Handle system to allow weak references to be passed through C code
|
// Handle system to allow weak references to be passed through C code
|
||||||
virtual const std::string& GetHandle();
|
virtual const std::string& GetHandle();
|
||||||
|
|
||||||
|
// Name suitable for exposing to content
|
||||||
|
virtual const std::string& GetName();
|
||||||
|
|
||||||
// ICE events
|
// ICE events
|
||||||
void IceConnectionStateChange(NrIceCtx* ctx,
|
void IceConnectionStateChange(NrIceCtx* ctx,
|
||||||
NrIceCtx::ConnectionState state);
|
NrIceCtx::ConnectionState state);
|
||||||
@ -540,32 +543,51 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
#ifdef MOZILLA_INTERNAL_API
|
#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.
|
// Fills in an RTCStatsReportInternal. Must be run on STS.
|
||||||
void GetStats_s(
|
static void GetStats_s(
|
||||||
mozilla::TrackID trackId,
|
const std::string& pcHandle,
|
||||||
|
const std::string& pcName,
|
||||||
|
nsCOMPtr<nsIThread> callbackThread,
|
||||||
bool internalStats,
|
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);
|
DOMHighResTimeStamp now);
|
||||||
|
|
||||||
nsresult GetStatsImpl_s(
|
static nsresult GetStatsImpl_s(
|
||||||
mozilla::TrackID trackId,
|
|
||||||
bool internalStats,
|
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,
|
DOMHighResTimeStamp now,
|
||||||
mozilla::dom::RTCStatsReportInternal *report);
|
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.
|
// Sends an RTCStatsReport to JS. Must run on main thread.
|
||||||
void OnStatsReport_m(
|
static void OnStatsReport_m(
|
||||||
|
const std::string& pcHandle,
|
||||||
nsresult result,
|
nsresult result,
|
||||||
nsAutoPtr<std::vector<mozilla::RefPtr<mozilla::MediaPipeline>>> pipelines,
|
const std::vector<mozilla::RefPtr<mozilla::MediaPipeline>> &pipelines,
|
||||||
nsAutoPtr<mozilla::dom::RTCStatsReportInternal> report);
|
nsAutoPtr<mozilla::dom::RTCStatsReportInternal> report);
|
||||||
|
|
||||||
// Fetches logs matching pattern from RLogRingBuffer. Must be run on STS.
|
// 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.
|
// Sends logging to JS. Must run on main thread.
|
||||||
void OnGetLogging_m(const std::string& pattern,
|
static void OnGetLogging_m(const std::string& pcHandle,
|
||||||
const std::deque<std::string>& logging);
|
const std::string& pattern,
|
||||||
|
nsAutoPtr<std::deque<std::string>> logging);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Timecard used to measure processing time. This should be the first class
|
// Timecard used to measure processing time. This should be the first class
|
||||||
@ -605,6 +627,9 @@ private:
|
|||||||
// A handle to refer to this PC with
|
// A handle to refer to this PC with
|
||||||
std::string mHandle;
|
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
|
// The target to run stuff on
|
||||||
nsCOMPtr<nsIEventTarget> mSTSThread;
|
nsCOMPtr<nsIEventTarget> mSTSThread;
|
||||||
|
|
||||||
|
@ -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
|
// TODO(ekr@rtfm.com): need some way to set not offerer later
|
||||||
// Looks like a bug in the NrIceCtx API.
|
// Looks like a bug in the NrIceCtx API.
|
||||||
mIceCtx = NrIceCtx::Create("PC:" + mParent->GetHandle(), true);
|
mIceCtx = NrIceCtx::Create("PC:" + mParent->GetName(), true);
|
||||||
if(!mIceCtx) {
|
if(!mIceCtx) {
|
||||||
CSFLogError(logTag, "%s: Failed to create Ice Context", __FUNCTION__);
|
CSFLogError(logTag, "%s: Failed to create Ice Context", __FUNCTION__);
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
@ -191,11 +191,11 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
|||||||
// One each for audio, video and DataChannel
|
// One each for audio, video and DataChannel
|
||||||
// TODO: this will be re-visited
|
// TODO: this will be re-visited
|
||||||
RefPtr<NrIceMediaStream> audioStream =
|
RefPtr<NrIceMediaStream> audioStream =
|
||||||
mIceCtx->CreateStream((mParent->GetHandle()+"/stream1/audio").c_str(), 2);
|
mIceCtx->CreateStream((mParent->GetName()+": stream1/audio").c_str(), 2);
|
||||||
RefPtr<NrIceMediaStream> videoStream =
|
RefPtr<NrIceMediaStream> videoStream =
|
||||||
mIceCtx->CreateStream((mParent->GetHandle()+"/stream2/video").c_str(), 2);
|
mIceCtx->CreateStream((mParent->GetName()+": stream2/video").c_str(), 2);
|
||||||
RefPtr<NrIceMediaStream> dcStream =
|
RefPtr<NrIceMediaStream> dcStream =
|
||||||
mIceCtx->CreateStream((mParent->GetHandle()+"/stream3/data").c_str(), 2);
|
mIceCtx->CreateStream((mParent->GetName()+": stream3/data").c_str(), 2);
|
||||||
|
|
||||||
if (!audioStream) {
|
if (!audioStream) {
|
||||||
CSFLogError(logTag, "%s: audio stream is NULL", __FUNCTION__);
|
CSFLogError(logTag, "%s: audio stream is NULL", __FUNCTION__);
|
||||||
|
@ -197,6 +197,7 @@ class TestAgentSend : public TestAgent {
|
|||||||
test_utils->sts_target(),
|
test_utils->sts_target(),
|
||||||
audio_,
|
audio_,
|
||||||
1,
|
1,
|
||||||
|
1,
|
||||||
audio_conduit_,
|
audio_conduit_,
|
||||||
audio_rtp_transport_.flow_,
|
audio_rtp_transport_.flow_,
|
||||||
audio_rtcp_transport_.flow_);
|
audio_rtcp_transport_.flow_);
|
||||||
@ -246,7 +247,7 @@ class TestAgentReceive : public TestAgent {
|
|||||||
test_pc,
|
test_pc,
|
||||||
nullptr,
|
nullptr,
|
||||||
test_utils->sts_target(),
|
test_utils->sts_target(),
|
||||||
audio_->GetStream(), 1,
|
audio_->GetStream(), 1, 1,
|
||||||
static_cast<mozilla::AudioSessionConduit *>(audio_conduit_.get()),
|
static_cast<mozilla::AudioSessionConduit *>(audio_conduit_.get()),
|
||||||
audio_rtp_transport_.flow_, audio_rtcp_transport_.flow_);
|
audio_rtp_transport_.flow_, audio_rtcp_transport_.flow_);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user