Skip to content
Permalink
Browse files
The size of a video track's settings is incorrect in the second Media…
…Stream created when the 'aspectRatio' contraint is applied

https://bugs.webkit.org/show_bug.cgi?id=245511
rdar://100254156

Reviewed by Youenn Fablet.

* LayoutTests/fast/mediastream/cloned-video-stream-aspect-ratio-expected.txt: Added.
* LayoutTests/fast/mediastream/cloned-video-stream-aspect-ratio.html: Added.

* Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::size const): Apply aspectRatio to size.
(WebCore::RealtimeMediaSource::setAspectRatio): Call `setSize` instead of modifying m_size
directly so observers will know the size has changed.

* Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp:
(WebCore::RealtimeVideoSource::settingsDidChange): Call setSizeAndFrameRate when size changes
so settings are updated.
* Source/WebCore/platform/mediastream/RealtimeVideoSource.h:

Canonical link: https://commits.webkit.org/256433@main
  • Loading branch information
eric-carlson committed Nov 8, 2022
1 parent 5f642f0 commit fc20b78a56dcc355e091918cd8e9e2e7981e00a3
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 2 deletions.
@@ -0,0 +1,5 @@


PASS First gUM stream
PASS Second gUM stream

@@ -0,0 +1,45 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>'aspectRatio' correct with cloned media stream</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<video id=video-1 autoplay playsinline controls></video>
<video id=video-2 autoplay playsinline controls></video>

<script>
const validateStream = async (video, message) => {

const stream = await navigator.mediaDevices.getUserMedia({ video: { aspectRatio: 1 }});

const settings = stream.getVideoTracks()[0].getSettings();
assert_equals(settings.width, settings.height, `settings.width === setting.height for ${message}`);

video.srcObject = stream;
await new Promise((resolve, reject) => {
video.oncanplay = resolve;
setTimeout(() => reject(`timeout waiting for video to load for ${message}`), 5000);
});

assert_equals(settings.width, video.videoWidth, `settings.width === video.videoWidth for ${message}`);
assert_equals(settings.height, video.videoHeight, `settings.height === video.videoHeight for ${message}`);
}

promise_test(async (test) => {

await validateStream(document.getElementById('video-1'), 'first stream');

}, 'First gUM stream');

promise_test(async (test) => {

await validateStream(document.getElementById('video-2'), 'second stream');

}, 'Second gUM stream');

</script>
</body>
</html>
@@ -1011,6 +1011,9 @@ const IntSize RealtimeMediaSource::size() const
size.setHeight(size.width() * (m_intrinsicSize.height() / static_cast<double>(m_intrinsicSize.width())));
else if (size.height())
size.setWidth(size.height() * (m_intrinsicSize.width() / static_cast<double>(m_intrinsicSize.height())));

if (m_aspectRatio)
size.setHeight(static_cast<int>(static_cast<float>(size.width()) / m_aspectRatio));
}

return size;
@@ -1059,8 +1062,14 @@ void RealtimeMediaSource::setAspectRatio(double ratio)
ALWAYS_LOG_IF(m_logger, LOGIDENTIFIER, ratio);

m_aspectRatio = ratio;
m_size.setHeight(m_size.width() / ratio);
notifySettingsDidChangeObservers({ RealtimeMediaSourceSettings::Flag::AspectRatio, RealtimeMediaSourceSettings::Flag::Height });

auto size = m_size;
if (!size.isEmpty()) {
size.setHeight(static_cast<int>(static_cast<float>(size.width()) / ratio));
setSize(size);
}

notifySettingsDidChangeObservers({ RealtimeMediaSourceSettings::Flag::AspectRatio });
}

void RealtimeMediaSource::setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode mode)
@@ -122,6 +122,14 @@ void RealtimeVideoSource::setSizeAndFrameRate(std::optional<int> width, std::opt
RealtimeMediaSource::setSizeAndFrameRate(width, height, frameRate);
}

void RealtimeVideoSource::settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag> settings)
{
if (settings.containsAny({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height })) {
auto size = this->size();
setSizeAndFrameRate(size.width(), size.height(), { });
}
}

void RealtimeVideoSource::sourceMutedChanged()
{
notifyMutedChange(m_source->muted());
@@ -51,6 +51,7 @@ class RealtimeVideoSource final
void stopProducingData() final;
bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate) final;
void setSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double> frameRate) final;
void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) final;
Ref<RealtimeMediaSource> clone() final;
void endProducingData() final;
void stopBeingObserved() final;

0 comments on commit fc20b78

Please sign in to comment.