Skip to content

Commit

Permalink
[GStreamer] Crash after 10 seconds on watchdog thread due to deadlock…
Browse files Browse the repository at this point in the history
… deep inside GStreamer

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

Reviewed by Xabier Rodriguez-Calvar.

Disable on-disk buffering for looping videos, due to high risks of deadlocking. The whole on-disk
buffering feature is doomed to disappear eventually anyway, since decodebin3/playbin3 have regressed
in that regard (by design).

* Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
(WebCore::MediaPlayerPrivateGStreamer::updateDownloadBufferingFlag):

Canonical link: https://commits.webkit.org/275786@main
  • Loading branch information
philn committed Mar 7, 2024
1 parent 4a1b2c8 commit 755898f
Showing 1 changed file with 27 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -425,12 +425,14 @@ void MediaPlayerPrivateGStreamer::play()
m_isEndReached = false;
m_isDelayingLoad = false;
m_preload = MediaPlayer::Preload::Auto;
updateDownloadBufferingFlag();
GST_INFO_OBJECT(pipeline(), "Play");
RefPtr player = m_player.get();
if (player && player->isLooping()) {
GST_DEBUG_OBJECT(pipeline(), "Scheduling initial SEGMENT seek");
doSeek(SeekTarget { playbackPosition() }, m_playbackRate);
if (player) {
if (player->isLooping()) {
GST_DEBUG_OBJECT(pipeline(), "Scheduling initial SEGMENT seek");
doSeek(SeekTarget { playbackPosition() }, m_playbackRate);
} else
updateDownloadBufferingFlag();
}
} else
loadingFailed(MediaPlayer::NetworkState::Empty);
Expand Down Expand Up @@ -2581,7 +2583,8 @@ void MediaPlayerPrivateGStreamer::updateStates()
break;
case GST_STATE_PAUSED:
FALLTHROUGH;
case GST_STATE_PLAYING:
case GST_STATE_PLAYING: {
bool isLooping = player && player->isLooping();
if (m_isBuffering) {
GRefPtr<GstQuery> query = adoptGRef(gst_query_new_buffering(GST_FORMAT_PERCENT));

Expand All @@ -2603,7 +2606,7 @@ void MediaPlayerPrivateGStreamer::updateStates()
m_readyState = MediaPlayer::ReadyState::HaveCurrentData;
m_networkState = MediaPlayer::NetworkState::Loading;
}
} else if (m_didDownloadFinish) {
} else if (m_didDownloadFinish || isLooping) {
m_readyState = MediaPlayer::ReadyState::HaveEnoughData;
m_networkState = MediaPlayer::NetworkState::Loaded;
} else {
Expand All @@ -2612,6 +2615,7 @@ void MediaPlayerPrivateGStreamer::updateStates()
}

break;
}
default:
ASSERT_NOT_REACHED();
break;
Expand Down Expand Up @@ -2966,10 +2970,23 @@ void MediaPlayerPrivateGStreamer::updateDownloadBufferingFlag()

unsigned flagDownload = getGstPlayFlag("download");

if (m_url.protocolIsBlob()) {
GST_DEBUG_OBJECT(pipeline(), "Blob URI detected. Disabling on-disk buffering");
auto disableDownloading = [&] {
GST_INFO_OBJECT(m_pipeline.get(), "Disabling on-disk buffering");
g_object_set(m_pipeline.get(), "flags", flags & ~flagDownload, nullptr);
m_fillTimer.stop();
};

RefPtr player = m_player.get();
if (player && player->isLooping()) {
// See also: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3129
GST_DEBUG_OBJECT(pipeline(), "Media is looping. Disabling deadlock-prone on-disk buffering");
disableDownloading();
return;
}

if (m_url.protocolIsBlob()) {
GST_DEBUG_OBJECT(pipeline(), "Blob URI detected. Disabling on-disk buffering");
disableDownloading();
return;
}

Expand All @@ -2987,11 +3004,8 @@ void MediaPlayerPrivateGStreamer::updateDownloadBufferingFlag()
GST_INFO_OBJECT(pipeline(), "Enabling on-disk buffering");
g_object_set(m_pipeline.get(), "flags", flags | flagDownload, nullptr);
m_fillTimer.startRepeating(200_ms);
} else {
GST_INFO_OBJECT(pipeline(), "Disabling on-disk buffering");
g_object_set(m_pipeline.get(), "flags", flags & ~flagDownload, nullptr);
m_fillTimer.stop();
}
} else
disableDownloading();
}

void MediaPlayerPrivateGStreamer::setPlaybackFlags(bool isMediaStream)
Expand Down

0 comments on commit 755898f

Please sign in to comment.