Title: [268837] branches/safari-610-branch/Source/WebCore
Revision
268837
Author
alanc...@apple.com
Date
2020-10-21 15:16:06 -0700 (Wed, 21 Oct 2020)

Log Message

Cherry-pick r268398. rdar://problem/70541902

    Webcam video from navigator.mediaDevices.getUserMedia() to 2D canvas fails on Safari on iPhone
    https://bugs.webkit.org/show_bug.cgi?id=217578
    <rdar://problem/70183875>

    Reviewed by Eric Carlson.

    It is unneeded for MediaStream video backends to enqueue samples to the display layer if the video element is hidden.
    In iOS, the samples may never be flushed which might cause capture failing after enqueuing too many camera samples.
    To avoid that, we no longer enqueue samples to the display layer when the player is not visible.
    In case of canvas painting, other backends need to be made visible for canvas painting to work.
    For MediaStream backend, we do not need that since we always keep the last sample.
    For that reason, we keep the backend as not visible even if canvas happens.
    We do so by introducing a setVisibleForCanvas that is a no-op for MediaStream backend and similar to setVisible for other backends.
    For good measure, we now flush the MediaStream display layer whenever visibility changed.

    Manually tested.

    * html/HTMLVideoElement.cpp:
    (WebCore::HTMLVideoElement::paintCurrentFrameInContext):
    * platform/graphics/MediaPlayer.cpp:
    (WebCore::MediaPlayer::setVisibleForCanvas):
    * platform/graphics/MediaPlayer.h:
    * platform/graphics/MediaPlayerPrivate.h:
    (WebCore::MediaPlayerPrivateInterface::setVisibleForCanvas):
    * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
    * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
    (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample):
    (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVisible):
    (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVisibleForCanvas):

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@268398 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: branches/safari-610-branch/Source/WebCore/ChangeLog (268836 => 268837)


--- branches/safari-610-branch/Source/WebCore/ChangeLog	2020-10-21 22:16:03 UTC (rev 268836)
+++ branches/safari-610-branch/Source/WebCore/ChangeLog	2020-10-21 22:16:06 UTC (rev 268837)
@@ -1,5 +1,73 @@
 2020-10-21  Russell Epstein  <repst...@apple.com>
 
+        Cherry-pick r268398. rdar://problem/70541902
+
+    Webcam video from navigator.mediaDevices.getUserMedia() to 2D canvas fails on Safari on iPhone
+    https://bugs.webkit.org/show_bug.cgi?id=217578
+    <rdar://problem/70183875>
+    
+    Reviewed by Eric Carlson.
+    
+    It is unneeded for MediaStream video backends to enqueue samples to the display layer if the video element is hidden.
+    In iOS, the samples may never be flushed which might cause capture failing after enqueuing too many camera samples.
+    To avoid that, we no longer enqueue samples to the display layer when the player is not visible.
+    In case of canvas painting, other backends need to be made visible for canvas painting to work.
+    For MediaStream backend, we do not need that since we always keep the last sample.
+    For that reason, we keep the backend as not visible even if canvas happens.
+    We do so by introducing a setVisibleForCanvas that is a no-op for MediaStream backend and similar to setVisible for other backends.
+    For good measure, we now flush the MediaStream display layer whenever visibility changed.
+    
+    Manually tested.
+    
+    * html/HTMLVideoElement.cpp:
+    (WebCore::HTMLVideoElement::paintCurrentFrameInContext):
+    * platform/graphics/MediaPlayer.cpp:
+    (WebCore::MediaPlayer::setVisibleForCanvas):
+    * platform/graphics/MediaPlayer.h:
+    * platform/graphics/MediaPlayerPrivate.h:
+    (WebCore::MediaPlayerPrivateInterface::setVisibleForCanvas):
+    * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
+    * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+    (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample):
+    (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVisible):
+    (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVisibleForCanvas):
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@268398 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-10-13  Youenn Fablet  <you...@apple.com>
+
+            Webcam video from navigator.mediaDevices.getUserMedia() to 2D canvas fails on Safari on iPhone
+            https://bugs.webkit.org/show_bug.cgi?id=217578
+            <rdar://problem/70183875>
+
+            Reviewed by Eric Carlson.
+
+            It is unneeded for MediaStream video backends to enqueue samples to the display layer if the video element is hidden.
+            In iOS, the samples may never be flushed which might cause capture failing after enqueuing too many camera samples.
+            To avoid that, we no longer enqueue samples to the display layer when the player is not visible.
+            In case of canvas painting, other backends need to be made visible for canvas painting to work.
+            For MediaStream backend, we do not need that since we always keep the last sample.
+            For that reason, we keep the backend as not visible even if canvas happens.
+            We do so by introducing a setVisibleForCanvas that is a no-op for MediaStream backend and similar to setVisible for other backends.
+            For good measure, we now flush the MediaStream display layer whenever visibility changed.
+
+            Manually tested.
+
+            * html/HTMLVideoElement.cpp:
+            (WebCore::HTMLVideoElement::paintCurrentFrameInContext):
+            * platform/graphics/MediaPlayer.cpp:
+            (WebCore::MediaPlayer::setVisibleForCanvas):
+            * platform/graphics/MediaPlayer.h:
+            * platform/graphics/MediaPlayerPrivate.h:
+            (WebCore::MediaPlayerPrivateInterface::setVisibleForCanvas):
+            * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h:
+            * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm:
+            (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample):
+            (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVisible):
+            (WebCore::MediaPlayerPrivateMediaStreamAVFObjC::setVisibleForCanvas):
+
+2020-10-21  Russell Epstein  <repst...@apple.com>
+
         Cherry-pick r268712. rdar://problem/70541891
 
     Fix crash in RenderLayerBacking::updateClippingStackLayerGeometry()

Modified: branches/safari-610-branch/Source/WebCore/html/HTMLVideoElement.cpp (268836 => 268837)


--- branches/safari-610-branch/Source/WebCore/html/HTMLVideoElement.cpp	2020-10-21 22:16:03 UTC (rev 268836)
+++ branches/safari-610-branch/Source/WebCore/html/HTMLVideoElement.cpp	2020-10-21 22:16:06 UTC (rev 268837)
@@ -296,7 +296,7 @@
     if (!player)
         return;
     
-    player->setVisible(true); // Make player visible or it won't draw.
+    player->setVisibleForCanvas(true); // Make player visible or it won't draw.
     player->paintCurrentFrameInContext(context, destRect);
 }
 

Modified: branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayer.cpp (268836 => 268837)


--- branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayer.cpp	2020-10-21 22:16:03 UTC (rev 268836)
+++ branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayer.cpp	2020-10-21 22:16:06 UTC (rev 268837)
@@ -951,6 +951,12 @@
     m_private->setVisible(b);
 }
 
+void MediaPlayer::setVisibleForCanvas(bool visible)
+{
+    m_visible = visible;
+    m_private->setVisibleForCanvas(visible);
+}
+
 MediaPlayer::Preload MediaPlayer::preload() const
 {
     return m_preload;

Modified: branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayer.h (268836 => 268837)


--- branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayer.h	2020-10-21 22:16:03 UTC (rev 268836)
+++ branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayer.h	2020-10-21 22:16:06 UTC (rev 268837)
@@ -344,6 +344,7 @@
 
     bool visible() const;
     void setVisible(bool);
+    void setVisibleForCanvas(bool);
 
     void prepareToPlay();
     void play();

Modified: branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayerPrivate.h (268836 => 268837)


--- branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayerPrivate.h	2020-10-21 22:16:03 UTC (rev 268836)
+++ branches/safari-610-branch/Source/WebCore/platform/graphics/MediaPlayerPrivate.h	2020-10-21 22:16:06 UTC (rev 268837)
@@ -95,6 +95,7 @@
     virtual bool hasAudio() const = 0;
 
     virtual void setVisible(bool) = 0;
+    virtual void setVisibleForCanvas(bool visible) { setVisible(visible); }
 
     virtual float duration() const { return 0; }
     virtual double durationDouble() const { return duration(); }

Modified: branches/safari-610-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h (268836 => 268837)


--- branches/safari-610-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h	2020-10-21 22:16:03 UTC (rev 268836)
+++ branches/safari-610-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.h	2020-10-21 22:16:06 UTC (rev 268837)
@@ -124,6 +124,7 @@
     bool hasAudio() const override;
 
     void setVisible(bool) final;
+    void setVisibleForCanvas(bool) final;
 
     MediaTime durationMediaTime() const override;
     MediaTime currentMediaTime() const override;

Modified: branches/safari-610-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm (268836 => 268837)


--- branches/safari-610-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm	2020-10-21 22:16:03 UTC (rev 268836)
+++ branches/safari-610-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaStreamAVFObjC.mm	2020-10-21 22:16:06 UTC (rev 268837)
@@ -252,6 +252,9 @@
 
 void MediaPlayerPrivateMediaStreamAVFObjC::enqueueVideoSample(MediaSample& sample)
 {
+    if (!m_visible)
+        return;
+
     auto locker = tryHoldLock(m_sampleBufferDisplayLayerLock);
     if (!locker)
         return;
@@ -593,10 +596,13 @@
         return;
 
     m_visible = visible;
-    if (m_visible)
-        flushRenderers();
+    flushRenderers();
 }
 
+void MediaPlayerPrivateMediaStreamAVFObjC::setVisibleForCanvas(bool)
+{
+}
+
 MediaTime MediaPlayerPrivateMediaStreamAVFObjC::durationMediaTime() const
 {
     return MediaTime::positiveInfiniteTime();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to