Bug 1055378 - Adds RTCRTPStreamStats.mediaType + test of getStats w/track arg. r=smaug,drno,jesup
authorJan-Ivar Bruaroey <jib@mozilla.com>
Thu, 21 Aug 2014 17:14:12 -0400
changeset 223742 e98290b4d2319e2d7cd37842f323bbd3cab07a9a
parent 223741 7fbcf09c084e44d4b354055660ad6fbd9a46c482
child 223743 edfbcca4ef084b3a47bf10c80e3f44661e128637
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, drno, jesup
bugs1055378
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1055378 - Adds RTCRTPStreamStats.mediaType + test of getStats w/track arg. r=smaug,drno,jesup
dom/media/tests/mochitest/pc.js
dom/media/tests/mochitest/templates.js
dom/webidl/RTCStatsReport.webidl
media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
--- a/dom/media/tests/mochitest/pc.js
+++ b/dom/media/tests/mochitest/pc.js
@@ -2276,16 +2276,44 @@ PeerConnectionWrapper.prototype = {
       ok(numRemoteCandidates, "Have remotecandidate stat(s)");
     } else {
       is(numLocalCandidates, 0, "Have no localcandidate stats");
       is(numRemoteCandidates, 0, "Have no remotecandidate stats");
     }
   },
 
   /**
+   * Property-matching function for finding a certain stat in passed-in stats
+   *
+   * @param {object} stats
+   *        The stats to check from this PeerConnectionWrapper
+   * @param {object} props
+   *        The properties to look for
+   * @returns {boolean} Whether an entry containing all match-props was found.
+   */
+  hasStat : function PCW_hasStat(stats, props) {
+    for (var key in stats) {
+      if (stats.hasOwnProperty(key)) {
+        var res = stats[key];
+        var match = true;
+        for (var prop in props) {
+          if (res[prop] !== props[prop]) {
+            match = false;
+            break;
+          }
+        }
+        if (match) {
+          return true;
+        }
+      }
+    }
+    return false;
+  },
+
+  /**
    * Closes the connection
    */
   close : function PCW_close() {
     // It might be that a test has already closed the pc. In those cases
     // we should not fail.
     try {
       this._pc.close();
       info(this + ": Closed connection.");
--- a/dom/media/tests/mochitest/templates.js
+++ b/dom/media/tests/mochitest/templates.js
@@ -408,16 +408,160 @@ var commandsPeerConnection = [
   [
     'PC_REMOTE_CHECK_STATS',
     function (test) {
       test.pcRemote.getStats(null, function(stats) {
         test.pcRemote.checkStats(stats);
         test.next();
       });
     }
+  ],
+  [
+    'PC_LOCAL_CHECK_GETSTATS_AUDIOTRACK_OUTBOUND',
+    function (test) {
+      var pc = test.pcLocal;
+      var stream = pc._pc.getLocalStreams()[0];
+      var track = stream && stream.getAudioTracks()[0];
+      if (track) {
+        pc.getStats(track, function(stats) {
+          ok(pc.hasStat(stats,
+                        { type:"outboundrtp", isRemote:false, mediaType:"audio" }),
+             "pcLocal.HasStat outbound audio rtp");
+          test.next();
+        });
+      } else {
+        test.next();
+      }
+    }
+  ],
+  [
+    'PC_LOCAL_CHECK_GETSTATS_VIDEOTRACK_OUTBOUND',
+    function (test) {
+      var pc = test.pcLocal;
+      var stream = pc._pc.getLocalStreams()[0];
+      var track = stream && stream.getVideoTracks()[0];
+      if (track) {
+        pc.getStats(track, function(stats) {
+          ok(pc.hasStat(stats,
+                        { type:"outboundrtp", isRemote:false, mediaType:"video" }),
+             "pcLocal.HasStat outbound video rtp");
+          test.next();
+        });
+      } else {
+        test.next();
+      }
+    }
+  ],
+  [
+    'PC_LOCAL_CHECK_GETSTATS_AUDIOTRACK_INBOUND',
+    function (test) {
+      var pc = test.pcLocal;
+      var stream = pc._pc.getRemoteStreams()[0];
+      var track = stream && stream.getAudioTracks()[0];
+      if (track) {
+        pc.getStats(track, function(stats) {
+          ok(pc.hasStat(stats,
+                        { type:"inboundrtp", isRemote:false, mediaType:"audio" }),
+             "pcLocal.HasStat inbound audio rtp");
+          test.next();
+        });
+      } else {
+        test.next();
+      }
+    }
+  ],
+  [
+    'PC_LOCAL_CHECK_GETSTATS_VIDEOTRACK_INBOUND',
+    function (test) {
+      var pc = test.pcLocal;
+      var stream = pc._pc.getRemoteStreams()[0];
+      var track = stream && stream.getVideoTracks()[0];
+      if (track) {
+        pc.getStats(track, function(stats) {
+          ok(pc.hasStat(stats,
+                        { type:"inboundrtp", isRemote:false, mediaType:"video" }),
+             "pcLocal.HasStat inbound video rtp");
+          test.next();
+        });
+      } else {
+        test.next();
+      }
+    }
+  ],
+  [
+    'PC_REMOTE_CHECK_GETSTATS_AUDIOTRACK_OUTBOUND',
+    function (test) {
+      var pc = test.pcRemote;
+      var stream = pc._pc.getLocalStreams()[0];
+      var track = stream && stream.getAudioTracks()[0];
+      if (track) {
+        pc.getStats(track, function(stats) {
+          ok(pc.hasStat(stats,
+                        { type:"outboundrtp", isRemote:false, mediaType:"audio" }),
+             "pcRemote.HasStat outbound audio rtp");
+          test.next();
+        });
+      } else {
+        test.next();
+      }
+    }
+  ],
+  [
+    'PC_REMOTE_CHECK_GETSTATS_VIDEOTRACK_OUTBOUND',
+    function (test) {
+      var pc = test.pcRemote;
+      var stream = pc._pc.getLocalStreams()[0];
+      var track = stream && stream.getVideoTracks()[0];
+      if (track) {
+        pc.getStats(track, function(stats) {
+          ok(pc.hasStat(stats,
+                        { type:"outboundrtp", isRemote:false, mediaType:"video" }),
+             "pcRemote.HasStat outbound audio rtp");
+          test.next();
+        });
+      } else {
+        test.next();
+      }
+    }
+  ],
+  [
+    'PC_REMOTE_CHECK_GETSTATS_AUDIOTRACK_INBOUND',
+    function (test) {
+      var pc = test.pcRemote;
+      var stream = pc._pc.getRemoteStreams()[0];
+      var track = stream && stream.getAudioTracks()[0];
+      if (track) {
+        pc.getStats(track, function(stats) {
+          ok(pc.hasStat(stats,
+                        { type:"inboundrtp", isRemote:false, mediaType:"audio" }),
+             "pcRemote.HasStat inbound audio rtp");
+          test.next();
+        });
+      } else {
+        test.next();
+      }
+    }
+  ],
+  [
+    'PC_REMOTE_CHECK_GETSTATS_VIDEOTRACK_INBOUND',
+    function (test) {
+      var pc = test.pcRemote;
+      var stream = pc._pc.getRemoteStreams()[0];
+      var track = stream && stream.getVideoTracks()[0];
+      if (track) {
+        pc.getStats(track, function(stats) {
+          ok(pc.hasStat(stats,
+                        { type:"inboundrtp", isRemote:false, mediaType:"video" }),
+             "pcRemote.HasStat inbound video rtp");
+          test.next();
+        });
+      } else {
+        test.next();
+      }
+    }
   ]
 ];
 
 
 /**
  * Default list of commands to execute for a Datachannel test.
  */
 var commandsDataChannel = [
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -22,16 +22,17 @@ enum RTCStatsType {
 dictionary RTCStats {
   DOMHighResTimeStamp timestamp;
   RTCStatsType type;
   DOMString id;
 };
 
 dictionary RTCRTPStreamStats : RTCStats {
   DOMString ssrc;
+  DOMString mediaType;
   DOMString remoteId;
   boolean isRemote = false;
   DOMString mediaTrackId;
   DOMString transportId;
   DOMString codecId;
 
   // Video encoder/decoder measurements (absent for rtcp)
   double bitrateMean;
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionImpl.cpp
@@ -2414,18 +2414,20 @@ PeerConnectionImpl::ExecuteStatsQuery_s(
 
   ASSERT_ON_THREAD(query->iceCtx->thread());
 
   // Gather stats from pipelines provided (can't touch mMedia + stream on STS)
 
   for (size_t p = 0; p < query->pipelines.Length(); ++p) {
     const MediaPipeline& mp = *query->pipelines[p];
     bool isAudio = (mp.Conduit()->type() == MediaSessionConduit::AUDIO);
-    nsString idstr = isAudio ?
-        NS_LITERAL_STRING("audio_") : NS_LITERAL_STRING("video_");
+    nsString mediaType = isAudio ?
+        NS_LITERAL_STRING("audio") : NS_LITERAL_STRING("video");
+    nsString idstr = mediaType;
+    idstr.AppendLiteral("_");
     idstr.AppendInt(mp.trackid());
 
     // Gather pipeline stats.
     switch (mp.direction()) {
       case MediaPipeline::TRANSMIT: {
         nsString localId = NS_LITERAL_STRING("outbound_rtp_") + idstr;
         nsString remoteId;
         nsString ssrc;
@@ -2451,16 +2453,17 @@ PeerConnectionImpl::ExecuteStatsQuery_s(
             remoteId = NS_LITERAL_STRING("outbound_rtcp_") + idstr;
             RTCInboundRTPStreamStats s;
             s.mTimestamp.Construct(timestamp);
             s.mId.Construct(remoteId);
             s.mType.Construct(RTCStatsType::Inboundrtp);
             if (ssrc.Length()) {
               s.mSsrc.Construct(ssrc);
             }
+            s.mMediaType.Construct(mediaType);
             s.mJitter.Construct(double(jitterMs)/1000);
             s.mRemoteId.Construct(localId);
             s.mIsRemote = true;
             s.mPacketsReceived.Construct(packetsReceived);
             s.mBytesReceived.Construct(bytesReceived);
             s.mPacketsLost.Construct(packetsLost);
             s.mMozRtt.Construct(rtt);
             query->report->mInboundRTPStreamStats.Value().AppendElement(s);
@@ -2470,16 +2473,17 @@ PeerConnectionImpl::ExecuteStatsQuery_s(
         {
           RTCOutboundRTPStreamStats s;
           s.mTimestamp.Construct(query->now);
           s.mId.Construct(localId);
           s.mType.Construct(RTCStatsType::Outboundrtp);
           if (ssrc.Length()) {
             s.mSsrc.Construct(ssrc);
           }
+          s.mMediaType.Construct(mediaType);
           s.mRemoteId.Construct(remoteId);
           s.mIsRemote = false;
           s.mPacketsSent.Construct(mp.rtp_packets_sent());
           s.mBytesSent.Construct(mp.rtp_bytes_sent());
 
           // Lastly, fill in video encoder stats if this is video
           if (!isAudio) {
             double framerateMean;
@@ -2521,31 +2525,33 @@ PeerConnectionImpl::ExecuteStatsQuery_s(
             remoteId = NS_LITERAL_STRING("inbound_rtcp_") + idstr;
             RTCOutboundRTPStreamStats s;
             s.mTimestamp.Construct(timestamp);
             s.mId.Construct(remoteId);
             s.mType.Construct(RTCStatsType::Outboundrtp);
             if (ssrc.Length()) {
               s.mSsrc.Construct(ssrc);
             }
+            s.mMediaType.Construct(mediaType);
             s.mRemoteId.Construct(localId);
             s.mIsRemote = true;
             s.mPacketsSent.Construct(packetsSent);
             s.mBytesSent.Construct(bytesSent);
             query->report->mOutboundRTPStreamStats.Value().AppendElement(s);
           }
         }
         // Then, fill in local side (with cross-link to remote only if present)
         RTCInboundRTPStreamStats s;
         s.mTimestamp.Construct(query->now);
         s.mId.Construct(localId);
         s.mType.Construct(RTCStatsType::Inboundrtp);
         if (ssrc.Length()) {
           s.mSsrc.Construct(ssrc);
         }
+        s.mMediaType.Construct(mediaType);
         unsigned int jitterMs, packetsLost;
         if (mp.Conduit()->GetRTPStats(&jitterMs, &packetsLost)) {
           s.mJitter.Construct(double(jitterMs)/1000);
           s.mPacketsLost.Construct(packetsLost);
         }
         if (remoteId.Length()) {
           s.mRemoteId.Construct(remoteId);
         }