Diff
Modified: trunk/LayoutTests/ChangeLog (214349 => 214350)
--- trunk/LayoutTests/ChangeLog 2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/LayoutTests/ChangeLog 2017-03-24 16:32:53 UTC (rev 214350)
@@ -1,3 +1,15 @@
+2017-03-24 Youenn Fablet <[email protected]>
+
+ Add support for DataChannel and MediaStreamTrack stats
+ https://bugs.webkit.org/show_bug.cgi?id=170031
+
+ Reviewed by Eric Carlson.
+
+ * webrtc/datachannel/datachannel-stats-expected.txt: Added.
+ * webrtc/datachannel/datachannel-stats.html: Added.
+ * webrtc/video-mediastreamtrack-stats-expected.txt: Added.
+ * webrtc/video-mediastreamtrack-stats.html: Added.
+
2017-03-24 Chris Dumez <[email protected]>
Extend svg/animations/animations-paused-disconnected-iframe.html
Added: trunk/LayoutTests/webrtc/datachannel/datachannel-stats-expected.txt (0 => 214350)
--- trunk/LayoutTests/webrtc/datachannel/datachannel-stats-expected.txt (rev 0)
+++ trunk/LayoutTests/webrtc/datachannel/datachannel-stats-expected.txt 2017-03-24 16:32:53 UTC (rev 214350)
@@ -0,0 +1,3 @@
+
+PASS Basic data channel exchange with stats
+
Added: trunk/LayoutTests/webrtc/datachannel/datachannel-stats.html (0 => 214350)
--- trunk/LayoutTests/webrtc/datachannel/datachannel-stats.html (rev 0)
+++ trunk/LayoutTests/webrtc/datachannel/datachannel-stats.html 2017-03-24 16:32:53 UTC (rev 214350)
@@ -0,0 +1,87 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing basic data channel from offerer to receiver</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src =""
+ <script>
+var localChannel;
+var remoteChannel;
+
+function receiveMessages(event) {
+ if (++counter === 1)
+ assert_equals(event.data, "one");
+ else if (counter === 2)
+ assert_equals(event.data, "two");
+ else if (counter === 3)
+ assert_equals(event.data, "three");
+ else if (counter === 4) {
+ assert_equals(event.data, "four");
+ finishTest();
+ } else
+ assert_unreached();
+}
+
+function sendMessages(channel)
+{
+ channel.send("one");
+ channel.send("two");
+ channel.send("three");
+ channel.send("four");
+}
+
+function getDataChannelStats(connection)
+{
+ return connection.getStats().then((report) => {
+ var stats;
+ report.forEach((statItem) => {
+ if (statItem.type === "data-channel") {
+ stats = statItem;
+ }
+ });
+ return stats;
+ });
+}
+
+var finishTest;
+promise_test((test) => {
+ counter = 0;
+ return new Promise((resolve, reject) => {
+ if (window.internals)
+ internals.useMockRTCPeerConnectionFactory("TwoRealPeerConnections");
+
+ var localConnection, remoteConnection;
+ finishTest = () => {
+ getDataChannelStats(localConnection).then((stats) => {
+ stats.id = "id";
+ stats.timestamp = 1;
+ assert_equals(JSON.stringify(stats), '{"id":"id","timestamp":1,"type":"data-channel","bytesReceived":0,"bytesSent":15,"datachannelid":1,"label":"sendDataChannel","messagesReceived":0,"messagesSent":4,"protocol":"","state":"open"}');
+ return getDataChannelStats(remoteConnection);
+ }).then((stats) => {
+ stats.id = "id";
+ stats.timestamp = 1;
+ assert_equals(JSON.stringify(stats), '{"id":"id","timestamp":1,"type":"data-channel","bytesReceived":15,"bytesSent":0,"datachannelid":1,"label":"sendDataChannel","messagesReceived":4,"messagesSent":0,"protocol":"","state":"open"}');
+ resolve();
+ });
+ };
+
+ createConnections((connection) => {
+ localConnection = connection;
+ localChannel = localConnection.createDataChannel('sendDataChannel');
+ localChannel._onopen_ = () => { sendMessages(localChannel) };
+ }, (connection) => {
+ remoteConnection = connection;
+ remoteConnection._ondatachannel_ = (event) => {
+ remoteChannel = event.channel;
+ remoteChannel._onmessage_ = receiveMessages;
+ };
+ });
+ });
+}, "Basic data channel exchange with stats");
+ </script>
+ </body>
+</html>
Added: trunk/LayoutTests/webrtc/video-mediastreamtrack-stats-expected.txt (0 => 214350)
--- trunk/LayoutTests/webrtc/video-mediastreamtrack-stats-expected.txt (rev 0)
+++ trunk/LayoutTests/webrtc/video-mediastreamtrack-stats-expected.txt 2017-03-24 16:32:53 UTC (rev 214350)
@@ -0,0 +1,3 @@
+
+PASS Basic video media stream track stats
+
Added: trunk/LayoutTests/webrtc/video-mediastreamtrack-stats.html (0 => 214350)
--- trunk/LayoutTests/webrtc/video-mediastreamtrack-stats.html (rev 0)
+++ trunk/LayoutTests/webrtc/video-mediastreamtrack-stats.html 2017-03-24 16:32:53 UTC (rev 214350)
@@ -0,0 +1,69 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>Testing basic video exchange from offerer to receiver</title>
+ <script src=""
+ <script src=""
+ </head>
+ <body>
+ <script src =""
+ <script>
+function getTrackStats(connection)
+{
+ return connection.getStats().then((report) => {
+ var stats;
+ report.forEach((statItem) => {
+ if (statItem.type === "track") {
+ stats = statItem;
+ }
+ });
+ return stats;
+ });
+}
+
+var firstConnection, secondConnection;
+promise_test((test) => {
+ if (window.testRunner)
+ testRunner.setUserMediaPermission(true);
+
+ var localStream, remoteStream;
+ return navigator.mediaDevices.getUserMedia({ video: true}).then((stream) => {
+ localStream = stream;
+ return new Promise((resolve, reject) => {
+ if (window.internals)
+ internals.useMockRTCPeerConnectionFactory("TwoRealPeerConnections");
+
+ createConnections((connection) => {
+ firstConnection = connection;
+ firstConnection.addTrack(stream.getVideoTracks()[0], stream);
+ }, (connection) => {
+ secondConnection = connection;
+ secondConnection._ontrack_ = (trackEvent) => {
+ remoteStream = trackEvent.streams[0];
+ resolve();
+ };
+ });
+ setTimeout(() => reject("Test timed out"), 5000);
+ });
+ }).then(() => {
+ return getTrackStats(secondConnection);
+ }).then((stats) => {
+ assert_true(!!stats, "tracks stats should not be null or undefined");
+ stats.id = "id";
+ stats.timestamp = 1;
+ stats.trackIdentifier = "trackid";
+ assert_equals(JSON.stringify(stats), '{"id":"id","timestamp":1,"type":"track","audioLevel":0,"detached":false,"echoReturnLoss":0,"echoReturnLossEnhancement":0,"ended":false,"frameHeight":0,"frameWidth":0,"framesCorrupted":0,"framesDecoded":0,"framesDropped":0,"framesPerSecond":0,"framesReceived":0,"framesSent":0,"fullFramesLost":0,"partialFramesLost":0,"remoteSource":true,"trackIdentifier":"trackid"}');
+ return waitFor(1000);
+ }).then(() => {
+ return getTrackStats(secondConnection);
+ }).then((stats) => {
+ assert_equals(stats.frameHeight, 480);
+ assert_equals(stats.frameWidth, 640);
+ assert_true(stats.framesDecoded > 0);
+ assert_true(stats.framesReceived > 0);
+ });
+}, "Basic video media stream track stats");
+ </script>
+ </body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (214349 => 214350)
--- trunk/Source/WebCore/ChangeLog 2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/Source/WebCore/ChangeLog 2017-03-24 16:32:53 UTC (rev 214350)
@@ -1,5 +1,26 @@
2017-03-24 Youenn Fablet <[email protected]>
+ Add support for DataChannel and MediaStreamTrack stats
+ https://bugs.webkit.org/show_bug.cgi?id=170031
+
+ Reviewed by Eric Carlson.
+
+ Tests: webrtc/datachannel/datachannel-stats.html
+ webrtc/video-mediastreamtrack-stats.html
+
+ Exposing libwebrtc stats through WebRTC stats API, gathered for data channel and media stream tracks.
+
+ * Modules/mediastream/RTCStatsReport.h:
+ (WebCore::RTCStatsReport::MediaStreamTrackStats::MediaStreamTrackStats):
+ (WebCore::RTCStatsReport::DataChannelStats::DataChannelStats):
+ * Modules/mediastream/RTCStatsReport.idl:
+ * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+ (WebCore::fillRTCMediaStreamTrackStats):
+ (WebCore::fillRTCDataChannelStats):
+ (WebCore::LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered):
+
+2017-03-24 Youenn Fablet <[email protected]>
+
Fix framesEncoded/framesDecoded RTC stats
https://bugs.webkit.org/show_bug.cgi?id=170024
Modified: trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h (214349 => 214350)
--- trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h 2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.h 2017-03-24 16:32:53 UTC (rev 214350)
@@ -116,6 +116,41 @@
unsigned long framesEncoded { 0 };
};
+ struct MediaStreamTrackStats : Stats {
+ MediaStreamTrackStats() { type = RTCStatsReport::Type::Track; }
+
+ String trackIdentifier;
+ bool remoteSource { false };
+ bool ended { false };
+ bool detached { false };
+ unsigned long frameWidth { 0 };
+ unsigned long frameHeight { 0};
+ double framesPerSecond { 0 };
+ unsigned long framesSent { 0 };
+ unsigned long framesReceived { 0 };
+ unsigned long framesDecoded { 0 };
+ unsigned long framesDropped { 0 };
+ unsigned long framesCorrupted { 0 };
+ unsigned long partialFramesLost { 0 };
+ unsigned long fullFramesLost { 0 };
+ double audioLevel { 0 };
+ double echoReturnLoss { 0 };
+ double echoReturnLossEnhancement { 0 };
+ };
+
+ struct DataChannelStats : Stats {
+ DataChannelStats() { type = RTCStatsReport::Type::DataChannel; }
+
+ String label;
+ String protocol;
+ long datachannelid { 0 };
+ String state;
+ unsigned long messagesSent { 0 };
+ unsigned long long bytesSent { 0 };
+ unsigned long messagesReceived { 0 };
+ unsigned long long bytesReceived { 0 };
+ };
+
private:
RTCStatsReport() = default;
Modified: trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl (214349 => 214350)
--- trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl 2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/Source/WebCore/Modules/mediastream/RTCStatsReport.idl 2017-03-24 16:32:53 UTC (rev 214350)
@@ -70,8 +70,6 @@
unsigned long long qpSum;
};
-// FIXME 169662: missing RTCCodecStats
-
[ JSGenerateToJSObject ]
dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
unsigned long packetsReceived;
@@ -101,10 +99,44 @@
unsigned long framesEncoded;
};
+[ JSGenerateToJSObject ]
+dictionary RTCMediaStreamTrackStats : RTCStats {
+ DOMString trackIdentifier;
+ boolean remoteSource;
+ boolean ended;
+ boolean detached;
+ // FIXME: Add sequence<DOMString> ssrcIds;
+ unsigned long frameWidth;
+ unsigned long frameHeight;
+ double framesPerSecond;
+ unsigned long framesSent;
+ unsigned long framesReceived;
+ unsigned long framesDecoded;
+ unsigned long framesDropped;
+ unsigned long framesCorrupted;
+ unsigned long partialFramesLost;
+ unsigned long fullFramesLost;
+ double audioLevel;
+ double echoReturnLoss;
+ double echoReturnLossEnhancement;
+};
+
+[ JSGenerateToJSObject ]
+dictionary RTCDataChannelStats : RTCStats {
+ DOMString label;
+ DOMString protocol;
+ long datachannelid;
+ // FIXME: Switch state to RTCDataChannelState
+ DOMString state;
+ unsigned long messagesSent;
+ unsigned long long bytesSent;
+ unsigned long messagesReceived;
+ unsigned long long bytesReceived;
+};
+
+// FIXME 169662: missing RTCCodecStats
// FIXME 169662: missing RTCPeerConnectionStats
// FIXME 169662: missing RTCMediaStreamStats
-// FIXME 169662: missing RTCMediaStreamTrackStats
-// FIXME 169662: missing RTCDataChannelStats
// FIXME 169662: missing RTCTransportStats
// FIXME 169662: missing RTCIceCandidateStats
// FIXME 169662: missing RTCIceCandidatePairStats
Modified: trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp (214349 => 214350)
--- trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp 2017-03-24 16:27:01 UTC (rev 214349)
+++ trunk/Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp 2017-03-24 16:32:53 UTC (rev 214350)
@@ -323,6 +323,65 @@
stats.framesEncoded = *rtcStats.frames_encoded;
}
+static inline void fillRTCMediaStreamTrackStats(RTCStatsReport::MediaStreamTrackStats& stats, const webrtc::RTCMediaStreamTrackStats& rtcStats)
+{
+ fillRTCStats(stats, rtcStats);
+ if (rtcStats.track_identifier.is_defined())
+ stats.trackIdentifier = fromStdString(*rtcStats.track_identifier);
+ if (rtcStats.remote_source.is_defined())
+ stats.remoteSource = *rtcStats.remote_source;
+ if (rtcStats.ended.is_defined())
+ stats.ended = *rtcStats.ended;
+ if (rtcStats.detached.is_defined())
+ stats.detached = *rtcStats.detached;
+ if (rtcStats.frame_width.is_defined())
+ stats.frameWidth = *rtcStats.frame_width;
+ if (rtcStats.frame_height.is_defined())
+ stats.frameHeight = *rtcStats.frame_height;
+ if (rtcStats.frames_per_second.is_defined())
+ stats.framesPerSecond = *rtcStats.frames_per_second;
+ if (rtcStats.frames_sent.is_defined())
+ stats.framesSent = *rtcStats.frames_sent;
+ if (rtcStats.frames_received.is_defined())
+ stats.framesReceived = *rtcStats.frames_received;
+ if (rtcStats.frames_decoded.is_defined())
+ stats.framesDecoded = *rtcStats.frames_decoded;
+ if (rtcStats.frames_dropped.is_defined())
+ stats.framesDropped = *rtcStats.frames_dropped;
+ if (rtcStats.partial_frames_lost.is_defined())
+ stats.partialFramesLost = *rtcStats.partial_frames_lost;
+ if (rtcStats.full_frames_lost.is_defined())
+ stats.fullFramesLost = *rtcStats.full_frames_lost;
+ if (rtcStats.audio_level.is_defined())
+ stats.audioLevel = *rtcStats.audio_level;
+ if (rtcStats.echo_return_loss.is_defined())
+ stats.echoReturnLoss = *rtcStats.echo_return_loss;
+ if (rtcStats.echo_return_loss_enhancement.is_defined())
+ stats.echoReturnLossEnhancement = *rtcStats.echo_return_loss_enhancement;
+}
+
+static inline void fillRTCDataChannelStats(RTCStatsReport::DataChannelStats& stats, const webrtc::RTCDataChannelStats& rtcStats)
+{
+ fillRTCStats(stats, rtcStats);
+
+ if (rtcStats.label.is_defined())
+ stats.label = fromStdString(*rtcStats.label);
+ if (rtcStats.protocol.is_defined())
+ stats.protocol = fromStdString(*rtcStats.protocol);
+ if (rtcStats.datachannelid.is_defined())
+ stats.datachannelid = *rtcStats.datachannelid;
+ if (rtcStats.state.is_defined())
+ stats.state = fromStdString(*rtcStats.state);
+ if (rtcStats.messages_sent.is_defined())
+ stats.messagesSent = *rtcStats.messages_sent;
+ if (rtcStats.bytes_sent.is_defined())
+ stats.bytesSent = *rtcStats.bytes_sent;
+ if (rtcStats.messages_received.is_defined())
+ stats.messagesReceived = *rtcStats.messages_received;
+ if (rtcStats.bytes_received.is_defined())
+ stats.bytesReceived = *rtcStats.bytes_received;
+}
+
void LibWebRTCMediaEndpoint::StatsCollector::OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>& rtcReport)
{
callOnMainThread([protectedThis = rtc::scoped_refptr<LibWebRTCMediaEndpoint::StatsCollector>(this), rtcReport] {
@@ -338,13 +397,18 @@
RTCStatsReport::InboundRTPStreamStats stats;
fillInboundRTPStreamStats(stats, static_cast<const webrtc::RTCInboundRTPStreamStats&>(rtcStats));
report->addStats<IDLDictionary<RTCStatsReport::InboundRTPStreamStats>>(WTFMove(stats));
- return;
- }
- if (rtcStats.type() == webrtc::RTCOutboundRTPStreamStats::kType) {
+ } else if (rtcStats.type() == webrtc::RTCOutboundRTPStreamStats::kType) {
RTCStatsReport::OutboundRTPStreamStats stats;
fillOutboundRTPStreamStats(stats, static_cast<const webrtc::RTCOutboundRTPStreamStats&>(rtcStats));
report->addStats<IDLDictionary<RTCStatsReport::OutboundRTPStreamStats>>(WTFMove(stats));
- return;
+ } else if (rtcStats.type() == webrtc::RTCMediaStreamTrackStats::kType) {
+ RTCStatsReport::MediaStreamTrackStats stats;
+ fillRTCMediaStreamTrackStats(stats, static_cast<const webrtc::RTCMediaStreamTrackStats&>(rtcStats));
+ report->addStats<IDLDictionary<RTCStatsReport::MediaStreamTrackStats>>(WTFMove(stats));
+ } else if (rtcStats.type() == webrtc::RTCDataChannelStats::kType) {
+ RTCStatsReport::DataChannelStats stats;
+ fillRTCDataChannelStats(stats, static_cast<const webrtc::RTCDataChannelStats&>(rtcStats));
+ report->addStats<IDLDictionary<RTCStatsReport::DataChannelStats>>(WTFMove(stats));
}
}
});