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), 13.80 KB, created by
Philippe Normand
on 2012-07-07 17:37:30 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Philippe Normand
Created:
2012-07-07 17:37:30 PDT
Size:
13.80 KB
patch
obsolete
>From c22bac5e3d7fe056a1191d91d6f302fbcc59f901 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 | 44 ++++++++++ > .../gstreamer/MediaPlayerPrivateGStreamer.cpp | 92 ++++++++++++++++---- > .../gstreamer/MediaPlayerPrivateGStreamer.h | 12 ++- > 3 files changed, 131 insertions(+), 17 deletions(-) > >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 9945106..521133c 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,47 @@ >+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::cacheTotalBytes): New >+ method to cache the media total size. >+ (WebCore::MediaPlayerPrivateGStreamer::cacheTotalBytes): 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 >+ and if the byte size reported by the source element is null. >+ > 2012-07-06 Lauro Neto <lauro.neto@openbossa.org> > > [Qt] Avoid deep copy of QImage in GraphicsContext3D::getImageData() >diff --git a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp >index 132db0d..3b33a83 100644 >--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp >+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp >@@ -224,7 +224,7 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player) > , m_fillTimer(this, &MediaPlayerPrivateGStreamer::fillTimerFired) > , m_maxTimeLoaded(0) > , m_bufferingPercentage(0) >- , m_preload(MediaPlayer::Auto) >+ , m_preload(MediaPlayer::None) > , m_delayingLoad(false) > , m_mediaDurationKnown(true) > , m_maxTimeLoadedAtLastDidLoadingProgress(0) >@@ -235,6 +235,9 @@ MediaPlayerPrivateGStreamer::MediaPlayerPrivateGStreamer(MediaPlayer* player) > , m_audioTimerHandler(0) > , m_videoTimerHandler(0) > , m_webkitAudioSink(0) >+ , m_preloadSet(false) >+ , m_totalBytes(0) >+ , m_totalBytesCached(false) > { > if (initializeGStreamerAndRegisterWebKitElements()) > createGSTPlayBin(); >@@ -292,6 +295,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 +411,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(); > } > >@@ -627,7 +631,7 @@ void MediaPlayerPrivateGStreamer::setRate(float rate) > || (pending == GST_STATE_PAUSED)) > return; > >- if (m_isStreaming) >+ if (isLiveStream()) > return; > > m_playbackRate = rate; >@@ -685,7 +689,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) >@@ -716,7 +720,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(); >@@ -742,12 +746,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"); > >@@ -809,7 +814,7 @@ gboolean MediaPlayerPrivateGStreamer::handleMessage(GstMessage* message) > break; > case GST_MESSAGE_DURATION: > LOG_VERBOSE(Media, "Duration changed"); >- durationChanged(); >+ durationChanged(true); > break; > default: > LOG_VERBOSE(Media, "Unhandled GStreamer message type: %s", >@@ -871,7 +876,7 @@ void MediaPlayerPrivateGStreamer::fillTimerFired(Timer<MediaPlayerPrivateGStream > LOG_VERBOSE(Media, "[Buffering] Download buffer filled up to %f%%", fillStatus); > > if (!m_mediaDuration) >- durationChanged(); >+ durationChanged(false); > > // Update maxTimeLoaded only if the media duration is > // available. Otherwise we can't compute it. >@@ -932,12 +937,24 @@ bool MediaPlayerPrivateGStreamer::didLoadingProgress() const > return didLoadingProgress; > } > >+bool MediaPlayerPrivateGStreamer::cacheTotalBytes() >+{ >+ if (m_totalBytes) >+ return false; >+ m_totalBytes = totalBytes(); >+ m_totalBytesCached = true; >+ return true; >+} >+ > unsigned MediaPlayerPrivateGStreamer::totalBytes() const > { >- if (!m_source) >+ if (m_errorOccured) > return 0; > >- if (m_errorOccured) >+ if (m_totalBytesCached) >+ return m_totalBytes; >+ >+ if (!m_source) > return 0; > > GstFormat fmt = GST_FORMAT_BYTES; >@@ -1143,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; > >@@ -1175,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) { >@@ -1396,8 +1428,9 @@ void MediaPlayerPrivateGStreamer::cacheDuration() > m_mediaDuration = newDuration; > } > >-void MediaPlayerPrivateGStreamer::durationChanged() >+void MediaPlayerPrivateGStreamer::durationChanged(bool attemptTotalBytesCache) > { >+ > float previousDuration = m_mediaDuration; > > cacheDuration(); >@@ -1406,6 +1439,14 @@ void MediaPlayerPrivateGStreamer::durationChanged() > // HTMLMediaElement. > if (previousDuration && m_mediaDuration != previousDuration) > m_player->durationChanged(); >+ >+ // We need to know the total amount of bytes occupied by the >+ // media, especially if on-disk buffering is requested. >+ if (attemptTotalBytesCache && cacheTotalBytes() && totalBytes() && !isLiveStream() && m_initialPreload == MediaPlayer::Auto) { >+ setPreload(m_initialPreload); >+ gst_element_set_state(m_playBin, GST_STATE_NULL); >+ gst_element_set_state(m_playBin, GST_STATE_PAUSED); >+ } > } > > bool MediaPlayerPrivateGStreamer::supportsMuting() const >@@ -1635,18 +1676,37 @@ PlatformMedia MediaPlayerPrivateGStreamer::platformMedia() const > return p; > } > >+MediaPlayer::MovieLoadType MediaPlayerPrivateGStreamer::movieLoadType() const >+{ >+ if (m_readyState < MediaPlayer::HaveMetadata) >+ return MediaPlayer::Unknown; >+ >+ if (isLiveStream()) >+ return MediaPlayer::LiveStream; >+ >+ return MediaPlayer::Download; >+} >+ > void MediaPlayerPrivateGStreamer::setPreload(MediaPlayer::Preload preload) > { >- ASSERT(m_playBin); >+ if (!m_preloadSet) { >+ m_preloadSet = true; >+ m_initialPreload = preload; >+ } > > m_preload = preload; > >+ ASSERT(m_playBin); >+ > GstPlayFlags flags; > g_object_get(m_playBin, "flags", &flags, NULL); >- if (preload == MediaPlayer::None) >+ if (m_preload < MediaPlayer::Auto) { >+ LOG_VERBOSE(Media, "Disabling on-disk buffering"); > g_object_set(m_playBin, "flags", flags & ~GST_PLAY_FLAG_DOWNLOAD, NULL); >- else >+ } else if (!m_url.isLocalFile()) { >+ LOG_VERBOSE(Media, "Enabling 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 506942c..bdb7e3d 100644 >--- a/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h >+++ b/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h >@@ -92,6 +92,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { > float maxTimeSeekable() const; > bool didLoadingProgress() const; > unsigned totalBytes() const; >+ bool cacheTotalBytes(); > > void setVisible(bool); > void setSize(const IntSize&); >@@ -100,7 +101,7 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { > void sizeChanged(); > void timeChanged(); > void didEnd(); >- void durationChanged(); >+ void durationChanged(bool attemptTotalBytesCache); > void loadingFailed(MediaPlayer::NetworkState); > > void triggerRepaint(GstBuffer*); >@@ -124,6 +125,8 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { > unsigned audioDecodedByteCount() const; > unsigned videoDecodedByteCount() const; > >+ MediaPlayer::MovieLoadType movieLoadType() const; >+ > private: > MediaPlayerPrivateGStreamer(MediaPlayer*); > >@@ -150,6 +153,8 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { > > void processBufferingStats(GstMessage*); > >+ bool isLiveStream() const { return m_isStreaming || !totalBytes(); } >+ > private: > MediaPlayer* m_player; > GstElement* m_playBin; >@@ -193,7 +198,12 @@ class MediaPlayerPrivateGStreamer : public MediaPlayerPrivateInterface { > guint m_audioTimerHandler; > guint m_videoTimerHandler; > GRefPtr<GstElement> m_webkitAudioSink; >+ bool m_preloadSet; >+ unsigned m_totalBytes; >+ bool m_totalBytesCached; > GRefPtr<GstPad> m_videoSinkPad; >+ KURL m_url; >+ MediaPlayer::Preload m_initialPreload; > }; > } > >-- >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
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 90084
:
151150
|
151155
|
153237
|
155549
|
155559