Skip to content

Commit

Permalink
VideoTrackGenerator muted should apply on the sink synchronously
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=267931
rdar://121449466

Reviewed by Eric Carlson.

We synchronously update the muted slot as defined by the spec.
Covered by added test.

* LayoutTests/http/wpt/mediastream/worker-mediastreamtrack.worker-expected.txt:
* LayoutTests/http/wpt/mediastream/worker-mediastreamtrack.worker.js:
(makeOffscreenCanvasVideoFrame):
(promise_test.async t):
* Source/WebCore/Modules/mediastream/VideoTrackGenerator.cpp:
(WebCore::VideoTrackGenerator::setMuted):

Canonical link: https://commits.webkit.org/273398@main
  • Loading branch information
youennf committed Jan 24, 2024
1 parent 4d97990 commit 3d9f010
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

PASS Tests that VideoTrackGenerator forwards frames only when unmuted
PASS Frames get closed when written in a VideoTrackGenerator writable
PASS Writable gets closed when writing a closed VideoFrame
PASS Writable gets closed when writing something else than a VideoFrame
Expand Down
47 changes: 45 additions & 2 deletions LayoutTests/http/wpt/mediastream/worker-mediastreamtrack.worker.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,57 @@
// META: title=MediaStreamTrack processor and generator tests.
importScripts("/resources/testharness.js");

function makeOffscreenCanvasVideoFrame(width, height) {
function makeOffscreenCanvasVideoFrame(width, height, timestamp) {
if (!timestamp)
timestamp = 1;
let canvas = new OffscreenCanvas(width, height);
let ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(50, 100, 150, 255)';
ctx.fillRect(0, 0, width, height);
return new VideoFrame(canvas, { timestamp: 1 });
return new VideoFrame(canvas, { timestamp });
}

promise_test(async t => {
const generator = new VideoTrackGenerator();
t.add_cleanup(() => generator.track.stop());

// Use a MediaStreamTrackProcessor as a sink for |generator| to verify
// that |processor| actually forwards the frames written to its writable
// field.
self.processor = new MediaStreamTrackProcessor(generator);
t.add_cleanup(() => self.processor = undefined);
const reader = processor.readable.getReader();

const writer = generator.writable.getWriter();
const videoFrame1 = makeOffscreenCanvasVideoFrame(100, 100, 1);
writer.write(videoFrame1);
const result1 = await reader.read();
t.add_cleanup(() => result1.value.close());
assert_equals(result1.value.codedWidth, 100);
generator.muted = true;

// This frame is expected to be discarded.
const videoFrame2 = makeOffscreenCanvasVideoFrame(200, 200, 2);
writer.write(videoFrame2);
generator.muted = false;

const videoFrame3 = makeOffscreenCanvasVideoFrame(300, 300, 3);
writer.write(videoFrame3);
const result3 = await reader.read();
t.add_cleanup(() => result3.value.close());
assert_equals(result3.value.codedWidth, 300);

// Set up a read ahead of time, then mute, enqueue and unmute.
const promise5 = reader.read();
generator.muted = true;
writer.write(makeOffscreenCanvasVideoFrame(400, 400, 4)); // Expected to be discarded.
generator.muted = false;
writer.write(makeOffscreenCanvasVideoFrame(500, 500, 5));
const result5 = await promise5;
t.add_cleanup(() => result5.value.close());
assert_equals(result5.value.codedWidth, 500);
}, 'Tests that VideoTrackGenerator forwards frames only when unmuted');

promise_test(async (t) => {
const frame1 = makeOffscreenCanvasVideoFrame(100, 100);
t.add_cleanup(() => frame1.close());
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/Modules/mediastream/VideoTrackGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,15 @@ void VideoTrackGenerator::setMuted(ScriptExecutionContext& context, bool muted)
return;

m_muted = muted;
m_sink->setMuted(m_muted);

if (m_hasMutedChanged)
return;

m_hasMutedChanged = true;
context.postTask([this, protectedThis = Ref { *this }] (auto&) {
m_hasMutedChanged = false;
m_track->privateTrack().setMuted(m_muted);
m_sink->setMuted(m_muted);
});
}

Expand Down

0 comments on commit 3d9f010

Please sign in to comment.