rendered paste bodydiff --git a/LayoutTests/platform/gtk/Skipped b/LayoutTests/platform/gtk/Skipped
index fc7a7d6..eeae147 100644
--- a/LayoutTests/platform/gtk/Skipped
+++ b/LayoutTests/platform/gtk/Skipped
@@ -3588,9 +3588,7 @@ media/video-source-error.html
# Tests timing out
media/controls-drag-timebar.html
-media/event-attributes.html
media/unsupported-rtsp.html
-media/video-played-collapse.html
# Tests generating new results
media/audio-controls-rendering.html
media/video-aspect-ratio.html
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index 11eb4d4..538b7fd 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -66,11 +66,11 @@ gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpo
LOG_VERBOSE(Media, "Error: %d, %s", err->code, err->message);
error = MediaPlayer::Empty;
- if (err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND ||
- err->code == GST_STREAM_ERROR_WRONG_TYPE ||
- err->code == GST_STREAM_ERROR_FAILED ||
- err->code == GST_CORE_ERROR_MISSING_PLUGIN ||
- err->code == GST_RESOURCE_ERROR_NOT_FOUND)
+ if (err->code == GST_STREAM_ERROR_CODEC_NOT_FOUND
+ || err->code == GST_STREAM_ERROR_WRONG_TYPE
+ || err->code == GST_STREAM_ERROR_FAILED
+ || err->code == GST_CORE_ERROR_MISSING_PLUGIN
+ || err->code == GST_RESOURCE_ERROR_NOT_FOUND)
error = MediaPlayer::FormatError;
else if (err->domain == GST_STREAM_ERROR)
error = MediaPlayer::DecodeError;
@@ -137,6 +137,7 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_videoSink(0)
, m_source(0)
, m_seekTime(0)
+ , m_changingRate(false)
, m_endTime(numeric_limits<float>::infinity())
, m_networkState(MediaPlayer::Empty)
, m_readyState(MediaPlayer::HaveNothing)
@@ -186,14 +187,26 @@ void MediaPlayerPrivate::load(const String& url)
void MediaPlayerPrivate::play()
{
- LOG_VERBOSE(Media, "Play");
- gst_element_set_state(m_playBin, GST_STATE_PLAYING);
+ GstState state;
+ GstState pending;
+
+ gst_element_get_state(m_playBin, &state, &pending, 250 * GST_NSECOND);
+ if (state != GST_STATE_PLAYING) {
+ LOG_VERBOSE(Media, "Play");
+ gst_element_set_state(m_playBin, GST_STATE_PLAYING);
+ }
}
void MediaPlayerPrivate::pause()
{
- LOG_VERBOSE(Media, "Pause");
- gst_element_set_state(m_playBin, GST_STATE_PAUSED);
+ GstState state;
+ GstState pending;
+
+ gst_element_get_state(m_playBin, &state, &pending, 250 * GST_NSECOND);
+ if (state != GST_STATE_PAUSED) {
+ LOG_VERBOSE(Media, "Pause");
+ gst_element_set_state(m_playBin, GST_STATE_PAUSED);
+ }
}
float MediaPlayerPrivate::duration() const
@@ -229,10 +242,17 @@ float MediaPlayerPrivate::currentTime() const
if (m_seeking)
return m_seekTime;
+ return playbackPosition(m_playBin);
+
+}
+
+float playbackPosition(GstElement* playbin)
+{
+
float ret = 0.0;
GstQuery* query = gst_query_new_position(GST_FORMAT_TIME);
- if (!gst_element_query(m_playBin, query)) {
+ if (!gst_element_query(playbin, query)) {
LOG_VERBOSE(Media, "Position query failed...");
gst_query_unref(query);
return ret;
@@ -269,6 +289,7 @@ void MediaPlayerPrivate::seek(float time)
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE))
LOG_VERBOSE(Media, "Seek to %f failed", time);
else {
+ gst_element_get_state(m_playBin, 0, 0, 40 * GST_MSECOND);
m_seeking = true;
m_seekTime = sec;
}
@@ -320,10 +341,10 @@ IntSize MediaPlayerPrivate::naturalSize() const
gfloat pixelAspectRatio;
gint pixelAspectRatioNumerator, pixelAspectRatioDenominator;
- if (!GST_IS_CAPS(caps) || !gst_caps_is_fixed(caps) ||
- !gst_video_format_parse_caps(caps, NULL, &width, &height) ||
- !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
- &pixelAspectRatioDenominator)) {
+ if (!GST_IS_CAPS(caps) || !gst_caps_is_fixed(caps)
+ || !gst_video_format_parse_caps(caps, 0, &width, &height)
+ || !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
+ &pixelAspectRatioDenominator)) {
gst_object_unref(GST_OBJECT(pad));
return IntSize();
}
@@ -363,16 +384,36 @@ void MediaPlayerPrivate::setVolume(float volume)
void MediaPlayerPrivate::setRate(float rate)
{
- if (rate == 0.0) {
- gst_element_set_state(m_playBin, GST_STATE_PAUSED);
+ GstState state;
+ GstState pending;
+
+ gst_element_get_state(m_playBin,
+ &state, &pending, 250 * GST_NSECOND);
+ if (state != GST_STATE_PLAYING)
return;
- }
if (m_isStreaming)
return;
+ m_changingRate = true;
+ float currentPosition = playbackPosition(m_playBin);
+ GstSeekFlags flags = (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE);
+ gint64 start, end;
+
LOG_VERBOSE(Media, "Set Rate to %f", rate);
- seek(currentTime());
+ if (rate >= 0) {
+ start = currentPosition;
+ end = GST_CLOCK_TIME_NONE;
+ } else {
+ start = 0;
+ end = currentPosition;
+ }
+ if (!gst_element_seek(m_playBin, rate, GST_FORMAT_TIME, flags,
+ GST_SEEK_TYPE_SET, start,
+ GST_SEEK_TYPE_SET, end))
+ LOG_VERBOSE(Media, "Set rate to %f failed", rate);
+ else
+ gst_element_get_state(m_playBin, 0, 0, 40 * GST_MSECOND);
}
int MediaPlayerPrivate::dataRate() const
@@ -507,6 +548,11 @@ void MediaPlayerPrivate::updateStates()
} else
m_paused = true;
+ if (m_changingRate) {
+ m_player->rateChanged();
+ m_changingRate = false;
+ }
+
if (m_seeking) {
shouldUpdateAfterSeek = true;
m_seeking = false;
@@ -643,10 +689,10 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
double scale, gapHeight, gapWidth;
GstVideoFormat format;
- GstCaps *caps = gst_buffer_get_caps(m_buffer);
+ GstCaps* caps = gst_buffer_get_caps(m_buffer);
- if (G_UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height) ||
- !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator, &pixelAspectRatioDenominator))) {
+ if (G_UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height)
+ || !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator, &pixelAspectRatioDenominator))) {
gst_caps_unref(caps);
return;
}
@@ -676,7 +722,7 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
displayHeight *= doublePixelAspectRatioDenominator / doublePixelAspectRatioNumerator;
// Calculate the largest scale factor that would fill the target surface
- scale = MIN(rect.width() / displayWidth, rect.height() / displayHeight);
+ scale = std::min(rect.width() / displayWidth, rect.height() / displayHeight);
// And calculate the new display width/height
displayWidth *= scale;
displayHeight *= scale;
@@ -743,15 +789,15 @@ static HashSet<String> mimeTypeCache()
// by default. In that case, we should not consider these types supportable by GStreamer.
// Examples of what GStreamer can support but should not be added:
// text/plain, text/html, image/jpeg, application/xml
- if (g_str_equal(mimetype[0], "audio") ||
- g_str_equal(mimetype[0], "video") ||
- (g_str_equal(mimetype[0], "application") &&
- !ignoredApplicationSubtypes.contains(String(mimetype[1])))) {
+ if (g_str_equal(mimetype[0], "audio")
+ || g_str_equal(mimetype[0], "video")
+ || (g_str_equal(mimetype[0], "application")
+ && !ignoredApplicationSubtypes.contains(String(mimetype[1])))) {
cache.add(String(capability[0]));
// These formats are supported by GStreamer, but not correctly advertised
- if (g_str_equal(capability[0], "video/x-h264") ||
- g_str_equal(capability[0], "audio/x-m4a")) {
+ if (g_str_equal(capability[0], "video/x-h264")
+ || g_str_equal(capability[0], "audio/x-m4a")) {
cache.add(String("video/mp4"));
cache.add(String("audio/aac"));
}
@@ -766,7 +812,7 @@ static HashSet<String> mimeTypeCache()
// This is what we are handling: mpegversion=(int)1, layer=(int)[ 1, 3 ]
gchar** versionAndLayer = g_strsplit(capability[1], ",", 2);
- if (g_str_has_suffix (versionAndLayer[0], "(int)1")) {
+ if (g_str_has_suffix(versionAndLayer[0], "(int)1")) {
for (int i = 0; versionAndLayer[1][i] != '\0'; i++) {
if (versionAndLayer[1][i] == '1')
cache.add(String("audio/mp1"));
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
index 3f0f29a..299e6cf 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
@@ -39,14 +39,15 @@ typedef struct _GstBus GstBus;
namespace WebCore {
- class GraphicsContext;
- class IntSize;
- class IntRect;
- class String;
+class GraphicsContext;
+class IntSize;
+class IntRect;
+class String;
- gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
+gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
+float playbackPosition(GstElement* playbin);
- class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
+class MediaPlayerPrivate : public MediaPlayerPrivateInterface {
friend gboolean mediaPlayerPrivateMessageCallback(GstBus* bus, GstMessage* message, gpointer data);
friend void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivate* playerPrivate);
@@ -126,6 +127,7 @@ namespace WebCore {
GstElement* m_videoSink;
GstElement* m_source;
GstClockTime m_seekTime;
+ bool m_changingRate;
float m_endTime;
bool m_isEndReached;
MediaPlayer::NetworkState m_networkState;