Add RTCCodecStats support
authoryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Sep 2018 19:39:41 +0000 (19:39 +0000)
committeryouenn@apple.com <youenn@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Sep 2018 19:39:41 +0000 (19:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189792
<rdar://problem/32370668>

Reviewed by Eric Carlson.

LayoutTests/imported/w3c:

* web-platform-tests/webrtc/RTCPeerConnection-addIceCandidate-expected.txt:
* web-platform-tests/webrtc/RTCRtpReceiver-getStats.https-expected.txt:
* web-platform-tests/webrtc/RTCRtpSender-getStats.https-expected.txt:

Source/WebCore:

Covered by updated and rebased tests.

* Modules/mediastream/RTCStatsReport.h:
Removed fields that are already defined in the base class.
(WebCore::RTCStatsReport::CodecStats::CodecStats):
Add support for RTCCodecStats.
* Modules/mediastream/RTCStatsReport.idl:
* Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
(WebCore::LibWebRTCMediaEndpoint::OnStatsDelivered):
* Modules/mediastream/libwebrtc/LibWebRTCStatsCollector.cpp:
(WebCore::fillRTCRTPStreamStats):
(WebCore::fillRTCCodecStats):
(WebCore::LibWebRTCStatsCollector::OnStatsDelivered):
Add routines to fill RTCCodecStats from libwebrtc stats.

LayoutTests:

* webrtc/video-stats.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236346 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getStats.https-expected.txt
LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpSender-getStats.https-expected.txt
LayoutTests/webrtc/video-stats.html
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/RTCStatsReport.h
Source/WebCore/Modules/mediastream/RTCStatsReport.idl
Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp
Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCStatsCollector.cpp

index 5452f9f..33c9af9 100644 (file)
@@ -1,3 +1,13 @@
+2018-09-21  Youenn Fablet  <youenn@apple.com>
+
+        Add RTCCodecStats support
+        https://bugs.webkit.org/show_bug.cgi?id=189792
+        <rdar://problem/32370668>
+
+        Reviewed by Eric Carlson.
+
+        * webrtc/video-stats.html:
+
 2018-09-21  Megan Gardner  <megan_gardner@apple.com>
 
         [iOS] Layout test fast/gradients/conic-gradient-alpha.html is failing
index da42047..95b1e16 100644 (file)
@@ -1,3 +1,15 @@
+2018-09-21  Youenn Fablet  <youenn@apple.com>
+
+        Add RTCCodecStats support
+        https://bugs.webkit.org/show_bug.cgi?id=189792
+        <rdar://problem/32370668>
+
+        Reviewed by Eric Carlson.
+
+        * web-platform-tests/webrtc/RTCPeerConnection-addIceCandidate-expected.txt:
+        * web-platform-tests/webrtc/RTCRtpReceiver-getStats.https-expected.txt:
+        * web-platform-tests/webrtc/RTCRtpSender-getStats.https-expected.txt:
+
 2018-09-20  Frederic Wang  <fwang@igalia.com>
 
         Synchronize CSSOM View test suite against upstream WPT
index 4ee77a4..f8d1e0d 100644 (file)
@@ -1,4 +1,4 @@
 
 FAIL receiver.getStats() via addTransceiver should return stats report containing inbound-rtp stats assert_true: Expect statsReport to contain stats object of type inbound-rtp expected true got false
-FAIL receiver.getStats() via addTrack should return stats report containing inbound-rtp stats assert_equals: Expect dictionary.mediaType to be string expected "string" but got "undefined"
+FAIL receiver.getStats() via addTrack should return stats report containing inbound-rtp stats assert_true: Expect stats report to have stats object with id RTCTransport_0_1 expected true got false
 
index 8e98e45..a0bd904 100644 (file)
@@ -1,4 +1,4 @@
 
 FAIL sender.getStats() via addTransceiver should return stats report containing outbound-rtp stats assert_true: Expect statsReport to contain stats object of type outbound-rtp expected true got false
-FAIL sender.getStats() via addTrack should return stats report containing outbound-rtp stats assert_equals: Expect dictionary.trackId to be string expected "string" but got "undefined"
+FAIL sender.getStats() via addTrack should return stats report containing outbound-rtp stats assert_true: Expect stats report to have stats object with id RTCTransport_0_1 expected true got false
 
index 8286ca7..dc1c4a5 100644 (file)
@@ -69,6 +69,8 @@ function checkInboundFramesNumberIncreased(secondConnection, statsSecondConnecti
         if (stats.framesDecoded > statsSecondConnection.framesDecoded) {
             if (testTimestampDifference(stats.timestamp - statsSecondConnection.timestamp, stats.framesDecoded - statsSecondConnection.framesDecoded))
                 return Promise.reject("timestamp and frames increment do not match");
+            assert_not_equals(Object.keys(stats).indexOf("codecId"), -1, "codecId");
+            assert_not_equals(Object.keys(stats).indexOf("trackId"), -1, "trackId");
             return;
         }
         if (++count === 20)
@@ -85,6 +87,8 @@ function checkOutboundFramesNumberIncreased(firstConnection, statsFirstConnectio
         if (stats.framesEncoded > statsFirstConnection.framesEncoded) {
             if (testTimestampDifference(stats.timestamp - statsFirstConnection.timestamp, stats.framesEncoded - statsFirstConnection.framesEncoded))
                 return Promise.reject("timestamp and frames increment do not match");
+            assert_not_equals(Object.keys(stats).indexOf("codecId"), -1, "codecId");
+            assert_not_equals(Object.keys(stats).indexOf("trackId"), -1, "trackId");
             return;
         }
         if (++count === 20)
@@ -133,10 +137,10 @@ promise_test(async (test) => {
     await checkOutboundFramesNumberIncreased(firstConnection, statsFirstConnection, 0);
 
     let types = await getStatsType(firstConnection);
-    assert_array_equals(types, ["candidate-pair", "certificate", "inbound-rtp", "outbound-rtp", "track"]);
+    assert_array_equals(types, ["candidate-pair", "certificate", "codec", "inbound-rtp", "outbound-rtp", "track"]);
 
     types = await getStatsType(secondConnection);
-    assert_array_equals(types, ["candidate-pair", "certificate", "inbound-rtp", "outbound-rtp", "track"]);
+    assert_array_equals(types, ["candidate-pair", "certificate", "codec", "inbound-rtp", "outbound-rtp", "track"]);
 }, "Basic video stats");
 
 promise_test(async (test) => {
index d8bf1ab..1d525f0 100644 (file)
@@ -1,3 +1,26 @@
+2018-09-21  Youenn Fablet  <youenn@apple.com>
+
+        Add RTCCodecStats support
+        https://bugs.webkit.org/show_bug.cgi?id=189792
+        <rdar://problem/32370668>
+
+        Reviewed by Eric Carlson.
+
+        Covered by updated and rebased tests.
+
+        * Modules/mediastream/RTCStatsReport.h:
+        Removed fields that are already defined in the base class.
+        (WebCore::RTCStatsReport::CodecStats::CodecStats):
+        Add support for RTCCodecStats.
+        * Modules/mediastream/RTCStatsReport.idl:
+        * Modules/mediastream/libwebrtc/LibWebRTCMediaEndpoint.cpp:
+        (WebCore::LibWebRTCMediaEndpoint::OnStatsDelivered):
+        * Modules/mediastream/libwebrtc/LibWebRTCStatsCollector.cpp:
+        (WebCore::fillRTCRTPStreamStats):
+        (WebCore::fillRTCCodecStats):
+        (WebCore::LibWebRTCStatsCollector::OnStatsDelivered):
+        Add routines to fill RTCCodecStats from libwebrtc stats.
+
 2018-09-20  Simon Fraser  <simon.fraser@apple.com>
 
         Make "overflow: overlay" a synonym for "overflow: auto"
index 01f3e7f..bac5831 100644 (file)
@@ -64,7 +64,7 @@ public:
         bool isRemote { false };
         String mediaType;
 
-        String mediaTrackId;
+        String trackId;
         String transportId;
         String codecId;
         unsigned long firCount { 0 };
@@ -77,18 +77,6 @@ public:
     struct InboundRTPStreamStats : RTCRTPStreamStats {
         InboundRTPStreamStats() { type = RTCStatsReport::Type::InboundRtp; }
 
-        uint32_t ssrc;
-        String associateStatsId;
-        bool isRemote { false };
-        String mediaType;
-        String mediaTrackId;
-        String transportId;
-        String codecId;
-        unsigned long firCount { 0 };
-        unsigned long pliCount { 0 };
-        unsigned long nackCount { 0 };
-        unsigned long sliCount { 0 };
-        unsigned long long qpSum { 0 };
         unsigned long packetsReceived { 0 };
         unsigned long long bytesReceived { 0 };
         unsigned long packetsLost { 0 };
@@ -198,6 +186,24 @@ public:
         String issuerCertificateId;
     };
 
+    enum class CodecType {
+        Encode,
+        Decode
+    };
+
+    struct CodecStats : Stats {
+        CodecStats() { type = RTCStatsReport::Type::Codec; }
+
+        unsigned long payloadType;
+        std::optional<CodecType> codecType;
+        String transportId;
+        String mimeType;
+        std::optional<unsigned> clockRate;
+        std::optional<unsigned> channels;
+        String sdpFmtpLine;
+        String implementation;
+    };
+
 private:
     RTCStatsReport() = default;
 
index 7460426..0e7d333 100644 (file)
@@ -59,7 +59,7 @@ dictionary RTCRTPStreamStats : RTCStats {
     DOMString associateStatsId;
     boolean isRemote = false;
     DOMString mediaType;
-    DOMString mediaTrackId;
+    DOMString trackId;
     DOMString transportId;
     DOMString codecId;
     unsigned long firCount;
@@ -173,7 +173,23 @@ dictionary RTCCertificateStats : RTCStats {
     DOMString issuerCertificateId;
 };
 
-// FIXME 169662: missing RTCCodecStats
+enum RTCCodecType {
+    "encode",
+    "decode"
+};
+
+[ JSGenerateToJSObject ]
+dictionary RTCCodecStats : RTCStats {
+    unsigned long payloadType;
+    RTCCodecType codecType;
+    DOMString transportId;
+    DOMString mimeType;
+    unsigned long clockRate;
+    unsigned long channels;
+    DOMString sdpFmtpLine;
+    DOMString implementation;
+};
+
 // FIXME 169662: missing RTCPeerConnectionStats
 // FIXME 169662: missing RTCMediaStreamStats
 // FIXME 169662: missing RTCTransportStats
index cd00353..44f651b 100644 (file)
@@ -798,12 +798,8 @@ void LibWebRTCMediaEndpoint::OnStatsDelivered(const rtc::scoped_refptr<const web
             m_statsLogTimer.startRepeating(statsLogInterval(timestamp));
         }
 
-        for (auto iterator = report->begin(); iterator != report->end(); ++iterator) {
-            if (iterator->type() == webrtc::RTCCodecStats::kType)
-                continue;
-
+        for (auto iterator = report->begin(); iterator != report->end(); ++iterator)
             ALWAYS_LOG(Logger::LogSiteIdentifier("LibWebRTCMediaEndpoint", "OnStatsDelivered", logIdentifier()), RTCStatsLogger { *iterator });
-        }
     });
 #else
     UNUSED_PARAM(report);
index 47df7be..298b1e3 100644 (file)
@@ -72,7 +72,7 @@ static inline void fillRTCRTPStreamStats(RTCStatsReport::RTCRTPStreamStats& stat
     if (rtcStats.media_type.is_defined())
         stats.mediaType = fromStdString(*rtcStats.media_type);
     if (rtcStats.track_id.is_defined())
-        stats.mediaTrackId = fromStdString(*rtcStats.track_id);
+        stats.trackId = fromStdString(*rtcStats.track_id);
     if (rtcStats.transport_id.is_defined())
         stats.transportId = fromStdString(*rtcStats.transport_id);
     if (rtcStats.codec_id.is_defined())
@@ -291,6 +291,25 @@ static inline void fillRTCCertificateStats(RTCStatsReport::CertificateStats& sta
     if (rtcStats.issuer_certificate_id.is_defined())
         stats.issuerCertificateId = fromStdString(*rtcStats.issuer_certificate_id);
 }
+
+static inline void fillRTCCodecStats(RTCStatsReport::CodecStats& stats, const webrtc::RTCCodecStats& rtcStats)
+{
+    fillRTCStats(stats, rtcStats);
+
+    if (rtcStats.payload_type.is_defined())
+        stats.payloadType = *rtcStats.payload_type;
+    if (rtcStats.mime_type.is_defined())
+        stats.mimeType = fromStdString(*rtcStats.mime_type);
+    if (rtcStats.clock_rate.is_defined())
+        stats.clockRate = *rtcStats.clock_rate;
+    if (rtcStats.channels.is_defined())
+        stats.channels = *rtcStats.channels;
+    if (rtcStats.sdp_fmtp_line.is_defined())
+        stats.sdpFmtpLine = fromStdString(*rtcStats.sdp_fmtp_line);
+    if (rtcStats.implementation.is_defined())
+        stats.implementation = fromStdString(*rtcStats.implementation);
+}
+
 void LibWebRTCStatsCollector::OnStatsDelivered(const rtc::scoped_refptr<const webrtc::RTCStatsReport>& rtcReport)
 {
     callOnMainThread([protectedThis = rtc::scoped_refptr<LibWebRTCStatsCollector>(this), rtcReport] {
@@ -325,6 +344,10 @@ void LibWebRTCStatsCollector::OnStatsDelivered(const rtc::scoped_refptr<const we
                 RTCStatsReport::CertificateStats stats;
                 fillRTCCertificateStats(stats, static_cast<const webrtc::RTCCertificateStats&>(rtcStats));
                 report->addStats<IDLDictionary<RTCStatsReport::CertificateStats>>(WTFMove(stats));
+            } else if (rtcStats.type() == webrtc::RTCCodecStats::kType) {
+                RTCStatsReport::CodecStats stats;
+                fillRTCCodecStats(stats, static_cast<const webrtc::RTCCodecStats&>(rtcStats));
+                report->addStats<IDLDictionary<RTCStatsReport::CodecStats>>(WTFMove(stats));
             }
         }
     });