--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -332,16 +332,18 @@ skip-if = (android_version == '18') # an
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_threeUnbundledConnections.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_selftest.html]
# Bug 1227781: Crash with bogus TURN server.
[test_peerConnection_bug1227781.html]
[test_peerConnection_stats.html]
skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
+[test_peerConnection_stats_persist_ids.html]
+skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
[test_peerConnection_sender_and_receiver_stats.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_trackless_sender_stats.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_verifyDescriptions.html]
skip-if = (android_version == '18')
[test_fingerprinting_resistance.html]
[test_getUserMedia_nonDefaultRate.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_stats_persist_ids.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+createHTML({
+ bug: "1463610",
+ title: "Persist WebRTC Stats Ids"
+});
+
+const NUMBER_OF_TRACKS_PER_TYPE = 5;
+
+const checkSenderReceiverStatsIdPersistence = async test => {
+ const pcStats = await test.pcLocal.getStats();
+ pcStats.forEach((v, k) => {
+ dump(`@@NG received key ${k}\n`);
+ });
+};
+
+// This MUST be run after PC_*_WAIT_FOR_MEDIA_FLOW to ensure that we have RTP
+// before checking for RTCP.
+const waitForSyncedRtcp = async pc => {
+ // Ensures that RTCP is present
+ const ensureSyncedRtcp = async () => {
+ const stats = await pc.getStats();
+ for (let [k, v] of stats) {
+ if (v.type.endsWith("bound-rtp") && !v.remoteId) {
+ throw new Error(v.id + " is missing remoteId: "
+ + JSON.stringify(v));
+ }
+ if (v.type == "inbound-rtp" && v.isRemote == true
+ && v.roundTripTime === undefined) {
+ throw new Error(v.id + " is missing roundTripTime: "
+ + JSON.stringify(v));
+ }
+ }
+ return stats;
+ }
+ const waitPeriod = 500;
+ const maxTime = 15000;
+ for (let totalTime = maxTime; totalTime > 0; totalTime -= waitPeriod) {
+ try {
+ return await ensureSyncedRtcp();
+ } catch (e) {
+ info(e);
+ await wait(waitPeriod);
+ }
+ }
+ throw new Error("Waiting for synced RTCP timed out after at least " + maxTime
+ + "ms");
+}
+
+const PC_TEST_STATS_PERSISTENCE = async test => {
+ await waitForSyncedRtcp(test.pcLocal);
+ await waitForSyncedRtcp(test.pcRemote);
+ await checkSenderReceiverStatsIdPersistence(test);
+}
+
+runNetworkTest(function (options) {
+ const test = new PeerConnectionTest(options);
+ test.chain.removeAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW");
+ test.chain.append([PC_TEST_STATS_PERSISTENCE]);
+
+ const constraints = Array(NUMBER_OF_TRACKS_PER_TYPE)
+ .fill([{audio: true}, {video: true}]).flatten();
+ test.setMediaConstraints(constraints, constraints);
+ test.run();
+});
+</script>
+</pre>
+</body>
+</html>
--- a/media/webrtc/signaling/gtest/mediaconduit_unittests.cpp
+++ b/media/webrtc/signaling/gtest/mediaconduit_unittests.cpp
@@ -343,16 +343,18 @@ private:
int numPkts;
bool mAudio, mVideo;
};
using namespace mozilla;
namespace test {
+static const MediaConduitStatisticsId sDummyStatsId{0};
+
class TransportConduitTest : public ::testing::Test
{
public:
TransportConduitTest()
{
//input and output file names
iAudiofilename = "input.wav";
@@ -373,22 +375,22 @@ class TransportConduitTest : public ::te
mVideoTransport = nullptr;
}
//1. Dump audio samples to dummy external transport
void TestDummyAudioAndTransport()
{
//get pointer to AudioSessionConduit
int err=0;
- mAudioSession = mozilla::AudioSessionConduit::Create();
+ mAudioSession = mozilla::AudioSessionConduit::Create(sDummyStatsId);
if( !mAudioSession ) {
ASSERT_NE(mAudioSession, (void*)nullptr);
}
- mAudioSession2 = mozilla::AudioSessionConduit::Create();
+ mAudioSession2 = mozilla::AudioSessionConduit::Create(sDummyStatsId);
if( !mAudioSession2 ) {
ASSERT_NE(mAudioSession2, (void*)nullptr);
}
WebrtcMediaTransport* xport = new WebrtcMediaTransport();
ASSERT_NE(xport, (void*)nullptr);
xport->SetAudioSession(mAudioSession, mAudioSession2);
mAudioTransport = xport;
@@ -434,17 +436,18 @@ class TransportConduitTest : public ::te
cerr << " ******************************************************** " << endl;
}
void TestVideoConduitCodecAPI()
{
int err = 0;
RefPtr<mozilla::VideoSessionConduit> videoSession;
//get pointer to VideoSessionConduit
- videoSession = VideoSessionConduit::Create(WebRtcCallWrapper::Create());
+ videoSession = VideoSessionConduit::Create(WebRtcCallWrapper::Create(),
+ sDummyStatsId);
if( !videoSession ) {
ASSERT_NE(videoSession, (void*)nullptr);
}
std::vector<unsigned int> ssrcs = {SSRC};
videoSession->SetLocalSSRCs(ssrcs);
//Test Configure Recv Codec APIS
--- a/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp
+++ b/media/webrtc/signaling/gtest/mediapipeline_unittest.cpp
@@ -220,21 +220,23 @@ class TransportInfo {
loopback_ = nullptr;
flow_ = nullptr;
}
RefPtr<TransportFlow> flow_;
TransportLayerLoopback *loopback_;
};
+static const MediaConduitStatisticsId sDummyStatsId{0};
+
class TestAgent {
public:
TestAgent() :
audio_config_(109, "opus", 48000, 960, 2, 64000, false),
- audio_conduit_(mozilla::AudioSessionConduit::Create()),
+ audio_conduit_(mozilla::AudioSessionConduit::Create(sDummyStatsId)),
audio_pipeline_(),
use_bundle_(false) {
}
static void ConnectRtp(TestAgent *client, TestAgent *server) {
TransportInfo::InitAndConnect(client->audio_rtp_transport_,
server->audio_rtp_transport_);
}
--- a/media/webrtc/signaling/gtest/videoconduit_unittests.cpp
+++ b/media/webrtc/signaling/gtest/videoconduit_unittests.cpp
@@ -76,27 +76,30 @@ public:
mVideoFrame = frame;
++mOnFrameCount;
}
size_t mOnFrameCount = 0;
webrtc::VideoFrame mVideoFrame;
};
+static const MediaConduitStatisticsId sDummyStatsId{0};
+
class VideoConduitTest : public ::testing::Test {
public:
VideoConduitTest()
: mCall(new MockCall())
, mAdapter(new MockVideoAdapter)
{
NSS_NoDB_Init(nullptr);
mVideoConduit = new WebrtcVideoConduit(WebRtcCallWrapper::Create(UniquePtr<MockCall>(mCall)),
- UniquePtr<cricket::VideoAdapter>(mAdapter));
+ UniquePtr<cricket::VideoAdapter>(mAdapter),
+ sDummyStatsId);
std::vector<unsigned int> ssrcs = {42};
mVideoConduit->SetLocalSSRCs(ssrcs);
}
~VideoConduitTest() override
{
mVideoConduit->DeleteStreams();
}
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.cpp
@@ -38,25 +38,27 @@ static const char* acLogTag ="WebrtcAudi
#undef LOGTAG
#endif
#define LOGTAG acLogTag
// 32 bytes is what WebRTC CodecInst expects
const unsigned int WebrtcAudioConduit::CODEC_PLNAME_SIZE = 32;
using LocalDirection = MediaSessionConduitLocalDirection;
+
/**
* Factory Method for AudioConduit
*/
-RefPtr<AudioSessionConduit> AudioSessionConduit::Create()
+RefPtr<AudioSessionConduit>
+AudioSessionConduit::Create(MediaConduitStatisticsId aStatsId)
{
CSFLogDebug(LOGTAG, "%s ", __FUNCTION__);
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
- WebrtcAudioConduit* obj = new WebrtcAudioConduit();
+ WebrtcAudioConduit* obj = new WebrtcAudioConduit(aStatsId);
if(obj->Init() != kMediaConduitNoError)
{
CSFLogError(LOGTAG, "%s AudioConduit Init Failed ", __FUNCTION__);
delete obj;
return nullptr;
}
CSFLogDebug(LOGTAG, "%s Successfully created AudioConduit ", __FUNCTION__);
return obj;
--- a/media/webrtc/signaling/src/media-conduit/AudioConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/AudioConduit.h
@@ -168,17 +168,18 @@ public:
virtual bool SendRtcp(const uint8_t *data,
size_t len) override;
virtual uint64_t CodecPluginID() override { return 0; }
virtual void SetPCHandle(const std::string& aPCHandle) override {}
virtual void DeleteStreams() override {}
- explicit WebrtcAudioConduit():
+ explicit WebrtcAudioConduit(MediaConduitStatisticsId aStatsId):
+ AudioSessionConduit(aStatsId),
mVoiceEngine(nullptr),
mFakeAudioDevice(new webrtc::FakeAudioDeviceModule()),
mTransportMonitor("WebrtcAudioConduit"),
mTransmitterTransport(nullptr),
mReceiverTransport(nullptr),
mEngineTransmitting(false),
mEngineReceiving(false),
mChannel(-1),
--- a/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
+++ b/media/webrtc/signaling/src/media-conduit/MediaConduitInterface.h
@@ -10,17 +10,17 @@
#include "nsDOMNavigationTiming.h"
#include "mozilla/RefPtr.h"
#include "mozilla/RefCounted.h"
#include "mozilla/UniquePtr.h"
#include "RtpSourceObserver.h"
#include "CodecConfig.h"
#include "VideoTypes.h"
#include "MediaConduitErrors.h"
-
+#include "MediaConduitStatisticsId.h"
#include "ImageContainer.h"
#include "webrtc/call.h"
#include "webrtc/config.h"
#include "webrtc/common_types.h"
#include "webrtc/common_types.h"
#include "webrtc/api/video/video_frame_buffer.h"
#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
@@ -184,16 +184,28 @@ public:
class MediaSessionConduit
{
protected:
virtual ~MediaSessionConduit() {}
public:
enum Type { AUDIO, VIDEO } ;
+ class StatisticsIdGenerator {
+ public:
+ virtual ~StatisticsIdGenerator() {}
+ MediaConduitStatisticsId Generate() { return mNext++; }
+ private:
+ Atomic<MediaConduitStatisticsId, ReleaseAcquire> mNext{0};
+ };
+
+
+ MediaSessionConduit(MediaConduitStatisticsId aStatsId):
+ mStatisticsId(aStatsId) {};
+
static std::string
LocalDirectionToString(const MediaSessionConduitLocalDirection aDirection) {
return aDirection == MediaSessionConduitLocalDirection::kSend ?
"send" : "receive";
}
virtual Type type() const = 0;
@@ -271,16 +283,19 @@ public:
virtual bool SetLocalCNAME(const char* cname) = 0;
virtual bool SetLocalMID(const std::string& mid) = 0;
/**
* Functions returning stats needed by w3c stats model.
*/
+ // The unique identifier associated with statistics provided by this conduit
+ virtual MediaConduitStatisticsId GetStatisticsId() { return mStatisticsId; };
+
virtual bool
GetSendPacketTypeStats(webrtc::RtcpPacketTypeCounter* aPacketCounts) = 0;
virtual bool
GetRecvPacketTypeStats(webrtc::RtcpPacketTypeCounter* aPacketCounts) = 0;
virtual bool GetVideoEncoderStats(double* framerateMean,
double* framerateStdDev,
@@ -312,16 +327,18 @@ public:
virtual uint64_t CodecPluginID() = 0;
virtual void SetPCHandle(const std::string& aPCHandle) = 0;
virtual void DeleteStreams() = 0;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaSessionConduit)
+ private:
+ const MediaConduitStatisticsId mStatisticsId;
};
// Abstract base classes for external encoder/decoder.
class CodecPluginID
{
public:
virtual ~CodecPluginID() {}
@@ -347,30 +364,37 @@ public:
*/
class VideoSessionConduit : public MediaSessionConduit
{
public:
/**
* Factory function to create and initialize a Video Conduit Session
* @param webrtc::Call instance shared by paired audio and video
* media conduits
+ * @param aStatisticsId an identifier that is unique within the
+ * PeerConnection that is used to identify the stats created
+ * by inspecting this conduit
* @result Concrete VideoSessionConduitObject or nullptr in the case
* of failure
*/
- static RefPtr<VideoSessionConduit> Create(RefPtr<WebRtcCallWrapper> aCall);
+ static RefPtr<VideoSessionConduit>
+ Create(RefPtr<WebRtcCallWrapper> aCall,
+ MediaConduitStatisticsId aStatsId);
enum FrameRequestType
{
FrameRequestNone,
FrameRequestFir,
FrameRequestPli,
FrameRequestUnknown
};
- VideoSessionConduit() : mFrameRequestMethod(FrameRequestNone),
+ VideoSessionConduit(MediaConduitStatisticsId aStatsId):
+ MediaSessionConduit(aStatsId),
+ mFrameRequestMethod(FrameRequestNone),
mUsingNackBasic(false),
mUsingTmmbr(false),
mUsingFEC(false) {}
virtual ~VideoSessionConduit() {}
Type type() const override { return VIDEO; }
@@ -463,20 +487,27 @@ public:
class AudioSessionConduit : public MediaSessionConduit
{
public:
/**
* Factory function to create and initialize an Audio Conduit Session
* @param webrtc::Call instance shared by paired audio and video
* media conduits
+ * @param aStatisticsId an identifier that is unique within the
+ * PeerConnection that is used to identify the stats created
+ * by inspecting this conduit
* @result Concrete AudioSessionConduitObject or nullptr in the case
* of failure
*/
- static RefPtr<AudioSessionConduit> Create();
+ static RefPtr<AudioSessionConduit>
+ Create(MediaConduitStatisticsId aStats);
+
+ AudioSessionConduit(MediaConduitStatisticsId aStats):
+ MediaSessionConduit(aStats) {};
virtual ~AudioSessionConduit() {}
Type type() const override { return AUDIO; }
MediaConduitErrorCode
SetLocalRTPExtensions(MediaSessionConduitLocalDirection aDirection,
const RtpExtList& extensions) override = 0;
new file mode 100644
--- /dev/null
+++ b/media/webrtc/signaling/src/media-conduit/MediaConduitStatisticsId.h
@@ -0,0 +1,10 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MEDIA_CONDUIT_STATISTICS_ID_H_
+#define MEDIA_CONDUIT_STATISTICS_ID_H_
+namespace mozilla {
+ typedef uint64_t MediaConduitStatisticsId;
+}
+#endif
\ No newline at end of file
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp
@@ -207,40 +207,44 @@ WebrtcVideoConduit::ReceiveStreamStatist
mFramesDecoded = aStats.frame_counts.key_frames
+ aStats.frame_counts.delta_frames;
}
/**
* Factory Method for VideoConduit
*/
RefPtr<VideoSessionConduit>
-VideoSessionConduit::Create(RefPtr<WebRtcCallWrapper> aCall)
+VideoSessionConduit::Create(RefPtr<WebRtcCallWrapper> aCall,
+ MediaConduitStatisticsId aStatsId)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
NS_ASSERTION(aCall, "missing required parameter: aCall");
CSFLogVerbose(LOGTAG, "%s", __FUNCTION__);
if (!aCall) {
return nullptr;
}
UniquePtr<cricket::VideoAdapter> videoAdapter(new cricket::VideoAdapter(1));
nsAutoPtr<WebrtcVideoConduit> obj(new WebrtcVideoConduit(aCall,
- std::move(videoAdapter)));
+ std::move(videoAdapter),
+ aStatsId));
if(obj->Init() != kMediaConduitNoError) {
CSFLogError(LOGTAG, "%s VideoConduit Init Failed ", __FUNCTION__);
return nullptr;
}
CSFLogVerbose(LOGTAG, "%s Successfully created VideoConduit ", __FUNCTION__);
return obj.forget();
}
WebrtcVideoConduit::WebrtcVideoConduit(RefPtr<WebRtcCallWrapper> aCall,
- UniquePtr<cricket::VideoAdapter>&& aVideoAdapter)
- : mTransportMonitor("WebrtcVideoConduit")
+ UniquePtr<cricket::VideoAdapter>&& aVideoAdapter,
+ MediaConduitStatisticsId aStatsId):
+ VideoSessionConduit(aStatsId)
+ , mTransportMonitor("WebrtcVideoConduit")
, mRenderer(nullptr)
, mVideoAdapter(std::move(aVideoAdapter))
, mVideoBroadcaster()
, mEngineTransmitting(false)
, mEngineReceiving(false)
, mCapId(-1)
, mCodecMutex("VideoConduit codec db")
, mRecvStream(nullptr)
@@ -273,17 +277,16 @@ WebrtcVideoConduit::WebrtcVideoConduit(R
, mWaitingForInitialSsrc(true)
, mRecvSSRC(0)
, mRecvSSRCSetInProgress(false)
, mSendCodecPlugin(nullptr)
, mRecvCodecPlugin(nullptr)
, mVideoStatsTimer(NS_NewTimer())
{
mRecvStreamConfig.renderer = this;
-
// Video Stats Callback
nsTimerCallbackFunc callback = [](nsITimer* aTimer, void* aClosure) {
CSFLogDebug(LOGTAG, "StreamStats polling scheduled for VideoConduit: %p", aClosure);
auto self = static_cast<WebrtcVideoConduit*>(aClosure);
MutexAutoLock lock(self->mCodecMutex);
if (self->mEngineTransmitting && self->mSendStream) {
const auto& stats = self->mSendStream->GetStats();
self->mSendStreamStats.Update(stats);
@@ -1201,17 +1204,16 @@ WebrtcVideoConduit::Init()
CSFLogDebug(LOGTAG, "%s this=%p", __FUNCTION__, this);
MediaConduitErrorCode result;
// Run code that must run on MainThread first
MOZ_ASSERT(NS_IsMainThread());
result = InitMain();
if (result != kMediaConduitNoError) {
return result;
}
-
CSFLogError(LOGTAG, "%s Initialization Done", __FUNCTION__);
return kMediaConduitNoError;
}
void
WebrtcVideoConduit::DeleteStreams()
{
// We can't delete the VideoEngine until all these are released!
--- a/media/webrtc/signaling/src/media-conduit/VideoConduit.h
+++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.h
@@ -260,17 +260,19 @@ public:
return mTemporalLayers;
}
webrtc::VideoCodecMode CodecMode() const {
return mCodecMode;
}
WebrtcVideoConduit(RefPtr<WebRtcCallWrapper> aCall,
- UniquePtr<cricket::VideoAdapter>&& aVideoAdapter);
+ UniquePtr<cricket::VideoAdapter>&& aVideoAdapter,
+ MediaConduitStatisticsId aStatsId);
+
virtual ~WebrtcVideoConduit();
MediaConduitErrorCode InitMain();
virtual MediaConduitErrorCode Init();
std::vector<unsigned int> GetLocalSSRCs() const override;
bool SetLocalSSRCs(const std::vector<unsigned int> & ssrcs) override;
bool GetRemoteSSRC(unsigned int* ssrc) override;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -3427,17 +3427,17 @@ PeerConnectionImpl::ExecuteStatsQuery_s(
continue;
}
const MediaPipeline& mp = *query->pipelines[p];
bool isAudio = (mp.Conduit()->type() == MediaSessionConduit::AUDIO);
nsString mediaType = isAudio ?
NS_LITERAL_STRING("audio") : NS_LITERAL_STRING("video");
nsString idstr = mediaType;
idstr.AppendLiteral("_");
- idstr.AppendInt((uint32_t)p);
+ idstr.AppendInt(mp.Conduit()->GetStatisticsId());
// TODO(@@NG):ssrcs handle Conduits having multiple stats at the same level
// This is pending spec work
// Gather pipeline stats.
switch (mp.Direction()) {
case MediaPipeline::DirectionType::TRANSMIT: {
nsString localId = NS_LITERAL_STRING("outbound_rtp_") + idstr;
nsString remoteId;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -1153,17 +1153,18 @@ PeerConnectionMedia::AddTransceiver(
RefPtr<TransceiverImpl> transceiver = new TransceiverImpl(
mParent->GetHandle(),
aJsepTransceiver,
mMainThread.get(),
mSTSThread.get(),
&aReceiveTrack,
aSendTrack,
- mCall.get());
+ mCall.get(),
+ mStatsIdGenerator.Generate());
if (!transceiver->IsValid()) {
return NS_ERROR_FAILURE;
}
if (aSendTrack) {
// implement checking for peerIdentity (where failure == black/silence)
nsIDocument* doc = mParent->GetWindow()->GetExtantDoc();
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.h
@@ -363,14 +363,17 @@ class PeerConnectionMedia : public sigsl
RefPtr<net::StunAddrsRequestChild> mStunAddrsRequest;
// Used to track the state of the stun addr IPC request
bool mLocalAddrsCompleted;
// Used to store the result of the stun addr IPC request
nsTArray<NrIceStunAddr> mStunAddrs;
+ // Used to create unique stats ids for conduits
+ MediaSessionConduit::StatisticsIdGenerator mStatsIdGenerator;
+
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PeerConnectionMedia)
};
} // namespace mozilla
#endif
--- a/media/webrtc/signaling/src/peerconnection/TransceiverImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/TransceiverImpl.cpp
@@ -36,31 +36,32 @@ using LocalDirection = MediaSessionCondu
TransceiverImpl::TransceiverImpl(
const std::string& aPCHandle,
JsepTransceiver* aJsepTransceiver,
nsIEventTarget* aMainThread,
nsIEventTarget* aStsThread,
dom::MediaStreamTrack* aReceiveTrack,
dom::MediaStreamTrack* aSendTrack,
- WebRtcCallWrapper* aCallWrapper) :
+ WebRtcCallWrapper* aCallWrapper,
+ MediaConduitStatisticsId aStatsId) :
mPCHandle(aPCHandle),
mJsepTransceiver(aJsepTransceiver),
mHaveStartedReceiving(false),
mHaveSetupTransport(false),
mMainThread(aMainThread),
mStsThread(aStsThread),
mReceiveTrack(aReceiveTrack),
mSendTrack(aSendTrack),
mCallWrapper(aCallWrapper)
{
if (IsVideo()) {
- InitVideo();
+ InitVideo(aStatsId);
} else {
- InitAudio();
+ InitAudio(aStatsId);
}
if (!IsValid()) {
return;
}
mConduit->SetPCHandle(mPCHandle);
@@ -74,19 +75,19 @@ TransceiverImpl::TransceiverImpl(
mTransmitPipeline->SetTrack(mSendTrack);
}
TransceiverImpl::~TransceiverImpl() = default;
NS_IMPL_ISUPPORTS0(TransceiverImpl)
void
-TransceiverImpl::InitAudio()
+TransceiverImpl::InitAudio(MediaConduitStatisticsId aStatsId)
{
- mConduit = AudioSessionConduit::Create();
+ mConduit = AudioSessionConduit::Create(aStatsId);
if (!mConduit) {
MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
": Failed to create AudioSessionConduit");
// TODO(bug 1422897): We need a way to record this when it happens in the
// wild.
return;
}
@@ -95,19 +96,19 @@ TransceiverImpl::InitAudio()
mPCHandle,
mMainThread.get(),
mStsThread.get(),
static_cast<AudioSessionConduit*>(mConduit.get()),
mReceiveTrack);
}
void
-TransceiverImpl::InitVideo()
+TransceiverImpl::InitVideo(MediaConduitStatisticsId aStatsId)
{
- mConduit = VideoSessionConduit::Create(mCallWrapper);
+ mConduit = VideoSessionConduit::Create(mCallWrapper, aStatsId);
if (!mConduit) {
MOZ_MTLOG(ML_ERROR, mPCHandle << "[" << mMid << "]: " << __FUNCTION__ <<
": Failed to create VideoSessionConduit");
// TODO(bug 1422897): We need a way to record this when it happens in the
// wild.
return;
}
--- a/media/webrtc/signaling/src/peerconnection/TransceiverImpl.h
+++ b/media/webrtc/signaling/src/peerconnection/TransceiverImpl.h
@@ -7,16 +7,17 @@
#include <string>
#include "mozilla/RefPtr.h"
#include "nsCOMPtr.h"
#include "nsIEventTarget.h"
#include "nsTArray.h"
#include "mozilla/OwningNonNull.h"
#include "mozilla/dom/MediaStreamTrack.h"
#include "ErrorList.h"
+#include "signaling/src/media-conduit/MediaConduitStatisticsId.h"
#include "mtransport/transportflow.h"
#include "signaling/src/jsep/JsepTransceiver.h"
class nsIPrincipal;
namespace mozilla {
class PeerIdentity;
class PeerConnectionMedia;
@@ -42,28 +43,30 @@ struct RTCRtpSourceEntry;
* together. This includes:
* MediaStreamTrack for rendering and capture
* TransportFlow for RTP transmission/reception
* Audio/VideoConduit for feeding RTP/RTCP into webrtc.org for decoding, and
* feeding audio/video frames into webrtc.org for encoding into RTP/RTCP.
*/
class TransceiverImpl : public nsISupports {
public:
+ typedef uint64_t StatisticsId;
/**
* |aReceiveStream| is always set; this holds even if the remote end has not
* negotiated one for this transceiver. |aSendTrack| might or might not be
* set.
*/
TransceiverImpl(const std::string& aPCHandle,
JsepTransceiver* aJsepTransceiver,
nsIEventTarget* aMainThread,
nsIEventTarget* aStsThread,
dom::MediaStreamTrack* aReceiveTrack,
dom::MediaStreamTrack* aSendTrack,
- WebRtcCallWrapper* aCallWrapper);
+ WebRtcCallWrapper* aCallWrapper,
+ MediaConduitStatisticsId aStatsId);
bool IsValid() const
{
return !!mConduit;
}
nsresult UpdateSendTrack(dom::MediaStreamTrack* aSendTrack);
@@ -124,18 +127,18 @@ public:
int64_t aTimestamp,
bool aHasLevel,
uint8_t aLevel);
NS_DECL_THREADSAFE_ISUPPORTS
private:
virtual ~TransceiverImpl();
- void InitAudio();
- void InitVideo();
+ void InitAudio(MediaConduitStatisticsId aStatsId);
+ void InitVideo(MediaConduitStatisticsId aStatsId);
nsresult UpdateAudioConduit();
nsresult UpdateVideoConduit();
nsresult ConfigureVideoCodecMode(VideoSessionConduit& aConduit);
void UpdateConduitRtpExtmap(const JsepTrackNegotiatedDetails& aDetails,
const MediaSessionConduitLocalDirection aDir);
void Stop();
const std::string mPCHandle;