Changeset 49401 in webkit
- Timestamp:
- Oct 9, 2009 12:37:40 PM (15 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r49400 r49401 1 2009-10-09 Philippe Normand <pnormand@igalia.com> 2 3 Reviewed by Gustavo Noronha. 4 5 [GTK] QoS support in the video sink 6 https://bugs.webkit.org/show_bug.cgi?id=29959 7 8 Removed the async buffer queue from the sink. Synchronize the 9 render method of the sink using a g_timeout_add() combined with a 10 gcond triggered when the buffer has been rendered. 11 Also fixed the video sink reference handling in the player, now 12 that the idle is not there anymore to mess up things. 13 14 * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp: 15 (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate): 16 (WebCore::MediaPlayerPrivate::createGSTPlayBin): 17 * platform/graphics/gtk/VideoSinkGStreamer.cpp: 18 (webkit_video_sink_init): 19 (webkit_video_sink_timeout_func): 20 (webkit_video_sink_render): 21 (webkit_video_sink_dispose): 22 (unlock_buffer_mutex): 23 (webkit_video_sink_unlock): 24 (webkit_video_sink_stop): 25 (webkit_video_sink_class_init): 26 1 27 2009-10-09 Dirk Schulze <krit@webkit.org> 2 28 -
trunk/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
r49019 r49401 159 159 } 160 160 161 static gboolean idleUnref(gpointer data)162 {163 g_object_unref(reinterpret_cast<GObject*>(data));164 return FALSE;165 }166 167 161 MediaPlayerPrivate::~MediaPlayerPrivate() 168 162 { … … 175 169 } 176 170 177 // FIXME: We should find a better way to handle the lifetime of this object; this is178 // needed because the object is sometimes being destroyed inbetween a call to179 // webkit_video_sink_render, and the idle it schedules. Adding a ref in180 // webkit_video_sink_render that would be balanced by the idle is not an option,181 // because in some cases the destruction of the sink may happen in time for the idle182 // to be removed from the queue, so it may not run. It would also cause lots of ref183 // counting churn (render/idle are called many times). This is an ugly race.184 171 if (m_videoSink) { 185 g_ idle_add(idleUnref,m_videoSink);172 g_object_unref(m_videoSink); 186 173 m_videoSink = 0; 187 174 } … … 816 803 m_videoSink = webkit_video_sink_new(m_surface); 817 804 818 // This ref is to protect the sink from being destroyed before we stop the idle it 819 // creates internally. See the comment in ~MediaPlayerPrivate. 820 g_object_ref(m_videoSink); 821 805 g_object_ref_sink(m_videoSink); 822 806 g_object_set(m_playBin, "video-sink", m_videoSink, NULL); 823 807 -
trunk/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
r49176 r49401 66 66 struct _WebKitVideoSinkPrivate { 67 67 cairo_surface_t* surface; 68 GAsyncQueue* async_queue;69 68 gboolean rgb_ordering; 70 69 int width; … … 74 73 int par_n; 75 74 int par_d; 75 GstBuffer* buffer; 76 guint timeout_id; 77 GMutex* buffer_mutex; 78 GCond* data_cond; 76 79 }; 77 80 … … 84 87 GST_BOILERPLATE_FULL(WebKitVideoSink, 85 88 webkit_video_sink, 86 Gst BaseSink,87 GST_TYPE_ BASE_SINK,89 GstVideoSink, 90 GST_TYPE_VIDEO_SINK, 88 91 _do_init); 89 92 … … 103 106 104 107 sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate); 105 priv->async_queue = g_async_queue_new(); 108 priv->data_cond = g_cond_new(); 109 priv->buffer_mutex = g_mutex_new(); 106 110 } 107 111 108 112 static gboolean 109 webkit_video_sink_ idle_func(gpointer data)113 webkit_video_sink_timeout_func(gpointer data) 110 114 { 111 115 WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(data); … … 118 122 gint bwidth, bheight; 119 123 120 if (!priv->async_queue) 124 g_mutex_lock(priv->buffer_mutex); 125 buffer = priv->buffer; 126 priv->timeout_id = 0; 127 128 if (!buffer || G_UNLIKELY(!GST_IS_BUFFER(buffer))) { 129 g_cond_signal(priv->data_cond); 130 g_mutex_unlock(priv->buffer_mutex); 121 131 return FALSE; 122 123 buffer = (GstBuffer*)g_async_queue_try_pop(priv->async_queue); 124 if (!buffer || G_UNLIKELY(!GST_IS_BUFFER(buffer))) 125 return FALSE; 132 } 126 133 127 134 caps = GST_BUFFER_CAPS(buffer); … … 129 136 GST_ERROR_OBJECT(sink, "Unknown video format in buffer caps '%s'", 130 137 gst_caps_to_string(caps)); 138 g_cond_signal(priv->data_cond); 139 g_mutex_unlock(priv->buffer_mutex); 131 140 return FALSE; 132 141 } … … 137 146 par = (gfloat) par_n / (gfloat) par_d; 138 147 139 // TODO: consider priv->rgb_ordering?140 148 cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer), 141 149 CAIRO_FORMAT_RGB24, … … 152 160 cairo_fill(cr); 153 161 cairo_destroy(cr); 162 154 163 gst_buffer_unref(buffer); 155 g_async_queue_unref(priv->async_queue);164 priv->buffer = 0; 156 165 157 166 g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0); 167 g_cond_signal(priv->data_cond); 168 g_mutex_unlock(priv->buffer_mutex); 158 169 159 170 return FALSE; … … 166 177 WebKitVideoSinkPrivate* priv = sink->priv; 167 178 168 g_async_queue_ref(priv->async_queue); 169 g_async_queue_push(priv->async_queue, gst_buffer_ref(buffer)); 170 g_idle_add_full(G_PRIORITY_HIGH_IDLE, webkit_video_sink_idle_func, sink, 0); 171 179 g_mutex_lock(priv->buffer_mutex); 180 priv->buffer = gst_buffer_ref(buffer); 181 182 // Use HIGH_IDLE+20 priority, like Gtk+ for redrawing operations. 183 priv->timeout_id = g_timeout_add_full(G_PRIORITY_HIGH_IDLE + 20, 0, 184 webkit_video_sink_timeout_func, 185 gst_object_ref(sink), 186 (GDestroyNotify)gst_object_unref); 187 188 g_cond_wait(priv->data_cond, priv->buffer_mutex); 189 g_mutex_unlock(priv->buffer_mutex); 172 190 return GST_FLOW_OK; 173 191 } … … 226 244 } 227 245 228 if (priv->async_queue) { 229 g_async_queue_unref(priv->async_queue); 230 priv->async_queue = 0; 246 if (priv->data_cond) { 247 g_cond_free(priv->data_cond); 248 priv->data_cond = 0; 249 } 250 251 if (priv->buffer_mutex) { 252 g_mutex_free(priv->buffer_mutex); 253 priv->buffer_mutex = 0; 231 254 } 232 255 … … 235 258 236 259 static void 237 webkit_video_sink_finalize(GObject* object) 238 { 239 G_OBJECT_CLASS(parent_class)->finalize(object); 260 unlock_buffer_mutex(WebKitVideoSinkPrivate* priv) 261 { 262 g_mutex_lock(priv->buffer_mutex); 263 264 if (priv->buffer) { 265 gst_buffer_unref(priv->buffer); 266 priv->buffer = 0; 267 } 268 269 g_cond_signal(priv->data_cond); 270 g_mutex_unlock(priv->buffer_mutex); 271 272 } 273 274 static gboolean 275 webkit_video_sink_unlock(GstBaseSink* object) 276 { 277 WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object); 278 unlock_buffer_mutex(sink->priv); 279 GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock, 280 (object), TRUE); 240 281 } 241 282 … … 277 318 { 278 319 WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(base_sink)->priv; 279 280 g_async_queue_lock(priv->async_queue); 281 282 /* Remove all remaining objects from the queue */ 283 while (GstBuffer* buffer = (GstBuffer*)g_async_queue_try_pop_unlocked(priv->async_queue)) 284 gst_buffer_unref(buffer); 285 286 g_async_queue_unlock(priv->async_queue); 287 288 g_idle_remove_by_data(base_sink); 289 320 unlock_buffer_mutex(priv); 290 321 return TRUE; 291 322 } … … 303 334 304 335 gobject_class->dispose = webkit_video_sink_dispose; 305 gobject_class->finalize = webkit_video_sink_finalize; 306 336 337 gstbase_sink_class->unlock = webkit_video_sink_unlock; 307 338 gstbase_sink_class->render = webkit_video_sink_render; 308 339 gstbase_sink_class->preroll = webkit_video_sink_render; -
trunk/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
r46587 r49401 23 23 #include <cairo.h> 24 24 #include <glib-object.h> 25 #include <gst/ base/gstbasesink.h>25 #include <gst/video/gstvideosink.h> 26 26 27 27 G_BEGIN_DECLS … … 55 55 struct _WebKitVideoSink { 56 56 /*< private >*/ 57 Gst BaseSink parent;57 GstVideoSink parent; 58 58 WebKitVideoSinkPrivate *priv; 59 59 }; … … 61 61 struct _WebKitVideoSinkClass { 62 62 /*< private >*/ 63 Gst BaseSinkClass parent_class;63 GstVideoSinkClass parent_class; 64 64 65 65 /* Future padding */
Note: See TracChangeset
for help on using the changeset viewer.