Bug 1363667 - P3 - JS impl of getContributingSources;r?mjf
MozReview-Commit-ID: 3oOXMP42PSt
--- a/dom/media/PeerConnection.js
+++ b/dom/media/PeerConnection.js
@@ -22,28 +22,34 @@ const PC_ICE_CONTRACT = "@mozilla.org/do
const PC_SESSION_CONTRACT = "@mozilla.org/dom/rtcsessiondescription;1";
const PC_MANAGER_CONTRACT = "@mozilla.org/dom/peerconnectionmanager;1";
const PC_STATS_CONTRACT = "@mozilla.org/dom/rtcstatsreport;1";
const PC_STATIC_CONTRACT = "@mozilla.org/dom/peerconnectionstatic;1";
const PC_SENDER_CONTRACT = "@mozilla.org/dom/rtpsender;1";
const PC_RECEIVER_CONTRACT = "@mozilla.org/dom/rtpreceiver;1";
const PC_COREQUEST_CONTRACT = "@mozilla.org/dom/createofferrequest;1";
const PC_DTMF_SENDER_CONTRACT = "@mozilla.org/dom/rtcdtmfsender;1";
+const PC_CONTRIB_SOURCE_CONTRACT = "@mozilla.org/dom/rtpcontributingsource;1";
+const PC_SYNC_SOURCE_CONTRACT = "@mozilla.org/dom/rtpsynchronizationsource;1";
const PC_CID = Components.ID("{bdc2e533-b308-4708-ac8e-a8bfade6d851}");
const PC_OBS_CID = Components.ID("{d1748d4c-7f6a-4dc5-add6-d55b7678537e}");
const PC_ICE_CID = Components.ID("{02b9970c-433d-4cc2-923d-f7028ac66073}");
const PC_SESSION_CID = Components.ID("{1775081b-b62d-4954-8ffe-a067bbf508a7}");
const PC_MANAGER_CID = Components.ID("{7293e901-2be3-4c02-b4bd-cbef6fc24f78}");
const PC_STATS_CID = Components.ID("{7fe6e18b-0da3-4056-bf3b-440ef3809e06}");
const PC_STATIC_CID = Components.ID("{0fb47c47-a205-4583-a9fc-cbadf8c95880}");
const PC_SENDER_CID = Components.ID("{4fff5d46-d827-4cd4-a970-8fd53977440e}");
const PC_RECEIVER_CID = Components.ID("{d974b814-8fde-411c-8c45-b86791b81030}");
const PC_COREQUEST_CID = Components.ID("{74b2122d-65a8-4824-aa9e-3d664cb75dc2}");
const PC_DTMF_SENDER_CID = Components.ID("{3610C242-654E-11E6-8EC0-6D1BE389A607}");
+const PC_CONTRIB_SOURCE_CID =
+ Components.ID("{be01cd41-25fe-4da9-bd31-0dc84be42828}");
+const PC_SYNC_SOURC_CID =
+ Components.ID("{06991841-FF13-4880-88A7-192D361D5F33}");
function logMsg(msg, file, line, flag, winID) {
let scriptErrorClass = Cc["@mozilla.org/scripterror;1"];
let scriptError = scriptErrorClass.createInstance(Ci.nsIScriptError);
scriptError.initWithWindowID(msg, file, null, line, 0, flag,
"content javascript", winID);
let console = Cc["@mozilla.org/consoleservice;1"].
getService(Ci.nsIConsoleService);
@@ -1092,16 +1098,20 @@ class RTCPeerConnection {
_insertDTMF(sender, tones, duration, interToneGap) {
return this._impl.insertDTMF(sender.__DOM_IMPL__, tones, duration, interToneGap);
}
_getDTMFToneBuffer(sender) {
return this._impl.getDTMFToneBuffer(sender.__DOM_IMPL__);
}
+ _getContributingSources(receiver) {
+ return this._impl.getContributingSources(receiver.track);
+ }
+
async _replaceTrack(sender, withTrack) {
this._checkClosed();
return this._chain(() => new Promise((resolve, reject) => {
this._onReplaceTrackSender = sender;
this._onReplaceTrackWithTrack = withTrack;
this._onReplaceTrackSuccess = resolve;
this._onReplaceTrackFailure = reject;
this._impl.replaceTrack(sender.track, withTrack);
@@ -1699,16 +1709,48 @@ class RTCDTMFSender {
}
}
setupPrototype(RTCDTMFSender, {
classID: PC_DTMF_SENDER_CID,
contractID: PC_DTMF_SENDER_CONTRACT,
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports])
});
+class RTCRtpContributingSource {
+ constructor(pc, entry, receiver) {
+ Object.assign(this, {
+ _pc:pc,
+ _receiver:receiver,
+ _entry: entry,
+ });
+ }
+
+ _fetch() {
+ this._receiver._fetchContributingSources();
+ }
+
+ get source() {
+ this._entry.source();
+ }
+
+ get timestamp () {
+ this._fetch(); // Update "live" fields
+ return this._entry.timestamp;
+ }
+
+ get audioLevel () {
+ this._fetch(); // Update "live" fields
+ return this._entry.audioLevel;
+ }
+}
+setupPrototype(RTCRtpContributingSource, {
+ classID: PC_CONTRIB_SOURCE_CID,
+ contractID: PC_CONTRIB_SOURCE_CONTRACT,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports])
+});
class RTCRtpSender {
constructor(pc, track, stream) {
let dtmf = pc._win.RTCDTMFSender._create(pc._win, new RTCDTMFSender(this));
Object.assign(this, { _pc: pc, track, _stream: stream, dtmf });
}
replaceTrack(withTrack) {
return this._pc._async(() => this._pc._replaceTrack(this, withTrack));
@@ -1731,23 +1773,55 @@ class RTCRtpSender {
setupPrototype(RTCRtpSender, {
classID: PC_SENDER_CID,
contractID: PC_SENDER_CONTRACT,
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports])
});
class RTCRtpReceiver {
constructor(pc, track) {
- Object.assign(this, { _pc: pc, track });
+ Object.assign(this, {
+ _pc: pc,
+ track,
+ _contributingSources: new Map(),
+ _contributingSourcesCurrent: false,
+ });
+ }
+
+ _fetchContributingSources() {
+ if (this._contributingSourcesCurrent) {
+ return;
+ }
+ this._contributingSourcesCurrent = true;
+ // Queue microtask to mark the cache as stale after this task completes
+ Promise.resolve().then(() => this._contributingSourcesCurrent = false);
+ for (let entry of this._pc._getContributingSources(this)) {
+ let cached = this._contributingSources.get(entry.source);
+ if (!cached) {
+ this._contributingSources.set(entry.source,
+ this._pc._win.RTCRtpContributingSource._create(this._pc._win,
+ new RTCRtpContributingSource(this._pc, entry, this)));
+ } else {
+ cached._entry = entry;
+ }
+ }
}
getStats() {
return this._pc._async(
async () => this._pc.getStats(this.track));
}
+
+ getContributingSources() {
+ this._fetchContributingSources();
+ // Only return the values from within the last 10 seconds as per the spec
+ let cutoffTime = new Date().getTime() - 10 * 1000;
+ return [...this._contributingSources.values()].filter(
+ (cs) => cs.timestamp >= cutoffTime);
+ }
}
setupPrototype(RTCRtpReceiver, {
classID: PC_RECEIVER_CID,
contractID: PC_RECEIVER_CONTRACT,
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports])
});
class CreateOfferRequest {
--- a/dom/media/PeerConnection.manifest
+++ b/dom/media/PeerConnection.manifest
@@ -4,20 +4,25 @@ component {02b9970c-433d-4cc2-923d-f7028
component {1775081b-b62d-4954-8ffe-a067bbf508a7} PeerConnection.js
component {7293e901-2be3-4c02-b4bd-cbef6fc24f78} PeerConnection.js
component {7fe6e18b-0da3-4056-bf3b-440ef3809e06} PeerConnection.js
component {0fb47c47-a205-4583-a9fc-cbadf8c95880} PeerConnection.js
component {4fff5d46-d827-4cd4-a970-8fd53977440e} PeerConnection.js
component {d974b814-8fde-411c-8c45-b86791b81030} PeerConnection.js
component {74b2122d-65a8-4824-aa9e-3d664cb75dc2} PeerConnection.js
component {3610C242-654E-11E6-8EC0-6D1BE389A607} PeerConnection.js
+component {be01cd41-25fe-4da9-bd31-0dc84be42828} PeerConnection.js
+component {06991841-FF13-4880-88A7-192D361D5F33} PeerConnection.js
contract @mozilla.org/dom/peerconnection;1 {bdc2e533-b308-4708-ac8e-a8bfade6d851}
contract @mozilla.org/dom/peerconnectionobserver;1 {d1748d4c-7f6a-4dc5-add6-d55b7678537e}
contract @mozilla.org/dom/rtcdtmfsender;1 {3610C242-654E-11E6-8EC0-6D1BE389A607}
contract @mozilla.org/dom/rtcicecandidate;1 {02b9970c-433d-4cc2-923d-f7028ac66073}
contract @mozilla.org/dom/rtcsessiondescription;1 {1775081b-b62d-4954-8ffe-a067bbf508a7}
contract @mozilla.org/dom/peerconnectionmanager;1 {7293e901-2be3-4c02-b4bd-cbef6fc24f78}
contract @mozilla.org/dom/rtcstatsreport;1 {7fe6e18b-0da3-4056-bf3b-440ef3809e06}
contract @mozilla.org/dom/peerconnectionstatic;1 {0fb47c47-a205-4583-a9fc-cbadf8c95880}
contract @mozilla.org/dom/rtpsender;1 {4fff5d46-d827-4cd4-a970-8fd53977440e}
contract @mozilla.org/dom/rtpreceiver;1 {d974b814-8fde-411c-8c45-b86791b81030}
contract @mozilla.org/dom/createofferrequest;1 {74b2122d-65a8-4824-aa9e-3d664cb75dc2}
+contract @mozilla.org/dom/rtpcontributingsource;1
+{be01cd41-25fe-4da9-bd31-0dc84be42828}
+contract @mozilla.org/dom/rtpsynchronizationsource;1 {06991841-FF13-4880-88A7-192D361D5F33}
--- a/dom/webidl/PeerConnectionImpl.webidl
+++ b/dom/webidl/PeerConnectionImpl.webidl
@@ -45,16 +45,19 @@ interface PeerConnectionImpl {
[Throws]
void removeTrack(MediaStreamTrack track);
[Throws]
void insertDTMF(RTCRtpSender sender, DOMString tones,
optional unsigned long duration = 100,
optional unsigned long interToneGap = 70);
[Throws]
DOMString getDTMFToneBuffer(RTCRtpSender sender);
+ sequence<RTCRtpContributingSourceEntry>
+ getContributingSources(MediaStreamTrack track);
+
[Throws]
void replaceTrack(MediaStreamTrack thisTrack, MediaStreamTrack withTrack);
[Throws]
void setParameters(MediaStreamTrack track,
optional RTCRtpParameters parameters);
[Throws]
RTCRtpParameters getParameters(MediaStreamTrack track);
[Throws]
--- a/dom/webidl/RTCRtpContributingSource.webidl
+++ b/dom/webidl/RTCRtpContributingSource.webidl
@@ -8,9 +8,15 @@
*/
[Pref="media.peerconnection.enabled",
JSImplementation="@mozilla.org/dom/rtpcontributingsource;1"]
interface RTCRtpContributingSource {
readonly attribute DOMHighResTimeStamp timestamp;
readonly attribute unsigned long source;
readonly attribute byte? audioLevel;
+};
+
+dictionary RTCRtpContributingSourceEntry {
+ DOMHighResTimeStamp timestamp;
+ unsigned long source;
+ byte? audioLevel;
};
\ No newline at end of file