WebKit Bugzilla
Attachment 373511 Details for
Bug 199519
: [iOS] Local capture MediaStreamTrack does not render in portrait mode
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-199519-20190705103408.patch (text/plain), 16.53 KB, created by
youenn fablet
on 2019-07-05 10:34:09 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
youenn fablet
Created:
2019-07-05 10:34:09 PDT
Size:
16.53 KB
patch
obsolete
>Subversion Revision: 247073 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index b4cb62fc54feca1472fd6cbb652a8b0dcf87d0c7..ada8b303cc1da4c856549aa4400e49c1fdc9f6ee 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,29 @@ >+2019-07-05 Youenn Fablet <youenn@apple.com> >+ >+ [iOS] Local capture MediaStreamTrack does not render in portrait mode >+ https://bugs.webkit.org/show_bug.cgi?id=199519 >+ <rdar://problem/52689720> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ RealtimeVideoSource was badly computing its size in case of rotation. >+ Whenever its underlying source is notifying of settings change, >+ compute the size and transpose it only in left/right case. >+ >+ Update mock video source to cover that case. >+ Covered by updated test. >+ >+ * platform/mediastream/RealtimeVideoSource.cpp: >+ (WebCore::RealtimeVideoSource::sourceSettingsChanged): >+ * platform/mediastream/mac/MockRealtimeVideoSourceMac.h: >+ * platform/mediastream/mac/MockRealtimeVideoSourceMac.mm: >+ (WebCore::MockRealtimeVideoSourceMac::updateSampleBuffer): >+ * platform/mock/MockRealtimeVideoSource.cpp: >+ (WebCore::MockRealtimeVideoSource::settings): >+ (WebCore::MockRealtimeVideoSource::orientationChanged): >+ (WebCore::MockRealtimeVideoSource::monitorOrientation): >+ * platform/mock/MockRealtimeVideoSource.h: >+ > 2019-07-05 Youenn Fablet <youenn@apple.com> > > Add fetch quirk for www.bnz.co.nz >diff --git a/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp b/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp >index 1437d2d21b34261c769df52e36a94b24977e438d..ec9370547516e47b253717d7c2bda4c65d6093ca 100644 >--- a/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp >+++ b/Source/WebCore/platform/mediastream/RealtimeVideoSource.cpp >@@ -92,12 +92,13 @@ void RealtimeVideoSource::sourceMutedChanged() > void RealtimeVideoSource::sourceSettingsChanged() > { > auto rotation = m_source->sampleRotation(); >- if (rotation == MediaSample::VideoRotation::Left || rotation == MediaSample::VideoRotation::Right) { >- auto size = this->size(); >+ auto size = this->size(); >+ if (size.isEmpty()) >+ size = m_source->size(); >+ if (rotation == MediaSample::VideoRotation::Left || rotation == MediaSample::VideoRotation::Right) > size = size.transposedSize(); >- m_currentSettings.setWidth(size.width()); >- m_currentSettings.setHeight(size.height()); >- } >+ m_currentSettings.setWidth(size.width()); >+ m_currentSettings.setHeight(size.height()); > > forEachObserver([&](auto& observer) { > observer.sourceSettingsChanged(); >diff --git a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h >index 5398b43a1abb31eb799c0d6b8bff7647e3604ebd..95a8cf0ae53380ed5773a272d6bdc543548b9943 100644 >--- a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h >+++ b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.h >@@ -33,7 +33,6 @@ > #if ENABLE(MEDIA_STREAM) > > #include "MockRealtimeVideoSource.h" >-#include "OrientationNotifier.h" > #include "PixelBufferConformerCV.h" > > typedef struct __CVBuffer *CVBufferRef; >@@ -45,7 +44,7 @@ namespace WebCore { > > class ImageTransferSessionVT; > >-class MockRealtimeVideoSourceMac final : public MockRealtimeVideoSource, private OrientationNotifier::Observer { >+class MockRealtimeVideoSourceMac final : public MockRealtimeVideoSource { > public: > virtual ~MockRealtimeVideoSourceMac() = default; > >@@ -57,11 +56,6 @@ private: > void updateSampleBuffer() final; > bool canResizeVideoFrames() const final { return true; } > >- void orientationChanged(int orientation) final; >- void monitorOrientation(OrientationNotifier&) final; >- MediaSample::VideoRotation sampleRotation() const final { return m_deviceOrientation; } >- >- MediaSample::VideoRotation m_deviceOrientation { MediaSample::VideoRotation::None }; > std::unique_ptr<ImageTransferSessionVT> m_imageTransferSession; > IntSize m_presetSize; > }; >diff --git a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm >index 83c63b177b6e80f0448ac1f1ae1bce347f3783f0..9ddff40c1c523ba21e4dc46db6911d811513c635 100644 >--- a/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm >+++ b/Source/WebCore/platform/mediastream/mac/MockRealtimeVideoSourceMac.mm >@@ -85,41 +85,13 @@ void MockRealtimeVideoSourceMac::updateSampleBuffer() > m_imageTransferSession = ImageTransferSessionVT::create(preferedPixelBufferFormat()); > > auto sampleTime = MediaTime::createWithDouble((elapsedTime() + 100_ms).seconds()); >- auto sampleBuffer = m_imageTransferSession->createMediaSample(imageBuffer->copyImage()->nativeImage().get(), sampleTime, size(), m_deviceOrientation); >+ auto sampleBuffer = m_imageTransferSession->createMediaSample(imageBuffer->copyImage()->nativeImage().get(), sampleTime, size(), sampleRotation()); > if (!sampleBuffer) > return; > >- // We use m_deviceOrientation to emulate sensor orientation > dispatchMediaSampleToObservers(*sampleBuffer); > } > >-void MockRealtimeVideoSourceMac::orientationChanged(int orientation) >-{ >- // FIXME: Do something with m_deviceOrientation. See bug 169822. >- switch (orientation) { >- case 0: >- m_deviceOrientation = MediaSample::VideoRotation::None; >- break; >- case 90: >- m_deviceOrientation = MediaSample::VideoRotation::Right; >- break; >- case -90: >- m_deviceOrientation = MediaSample::VideoRotation::Left; >- break; >- case 180: >- m_deviceOrientation = MediaSample::VideoRotation::UpsideDown; >- break; >- default: >- return; >- } >-} >- >-void MockRealtimeVideoSourceMac::monitorOrientation(OrientationNotifier& notifier) >-{ >- notifier.addObserver(*this); >- orientationChanged(notifier.orientation()); >-} >- > } // namespace WebCore > > #endif // ENABLE(MEDIA_STREAM) >diff --git a/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp b/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp >index 49a48be0faa299fa4fa693d742348b3044c5e38f..d768b2fe0a9f3ff780a95b4207d4d17675d05544 100644 >--- a/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp >+++ b/Source/WebCore/platform/mock/MockRealtimeVideoSource.cpp >@@ -157,7 +157,11 @@ const RealtimeMediaSourceSettings& MockRealtimeVideoSource::settings() > settings.setLogicalSurface(false); > } > settings.setFrameRate(frameRate()); >- auto& size = this->size(); >+ auto size = this->size(); >+ if (mockCamera()) { >+ if (m_deviceOrientation == MediaSample::VideoRotation::Left || m_deviceOrientation == MediaSample::VideoRotation::Right) >+ size = size.transposedSize(); >+ } > settings.setWidth(size.width()); > settings.setHeight(size.height()); > if (aspectRatio()) >@@ -472,6 +476,41 @@ bool MockRealtimeVideoSource::mockDisplayType(CaptureDevice::DeviceType type) co > return WTF::get<MockDisplayProperties>(m_device.properties).type == type; > } > >+void MockRealtimeVideoSource::orientationChanged(int orientation) >+{ >+ auto deviceOrientation = m_deviceOrientation; >+ switch (orientation) { >+ case 0: >+ m_deviceOrientation = MediaSample::VideoRotation::None; >+ break; >+ case 90: >+ m_deviceOrientation = MediaSample::VideoRotation::Right; >+ break; >+ case -90: >+ m_deviceOrientation = MediaSample::VideoRotation::Left; >+ break; >+ case 180: >+ m_deviceOrientation = MediaSample::VideoRotation::UpsideDown; >+ break; >+ default: >+ return; >+ } >+ >+ if (deviceOrientation == m_deviceOrientation) >+ return; >+ >+ notifySettingsDidChangeObservers({ RealtimeMediaSourceSettings::Flag::Width, RealtimeMediaSourceSettings::Flag::Height }); >+} >+ >+void MockRealtimeVideoSource::monitorOrientation(OrientationNotifier& notifier) >+{ >+ if (!mockCamera()) >+ return; >+ >+ notifier.addObserver(*this); >+ orientationChanged(notifier.orientation()); >+} >+ > } // namespace WebCore > > #endif // ENABLE(MEDIA_STREAM) >diff --git a/Source/WebCore/platform/mock/MockRealtimeVideoSource.h b/Source/WebCore/platform/mock/MockRealtimeVideoSource.h >index cbe1a004ab7f2f415a85c075cc5a5fb5aa489097..e599076b4f74cc5488c4b39fbce013ab2f8013c9 100644 >--- a/Source/WebCore/platform/mock/MockRealtimeVideoSource.h >+++ b/Source/WebCore/platform/mock/MockRealtimeVideoSource.h >@@ -36,6 +36,7 @@ > #include "FontCascade.h" > #include "ImageBuffer.h" > #include "MockMediaDevice.h" >+#include "OrientationNotifier.h" > #include "RealtimeMediaSourceFactory.h" > #include "RealtimeVideoCaptureSource.h" > #include <wtf/RunLoop.h> >@@ -45,7 +46,7 @@ namespace WebCore { > class FloatRect; > class GraphicsContext; > >-class MockRealtimeVideoSource : public RealtimeVideoCaptureSource { >+class MockRealtimeVideoSource : public RealtimeVideoCaptureSource, private OrientationNotifier::Observer { > public: > > static CaptureSourceOrError create(String&& deviceID, String&& name, String&& hashSalt, const MediaConstraints*); >@@ -60,6 +61,7 @@ protected: > > Seconds elapsedTime(); > void settingsDidChange(OptionSet<RealtimeMediaSourceSettings::Flag>) override; >+ MediaSample::VideoRotation sampleRotation() const final { return m_deviceOrientation; } > > private: > const RealtimeMediaSourceCapabilities& capabilities() final; >@@ -76,6 +78,10 @@ private: > > void generatePresets() final; > >+ // OrientationNotifier::Observer >+ void orientationChanged(int orientation) final; >+ void monitorOrientation(OrientationNotifier&) final; >+ > void drawAnimation(GraphicsContext&); > void drawText(GraphicsContext&); > void drawBoxes(GraphicsContext&); >@@ -83,7 +89,7 @@ private: > void generateFrame(); > void startCaptureTimer(); > >- void delaySamples(Seconds) override; >+ void delaySamples(Seconds) final; > > bool mockCamera() const { return WTF::holds_alternative<MockCameraProperties>(m_device.properties); } > bool mockDisplay() const { return WTF::holds_alternative<MockDisplayProperties>(m_device.properties); } >@@ -112,6 +118,7 @@ private: > Color m_fillColor { Color::black }; > MockMediaDevice m_device; > RefPtr<VideoPreset> m_preset; >+ MediaSample::VideoRotation m_deviceOrientation { MediaSample::VideoRotation::None }; > }; > > } // namespace WebCore >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 1b13039039c0bc2eb3b82ab58f7dca865ebb793c..78d18f9998846ed41de62846bee02c1279c690e2 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,14 @@ >+2019-07-05 Youenn Fablet <youenn@apple.com> >+ >+ [iOS] Local capture MediaStreamTrack does not render in portrait mode >+ https://bugs.webkit.org/show_bug.cgi?id=199519 >+ <rdar://problem/52689720> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * webrtc/video-rotation-expected.txt: >+ * webrtc/video-rotation.html: >+ > 2019-07-02 Andres Gonzalez <andresg_22@apple.com> > > Enhance support of aria-haspopup per ARIA 1.1 specification. >diff --git a/LayoutTests/webrtc/video-rotation-expected.txt b/LayoutTests/webrtc/video-rotation-expected.txt >index 70dd4fcbdaa9d9af385d9b024d5d42219630a508..4ee3ffa0dcdf04d795d1ac88c47a96197989716f 100644 >--- a/LayoutTests/webrtc/video-rotation-expected.txt >+++ b/LayoutTests/webrtc/video-rotation-expected.txt >@@ -1,7 +1,8 @@ >- >+ > > PASS Setting video exchange > PASS Track is enabled, video should not be black >-PASS Track is enabled and rotated, video should not be black and should change size >+PASS Track is enabled and rotated, local video should not be black and should change size >+PASS Track is enabled and rotated, remote video should not be black and should change size > PASS Track is enabled and rotated again, video should not be black and should change size > >diff --git a/LayoutTests/webrtc/video-rotation.html b/LayoutTests/webrtc/video-rotation.html >index a87698dc1d7ecf238aacad09fad97fc05a584000..584056c932565c7b7dc38dd65b3634dacae2e38d 100644 >--- a/LayoutTests/webrtc/video-rotation.html >+++ b/LayoutTests/webrtc/video-rotation.html >@@ -7,15 +7,17 @@ > <script src="../resources/testharnessreport.js"></script> > </head> > <body> >- <video id="video" autoplay playsInline width="320" height="240"></video> >+ <video id="localVideo" autoplay playsInline width="320" height="240"></video> >+ <video id="remoteVideo" autoplay playsInline width="320" height="240"></video> >+ <canvas id="canvas0" width="320" height="240"></canvas> > <canvas id="canvas1" width="320" height="240"></canvas> > <canvas id="canvas2" width="320" height="240"></canvas> > <canvas id="canvas3" width="320" height="240"></canvas> > <script src ="routines.js"></script> > <script> >-function isVideoBlack(id) >+function isVideoBlack(video, canvasId) > { >- var canvas = document.getElementById(id); >+ var canvas = document.getElementById(canvasId); > canvas.width = video.videoWidth; > canvas.height = video.videoHeight; > canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); >@@ -30,21 +32,21 @@ function isVideoBlack(id) > return true; > } > >-function pollVideoBlackCheck(expected, id, resolve) >+function pollVideoBlackCheck(expected, video, canvasId, resolve) > { >- if (isVideoBlack(id) === expected) { >+ if (isVideoBlack(video, canvasId) === expected) { > resolve(); > return; > } > >- setTimeout(() => pollVideoBlackCheck(expected, id, resolve), 100); >+ setTimeout(() => pollVideoBlackCheck(expected, video, canvasId, resolve), 100); > } > >-function checkVideoBlack(expected, id) >+function checkVideoBlack(expected, video, canvasId) > { > return new Promise((resolve, reject) => { >- pollVideoBlackCheck(expected, id, resolve); >- setTimeout(() => reject("checkVideoBlack timed out for '" + id + "', expected " + expected), 5000); >+ pollVideoBlackCheck(expected, video, canvasId, resolve); >+ setTimeout(() => reject("checkVideoBlack timed out for '" + canvasId + "', expected " + expected), 5000); > }); > } > >@@ -54,6 +56,7 @@ promise_test((test) => { > testRunner.setUserMediaPermission(true); > > return navigator.mediaDevices.getUserMedia({video: {width: 320, height: 240, facingMode: "environment"}}).then((localStream) => { >+ localVideo.srcObject = localStream; > return new Promise((resolve, reject) => { > track = localStream.getVideoTracks()[0]; > >@@ -69,30 +72,42 @@ promise_test((test) => { > setTimeout(() => reject("Test timed out"), 5000); > }); > }).then((remoteStream) => { >- video.srcObject = remoteStream; >- return video.play(); >+ remoteVideo.srcObject = remoteStream; >+ return remoteVideo.play(); > }); > }, "Setting video exchange"); > >-promise_test((test) => { >- return checkVideoBlack(false, "canvas1"); >+promise_test(async (test) => { >+ await checkVideoBlack(false, remoteVideo, "canvas0"); >+ await waitForVideoSize(remoteVideo, 320, 240); > }, "Track is enabled, video should not be black"); > >+promise_test(async (test) => { >+ await checkVideoBlack(false, localVideo, "canvas0"); >+ await waitForVideoSize(localVideo, 320, 240); >+ >+ if (window.internals) >+ window.internals.setCameraMediaStreamTrackOrientation(track, 90); >+ >+ await checkVideoBlack(false, localVideo, "canvas1"); >+ await waitForVideoSize(localVideo, 240, 320); >+}, "Track is enabled and rotated, local video should not be black and should change size"); >+ > promise_test((test) => { > if (window.internals) > window.internals.setCameraMediaStreamTrackOrientation(track, 90); > >- return checkVideoBlack(false, "canvas1").then(() => { >- return waitForVideoSize(video, 240, 320); >+ return checkVideoBlack(false, remoteVideo, "canvas2").then(() => { >+ return waitForVideoSize(remoteVideo, 240, 320); > }); >-}, "Track is enabled and rotated, video should not be black and should change size"); >+}, "Track is enabled and rotated, remote video should not be black and should change size"); > > promise_test((test) => { > if (window.internals) > window.internals.setCameraMediaStreamTrackOrientation(track, 180); > >- return checkVideoBlack(false, "canvas1").then(() => { >- return waitForVideoSize(video, 320, 240); >+ return checkVideoBlack(false, remoteVideo, "canvas3").then(() => { >+ return waitForVideoSize(remoteVideo, 320, 240); > }); > }, "Track is enabled and rotated again, video should not be black and should change size"); > </script>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 199519
:
373511
|
373512