Skip to content

Commit

Permalink
Add a test for ReplaceTrack that verifies video track content.
Browse files Browse the repository at this point in the history
This verifies that replaceTrack() actually replaces the track.
Adds a new helper function to add a "signal" square into a noise track.

Bug: none
Change-Id: Ia90535c984d65adcdf2c63a5700b08d7c1e384c0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2141913
Commit-Queue: Harald Alvestrand <[email protected]>
Reviewed-by: Guido Urdaneta <[email protected]>
Cr-Commit-Position: refs/heads/master@{#758062}
  • Loading branch information
alvestrand authored and foolip committed Apr 30, 2020
1 parent c46ec78 commit 0de19dc
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 5 deletions.
40 changes: 36 additions & 4 deletions webrtc/RTCPeerConnection-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ const trackFactories = {
return dst.stream.getAudioTracks()[0];
},

video({width = 640, height = 480} = {}) {
video({width = 640, height = 480, signal = null} = {}) {
const canvas = Object.assign(
document.createElement("canvas"), {width, height}
);
Expand All @@ -593,8 +593,13 @@ const trackFactories = {
setInterval(() => {
ctx.fillStyle = `rgb(${count%255}, ${count*count%255}, ${count%255})`;
count += 1;

ctx.fillRect(0, 0, width, height);
// If signal is set, add a constant-color box to the video frame.
if (signal !== null) {
ctx.fillStyle = `rgb(${signal}, ${signal}, ${signal})`;
ctx.fillRect(10, 10, 20, 20);
let pixel = ctx.getImageData(15, 15, 1, 1);
}
}, 100);

if (document.body) {
Expand All @@ -609,13 +614,40 @@ const trackFactories = {
}
};

// Get the signal from a video element inserted by createNoiseStream
function getVideoSignal(v) {
if (v.videoWidth < 21 || v.videoHeight < 21) {
return null;
}
const canvas = new OffscreenCanvas(v.videoWidth, v.videoHeight);
let context = canvas.getContext('2d');
context.drawImage(v, 0, 0, v.videoWidth, v.videoHeight);
// Extract pixel value at position 20, 20
let pixel = context.getImageData(20, 20, 1, 1);
return (pixel.data[0] + pixel.data[1] + pixel.data[2]) / 3;
}

function detectSignal(t, v, value) {
return new Promise((resolve) => {
let check = () => {
const signal = getVideoSignal(v);
if (signal !== null && signal < value + 1 && signal > value - 1) {
resolve();
} else {
t.step_timeout(check, 100);
}
}
check();
});
}

// Generate a MediaStream bearing the specified tracks.
//
// @param {object} [caps]
// @param {boolean} [caps.audio] - flag indicating whether the generated stream
// should include an audio track
// @param {boolean} [caps.video] - flag indicating whether the generated stream
// should include a video track
// should include a video track, or parameters for video
async function getNoiseStream(caps = {}) {
if (!trackFactories.canCreate(caps)) {
return navigator.mediaDevices.getUserMedia(caps);
Expand All @@ -627,7 +659,7 @@ async function getNoiseStream(caps = {}) {
}

if (caps.video) {
tracks.push(trackFactories.video());
tracks.push(trackFactories.video(caps.video));
}

return new MediaStream(tracks);
Expand Down
32 changes: 31 additions & 1 deletion webrtc/RTCRtpSender-replaceTrack.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -272,5 +272,35 @@
without negotiating.
3. Queue a task that runs the following steps:
1. If connection's [[isClosed]] slot is true, abort these steps.
*/
*/

promise_test(async t => {
const v = document.createElement('video');
v.autoplay = true;
const pc1 = new RTCPeerConnection();
t.add_cleanup(() => pc1.close());
const pc2 = new RTCPeerConnection();
t.add_cleanup(() => pc2.close());
const stream1 = await getNoiseStream({video: {signal: 20}});
t.add_cleanup(() => stream1.getTracks().forEach(track => track.stop()));
const [track1] = stream1.getTracks();
const stream2 = await getNoiseStream({video: {signal: 250}});
t.add_cleanup(() => stream2.getTracks().forEach(track => track.stop()));
const [track2] = stream2.getTracks();
const sender = pc1.addTrack(track1);
pc2.ontrack = (e) => {
v.srcObject = new MediaStream([e.track]);
};
const metadataToBeLoaded = new Promise((resolve) => {
v.addEventListener('loadedmetadata', () => {
resolve();
});
});
exchangeIceCandidates(pc1, pc2);
doSignalingHandshake(pc1, pc2);
await metadataToBeLoaded;
await detectSignal(t, v, 20);
await sender.replaceTrack(track2);
await detectSignal(t, v, 250);
}, 'ReplaceTrack transmits the new track not the old track');
</script>

0 comments on commit 0de19dc

Please sign in to comment.