- Revision
- 247391
- Author
- you...@apple.com
- Date
- 2019-07-12 10:27:53 -0700 (Fri, 12 Jul 2019)
Log Message
Stopping a cloned MediaStream video track should not stop any other video track
https://bugs.webkit.org/show_bug.cgi?id=199635
Reviewed by Eric Carlson.
Source/WebCore:
In case a track is requesting its source to end, the
RealtimeVideoSource should request its own source to end and not stop it directly.
Also, if a track is removing itself as an observer to a RealtimeVideoSource, we should
stop the underlying source only if this one does not have any other observer.
Covered by updated test.
* platform/mediastream/RealtimeMediaSource.cpp:
(WebCore::RealtimeMediaSource::removeObserver):
* platform/mediastream/RealtimeMediaSource.h:
* platform/mediastream/RealtimeVideoSource.cpp:
(WebCore::RealtimeVideoSource::requestToEnd):
(WebCore::RealtimeVideoSource::stopBeingObserved):
* platform/mediastream/RealtimeVideoSource.h:
LayoutTests:
* fast/mediastream/mediastreamtrack-video-clone-expected.txt:
* fast/mediastream/mediastreamtrack-video-clone.html:
Modified Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (247390 => 247391)
--- trunk/LayoutTests/ChangeLog 2019-07-12 17:11:31 UTC (rev 247390)
+++ trunk/LayoutTests/ChangeLog 2019-07-12 17:27:53 UTC (rev 247391)
@@ -1,3 +1,13 @@
+2019-07-12 Youenn Fablet <you...@apple.com>
+
+ Stopping a cloned MediaStream video track should not stop any other video track
+ https://bugs.webkit.org/show_bug.cgi?id=199635
+
+ Reviewed by Eric Carlson.
+
+ * fast/mediastream/mediastreamtrack-video-clone-expected.txt:
+ * fast/mediastream/mediastreamtrack-video-clone.html:
+
2019-07-12 Timothy Hatcher <timo...@apple.com>
Drop DarkModeCSSEnabled as an experimental feature and always enable it.
Modified: trunk/LayoutTests/fast/mediastream/mediastreamtrack-video-clone-expected.txt (247390 => 247391)
--- trunk/LayoutTests/fast/mediastream/mediastreamtrack-video-clone-expected.txt 2019-07-12 17:11:31 UTC (rev 247390)
+++ trunk/LayoutTests/fast/mediastream/mediastreamtrack-video-clone-expected.txt 2019-07-12 17:27:53 UTC (rev 247391)
@@ -3,6 +3,9 @@
PASS Setup for width test
PASS Setup for height test
PASS Setup for width+height test
+PASS Stopping a track should not stop its clone
+PASS Stopping a cloned track should not stop the original track
+PASS Collecting a cloned track should not stop the original track
PASS Check cloned track settings after applying width constraints
PASS Check cloned track settings after applying width constraint to original track
PASS Check cloned track settings after applying height constraints
Modified: trunk/LayoutTests/fast/mediastream/mediastreamtrack-video-clone.html (247390 => 247391)
--- trunk/LayoutTests/fast/mediastream/mediastreamtrack-video-clone.html 2019-07-12 17:11:31 UTC (rev 247390)
+++ trunk/LayoutTests/fast/mediastream/mediastreamtrack-video-clone.html 2019-07-12 17:27:53 UTC (rev 247391)
@@ -3,6 +3,7 @@
<head>
<meta charset="utf-8">
<title>Clone a video track.</title>
+ <script src=""
<script src=""
<script src=""
</head>
@@ -105,6 +106,38 @@
}, "Check cloned track settings after applying width+height constraints to original track");
}, "Setup for width+height test");
+ promise_test(async (t) => {
+ const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 100, height: 100 } });
+ const streamClone = stream.clone();
+
+ video1.srcObject = streamClone;
+ stream.getVideoTracks()[0].stop();
+
+ await video1.play();
+ assert_equals(video1.videoWidth, 100);
+ }, "Stopping a track should not stop its clone");
+
+ promise_test(async (t) => {
+ const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 100, height: 100 } });
+ const streamClone = stream.clone();
+
+ video1.srcObject = stream;
+ streamClone.getVideoTracks()[0].stop();
+
+ await video1.play();
+ assert_equals(video1.videoWidth, 100);
+ }, "Stopping a cloned track should not stop the original track");
+
+ promise_test(async (t) => {
+ const stream = await navigator.mediaDevices.getUserMedia({ video: { width: 100, height: 100 } });
+ stream.clone().getVideoTracks()[0].stop();
+ gc();
+
+ video1.srcObject = stream;
+
+ await video1.play();
+ assert_equals(video1.videoWidth, 100);
+ }, "Collecting a cloned track should not stop the original track");
</script>
</body>
</html>
Modified: trunk/Source/WebCore/ChangeLog (247390 => 247391)
--- trunk/Source/WebCore/ChangeLog 2019-07-12 17:11:31 UTC (rev 247390)
+++ trunk/Source/WebCore/ChangeLog 2019-07-12 17:27:53 UTC (rev 247391)
@@ -1,3 +1,25 @@
+2019-07-12 Youenn Fablet <you...@apple.com>
+
+ Stopping a cloned MediaStream video track should not stop any other video track
+ https://bugs.webkit.org/show_bug.cgi?id=199635
+
+ Reviewed by Eric Carlson.
+
+ In case a track is requesting its source to end, the
+ RealtimeVideoSource should request its own source to end and not stop it directly.
+
+ Also, if a track is removing itself as an observer to a RealtimeVideoSource, we should
+ stop the underlying source only if this one does not have any other observer.
+ Covered by updated test.
+
+ * platform/mediastream/RealtimeMediaSource.cpp:
+ (WebCore::RealtimeMediaSource::removeObserver):
+ * platform/mediastream/RealtimeMediaSource.h:
+ * platform/mediastream/RealtimeVideoSource.cpp:
+ (WebCore::RealtimeVideoSource::requestToEnd):
+ (WebCore::RealtimeVideoSource::stopBeingObserved):
+ * platform/mediastream/RealtimeVideoSource.h:
+
2019-07-12 Timothy Hatcher <timo...@apple.com>
Drop DarkModeCSSEnabled as an experimental feature and always enable it.
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp (247390 => 247391)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp 2019-07-12 17:11:31 UTC (rev 247390)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.cpp 2019-07-12 17:27:53 UTC (rev 247391)
@@ -69,10 +69,9 @@
void RealtimeMediaSource::removeObserver(RealtimeMediaSource::Observer& observer)
{
auto locker = holdLock(m_observersLock);
-
m_observers.remove(&observer);
if (m_observers.isEmpty())
- stop();
+ stopBeingObserved();
}
void RealtimeMediaSource::setInterrupted(bool interrupted, bool pageMuted)
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h (247390 => 247391)
--- trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h 2019-07-12 17:11:31 UTC (rev 247390)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeMediaSource.h 2019-07-12 17:27:53 UTC (rev 247391)
@@ -109,7 +109,7 @@
bool isProducingData() const { return m_isProducingData; }
void start();
void stop();
- void requestToEnd(Observer& callingObserver);
+ virtual void requestToEnd(Observer& callingObserver);
bool muted() const { return m_muted; }
void setMuted(bool);
@@ -233,6 +233,8 @@
virtual void stopProducingData() { }
virtual void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) { }
+ virtual void stopBeingObserved() { stop(); }
+
virtual void hasEnded() { }
#if !RELEASE_LOG_DISABLED
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp (247390 => 247391)
--- trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp 2019-07-12 17:11:31 UTC (rev 247390)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp 2019-07-12 17:27:53 UTC (rev 247391)
@@ -118,6 +118,16 @@
return hasObserverPreventingStopping;
}
+void RealtimeVideoSource::requestToEnd(RealtimeMediaSource::Observer&)
+{
+ m_source->requestToEnd(*this);
+}
+
+void RealtimeVideoSource::stopBeingObserved()
+{
+ m_source->requestToEnd(*this);
+}
+
void RealtimeVideoSource::sourceStopped()
{
if (m_source->captureDidFail()) {
Modified: trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.h (247390 => 247391)
--- trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.h 2019-07-12 17:11:31 UTC (rev 247390)
+++ trunk/Source/WebCore/platform/mediastream/RealtimeVideoSource.h 2019-07-12 17:27:53 UTC (rev 247391)
@@ -46,6 +46,8 @@
bool supportsSizeAndFrameRate(Optional<int> width, Optional<int> height, Optional<double> frameRate) final;
void setSizeAndFrameRate(Optional<int> width, Optional<int> height, Optional<double> frameRate) final;
Ref<RealtimeMediaSource> clone() final;
+ void requestToEnd(RealtimeMediaSource::Observer& callingObserver) final;
+ void stopBeingObserved() final;
const RealtimeMediaSourceCapabilities& capabilities() final { return m_source->capabilities(); }
const RealtimeMediaSourceSettings& settings() final { return m_currentSettings; }