WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
Patch.patch (text/plain), 12.12 KB, created by
Philippe Normand
on 2012-07-31 09:08:44 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Philippe Normand
Created:
2012-07-31 09:08:44 PDT
Size:
12.12 KB
patch
obsolete
>From c172dee4e1685e54c588d1fa58451f7e93380d77 Mon Sep 17 00:00:00 2001 >From: Philippe Normand <pnormand@igalia.com> >Date: Sat, 7 Jul 2012 17:37:01 -0700 >Subject: [PATCH] Patch > >--- > Source/WebCore/ChangeLog | 42 ++++++++++ > .../gstreamer/MediaPlayerPrivateGStreamer.cpp | 82 ++++++++++++++++---- > .../gstreamer/MediaPlayerPrivateGStreamer.h | 6 ++ > 3 files changed, 114 insertions(+), 16 deletions(-) > >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index c1fe1a9..f281361 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,45 @@ >+2012-07-07 Philippe Normand <pnormand@igalia.com> >+ >+ [GStreamer] Live stream support is weak >+ https://bugs.webkit.org/show_bug.cgi?id=90084 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Make sure on-disk buffering is disabled for live streams. It is >+ enabled initially when loading any remote media file if preload is >+ set to Auto. Later on if the player detects that the media is live >+ it disables on-disk buffering. This patch also adds support for >+ caching the total size of the media. >+ >+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp: >+ (WebCore::MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer): >+ (WebCore::MediaPlayerPrivateGStreamer::load): Keep track of the >+ media url as an instance attribute. >+ (WebCore::MediaPlayerPrivateGStreamer::duration): Logging improvement. >+ (WebCore::MediaPlayerPrivateGStreamer::setRate): use the new >+ isLiveStream() method. >+ (WebCore::MediaPlayerPrivateGStreamer::buffered): Ditto. >+ (WebCore::MediaPlayerPrivateGStreamer::handleMessage): Indicate >+ source of duration message. >+ (WebCore::MediaPlayerPrivateGStreamer::fillTimerFired): Perform an >+ anonymous duration change emission, mostly to cache its value. >+ (WebCore::MediaPlayerPrivateGStreamer::totalBytes): Return >+ cached size when available. >+ (WebCore::MediaPlayerPrivateGStreamer::updateStates): Use the new >+ isLiveStream() method and handle state change corner cases for live streams. >+ (WebCore::MediaPlayerPrivateGStreamer::durationChanged): Cache >+ media total size and re-enable on-disk buffering if caching succeeds. >+ (WebCore::MediaPlayerPrivateGStreamer::movieLoadType): New >+ implementation handling on-disk buffered and live streaming cases. >+ (WebCore::MediaPlayerPrivateGStreamer::setPreload): Record initial >+ preload attribute value, do on-disk buffering only for Auto >+ preload attribute and non-local media. >+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: >+ (MediaPlayerPrivateGStreamer): >+ (WebCore::MediaPlayerPrivateGStreamer::isLiveStream): Utility >+ method, a stream is live if it goes to PAUSE without prerolling >+ or if the byte size reported by the source element is null. >+ > 2012-07-31 Tommy Widenflycht <tommyw@google.com> > > Introduce a minimal RTCPeerConnection together with Dictionary changes >diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp >index fba8252..193f665 100644 >--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp >+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp >@@ -235,6 +235,8 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player) > , m_audioTimerHandler(0) > , m_videoTimerHandler(0) > , m_webkitAudioSink(0) >+ , m_totalBytes(-1) >+ , m_originalPreloadWasAutoAndWasOverridden(false) > { > if (initializeGStreamerAndRegisterWebKitElements()) > createGSTPlayBin(); >@@ -292,6 +294,7 @@ void MediaPlayerPrivateGStreamer::load(const String& url) > if (kurl.isLocalFile()) > cleanUrl = cleanUrl.substring(0, kurl.pathEnd()); > >+ m_url = KURL(KURL(), cleanUrl); > g_object_set(m_playBin, "uri", cleanUrl.utf8().data(), NULL); > > LOG_VERBOSE(Media, "Load %s", cleanUrl.utf8().data()); >@@ -407,7 +410,7 @@ float MediaPlayerPrivateGStreamer::duration() const > bool failure = !gst_element_query_duration(m_playBin, &timeFormat, &timeLength) || timeFormat != GST_FORMAT_TIME || static_cast<guint64>(timeLength) == GST_CLOCK_TIME_NONE; > #endif > if (failure) { >- LOG_VERBOSE(Media, "Time duration query failed."); >+ LOG_VERBOSE(Media, "Time duration query failed for %s", m_url.string().utf8().data()); > return numeric_limits<float>::infinity(); > } > >@@ -634,7 +637,7 @@ void MediaPlayerPrivateGStreamer::setRate(float rate) > || (pending == GST_STATE_PAUSED)) > return; > >- if (m_isStreaming) >+ if (isLiveStream()) > return; > > m_playbackRate = rate; >@@ -692,7 +695,7 @@ MediaPlayer::ReadyState MediaPlayerPrivateGStreamer::readyState() const > PassRefPtr<TimeRanges> MediaPlayerPrivateGStreamer::buffered() const > { > RefPtr<TimeRanges> timeRanges = TimeRanges::create(); >- if (m_errorOccured || m_isStreaming) >+ if (m_errorOccured || isLiveStream()) > return timeRanges.release(); > > #if GST_CHECK_VERSION(0, 10, 31) >@@ -723,7 +726,7 @@ PassRefPtr<TimeRanges> MediaPlayerPrivateGStreamer::buffered() const > gst_query_unref(query); > #else > float loaded = maxTimeLoaded(); >- if (!m_errorOccured && !m_isStreaming && loaded > 0) >+ if (!m_errorOccured && !isLiveStream() && loaded > 0) > timeRanges->add(0, loaded); > #endif > return timeRanges.release(); >@@ -749,12 +752,13 @@ gboolean MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message) > } > } > >+ LOG_VERBOSE(Media, "Message received from element %s", GST_MESSAGE_SRC_NAME(message)); > switch (GST_MESSAGE_TYPE(message)) { > case GST_MESSAGE_ERROR: > if (m_resetPipeline) > break; > gst_message_parse_error(message, &err.outPtr(), &debug.outPtr()); >- LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message); >+ LOG_VERBOSE(Media, "Error %d: %s (url=%s)", err->code, err->message, m_url.string().utf8().data()); > > GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS(GST_BIN(m_playBin), GST_DEBUG_GRAPH_SHOW_ALL, "webkit-video.error"); > >@@ -941,10 +945,13 @@ bool MediaPlayerPrivateGStreamer::didLoadingProgress() const > > unsigned MediaPlayerPrivateGStreamer::totalBytes() const > { >- if (!m_source) >+ if (m_errorOccured) > return 0; > >- if (m_errorOccured) >+ if (m_totalBytes != -1) >+ return m_totalBytes; >+ >+ if (!m_source) > return 0; > > GstFormat fmt = GST_FORMAT_BYTES; >@@ -955,7 +962,9 @@ unsigned MediaPlayerPrivateGStreamer::totalBytes() const > if (gst_element_query_duration(m_source.get(), &fmt, &length)) { > #endif > LOG_VERBOSE(Media, "totalBytes %" G_GINT64_FORMAT, length); >- return static_cast<unsigned>(length); >+ m_totalBytes = static_cast<unsigned>(length); >+ m_isStreaming = !length; >+ return m_totalBytes; > } > > // Fall back to querying the source pads manually. >@@ -1003,8 +1012,9 @@ unsigned MediaPlayerPrivateGStreamer::totalBytes() const > gst_iterator_free(iter); > > LOG_VERBOSE(Media, "totalBytes %" G_GINT64_FORMAT, length); >- >- return static_cast<unsigned>(length); >+ m_totalBytes = static_cast<unsigned>(length); >+ m_isStreaming = !length; >+ return m_totalBytes; > } > > unsigned MediaPlayerPrivateGStreamer::decodedFrameCount() const >@@ -1150,7 +1160,7 @@ void MediaPlayerPrivateGStreamer::updateStates() > m_readyState = MediaPlayer::HaveEnoughData; > m_paused = false; > >- if (m_buffering) { >+ if (m_buffering && !isLiveStream()) { > m_readyState = MediaPlayer::HaveCurrentData; > m_networkState = MediaPlayer::Loading; > >@@ -1182,7 +1192,22 @@ void MediaPlayerPrivateGStreamer::updateStates() > gst_element_state_get_name(pending)); > // Change in progress > >- if (!m_isStreaming && !m_buffering) >+ // On-disk buffering was attempted but the media is live. This >+ // can't work so disable on-disk buffering and reset the >+ // pipeline. >+ if (state == GST_STATE_READY && isLiveStream() && m_preload == MediaPlayer::Auto) { >+ setPreload(MediaPlayer::None); >+ gst_element_set_state(m_playBin, GST_STATE_NULL); >+ gst_element_set_state(m_playBin, GST_STATE_PAUSED); >+ } >+ >+ // A live stream was paused, reset the pipeline. >+ if (state == GST_STATE_PAUSED && pending == GST_STATE_PLAYING && isLiveStream()) { >+ gst_element_set_state(m_playBin, GST_STATE_NULL); >+ gst_element_set_state(m_playBin, GST_STATE_PLAYING); >+ } >+ >+ if (!isLiveStream() && !m_buffering) > return; > > if (m_seeking) { >@@ -1413,6 +1438,15 @@ void MediaPlayerPrivateGStreamer::durationChanged() > // HTMLMediaElement. > if (previousDuration && m_mediaDuration != previousDuration) > m_player->durationChanged(); >+ >+ if (m_preload == MediaPlayer::None && m_originalPreloadWasAutoAndWasOverridden) { >+ m_totalBytes = -1; >+ if (totalBytes() && !isLiveStream()) { >+ setPreload(MediaPlayer::Auto); >+ gst_element_set_state(m_playBin, GST_STATE_NULL); >+ gst_element_set_state(m_playBin, GST_STATE_PAUSED); >+ } >+ } > } > > bool MediaPlayerPrivateGStreamer::supportsMuting() const >@@ -1642,18 +1676,34 @@ PlatformMedia MediaPlayerPrivateGStreamer::platformMedia() const > return p; > } > >+MediaPlayer::MovieLoadType MediaPlayerPrivateGStreamer::movieLoadType() const >+{ >+ if (m_readyState == MediaPlayer::HaveNothing) >+ return MediaPlayer::Unknown; >+ >+ if (isLiveStream()) >+ return MediaPlayer::LiveStream; >+ >+ return MediaPlayer::Download; >+} >+ > void MediaPlayerPrivateGStreamer::setPreload(MediaPlayer::Preload preload) > { >- ASSERT(m_playBin); >+ m_originalPreloadWasAutoAndWasOverridden = m_preload != preload && m_preload == MediaPlayer::Auto; > > m_preload = preload; > >+ ASSERT(m_playBin); >+ > GstPlayFlags flags; > g_object_get(m_playBin, "flags", &flags, NULL); >- if (preload == MediaPlayer::None) >- g_object_set(m_playBin, "flags", flags & ~GST_PLAY_FLAG_DOWNLOAD, NULL); >- else >+ if (m_preload == MediaPlayer::Auto) { >+ LOG_VERBOSE(Media, "Enabling on-disk buffering"); > g_object_set(m_playBin, "flags", flags | GST_PLAY_FLAG_DOWNLOAD, NULL); >+ } else { >+ LOG_VERBOSE(Media, "Disabling on-disk buffering"); >+ g_object_set(m_playBin, "flags", flags & ~GST_PLAY_FLAG_DOWNLOAD, NULL); >+ } > > if (m_delayingLoad && m_preload != MediaPlayer::None) { > m_delayingLoad = false; >diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h >index f454fe3..d14d004 100644 >--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h >+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h >@@ -124,6 +124,8 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { > unsigned audioDecodedByteCount() const; > unsigned videoDecodedByteCount() const; > >+ MediaPlayer::MovieLoadType movieLoadType() const; >+ > private: > MediaPlayerPrivateGStreamer(MediaPlayer*); > >@@ -151,6 +153,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { > void processBufferingStats(GstMessage*); > > virtual String engineDescription() const { return "GStreamer"; } >+ bool isLiveStream() const { return m_isStreaming; } > > private: > MediaPlayer* m_player; >@@ -195,8 +198,11 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { > guint m_audioTimerHandler; > guint m_videoTimerHandler; > GRefPtr<GstElement> m_webkitAudioSink; >+ mutable long m_totalBytes; > GRefPtr<GstPad> m_videoSinkPad; > mutable IntSize m_videoSize; >+ KURL m_url; >+ bool m_originalPreloadWasAutoAndWasOverridden; > }; > } > >-- >1.7.10.4
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
mrobinson
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 90084
:
151150
|
151155
|
153237
|
155549
| 155559