Modified: trunk/Source/WebCore/ChangeLog (254683 => 254684)
--- trunk/Source/WebCore/ChangeLog 2020-01-16 16:04:54 UTC (rev 254683)
+++ trunk/Source/WebCore/ChangeLog 2020-01-16 16:14:13 UTC (rev 254684)
@@ -1,3 +1,27 @@
+2020-01-16 Thibault Saunier <[email protected]>
+
+ [GStreamer] Several buffering fixes
+ https://bugs.webkit.org/show_bug.cgi?id=206234
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ No new tests as this is already tested.
+
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivateGStreamer::durationChanged): Minor typo fix
+ (WebCore::MediaPlayerPrivateGStreamer::fillTimerFired): Query buffering on the pipeline not the source
+ otherwise GstBaseSrc returns some useless values before `downloadbuffer` actually gives us the
+ info about DOWNLOAD buffering status.
+ (WebCore::MediaPlayerPrivateGStreamer::handleMessage):
+ - Detect when DOWNLOAD is done by using the `downloadbuffer` `GstCacheDownloadComplete`
+ element message which is what is supposed to be used for that purpose.
+ - Fix the way we detect that buffering is done (mostly when using a `downloadbuffer`) by relying on a
+ buffering query to check if it is still buffering.
+ (WebCore::MediaPlayerPrivateGStreamer::updateBufferingStatus): Ensure that we properly pause the pipeline when
+ restarting buffering. There were cases when not using `downloadbuffer` where we didn't pause the pipeline
+ leading to pretty bad user experience.
+ (WebCore::MediaPlayerPrivateGStreamer::updateStates): Buffering should happen only on **non live** pipelines.
+
2020-01-16 Philippe Normand <[email protected]>
[GStreamer][WPE] Client-side video rendering support
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (254683 => 254684)
--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 2020-01-16 16:04:54 UTC (rev 254683)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 2020-01-16 16:14:13 UTC (rev 254684)
@@ -1101,7 +1101,7 @@
MediaTime previousDuration = durationMediaTime();
m_cachedDuration = MediaTime::invalidTime();
- // Avoid emiting durationchanged in the case where the previous
+ // Avoid emitting durationChanged in the case where the previous
// duration was 0 because that case is already handled by the
// HTMLMediaElement.
if (previousDuration && durationMediaTime() != previousDuration)
@@ -1504,7 +1504,7 @@
double fillStatus = 100.0;
GstBufferingMode mode = GST_BUFFERING_DOWNLOAD;
- if (gst_element_query(m_source.get(), query.get())) {
+ if (gst_element_query(pipeline(), query.get())) {
gst_query_parse_buffering_stats(query.get(), &mode, nullptr, nullptr, nullptr);
int percentage;
@@ -2246,6 +2246,11 @@
if (const char* uri = gst_structure_get_string(structure, "uri"))
m_hasTaintedOrigin = webKitSrcWouldTaintOrigin(WEBKIT_WEB_SRC_CAST(m_source.get()), SecurityOrigin::create(URL(URL(), uri)));
}
+ } else if (gst_structure_has_name(structure, "GstCacheDownloadComplete")) {
+ GST_INFO_OBJECT(pipeline(), "Stream is fully downloaded, stopping monitoring downloading progress.");
+ m_fillTimer.stop();
+ m_bufferingPercentage = 100;
+ updateStates();
} else
GST_DEBUG_OBJECT(pipeline(), "Unhandled element message: %" GST_PTR_FORMAT, structure);
break;
@@ -2340,17 +2345,23 @@
void MediaPlayerPrivateGStreamer::updateBufferingStatus(GstBufferingMode mode, double percentage)
{
+ bool wasBuffering = m_isBuffering;
+
GST_DEBUG_OBJECT(pipeline(), "[Buffering] mode: %s, status: %f%%", enumToString(GST_TYPE_BUFFERING_MODE, mode).data(), percentage);
m_didDownloadFinish = percentage == 100;
m_isBuffering = !m_didDownloadFinish;
+ if (!m_didDownloadFinish)
+ m_isBuffering = true;
+
+ m_bufferingPercentage = percentage;
switch (mode) {
case GST_BUFFERING_STREAM: {
updateMaxTimeLoaded(percentage);
m_bufferingPercentage = percentage;
- if (m_didDownloadFinish)
+ if (m_didDownloadFinish || (!wasBuffering && m_isBuffering))
updateStates();
break;
@@ -2357,12 +2368,6 @@
}
case GST_BUFFERING_DOWNLOAD: {
updateMaxTimeLoaded(percentage);
-
- // Media is now fully loaded. It will play even if network connection is
- // cut. Buffering is done, remove the fill source from the main loop.
- if (m_didDownloadFinish)
- m_fillTimer.stop();
-
updateStates();
break;
}
@@ -2625,9 +2630,17 @@
FALLTHROUGH;
case GST_STATE_PLAYING:
if (m_isBuffering) {
- if (m_bufferingPercentage == 100) {
- GST_DEBUG_OBJECT(pipeline(), "[Buffering] Complete.");
- m_isBuffering = false;
+ GRefPtr<GstQuery> query = adoptGRef(gst_query_new_buffering(GST_FORMAT_PERCENT));
+
+ m_isBuffering = m_bufferingPercentage == 100;
+ if (gst_element_query(m_pipeline.get(), query.get())) {
+ gboolean isBuffering = m_isBuffering;
+ gst_query_parse_buffering_percent(query.get(), &isBuffering, nullptr);
+ m_isBuffering = isBuffering;
+ }
+
+ if (!m_isBuffering) {
+ GST_INFO_OBJECT(pipeline(), "[Buffering] Complete.");
m_readyState = MediaPlayer::ReadyState::HaveEnoughData;
m_networkState = m_didDownloadFinish ? MediaPlayer::NetworkState::Idle : MediaPlayer::NetworkState::Loading;
} else {
@@ -2657,7 +2670,7 @@
}
if (didBuffering && !m_isBuffering && !m_isPaused && m_playbackRate) {
- GST_DEBUG_OBJECT(pipeline(), "[Buffering] Restarting playback.");
+ GST_INFO_OBJECT(pipeline(), "[Buffering] Restarting playback.");
changePipelineState(GST_STATE_PLAYING);
}
} else if (m_currentState == GST_STATE_PLAYING) {
@@ -2664,7 +2677,7 @@
m_isPaused = false;
if ((m_isBuffering && !m_isLiveStream) || !m_playbackRate) {
- GST_DEBUG_OBJECT(pipeline(), "[Buffering] Pausing stream for buffering.");
+ GST_INFO_OBJECT(pipeline(), "[Buffering] Pausing stream for buffering.");
changePipelineState(GST_STATE_PAUSED);
}
} else