<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[243589] releases/WebKitGTK/webkit-2.24</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/243589">243589</a></dd>
<dt>Author</dt> <dd>aperez@igalia.com</dd>
<dt>Date</dt> <dd>2019-03-27 16:48:01 -0700 (Wed, 27 Mar 2019)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merged <a href="http://trac.webkit.org/projects/webkit/changeset/243489">r243489</a> - [GStreamer] Sound loop with Google Hangouts and WhatsApp notifications
https://bugs.webkit.org/show_bug.cgi?id=189471

Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

The media duration is now cached (again). The loop issue was
triggered by the previous version of the code returning positive
infinite duration in didEnd(), followed by the timeupdate event
propagation that would trick the HTMLMediaElement into a new call
to play(). Now the cached duration is updated to current position
at EOS (for forward playback direction only), so the media element
no longer triggers a new play call for those cases.

* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer):
(WebCore::MediaPlayerPrivateGStreamer::loadFull):
(WebCore::MediaPlayerPrivateGStreamer::playbackPosition const):
(WebCore::MediaPlayerPrivateGStreamer::platformDuration const):
(WebCore::MediaPlayerPrivateGStreamer::durationMediaTime const):
(WebCore::MediaPlayerPrivateGStreamer::currentMediaTime const):
(WebCore::MediaPlayerPrivateGStreamer::didEnd):
(WebCore::MediaPlayerPrivateGStreamer::durationChanged):
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
* platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:
(WebCore::MediaPlayerPrivateGStreamerMSE::currentMediaTime const):

LayoutTests:

* platform/gtk/TestExpectations:
* platform/gtk/media/video-playing-and-pause-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit224LayoutTestsChangeLog">releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit224LayoutTestsplatformgtkTestExpectations">releases/WebKitGTK/webkit-2.24/LayoutTests/platform/gtk/TestExpectations</a></li>
<li><a href="#releasesWebKitGTKwebkit224LayoutTestsplatformgtkmediavideoplayingandpauseexpectedtxt">releases/WebKitGTK/webkit-2.24/LayoutTests/platform/gtk/media/video-playing-and-pause-expected.txt</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceWebCoreChangeLog">releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamercpp">releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerh">releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h</a></li>
<li><a href="#releasesWebKitGTKwebkit224SourceWebCoreplatformgraphicsgstreamermseMediaPlayerPrivateGStreamerMSEcpp">releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit224LayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog (243588 => 243589)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog     2019-03-27 23:47:47 UTC (rev 243588)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/ChangeLog        2019-03-27 23:48:01 UTC (rev 243589)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2019-03-26  Philippe Normand  <pnormand@igalia.com>
+
+        [GStreamer] Sound loop with Google Hangouts and WhatsApp notifications
+        https://bugs.webkit.org/show_bug.cgi?id=189471
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        * platform/gtk/TestExpectations:
+        * platform/gtk/media/video-playing-and-pause-expected.txt:
+
</ins><span class="cx"> 2019-03-22  Alicia Boya García  <aboya@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         [MSE][GStreamer] Don't construct segments on PlaybackPipeline::flush
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224LayoutTestsplatformgtkTestExpectations"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/platform/gtk/TestExpectations (243588 => 243589)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/LayoutTests/platform/gtk/TestExpectations 2019-03-27 23:47:47 UTC (rev 243588)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/platform/gtk/TestExpectations    2019-03-27 23:48:01 UTC (rev 243589)
</span><span class="lines">@@ -1485,14 +1485,8 @@
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/116976 media/video-played-collapse.html [ Failure Pass Crash ]
</span><span class="cx"> 
</span><del>-webkit.org/b/116977 media/event-attributes.html [ Crash Failure Timeout Pass ]
-
</del><span class="cx"> webkit.org/b/103443 fast/parser/parser-yield-timing.html [ Failure Pass ]
</span><span class="cx"> 
</span><del>-webkit.org/b/105191 media/video-playing-and-pause.html [ Failure Pass ]
-
-webkit.org/b/118460 media/media-element-play-after-eos.html [ Timeout Pass ]
-
</del><span class="cx"> webkit.org/b/119009 http/tests/cache/subresource-failover-to-network.html [ Failure Pass ]
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/119040 perf/nested-combined-selectors.html [ Failure Pass ]
</span><span class="lines">@@ -1702,8 +1696,6 @@
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/134981 fast/parser/document-write-during-load.html [ Timeout Pass Crash ]
</span><span class="cx"> 
</span><del>-webkit.org/b/81604 media/video-loop.html [ Timeout Pass ]
-
</del><span class="cx"> webkit.org/b/134998 plugins/change-widget-and-click-crash.html [ Timeout Pass Crash ]
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/135003 jquery/attributes.html [ Timeout Pass ]
</span><span class="lines">@@ -3755,6 +3747,84 @@
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/194611 http/wpt/webrtc/getUserMedia-processSwapping.html [ Failure ]
</span><span class="cx"> 
</span><ins>+webkit.org/b/195133 imported/w3c/web-platform-tests/mathml/relations/css-styling/lengths-3.html [ Failure ]
+
+webkit.org/b/195134 inspector/cpu-profiler/threads.html [ Failure ]
+webkit.org/b/195134 inspector/cpu-profiler/tracking.html [ Failure ]
+
+webkit.org/b/195259 compositing/geometry/fixed-position-composited-page-scale-smaller-than-viewport.html [ ImageOnlyFailure ]
+
+webkit.org/b/195670 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html [ Failure ]
+webkit.org/b/195670 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html [ Failure ]
+webkit.org/b/195670 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html [ Failure ]
+webkit.org/b/195670 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html [ Failure ]
+webkit.org/b/195670 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html [ Failure ]
+webkit.org/b/195670 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html [ Failure ]
+webkit.org/b/195670 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html [ Failure ]
+webkit.org/b/195670 imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html [ Failure ]
+
+webkit.org/b/195671 imported/w3c/web-platform-tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_allow_downloads_without_user_activation.sub.tentative.html [ Failure ]
+webkit.org/b/195671 imported/w3c/web-platform-tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_navigation_download_block_downloads_without_user_activation.sub.tentative.html [ Failure ]
+
+webkit.org/b/195712 inspector/canvas/recording-html-2d.html [ Failure ]
+
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/event-dispatch-active-flag.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idb-binary-key-roundtrip.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-advance-continue-async.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-advance-exception-order.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-advance-invalid.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-advance.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-continue-exception-order.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-continuePrimaryKey-exception-order.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-continuePrimaryKey-exceptions.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-delete-exception-order.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-direction-index-keyrange.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-direction-index.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-direction-objectstore-keyrange.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-direction-objectstore.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-direction.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-iterating-update.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-key.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-primarykey.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor-update-exception-order.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbcursor_iterating.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbindex-query-exception-order.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbindex-request-source.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbobjectstore-deleteIndex-exception-order.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbobjectstore_createIndex14-exception_order.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbobjectstore_openKeyCursor.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbrequest-onupgradeneeded.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/idbtransaction_objectStoreNames.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/interleaved-cursors-small.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/key-conversion-exceptions.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/key_valid.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/keygenerator-explicit.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/keygenerator-inject.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/keygenerator.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/keypath-special-identifiers.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/keypath_maxsize.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/large-requests-abort.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/list_ordering.htm [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/request-event-ordering.html [ Failure ]
+webkit.org/b/196069 imported/w3c/web-platform-tests/IndexedDB/value_recursive.htm [ Failure ]
+webkit.org/b/196069 storage/indexeddb/transaction-coordination-across-databases.html [ Failure ]
+
+webkit.org/b/196061 editing/pasteboard/smart-paste-paragraph-001.html [ Failure ]
+webkit.org/b/196061 editing/pasteboard/smart-paste-paragraph-002.html [ Failure ]
+webkit.org/b/196061 editing/pasteboard/smart-paste-paragraph-004.html [ Failure ]
+
+webkit.org/b/196195 inspector/console/console-screenshot.html [ Failure ]
+
+webkit.org/b/196196 inspector/audit/run-resources.html [ Failure ]
+
+webkit.org/b/196197 http/wpt/cache-storage/cache-quota-after-restart.any.html [ Failure ]
+
+webkit.org/b/196199 http/tests/IndexedDB/storage-limit-1.https.html [ Failure ]
+
+webkit.org/b/196201 fast/text/ja-sans-serif.html [ ImageOnlyFailure ]
+
+webkit.org/b/116977 media/event-attributes.html [ Failure ]
+
</ins><span class="cx"> #////////////////////////////////////////////////////////////////////////////////////////
</span><span class="cx"> # End of non-crashing, non-flaky tests failing
</span><span class="cx"> #////////////////////////////////////////////////////////////////////////////////////////
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224LayoutTestsplatformgtkmediavideoplayingandpauseexpectedtxt"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/LayoutTests/platform/gtk/media/video-playing-and-pause-expected.txt (243588 => 243589)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/LayoutTests/platform/gtk/media/video-playing-and-pause-expected.txt       2019-03-27 23:47:47 UTC (rev 243588)
+++ releases/WebKitGTK/webkit-2.24/LayoutTests/platform/gtk/media/video-playing-and-pause-expected.txt  2019-03-27 23:48:01 UTC (rev 243589)
</span><span class="lines">@@ -1,28 +1,29 @@
</span><span class="cx"> layer at (0,0) size 800x600
</span><span class="cx">   RenderView at (0,0) size 800x600
</span><del>-layer at (0,0) size 800x317
-  RenderBlock {HTML} at (0,0) size 800x317
-    RenderBody {BODY} at (8,16) size 784x293
-      RenderBlock {P} at (0,0) size 784x34
-        RenderText {#text} at (0,0) size 766x34
-          text run at (0,0) width 766: "Test that pausing the media element in \"playing\" event handler pauses the media immediately. The video should show the"
-          text run at (0,17) width 68: "first frame."
-      RenderBlock (anonymous) at (0,50) size 784x243
</del><ins>+layer at (0,0) size 800x320
+  RenderBlock {HTML} at (0,0) size 800x320
+    RenderBody {BODY} at (8,16) size 784x296
+      RenderBlock {P} at (0,0) size 784x36
+        RenderText {#text} at (0,0) size 764x35
+          text run at (0,0) width 764: "Test that pausing the media element in \"playing\" event handler pauses the media immediately. The video should show the"
+          text run at (0,18) width 68: "first frame."
+      RenderBlock (anonymous) at (0,52) size 784x244
</ins><span class="cx">         RenderText {#text} at (0,0) size 0x0
</span><del>-layer at (8,66) size 320x240
</del><ins>+layer at (8,68) size 320x240
</ins><span class="cx">   RenderVideo {VIDEO} at (0,0) size 320x240
</span><del>-layer at (8,66) size 320x240
</del><ins>+layer at (8,68) size 320x240
</ins><span class="cx">   RenderFlexibleBox {DIV} at (0,0) size 320x240
</span><span class="cx">     RenderBlock {DIV} at (0,200) size 320x40
</span><del>-layer at (13,271) size 310x30
</del><ins>+layer at (13,273) size 310x30
</ins><span class="cx">   RenderFlexibleBox {DIV} at (5,5) size 310x30 [bgcolor=#141414CC]
</span><del>-    RenderButton {INPUT} at (9,0) size 30x30
</del><ins>+    RenderButton {BUTTON} at (9,0) size 30x30
</ins><span class="cx">     RenderSlider {INPUT} at (49,11) size 93x8 [color=#E6E6E659]
</span><span class="cx">       RenderFlexibleBox {DIV} at (0,0) size 93x8 [border: (1px solid #E6E6E659)]
</span><span class="cx">         RenderBlock {DIV} at (1,-2) size 105x12
</span><del>-          RenderBlock {DIV} at (-7,0) size 13x12 [color=#FFFFFF]
</del><ins>+          RenderBlock {DIV} at (-7,0) size 12x12 [color=#FFFFFF]
</ins><span class="cx">     RenderBlock {DIV} at (157,0) size 74x30 [color=#FFFFFF]
</span><span class="cx">       RenderText {#text} at (0,7) size 74x15
</span><span class="cx">         text run at (0,7) width 74: "00:00 / 00:06"
</span><del>-    RenderButton {INPUT} at (239,0) size 30x30
-    RenderButton {INPUT} at (271,0) size 30x30
</del><ins>+    RenderButton {BUTTON} at (239,0) size 30x30
+    RenderFlexibleBox {DIV} at (271,0) size 30x30
+      RenderButton {BUTTON} at (0,0) size 30x30
</ins></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog (243588 => 243589)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog  2019-03-27 23:47:47 UTC (rev 243588)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/ChangeLog     2019-03-27 23:48:01 UTC (rev 243589)
</span><span class="lines">@@ -1,3 +1,31 @@
</span><ins>+2019-03-26  Philippe Normand  <pnormand@igalia.com>
+
+        [GStreamer] Sound loop with Google Hangouts and WhatsApp notifications
+        https://bugs.webkit.org/show_bug.cgi?id=189471
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        The media duration is now cached (again). The loop issue was
+        triggered by the previous version of the code returning positive
+        infinite duration in didEnd(), followed by the timeupdate event
+        propagation that would trick the HTMLMediaElement into a new call
+        to play(). Now the cached duration is updated to current position
+        at EOS (for forward playback direction only), so the media element
+        no longer triggers a new play call for those cases.
+
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer):
+        (WebCore::MediaPlayerPrivateGStreamer::loadFull):
+        (WebCore::MediaPlayerPrivateGStreamer::playbackPosition const):
+        (WebCore::MediaPlayerPrivateGStreamer::platformDuration const):
+        (WebCore::MediaPlayerPrivateGStreamer::durationMediaTime const):
+        (WebCore::MediaPlayerPrivateGStreamer::currentMediaTime const):
+        (WebCore::MediaPlayerPrivateGStreamer::didEnd):
+        (WebCore::MediaPlayerPrivateGStreamer::durationChanged):
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
+        * platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp:
+        (WebCore::MediaPlayerPrivateGStreamerMSE::currentMediaTime const):
+
</ins><span class="cx"> 2019-03-22  Alicia Boya García  <aboya@igalia.com>
</span><span class="cx"> 
</span><span class="cx">         [MSE][GStreamer] Don't construct segments on PlaybackPipeline::flush
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamercpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (243588 => 243589)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp        2019-03-27 23:47:47 UTC (rev 243588)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp   2019-03-27 23:48:01 UTC (rev 243589)
</span><span class="lines">@@ -136,6 +136,7 @@
</span><span class="cx">     , m_buffering(false)
</span><span class="cx">     , m_bufferingPercentage(0)
</span><span class="cx">     , m_cachedPosition(MediaTime::invalidTime())
</span><ins>+    , m_cachedDuration(MediaTime::invalidTime())
</ins><span class="cx">     , m_canFallBackToLastFinishedSeekPosition(false)
</span><span class="cx">     , m_changingRate(false)
</span><span class="cx">     , m_downloadFinished(false)
</span><span class="lines">@@ -142,7 +143,6 @@
</span><span class="cx">     , m_errorOccured(false)
</span><span class="cx">     , m_isEndReached(false)
</span><span class="cx">     , m_isStreaming(false)
</span><del>-    , m_durationAtEOS(MediaTime::invalidTime())
</del><span class="cx">     , m_paused(true)
</span><span class="cx">     , m_playbackRate(1)
</span><span class="cx">     , m_requestedState(GST_STATE_VOID_PENDING)
</span><span class="lines">@@ -310,7 +310,6 @@
</span><span class="cx">     m_readyState = MediaPlayer::HaveNothing;
</span><span class="cx">     m_player->readyStateChanged();
</span><span class="cx">     m_volumeAndMuteInitialized = false;
</span><del>-    m_durationAtEOS = MediaTime::invalidTime();
</del><span class="cx">     m_hasTaintedOrigin = WTF::nullopt;
</span><span class="cx"> 
</span><span class="cx">     if (!m_delayingLoad)
</span><span class="lines">@@ -366,6 +365,7 @@
</span><span class="cx"> 
</span><span class="cx"> MediaTime MediaPlayerPrivateGStreamer::playbackPosition() const
</span><span class="cx"> {
</span><ins>+    GST_TRACE_OBJECT(pipeline(), "isEndReached: %s, seeking: %s, seekTime: %s", boolForPrinting(m_isEndReached), boolForPrinting(m_seeking), m_seekTime.toString().utf8().data());
</ins><span class="cx">     if (m_isEndReached && m_seeking)
</span><span class="cx">         return m_seekTime;
</span><span class="cx"> 
</span><span class="lines">@@ -372,8 +372,10 @@
</span><span class="cx">     // This constant should remain lower than HTMLMediaElement's maxTimeupdateEventFrequency.
</span><span class="cx">     static const Seconds positionCacheThreshold = 200_ms;
</span><span class="cx">     Seconds now = WTF::WallTime::now().secondsSinceEpoch();
</span><del>-    if (m_lastQueryTime && (now - m_lastQueryTime.value()) < positionCacheThreshold && m_cachedPosition.isValid())
</del><ins>+    if (m_lastQueryTime && (now - m_lastQueryTime.value()) < positionCacheThreshold && m_cachedPosition.isValid()) {
+        GST_TRACE_OBJECT(pipeline(), "Returning cached position: %s", m_cachedPosition.toString().utf8().data());
</ins><span class="cx">         return m_cachedPosition;
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     m_lastQueryTime = now;
</span><span class="cx"> 
</span><span class="lines">@@ -384,7 +386,7 @@
</span><span class="cx">         gst_query_parse_position(query, 0, &position);
</span><span class="cx">     gst_query_unref(query);
</span><span class="cx"> 
</span><del>-    GST_TRACE_OBJECT(pipeline(), "Position %" GST_TIME_FORMAT, GST_TIME_ARGS(position));
</del><ins>+    GST_TRACE_OBJECT(pipeline(), "Position %" GST_TIME_FORMAT ", canFallBackToLastFinishedSeekPosition: %s", GST_TIME_ARGS(position), boolForPrinting(m_canFallBackToLastFinishedSeekPosition));
</ins><span class="cx"> 
</span><span class="cx">     MediaTime playbackPosition = MediaTime::zeroTime();
</span><span class="cx">     GstClockTime gstreamerPosition = static_cast<GstClockTime>(position);
</span><span class="lines">@@ -486,29 +488,39 @@
</span><span class="cx">         loadingFailed(MediaPlayer::Empty);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-MediaTime MediaPlayerPrivateGStreamer::durationMediaTime() const
</del><ins>+MediaTime MediaPlayerPrivateGStreamer::platformDuration() const
</ins><span class="cx"> {
</span><del>-    if (!m_pipeline || m_errorOccured)
</del><ins>+    GST_TRACE_OBJECT(pipeline(), "errorOccured: %s, pipeline state: %s", boolForPrinting(m_errorOccured), gst_element_state_get_name(GST_STATE(m_pipeline.get())));
+    if (m_errorOccured)
</ins><span class="cx">         return MediaTime::invalidTime();
</span><span class="cx"> 
</span><del>-    if (m_durationAtEOS.isValid())
-        return m_durationAtEOS;
-
</del><span class="cx">     // The duration query would fail on a not-prerolled pipeline.
</span><span class="cx">     if (GST_STATE(m_pipeline.get()) < GST_STATE_PAUSED)
</span><del>-        return MediaTime::positiveInfiniteTime();
</del><ins>+        return MediaTime::invalidTime();
</ins><span class="cx"> 
</span><del>-    gint64 timeLength = 0;
-
-    if (!gst_element_query_duration(m_pipeline.get(), GST_FORMAT_TIME, &timeLength) || !GST_CLOCK_TIME_IS_VALID(timeLength)) {
</del><ins>+    int64_t duration = 0;
+    if (!gst_element_query_duration(m_pipeline.get(), GST_FORMAT_TIME, &duration) || !GST_CLOCK_TIME_IS_VALID(duration)) {
</ins><span class="cx">         GST_DEBUG_OBJECT(pipeline(), "Time duration query failed for %s", m_url.string().utf8().data());
</span><span class="cx">         return MediaTime::positiveInfiniteTime();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    GST_LOG("Duration: %" GST_TIME_FORMAT, GST_TIME_ARGS(timeLength));
</del><ins>+    GST_LOG_OBJECT(pipeline(), "Duration: %" GST_TIME_FORMAT, GST_TIME_ARGS(duration));
+    return MediaTime(duration, GST_SECOND);
+}
</ins><span class="cx"> 
</span><del>-    return MediaTime(timeLength, GST_SECOND);
-    // FIXME: handle 3.14.9.5 properly
</del><ins>+MediaTime MediaPlayerPrivateGStreamer::durationMediaTime() const
+{
+    GST_TRACE_OBJECT(pipeline(), "Cached duration: %s", m_cachedDuration.toString().utf8().data());
+    if (m_cachedDuration.isValid())
+        return m_cachedDuration;
+
+    MediaTime duration = platformDuration();
+    if (!duration || duration.isInvalid())
+        return MediaTime::zeroTime();
+
+    m_cachedDuration = duration;
+
+    return m_cachedDuration;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> MediaTime MediaPlayerPrivateGStreamer::currentMediaTime() const
</span><span class="lines">@@ -516,6 +528,7 @@
</span><span class="cx">     if (!m_pipeline || m_errorOccured)
</span><span class="cx">         return MediaTime::invalidTime();
</span><span class="cx"> 
</span><ins>+    GST_TRACE_OBJECT(pipeline(), "seeking: %s, seekTime: %s", boolForPrinting(m_seeking), m_seekTime.toString().utf8().data());
</ins><span class="cx">     if (m_seeking)
</span><span class="cx">         return m_seekTime;
</span><span class="cx"> 
</span><span class="lines">@@ -2185,27 +2198,26 @@
</span><span class="cx">     // position is not always reported as 0 for instance.
</span><span class="cx">     m_cachedPosition = MediaTime::invalidTime();
</span><span class="cx">     MediaTime now = currentMediaTime();
</span><del>-    if (now > MediaTime { } && now <= durationMediaTime())
</del><ins>+    if (now > MediaTime::zeroTime() && !m_seeking) {
+        m_cachedDuration = now;
</ins><span class="cx">         m_player->durationChanged();
</span><ins>+    }
</ins><span class="cx"> 
</span><span class="cx">     m_isEndReached = true;
</span><del>-    timeChanged();
</del><span class="cx"> 
</span><span class="cx">     if (!m_player->client().mediaPlayerIsLooping()) {
</span><span class="cx">         m_paused = true;
</span><del>-        m_durationAtEOS = durationMediaTime();
</del><span class="cx">         changePipelineState(GST_STATE_READY);
</span><span class="cx">         m_downloadFinished = false;
</span><span class="cx">     }
</span><ins>+    timeChanged();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MediaPlayerPrivateGStreamer::durationChanged()
</span><span class="cx"> {
</span><span class="cx">     MediaTime previousDuration = durationMediaTime();
</span><ins>+    m_cachedDuration = MediaTime::invalidTime();
</ins><span class="cx"> 
</span><del>-    // FIXME: Check if this method is still useful, because it's not doing its work at all
-    // since bug #159458 removed a cacheDuration() call here.
-
</del><span class="cx">     // Avoid emiting durationchanged in the case where the previous
</span><span class="cx">     // duration was 0 because that case is already handled by the
</span><span class="cx">     // HTMLMediaElement.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceWebCoreplatformgraphicsgstreamerMediaPlayerPrivateGStreamerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h (243588 => 243589)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h  2019-03-27 23:47:47 UTC (rev 243588)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h     2019-03-27 23:48:01 UTC (rev 243589)
</span><span class="lines">@@ -91,6 +91,7 @@
</span><span class="cx">     bool paused() const override;
</span><span class="cx">     bool seeking() const override;
</span><span class="cx"> 
</span><ins>+    MediaTime platformDuration() const;
</ins><span class="cx">     MediaTime durationMediaTime() const override;
</span><span class="cx">     MediaTime currentMediaTime() const override;
</span><span class="cx">     void seek(const MediaTime&) override;
</span><span class="lines">@@ -187,11 +188,10 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    void cacheDuration();
-
</del><span class="cx">     bool m_buffering;
</span><span class="cx">     int m_bufferingPercentage;
</span><span class="cx">     mutable MediaTime m_cachedPosition;
</span><ins>+    mutable MediaTime m_cachedDuration;
</ins><span class="cx">     bool m_canFallBackToLastFinishedSeekPosition;
</span><span class="cx">     bool m_changingRate;
</span><span class="cx">     bool m_downloadFinished;
</span><span class="lines">@@ -198,7 +198,6 @@
</span><span class="cx">     bool m_errorOccured;
</span><span class="cx">     mutable bool m_isEndReached;
</span><span class="cx">     mutable bool m_isStreaming;
</span><del>-    mutable MediaTime m_durationAtEOS;
</del><span class="cx">     bool m_paused;
</span><span class="cx">     float m_playbackRate;
</span><span class="cx">     GstState m_currentState;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit224SourceWebCoreplatformgraphicsgstreamermseMediaPlayerPrivateGStreamerMSEcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp (243588 => 243589)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp 2019-03-27 23:47:47 UTC (rev 243588)
+++ releases/WebKitGTK/webkit-2.24/Source/WebCore/platform/graphics/gstreamer/mse/MediaPlayerPrivateGStreamerMSE.cpp    2019-03-27 23:48:01 UTC (rev 243589)
</span><span class="lines">@@ -782,7 +782,6 @@
</span><span class="cx">         m_eosPending = false;
</span><span class="cx">         m_isEndReached = true;
</span><span class="cx">         m_cachedPosition = m_mediaTimeDuration;
</span><del>-        m_durationAtEOS = m_mediaTimeDuration;
</del><span class="cx">         m_player->timeChanged();
</span><span class="cx">     }
</span><span class="cx">     return position;
</span></span></pre>
</div>
</div>

</body>
</html>