Changeset 96310 in webkit


Ignore:
Timestamp:
Sep 29, 2011 1:03:31 AM (13 years ago)
Author:
Philippe Normand
Message:

[GStreamer] fullscreen video pause/play fails
https://bugs.webkit.org/show_bug.cgi?id=66936

Reviewed by Martin Robinson.

Don't use the identity element to avoid painting of the in-window
video. Instead simply make the sink aware of the fullscreen state
and ignore buffers if fullscreen and autovideosink are
active. Also fixed two deadlocks happening when a paused pipeline
is switched to fullscreen and when fullscreen is disabled for a
paused pipeline.

  • platform/graphics/gstreamer/GStreamerGWorld.cpp:

(WebCore::GStreamerGWorld::enterFullscreen):
(WebCore::GStreamerGWorld::exitFullscreen):

  • platform/graphics/gstreamer/GStreamerGWorld.h:

(WebCore::GStreamerGWorld::isFullscreen):

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

(WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin):

  • platform/graphics/gstreamer/VideoSinkGStreamer.cpp:

(webkit_video_sink_render):
(webkit_video_sink_new):

  • platform/graphics/gstreamer/VideoSinkGStreamer.h:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r96307 r96310  
     12011-09-29  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer] fullscreen video pause/play fails
     4        https://bugs.webkit.org/show_bug.cgi?id=66936
     5
     6        Reviewed by Martin Robinson.
     7
     8        Don't use the identity element to avoid painting of the in-window
     9        video. Instead simply make the sink aware of the fullscreen state
     10        and ignore buffers if fullscreen and autovideosink are
     11        active. Also fixed two deadlocks happening when a paused pipeline
     12        is switched to fullscreen and when fullscreen is disabled for a
     13        paused pipeline.
     14
     15        * platform/graphics/gstreamer/GStreamerGWorld.cpp:
     16        (WebCore::GStreamerGWorld::enterFullscreen):
     17        (WebCore::GStreamerGWorld::exitFullscreen):
     18        * platform/graphics/gstreamer/GStreamerGWorld.h:
     19        (WebCore::GStreamerGWorld::isFullscreen):
     20        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     21        (WebCore::MediaPlayerPrivateGStreamer::createGSTPlayBin):
     22        * platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
     23        (webkit_video_sink_render):
     24        (webkit_video_sink_new):
     25        * platform/graphics/gstreamer/VideoSinkGStreamer.h:
     26
    1272011-09-29  Tim Horton  <timothy_horton@apple.com>
    228
  • trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.cpp

    r95901 r96310  
    9090    g_object_get(m_pipeline, "video-sink", &videoSink.outPtr(), NULL);
    9191    GstElement* tee = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoTee");
    92     GstElement* valve = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoValve");
    93 
    94     g_object_set(valve, "drop-probability", 1.0, NULL);
    9592
    9693    // Add and link a queue, ffmpegcolorspace, videoscale and sink in the bin.
     
    110107    m_dynamicPadName = gst_pad_get_name(srcPad);
    111108
    112     // Roll new elements to pipeline state.
    113     gst_element_sync_state_with_parent(queue);
    114     gst_element_sync_state_with_parent(colorspace);
    115     gst_element_sync_state_with_parent(videoScale);
    116     gst_element_sync_state_with_parent(platformVideoSink);
    117 
     109    // Synchronize the new elements with pipeline state. If it's
     110    // paused limit the state change to pre-rolling.
     111    GstState state;
     112    gst_element_get_state(m_pipeline, &state, 0, 0);
     113    if (state < GST_STATE_PLAYING)
     114        state = GST_STATE_READY;
     115
     116    gst_element_set_state(platformVideoSink, state);
     117    gst_element_set_state(videoScale, state);
     118    gst_element_set_state(colorspace, state);
     119    gst_element_set_state(queue, state);
    118120    gst_object_unref(tee);
    119121
     
    161163    GstElement* videoScale = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoScale");
    162164
    163     GstElement* valve = gst_bin_get_by_name(GST_BIN(videoSink.get()), "videoValve");
    164 
    165     g_object_set(valve, "drop-probability", 0.0, NULL);
    166 
    167165    // Get pads to unlink and remove.
    168166    GstPad* srcPad = gst_element_get_static_pad(tee, m_dynamicPadName);
    169167    GstPad* sinkPad = gst_element_get_static_pad(queue, "sink");
    170168
    171     // Block data flow towards the pipeline branch to remove.
    172     gst_pad_set_blocked(srcPad, true);
    173 
    174     // Unlink and release request pad.
    175     gst_pad_unlink(srcPad, sinkPad);
    176     gst_element_release_request_pad(tee, srcPad);
     169    // Block data flow towards the pipeline branch to remove. No need
     170    // for pad blocking if the pipeline is paused.
     171    GstState state;
     172    gst_element_get_state(m_pipeline, &state, 0, 0);
     173    if (state < GST_STATE_PLAYING || gst_pad_set_blocked(srcPad, true)) {
     174
     175        // Unlink and release request pad.
     176        gst_pad_unlink(srcPad, sinkPad);
     177        gst_element_release_request_pad(tee, srcPad);
     178
     179        // Unlink, remove and cleanup queue, ffmpegcolorspace, videoScale and sink.
     180        gst_element_unlink_many(queue, colorspace, videoScale, platformVideoSink, NULL);
     181        gst_bin_remove_many(GST_BIN(videoSink.get()), queue, colorspace, videoScale, platformVideoSink, NULL);
     182        gst_element_set_state(platformVideoSink, GST_STATE_NULL);
     183        gst_element_set_state(videoScale, GST_STATE_NULL);
     184        gst_element_set_state(colorspace, GST_STATE_NULL);
     185        gst_element_set_state(queue, GST_STATE_NULL);
     186    }
     187
    177188    gst_object_unref(GST_OBJECT(srcPad));
    178189    gst_object_unref(GST_OBJECT(sinkPad));
    179190
    180     // Unlink, remove and cleanup queue, ffmpegcolorspace, videoScale and sink.
    181     gst_element_unlink_many(queue, colorspace, videoScale, platformVideoSink, NULL);
    182     gst_bin_remove_many(GST_BIN(videoSink.get()), queue, colorspace, videoScale, platformVideoSink, NULL);
    183     gst_element_set_state(queue, GST_STATE_NULL);
    184     gst_element_set_state(colorspace, GST_STATE_NULL);
    185     gst_element_set_state(videoScale, GST_STATE_NULL);
    186     gst_element_set_state(platformVideoSink, GST_STATE_NULL);
    187191    gst_object_unref(queue);
    188192    gst_object_unref(colorspace);
  • trunk/Source/WebCore/platform/graphics/gstreamer/GStreamerGWorld.h

    r95901 r96310  
    5252    void exitFullscreen();
    5353
     54    bool isFullscreen() const { return m_dynamicPadName; }
     55
    5456    void setWindowOverlay(GstMessage* message);
    5557    PlatformVideoWindow* platformVideoWindow() const { return m_videoWindow.get(); }
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r95799 r96310  
    16701670    g_signal_connect(m_playBin, "audio-changed", G_CALLBACK(mediaPlayerPrivateAudioChangedCallback), this);
    16711671
    1672     m_webkitVideoSink = webkit_video_sink_new();
     1672    m_webkitVideoSink = webkit_video_sink_new(m_gstGWorld.get());
    16731673
    16741674    g_signal_connect(m_webkitVideoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this);
     
    16771677    GstElement* videoTee = gst_element_factory_make("tee", "videoTee");
    16781678    GstElement* queue = gst_element_factory_make("queue", 0);
    1679     GstElement* identity = gst_element_factory_make("identity", "videoValve");
    16801679
    16811680    // Take ownership.
     
    16871686    // and initially block the data flow towards it and configure it
    16881687
    1689     gst_bin_add_many(GST_BIN(m_videoSinkBin), videoTee, queue, identity, NULL);
     1688    gst_bin_add_many(GST_BIN(m_videoSinkBin), videoTee, queue, NULL);
    16901689
    16911690    // Link a new src pad from tee to queue1.
     
    17291728
    17301729    // Faster elements linking.
    1731     gst_element_link_pads_full(queue, "src", identity, "sink", GST_PAD_LINK_CHECK_NOTHING);
    1732     gst_element_link_pads_full(identity, "src", actualVideoSink, "sink", GST_PAD_LINK_CHECK_NOTHING);
     1730    gst_element_link_pads_full(queue, "src", actualVideoSink, "sink", GST_PAD_LINK_CHECK_NOTHING);
    17331731
    17341732    // Add a ghostpad to the bin so it can proxy to tee.
  • trunk/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp

    r94155 r96310  
    6464    GMutex* buffer_mutex;
    6565    GCond* data_cond;
     66    WebCore::GStreamerGWorld* gstGWorld;
    6667
    6768    // If this is TRUE all processing should finish ASAP
     
    144145
    145146    if (priv->unlocked) {
     147        g_mutex_unlock(priv->buffer_mutex);
     148        return GST_FLOW_OK;
     149    }
     150
     151    // Ignore buffers if the video is already in fullscreen using
     152    // another sink.
     153    if (priv->gstGWorld->isFullscreen()) {
    146154        g_mutex_unlock(priv->buffer_mutex);
    147155        return GST_FLOW_OK;
     
    366374 * Return value: a #GstElement for the newly created video sink
    367375 */
    368 GstElement*
    369 webkit_video_sink_new(void)
    370 {
    371     return (GstElement*)g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0);
     376GstElement* webkit_video_sink_new(WebCore::GStreamerGWorld* gstGWorld)
     377{
     378    GstElement* element = GST_ELEMENT(g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0));
     379    WEBKIT_VIDEO_SINK(element)->priv->gstGWorld = gstGWorld;
     380    return element;
    372381}
    373382
  • trunk/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.h

    r94155 r96310  
    2323#if ENABLE(VIDEO) && USE(GSTREAMER)
    2424
     25#include "GStreamerGWorld.h"
    2526#include <glib-object.h>
    2627#include <gst/video/gstvideosink.h>
     
    7374};
    7475
     76
    7577GType       webkit_video_sink_get_type(void) G_GNUC_CONST;
    76 GstElement *webkit_video_sink_new(void);
     78GstElement *webkit_video_sink_new(WebCore::GStreamerGWorld*);
    7779
    7880G_END_DECLS
Note: See TracChangeset for help on using the changeset viewer.