Skip to content
Permalink
Browse files
[GStreamer] Videos start playing muted in epiphany with no unmute ico…
…n visible in tab, webkit_web_view_get_is_muted() returns incorrect results

https://bugs.webkit.org/show_bug.cgi?id=223195

Patch by Philippe Normand <pnormand@igalia.com> on 2021-04-07
Source/WebCore:

Reviewed by Eric Carlson.

For GStreamer ports the semantics of IsPlayingAudio slightly differ from Apple ports. The
webkit_web_view_is_playing_audio() API is expected to return true if a page is producing
audio even though it might be muted.

The second change affects the private player mute state when the page mute state has been
updated.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaState const):
(WebCore::HTMLMediaElement::pageMutedStateDidChange):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: Logging improvements.
(WebCore::MediaPlayerPrivateGStreamer::isMuted const):
(WebCore::MediaPlayerPrivateGStreamer::volume const):
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange):
(WebCore::MediaPlayerPrivateGStreamer::setMuted):
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfMute):

Tools:

Reviewed by Michael Catanzaro.

Adapt is-playing test, after muting the page, webkit_web_view_is_playing_audio() should
still return TRUE.

* TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp:
(IsPlayingAudioWebViewTest::periodicallyCheckIsPlayingForAWhile):
(testWebViewIsPlayingAudio):

Canonical link: https://commits.webkit.org/236245@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275600 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
philn authored and webkit-commit-queue committed Apr 7, 2021
1 parent 256789e commit deee5f6a92527d25071abe3921ff7bbb27d0c056
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 13 deletions.
@@ -1,3 +1,27 @@
2021-04-07 Philippe Normand <pnormand@igalia.com>

[GStreamer] Videos start playing muted in epiphany with no unmute icon visible in tab, webkit_web_view_get_is_muted() returns incorrect results
https://bugs.webkit.org/show_bug.cgi?id=223195

Reviewed by Eric Carlson.

For GStreamer ports the semantics of IsPlayingAudio slightly differ from Apple ports. The
webkit_web_view_is_playing_audio() API is expected to return true if a page is producing
audio even though it might be muted.

The second change affects the private player mute state when the page mute state has been
updated.

* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::mediaState const):
(WebCore::HTMLMediaElement::pageMutedStateDidChange):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: Logging improvements.
(WebCore::MediaPlayerPrivateGStreamer::isMuted const):
(WebCore::MediaPlayerPrivateGStreamer::volume const):
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange):
(WebCore::MediaPlayerPrivateGStreamer::setMuted):
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfMute):

2021-04-07 Enrique Ocaña González <eocanha@igalia.com>

[EME][GStreamer] Abort decryptor operations immediately and without errors on flush
@@ -7730,7 +7730,14 @@ MediaProducer::MediaStateFlags HTMLMediaElement::mediaState() const
if (!isPlaying())
return state;

if (hasAudio && !muted() && volume())
// For GStreamer ports the semantics of IsPlayingAudio slightly differ from Apple ports. The
// webkit_web_view_is_playing_audio() API is expected to return true if a page is producing
// audio even though it might be muted.
bool isPlayingAudio = hasAudio && volume();
#if !USE(GSTREAMER)
isPlayingAudio = isPlayingAudio && !muted();
#endif
if (isPlayingAudio)
state |= IsPlayingAudio;

if (hasActiveVideo)
@@ -7787,9 +7794,10 @@ void HTMLMediaElement::setAutoplayEventPlaybackState(AutoplayEventPlaybackState

void HTMLMediaElement::pageMutedStateDidChange()
{
updateVolume();

if (Page* page = document().page()) {
// Propagate the new state to the platform player.
if (m_player)
m_player->setMuted(page->isAudioMuted());
if (hasAudio() && !muted() && page->isAudioMuted())
userDidInterfereWithAutoplay();
}
@@ -1232,7 +1232,7 @@ bool MediaPlayerPrivateGStreamer::isMuted() const

gboolean isMuted;
g_object_get(m_volumeElement.get(), "mute", &isMuted, nullptr);
GST_INFO_OBJECT(pipeline(), "Player is muted: %s", boolForPrinting(!!isMuted));
GST_INFO_OBJECT(pipeline(), "Player is muted: %s", boolForPrinting(isMuted));
return isMuted;
}

@@ -1667,20 +1667,24 @@ float MediaPlayerPrivateGStreamer::volume() const
if (!m_volumeElement)
return 0;

return gst_stream_volume_get_volume(m_volumeElement.get(), GST_STREAM_VOLUME_FORMAT_LINEAR);
auto volume = gst_stream_volume_get_volume(m_volumeElement.get(), GST_STREAM_VOLUME_FORMAT_LINEAR);
GST_DEBUG_OBJECT(pipeline(), "Volume: %f", volume);
return volume;
}

void MediaPlayerPrivateGStreamer::notifyPlayerOfVolumeChange()
{
if (!m_player || !m_volumeElement)
return;
double volume;
volume = gst_stream_volume_get_volume(m_volumeElement.get(), GST_STREAM_VOLUME_FORMAT_LINEAR);
// get_volume() can return values superior to 1.0 if the user
// applies software user gain via third party application (GNOME
// volume control for instance).
volume = CLAMP(volume, 0.0, 1.0);
m_player->volumeChanged(static_cast<float>(volume));

// get_volume() can return values superior to 1.0 if the user applies software user gain via
// third party application (GNOME volume control for instance).
auto oldVolume = this->volume();
auto volume = CLAMP(oldVolume, 0.0, 1.0);

if (volume != oldVolume)
GST_DEBUG_OBJECT(pipeline(), "Volume value (%f) was not in [0,1] range. Clamped to %f", oldVolume, volume);
m_player->volumeChanged(volume);
}

void MediaPlayerPrivateGStreamer::volumeChangedCallback(MediaPlayerPrivateGStreamer* player)
@@ -1711,7 +1715,7 @@ void MediaPlayerPrivateGStreamer::setMuted(bool shouldMute)
if (!m_volumeElement || shouldMute == isMuted())
return;

GST_INFO_OBJECT(pipeline(), "Muted? %s", boolForPrinting(shouldMute));
GST_INFO_OBJECT(pipeline(), "Setting muted state to %s", boolForPrinting(shouldMute));
g_object_set(m_volumeElement.get(), "mute", shouldMute, nullptr);
}

@@ -1722,6 +1726,7 @@ void MediaPlayerPrivateGStreamer::notifyPlayerOfMute()

gboolean muted;
g_object_get(m_volumeElement.get(), "mute", &muted, nullptr);
GST_DEBUG_OBJECT(pipeline(), "Notifying player of new mute value: %s", boolForPrinting(muted));
m_player->muteChanged(static_cast<bool>(muted));
}

@@ -1,3 +1,17 @@
2021-04-07 Philippe Normand <pnormand@igalia.com>

[GStreamer] Videos start playing muted in epiphany with no unmute icon visible in tab, webkit_web_view_get_is_muted() returns incorrect results
https://bugs.webkit.org/show_bug.cgi?id=223195

Reviewed by Michael Catanzaro.

Adapt is-playing test, after muting the page, webkit_web_view_is_playing_audio() should
still return TRUE.

* TestWebKitAPI/Tests/WebKitGLib/TestWebKitWebView.cpp:
(IsPlayingAudioWebViewTest::periodicallyCheckIsPlayingForAWhile):
(testWebViewIsPlayingAudio):

2021-04-07 Philippe Normand <pnormand@igalia.com>

[Flatpak SDK] Enable LLVM extension
@@ -44,6 +44,25 @@ class IsPlayingAudioWebViewTest : public WebViewTest {
g_signal_connect(m_webView, "notify::is-playing-audio", G_CALLBACK(isPlayingAudioChanged), this);
g_main_loop_run(m_mainLoop);
}

void periodicallyCheckIsPlayingForAWhile()
{
m_tickCount = 0;
g_timeout_add(50, [](gpointer userData) -> gboolean {
auto* test = static_cast<IsPlayingAudioWebViewTest*>(userData);
g_assert_true(webkit_web_view_is_playing_audio(test->m_webView));
test->m_tickCount++;
if (test->m_tickCount >= 10) {
test->quitMainLoop();
return G_SOURCE_REMOVE;
}
return G_SOURCE_CONTINUE;
}, this);
g_main_loop_run(m_mainLoop);
}

private:
uint32_t m_tickCount { 0 };
};

static WebKitTestServer* gServer;
@@ -1114,6 +1133,7 @@ static void testWebViewIsPlayingAudio(IsPlayingAudioWebViewTest* test, gconstpoi

// Initially, web views should always report no audio being played.
g_assert_false(webkit_web_view_is_playing_audio(test->m_webView));
g_assert_false(webkit_web_view_get_is_muted(test->m_webView));

GUniquePtr<char> resourcePath(g_build_filename(Test::getResourcesDir(Test::WebKit2Resources).data(), "file-with-video.html", nullptr));
GUniquePtr<char> resourceURL(g_filename_to_uri(resourcePath.get(), nullptr, nullptr));
@@ -1126,6 +1146,15 @@ static void testWebViewIsPlayingAudio(IsPlayingAudioWebViewTest* test, gconstpoi
test->waitUntilIsPlayingAudioChanged();
g_assert_true(webkit_web_view_is_playing_audio(test->m_webView));

// Mute the page, webkit_web_view_is_playing_audio() should still return TRUE.
webkit_web_view_set_is_muted(test->m_webView, TRUE);
g_assert_true(webkit_web_view_get_is_muted(test->m_webView));
test->periodicallyCheckIsPlayingForAWhile();
g_assert_true(webkit_web_view_is_playing_audio(test->m_webView));
webkit_web_view_set_is_muted(test->m_webView, FALSE);
g_assert_false(webkit_web_view_get_is_muted(test->m_webView));
g_assert_true(webkit_web_view_is_playing_audio(test->m_webView));

// Pause the video, and check again.
test->runJavaScriptAndWaitUntilFinished("document.getElementById('test-video').pause();", nullptr);
if (webkit_web_view_is_playing_audio(test->m_webView))

0 comments on commit deee5f6

Please sign in to comment.