[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.19-706-ge5415e9
philn at webkit.org
philn at webkit.org
Thu Feb 4 21:23:05 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit fe28ca8890da5647b2b3a772654cd64cbab9e1a3
Author: philn at webkit.org <philn at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Jan 21 09:43:18 2010 +0000
2010-01-13 Philippe Normand <pnormand at igalia.com>
Reviewed by Oliver Hunt.
[GTK] handle media redirections
https://bugs.webkit.org/show_bug.cgi?id=33539
Media redirections support.
* platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
(WebCore::mediaPlayerPrivateMessageCallback):
(WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
(WebCore::MediaPlayerPrivate::~MediaPlayerPrivate):
(WebCore::MediaPlayerPrivate::mediaLocationChanged):
(WebCore::MediaPlayerPrivate::loadNextLocation):
* platform/graphics/gtk/MediaPlayerPrivateGStreamer.h:
(WebCore::MediaPlayerPrivate::pipelineReset):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53617 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index dff61e4..9e94f0f 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,21 @@
+2010-01-13 Philippe Normand <pnormand at igalia.com>
+
+ Reviewed by Oliver Hunt.
+
+ [GTK] handle media redirections
+ https://bugs.webkit.org/show_bug.cgi?id=33539
+
+ Media redirections support.
+
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::mediaPlayerPrivateMessageCallback):
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
+ (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate):
+ (WebCore::MediaPlayerPrivate::mediaLocationChanged):
+ (WebCore::MediaPlayerPrivate::loadNextLocation):
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.h:
+ (WebCore::MediaPlayerPrivate::pipelineReset):
+
2010-01-21 No'am Rosenthal <noam.rosenthal at nokia.com>
Reviewed by Simon Hausmann.
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index f0ff519..1ed4941 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -36,6 +36,7 @@
#include "MediaPlayer.h"
#include "NotImplemented.h"
#include "ScrollView.h"
+#include "SecurityOrigin.h"
#include "TimeRanges.h"
#include "VideoSinkGStreamer.h"
#include "Widget.h"
@@ -59,9 +60,24 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
MediaPlayer::NetworkState error;
MediaPlayerPrivate* mp = reinterpret_cast<MediaPlayerPrivate*>(data);
gint percent = 0;
+ bool issueError = true;
+ bool attemptNextLocation = false;
+
+ if (message->structure) {
+ const gchar* messageTypeName = gst_structure_get_name(message->structure);
+
+ // Redirect messages are sent from elements, like qtdemux, to
+ // notify of the new location(s) of the media.
+ if (!g_strcmp0(messageTypeName, "redirect")) {
+ mp->mediaLocationChanged(message);
+ return true;
+ }
+ }
switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_ERROR:
+ if (mp && mp->pipelineReset())
+ break;
gst_message_parse_error(message, &err.outPtr(), &debug.outPtr());
LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message);
@@ -72,13 +88,18 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
|| err->code == GST_CORE_ERROR_MISSING_PLUGIN
|| err->code == GST_RESOURCE_ERROR_NOT_FOUND)
error = MediaPlayer::FormatError;
- else if (err->domain == GST_STREAM_ERROR)
+ else if (err->domain == GST_STREAM_ERROR) {
error = MediaPlayer::DecodeError;
- else if (err->domain == GST_RESOURCE_ERROR)
+ attemptNextLocation = true;
+ } else if (err->domain == GST_RESOURCE_ERROR)
error = MediaPlayer::NetworkError;
- if (mp)
- mp->loadingFailed(error);
+ if (mp) {
+ if (attemptNextLocation)
+ issueError = !mp->loadNextLocation();
+ if (issueError)
+ mp->loadingFailed(error);
+ }
break;
case GST_MESSAGE_EOS:
LOG_VERBOSE(Media, "End of Stream");
@@ -208,6 +229,9 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_isStreaming(false)
, m_size(IntSize())
, m_buffer(0)
+ , m_mediaLocations(0)
+ , m_mediaLocationCurrentIndex(0)
+ , m_resetPipeline(false)
, m_paused(true)
, m_seeking(false)
, m_playbackRate(1)
@@ -228,6 +252,11 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
gst_buffer_unref(m_buffer);
m_buffer = 0;
+ if (m_mediaLocations) {
+ gst_structure_free(m_mediaLocations);
+ m_mediaLocations = 0;
+ }
+
if (m_playBin) {
gst_element_set_state(m_playBin, GST_STATE_NULL);
gst_object_unref(GST_OBJECT(m_playBin));
@@ -628,6 +657,8 @@ void MediaPlayerPrivate::updateStates()
gst_element_state_get_name(state),
gst_element_state_get_name(pending));
+ m_resetPipeline = state <= GST_STATE_READY;
+
if (state == GST_STATE_READY)
m_readyState = MediaPlayer::HaveNothing;
else if (state == GST_STATE_PAUSED)
@@ -702,6 +733,105 @@ void MediaPlayerPrivate::updateStates()
}
}
+void MediaPlayerPrivate::mediaLocationChanged(GstMessage* message)
+{
+ if (m_mediaLocations)
+ gst_structure_free(m_mediaLocations);
+
+ if (message->structure) {
+ // This structure can contain:
+ // - both a new-location string and embedded locations structure
+ // - or only a new-location string.
+ m_mediaLocations = gst_structure_copy(message->structure);
+ const GValue* locations = gst_structure_get_value(m_mediaLocations, "locations");
+
+ if (locations)
+ m_mediaLocationCurrentIndex = gst_value_list_get_size(locations) -1;
+
+ loadNextLocation();
+ }
+}
+
+bool MediaPlayerPrivate::loadNextLocation()
+{
+ if (!m_mediaLocations)
+ return false;
+
+ const GValue* locations = gst_structure_get_value(m_mediaLocations, "locations");
+ const gchar* newLocation = 0;
+
+ if (!locations) {
+ // Fallback on new-location string.
+ newLocation = gst_structure_get_string(m_mediaLocations, "new-location");
+ if (!newLocation)
+ return false;
+ }
+
+ if (!newLocation) {
+ if (m_mediaLocationCurrentIndex < 0) {
+ m_mediaLocations = 0;
+ return false;
+ }
+
+ const GValue* location = gst_value_list_get_value(locations,
+ m_mediaLocationCurrentIndex);
+ const GstStructure* structure = gst_value_get_structure(location);
+
+ if (!structure) {
+ m_mediaLocationCurrentIndex--;
+ return false;
+ }
+
+ newLocation = gst_structure_get_string(structure, "new-location");
+ }
+
+ if (newLocation) {
+ // Found a candidate. new-location is not always an absolute url
+ // though. We need to take the base of the current url and
+ // append the value of new-location to it.
+
+ gchar* currentLocation = 0;
+ g_object_get(m_playBin, "uri", ¤tLocation, NULL);
+
+ KURL currentUrl(KURL(), currentLocation);
+ g_free(currentLocation);
+
+ KURL newUrl;
+
+ if (gst_uri_is_valid(newLocation))
+ newUrl = KURL(KURL(), newLocation);
+ else
+ newUrl = KURL(KURL(), currentUrl.baseAsString() + newLocation);
+
+ RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::create(currentUrl);
+ if (securityOrigin->canRequest(newUrl)) {
+ LOG_VERBOSE(Media, "New media url: %s", newUrl.string().utf8().data());
+
+ // Reset player states.
+ m_networkState = MediaPlayer::Loading;
+ m_player->networkStateChanged();
+ m_readyState = MediaPlayer::HaveNothing;
+ m_player->readyStateChanged();
+
+ // Reset pipeline state.
+ m_resetPipeline = true;
+ gst_element_set_state(m_playBin, GST_STATE_READY);
+
+ GstState state;
+ gst_element_get_state(m_playBin, &state, 0, 0);
+ if (state <= GST_STATE_READY) {
+ // Set the new uri and start playing.
+ g_object_set(m_playBin, "uri", newUrl.string().utf8().data(), NULL);
+ gst_element_set_state(m_playBin, GST_STATE_PLAYING);
+ return true;
+ }
+ }
+ }
+ m_mediaLocationCurrentIndex--;
+ return false;
+
+}
+
void MediaPlayerPrivate::loadStateChanged()
{
updateStates();
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
index 9043fa9..369a960 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
@@ -61,6 +61,7 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
void load(const String &url);
void cancelLoad();
+ bool loadNextLocation();
void play();
void pause();
@@ -91,6 +92,7 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
void setVisible(bool);
void setSize(const IntSize&);
+ void mediaLocationChanged(GstMessage*);
void loadStateChanged();
void sizeChanged();
void timeChanged();
@@ -105,6 +107,8 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
bool supportsFullscreen() const;
+ bool pipelineReset() const { return m_resetPipeline; }
+
private:
MediaPlayerPrivate(MediaPlayer*);
static MediaPlayerPrivateInterface* create(MediaPlayer* player);
@@ -138,7 +142,9 @@ class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
mutable bool m_isStreaming;
IntSize m_size;
GstBuffer* m_buffer;
-
+ GstStructure* m_mediaLocations;
+ gint m_mediaLocationCurrentIndex;
+ bool m_resetPipeline;
bool m_paused;
bool m_seeking;
float m_playbackRate;
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list