Title: [274175] trunk/Source/WebCore
Revision
274175
Author
eric.carl...@apple.com
Date
2021-03-09 14:17:26 -0800 (Tue, 09 Mar 2021)

Log Message

[GPU Process] MSE videos are unable to AirPlay
https://bugs.webkit.org/show_bug.cgi?id=222956
rdar://72798835

When a user picks an device from the AirPlay menu, WebKit fires a
'webkitcurrentplaybacktargetiswirelesschanged' event at the <video> element and
sets `video.webkitCurrentPlaybackTargetIsWireless` to true so script in the page
is aware that the user wants to use AirPlay. AirPlay requires a <video> element to
be backed by a url that an AppleTV can load and play, so this is also a signal for
a page's script to change the <video> source if it is currently backed by a source
that is incompatible with AirPlay, e.g. MSE, MediaStream, data:. If the current media engine
does not support AirPlay (`m_player->canPlayToWirelessPlaybackTarget()` returns false)
by the next runloop, HTMLMediaElement fires `webkitcurrentplaybacktargetiswirelesschanged`
again and sets `video.webkitCurrentPlaybackTargetIsWireless` to false to signal
that AirPlay is not active.

When media is played in the GPU Process, one turn of the runloop isn't long enough
for the new media engine to be set up, configured, and have the new state pushed
back to the web process, so HTMLMediaElement will now wait for up to 500ms for
`m_player->canPlayToWirelessPlaybackTarget()` to return true.

Reviewed by Jer Noble.

Tested manually, this requires and AppleTV to test.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::checkPlaybackTargetCompatablity):
(WebCore::HTMLMediaElement::setIsPlayingToWirelessTarget):
* html/HTMLMediaElement.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (274174 => 274175)


--- trunk/Source/WebCore/ChangeLog	2021-03-09 22:07:00 UTC (rev 274174)
+++ trunk/Source/WebCore/ChangeLog	2021-03-09 22:17:26 UTC (rev 274175)
@@ -1,3 +1,35 @@
+2021-03-09  Eric Carlson  <eric.carl...@apple.com>
+
+        [GPU Process] MSE videos are unable to AirPlay
+        https://bugs.webkit.org/show_bug.cgi?id=222956
+        rdar://72798835
+
+        When a user picks an device from the AirPlay menu, WebKit fires a 
+        'webkitcurrentplaybacktargetiswirelesschanged' event at the <video> element and
+        sets `video.webkitCurrentPlaybackTargetIsWireless` to true so script in the page
+        is aware that the user wants to use AirPlay. AirPlay requires a <video> element to
+        be backed by a url that an AppleTV can load and play, so this is also a signal for
+        a page's script to change the <video> source if it is currently backed by a source
+        that is incompatible with AirPlay, e.g. MSE, MediaStream, data:. If the current media engine
+        does not support AirPlay (`m_player->canPlayToWirelessPlaybackTarget()` returns false)
+        by the next runloop, HTMLMediaElement fires `webkitcurrentplaybacktargetiswirelesschanged`
+        again and sets `video.webkitCurrentPlaybackTargetIsWireless` to false to signal
+        that AirPlay is not active.
+        
+        When media is played in the GPU Process, one turn of the runloop isn't long enough
+        for the new media engine to be set up, configured, and have the new state pushed
+        back to the web process, so HTMLMediaElement will now wait for up to 500ms for
+        `m_player->canPlayToWirelessPlaybackTarget()` to return true.
+
+        Reviewed by Jer Noble.
+
+        Tested manually, this requires and AppleTV to test.
+
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::checkPlaybackTargetCompatablity):
+        (WebCore::HTMLMediaElement::setIsPlayingToWirelessTarget):
+        * html/HTMLMediaElement.h:
+
 2021-03-09  Manuel Rego Casasnovas  <r...@igalia.com>
 
         [selectors] Move :focus-viisble & :focus-within flags from Node to UserActionElementSet

Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (274174 => 274175)


--- trunk/Source/WebCore/html/HTMLMediaElement.cpp	2021-03-09 22:07:00 UTC (rev 274174)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp	2021-03-09 22:17:26 UTC (rev 274175)
@@ -966,11 +966,8 @@
     if (m_checkPlaybackTargetCompatablityTask.hasPendingTask())
         return;
 
-    auto logSiteIdentifier = LOGIDENTIFIER;
-    ALWAYS_LOG(logSiteIdentifier, "task scheduled");
-    m_checkPlaybackTargetCompatablityTask.scheduleTask([this, logSiteIdentifier] {
-        UNUSED_PARAM(logSiteIdentifier);
-        ALWAYS_LOG(logSiteIdentifier, "lambda(), task fired");
+    ALWAYS_LOG(LOGIDENTIFIER);
+    m_checkPlaybackTargetCompatablityTask.scheduleTask([this] {
         checkPlaybackTargetCompatablity();
     });
 }
@@ -979,7 +976,14 @@
 {
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     if (m_isPlayingToWirelessTarget && !m_player->canPlayToWirelessPlaybackTarget()) {
-        ALWAYS_LOG(LOGIDENTIFIER, "calling setShouldPlayToPlaybackTarget(false)");
+        static const Seconds maxIntervalForWirelessPlaybackPlayerUpdate { 500_ms };
+        Seconds delta = MonotonicTime::now() - m_currentPlaybackTargetIsWirelessEventFiredTime;
+        if (delta < maxIntervalForWirelessPlaybackPlayerUpdate) {
+            scheduleCheckPlaybackTargetCompatability();
+            return;
+        }
+
+        ERROR_LOG(LOGIDENTIFIER, "player incompatible after ", delta.value(), ", calling setShouldPlayToPlaybackTarget(false)");
         m_failedToPlayToWirelessTarget = true;
         m_player->setShouldPlayToPlaybackTarget(false);
     }
@@ -5750,10 +5754,8 @@
 void HTMLMediaElement::setIsPlayingToWirelessTarget(bool isPlayingToWirelessTarget)
 {
     auto logSiteIdentifier = LOGIDENTIFIER;
-    ALWAYS_LOG(logSiteIdentifier, isPlayingToWirelessTarget);
     m_playbackTargetIsWirelessQueue.enqueueTask([this, isPlayingToWirelessTarget, logSiteIdentifier] {
         UNUSED_PARAM(logSiteIdentifier);
-        ALWAYS_LOG(logSiteIdentifier, "lambda(), task fired");
 
         if (isPlayingToWirelessTarget == m_isPlayingToWirelessTarget)
             return;
@@ -5768,6 +5770,7 @@
         updateSleepDisabling();
 
         m_failedToPlayToWirelessTarget = false;
+        m_currentPlaybackTargetIsWirelessEventFiredTime = MonotonicTime::now();
         scheduleCheckPlaybackTargetCompatability();
 
         if (!isContextStopped())

Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (274174 => 274175)


--- trunk/Source/WebCore/html/HTMLMediaElement.h	2021-03-09 22:07:00 UTC (rev 274174)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h	2021-03-09 22:17:26 UTC (rev 274175)
@@ -1173,6 +1173,7 @@
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };
+    MonotonicTime m_currentPlaybackTargetIsWirelessEventFiredTime;
     bool m_hasPlaybackTargetAvailabilityListeners { false };
     bool m_failedToPlayToWirelessTarget { false };
 #endif
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to