aboutsummaryrefslogtreecommitdiffstats
path: root/ext
diff options
context:
space:
mode:
authorSreerenj Balachandran2011-11-02 06:51:13 -0500
committerNikhil Devshatwar2013-05-15 08:18:24 -0500
commitbd2f3ee9928e301bc8156323f9ac4b5313f54908 (patch)
tree88f580d0c9a633a5fb73b24654ab35ff4d00f422 /ext
parent82fa36802a44346a825400f89018cbb982fd04a2 (diff)
downloadgst-plugins-bad0-10-bd2f3ee9928e301bc8156323f9ac4b5313f54908.tar.gz
gst-plugins-bad0-10-bd2f3ee9928e301bc8156323f9ac4b5313f54908.tar.xz
gst-plugins-bad0-10-bd2f3ee9928e301bc8156323f9ac4b5313f54908.zip
More Fixes: * Adding buffer_alloc * perform buffer_damage before surface_attach * Fix typo, Remove Dead code etc.
Diffstat (limited to 'ext')
-rwxr-xr-xext/wayland/gstwaylandsink.c402
-rwxr-xr-xext/wayland/gstwaylandsink.h49
2 files changed, 298 insertions, 153 deletions
diff --git a/ext/wayland/gstwaylandsink.c b/ext/wayland/gstwaylandsink.c
index 43c9d46f2..a78f8fbb3 100755
--- a/ext/wayland/gstwaylandsink.c
+++ b/ext/wayland/gstwaylandsink.c
@@ -20,13 +20,7 @@
20 */ 20 */
21 21
22 22
23/* The waylandsink is currently just a prototype . It creates its own window and render the decoded video frames to that.*/ 23/* The waylandsink is creating its own window and render the decoded video frames to that.*/
24
25/* FixMe: Needs to add more synchronization stuffs */
26/* FixMe: Remove the extra memcopy by giving buffer to decoder with buffer_alloc*/
27/* FixMe: Add signals so that the application/compositor is responsible for rendering */
28/* FixMe: Add h/w decoding support: buffers/libva surface */
29/* FixMe: Add the interfaces */
30 24
31#ifdef HAVE_CONFIG_H 25#ifdef HAVE_CONFIG_H
32#include <config.h> 26#include <config.h>
@@ -48,7 +42,6 @@
48#include "gstwaylandsink.h" 42#include "gstwaylandsink.h"
49 43
50#include <wayland-client.h> 44#include <wayland-client.h>
51#include <wayland-egl.h>
52 45
53/* signals */ 46/* signals */
54enum 47enum
@@ -79,32 +72,36 @@ static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
79 "green_mask = (int) 16711680, " 72 "green_mask = (int) 16711680, "
80 "blue_mask = (int) -16777216," 73 "blue_mask = (int) -16777216,"
81 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ] ")); 74 "width = (int) [ 1, MAX ], " "height = (int) [ 1, MAX ] "));
82 75GType gst_wlbuffer_get_type (void);
83GType gst_wayland_sink_get_type (void);
84 76
85/*Fixme: Add more interfaces */ 77/*Fixme: Add more interfaces */
86GST_BOILERPLATE (GstWayLandSink, gst_wayland_sink, GstVideoSink, 78GST_BOILERPLATE (GstWaylandSink, gst_wayland_sink, GstVideoSink,
87 GST_TYPE_VIDEO_SINK); 79 GST_TYPE_VIDEO_SINK);
88 80
81static void gst_wlbuffer_finalize (GstWlBuffer * wbuffer);
82static GstBufferClass *wlbuffer_parent_class = NULL;
83
89static void gst_wayland_sink_get_property (GObject * object, 84static void gst_wayland_sink_get_property (GObject * object,
90 guint prop_id, GValue * value, GParamSpec * pspec); 85 guint prop_id, GValue * value, GParamSpec * pspec);
91static void gst_wayland_sink_set_property (GObject * object, 86static void gst_wayland_sink_set_property (GObject * object,
92 guint prop_id, const GValue * value, GParamSpec * pspec); 87 guint prop_id, const GValue * value, GParamSpec * pspec);
93static void gst_wayland_sink_dispose (GObject * object); 88static void gst_wayland_sink_dispose (GObject * object);
94static void gst_wayland_sink_finalize (GObject * object); 89static void gst_wayland_sink_finalize (GObject * object);
95
96static GstCaps *gst_wayland_sink_get_caps (GstBaseSink * bsink); 90static GstCaps *gst_wayland_sink_get_caps (GstBaseSink * bsink);
97static gboolean gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps); 91static gboolean gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps);
98static gboolean gst_wayland_sink_start (GstBaseSink * bsink); 92static gboolean gst_wayland_sink_start (GstBaseSink * bsink);
99static gboolean gst_wayland_sink_stop (GstBaseSink * bsink); 93static gboolean gst_wayland_sink_stop (GstBaseSink * bsink);
100static gboolean gst_wayland_sink_unlock (GstBaseSink * bsink); 94static GstFlowReturn
101static gboolean gst_wayland_sink_unlock_stop (GstBaseSink * bsink); 95gst_wayland_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
96 GstCaps * caps, GstBuffer ** buf);
102static gboolean gst_wayland_sink_preroll (GstBaseSink * bsink, 97static gboolean gst_wayland_sink_preroll (GstBaseSink * bsink,
103 GstBuffer * buffer); 98 GstBuffer * buffer);
104static gboolean gst_wayland_sink_render (GstBaseSink * bsink, 99static gboolean gst_wayland_sink_render (GstBaseSink * bsink,
105 GstBuffer * buffer); 100 GstBuffer * buffer);
101static void gst_wayland_bufferpool_clear (GstWaylandSink * sink);
102static void
103gst_wayland_buffer_destroy (GstWaylandSink * sink, GstWlBuffer * buffer);
106 104
107static gboolean create_shm_buffer (GstWayLandSink * sink);
108static int event_mask_update (uint32_t mask, void *data); 105static int event_mask_update (uint32_t mask, void *data);
109static void sync_callback (void *data); 106static void sync_callback (void *data);
110static struct display *create_display (void); 107static struct display *create_display (void);
@@ -113,10 +110,75 @@ static void display_handle_global (struct wl_display *display, uint32_t id,
113static void compositor_handle_visual (void *data, 110static void compositor_handle_visual (void *data,
114 struct wl_compositor *compositor, uint32_t id, uint32_t token); 111 struct wl_compositor *compositor, uint32_t id, uint32_t token);
115static void redraw (struct wl_surface *surface, void *data, uint32_t time); 112static void redraw (struct wl_surface *surface, void *data, uint32_t time);
116static struct window *create_window (GstWayLandSink * sink, 113static struct window *create_window (GstWaylandSink * sink,
117 struct display *display, int width, int height); 114 struct display *display, int width, int height);
118 115
119static guint gst_wayland_sink_signals[LAST_SIGNAL] = { 0 }; 116static void
117gst_wlbuffer_init (GstWlBuffer * buffer, gpointer g_class)
118{
119 buffer->wbuffer = NULL;
120 buffer->wlsink = NULL;
121}
122
123static void
124gst_wlbuffer_class_init (gpointer g_class, gpointer class_data)
125{
126 GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
127
128 wlbuffer_parent_class = g_type_class_peek_parent (g_class);
129
130 mini_object_class->finalize = (GstMiniObjectFinalizeFunction)
131 gst_wlbuffer_finalize;
132}
133
134GType
135gst_wlbuffer_get_type (void)
136{
137 static GType _gst_wlbuffer_type;
138
139 if (G_UNLIKELY (_gst_wlbuffer_type == 0)) {
140 static const GTypeInfo wlbuffer_info = {
141 sizeof (GstBufferClass),
142 NULL,
143 NULL,
144 gst_wlbuffer_class_init,
145 NULL,
146 NULL,
147 sizeof (GstWlBuffer),
148 0,
149 (GInstanceInitFunc) gst_wlbuffer_init,
150 NULL
151 };
152 _gst_wlbuffer_type = g_type_register_static (GST_TYPE_BUFFER,
153 "GstWlBuffer", &wlbuffer_info, 0);
154 }
155 return _gst_wlbuffer_type;
156}
157
158static void
159gst_wlbuffer_finalize (GstWlBuffer * wbuffer)
160{
161 GstWaylandSink *sink = NULL;
162
163 g_return_if_fail (wbuffer != NULL);
164
165 GST_DEBUG_OBJECT (sink, "Finalizing the WlBuffer");
166 sink = wbuffer->wlsink;
167 if (!sink) {
168 GST_WARNING_OBJECT (wbuffer, "No sink..");
169 goto beach;
170 }
171
172 GST_DEBUG_OBJECT (sink, "recycling buffer %p in pool", wbuffer);
173 /* need to increment the refcount again to recycle */
174 gst_buffer_ref (GST_BUFFER (wbuffer));
175 g_mutex_lock (sink->pool_lock);
176 sink->buffer_pool = g_slist_prepend (sink->buffer_pool, wbuffer);
177 g_mutex_unlock (sink->pool_lock);
178
179beach:
180 return;
181}
120 182
121static void 183static void
122gst_wayland_sink_base_init (gpointer gclass) 184gst_wayland_sink_base_init (gpointer gclass)
@@ -134,7 +196,7 @@ gst_wayland_sink_base_init (gpointer gclass)
134} 196}
135 197
136static void 198static void
137gst_wayland_sink_class_init (GstWayLandSinkClass * klass) 199gst_wayland_sink_class_init (GstWaylandSinkClass * klass)
138{ 200{
139 GObjectClass *gobject_class; 201 GObjectClass *gobject_class;
140 GstElementClass *gstelement_class; 202 GstElementClass *gstelement_class;
@@ -152,50 +214,39 @@ gst_wayland_sink_class_init (GstWayLandSinkClass * klass)
152 gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_get_caps); 214 gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_get_caps);
153 gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_set_caps); 215 gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_wayland_sink_set_caps);
154 gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_wayland_sink_start); 216 gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_wayland_sink_start);
155 gstbasesink_class->unlock = GST_DEBUG_FUNCPTR (gst_wayland_sink_unlock); 217 gstbasesink_class->buffer_alloc =
156 gstbasesink_class->unlock_stop = 218 GST_DEBUG_FUNCPTR (gst_wayland_sink_buffer_alloc);
157 GST_DEBUG_FUNCPTR (gst_wayland_sink_unlock_stop);
158 gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_wayland_sink_stop); 219 gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_wayland_sink_stop);
159 gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_wayland_sink_preroll); 220 gstbasesink_class->preroll = GST_DEBUG_FUNCPTR (gst_wayland_sink_preroll);
160 gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_wayland_sink_render); 221 gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_wayland_sink_render);
161 222
162 g_object_class_install_property (gobject_class, PROP_WAYLAND_DISPLAY, 223 g_object_class_install_property (gobject_class, PROP_WAYLAND_DISPLAY,
163 g_param_spec_pointer ("wayland-display", "WayLand Display", 224 g_param_spec_pointer ("wayland-display", "Wayland Display",
164 "WayLand Display id created by the application ", 225 "Wayland Display id created by the application ",
165 G_PARAM_READWRITE)); 226 G_PARAM_READWRITE));
166 227
167 /*Fixme: not using now */
168 gst_wayland_sink_signals[SIGNAL_FRAME_READY] =
169 g_signal_new ("frame-ready",
170 G_TYPE_FROM_CLASS (klass),
171 G_SIGNAL_RUN_LAST,
172 0, NULL, NULL,
173 g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
174
175 parent_class = g_type_class_peek_parent (klass); 228 parent_class = g_type_class_peek_parent (klass);
176} 229}
177 230
178static void 231static void
179gst_wayland_sink_init (GstWayLandSink * sink, 232gst_wayland_sink_init (GstWaylandSink * sink,
180 GstWayLandSinkClass * wayland_sink_class) 233 GstWaylandSinkClass * wayland_sink_class)
181{ 234{
182 235
183 sink->caps = NULL; 236 sink->caps = NULL;
184 237
185 sink->buffer_cond = g_cond_new (); 238 sink->pool_lock = g_mutex_new ();
186 sink->buffer_lock = g_mutex_new (); 239 sink->buffer_pool = NULL;
187 240
188 sink->wayland_cond = g_cond_new ();
189 sink->wayland_lock = g_mutex_new (); 241 sink->wayland_lock = g_mutex_new ();
190 242
191 sink->render_finish = TRUE;
192} 243}
193 244
194static void 245static void
195gst_wayland_sink_get_property (GObject * object, 246gst_wayland_sink_get_property (GObject * object,
196 guint prop_id, GValue * value, GParamSpec * pspec) 247 guint prop_id, GValue * value, GParamSpec * pspec)
197{ 248{
198 GstWayLandSink *sink = GST_WAYLAND_SINK (object); 249 GstWaylandSink *sink = GST_WAYLAND_SINK (object);
199 250
200 switch (prop_id) { 251 switch (prop_id) {
201 case PROP_WAYLAND_DISPLAY: 252 case PROP_WAYLAND_DISPLAY:
@@ -211,7 +262,7 @@ static void
211gst_wayland_sink_set_property (GObject * object, 262gst_wayland_sink_set_property (GObject * object,
212 guint prop_id, const GValue * value, GParamSpec * pspec) 263 guint prop_id, const GValue * value, GParamSpec * pspec)
213{ 264{
214 GstWayLandSink *sink = GST_WAYLAND_SINK (object); 265 GstWaylandSink *sink = GST_WAYLAND_SINK (object);
215 266
216 switch (prop_id) { 267 switch (prop_id) {
217 case PROP_WAYLAND_DISPLAY: 268 case PROP_WAYLAND_DISPLAY:
@@ -226,24 +277,29 @@ gst_wayland_sink_set_property (GObject * object,
226static void 277static void
227gst_wayland_sink_dispose (GObject * object) 278gst_wayland_sink_dispose (GObject * object)
228{ 279{
229 GstWayLandSink *sink = GST_WAYLAND_SINK (object);
230
231 G_OBJECT_CLASS (parent_class)->dispose (object); 280 G_OBJECT_CLASS (parent_class)->dispose (object);
232} 281}
233 282
234static void 283static void
235gst_wayland_sink_finalize (GObject * object) 284gst_wayland_sink_finalize (GObject * object)
236{ 285{
237 GstWayLandSink *sink = GST_WAYLAND_SINK (object); 286 GstWaylandSink *sink = GST_WAYLAND_SINK (object);
238 287
288 GST_DEBUG_OBJECT (sink, "Finalizing the sink..");
239 gst_caps_replace (&sink->caps, NULL); 289 gst_caps_replace (&sink->caps, NULL);
240 290
241 free (sink->display); 291 free (sink->display);
242 free (sink->window); 292 free (sink->window);
243 293
244 g_cond_free (sink->buffer_cond); 294 if (sink->pool_lock) {
245 g_cond_free (sink->wayland_cond); 295 g_mutex_free (sink->pool_lock);
246 g_mutex_free (sink->buffer_lock); 296 sink->pool_lock = NULL;
297 }
298
299 if (sink->buffer_pool) {
300 gst_wayland_bufferpool_clear (sink);
301 }
302
247 g_mutex_free (sink->wayland_lock); 303 g_mutex_free (sink->wayland_lock);
248 304
249 G_OBJECT_CLASS (parent_class)->finalize (object); 305 G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -306,6 +362,7 @@ create_display (void)
306 362
307 wl_display_add_global_listener (display->display, 363 wl_display_add_global_listener (display->display,
308 display_handle_global, display); 364 display_handle_global, display);
365
309 wl_display_iterate (display->display, WL_DISPLAY_READABLE); 366 wl_display_iterate (display->display, WL_DISPLAY_READABLE);
310 367
311 wl_display_get_fd (display->display, event_mask_update, display); 368 wl_display_get_fd (display->display, event_mask_update, display);
@@ -319,29 +376,38 @@ create_display (void)
319 return display; 376 return display;
320} 377}
321 378
322static gboolean 379static GstWlBuffer *
323create_shm_buffer (GstWayLandSink * sink) 380wayland_buffer_create (GstWaylandSink * sink)
324{ 381{
325 char filename[] = "/tmp/wayland-shm-XXXXXX"; 382 char filename[1024];
326 struct wl_buffer *wbuffer; 383 int fd, size, stride;
327 int i, fd, size, stride;
328 static void *data; 384 static void *data;
385 static int init = 0;
386 GstWlBuffer *wbuffer;
329 387
330 GST_DEBUG_OBJECT (sink, "Creating wayland-shm buffers"); 388 GST_DEBUG_OBJECT (sink, "Creating wayland-shm buffers");
331 389
332 wl_display_iterate (sink->display->display, sink->display->mask); 390 wbuffer = (GstWlBuffer *) gst_mini_object_new (GST_TYPE_WLBUFFER);
391 wbuffer->wlsink = gst_object_ref (sink);
392
393 if (!init) {
394 wl_display_iterate (sink->display->display, sink->display->mask);
395 init++;
396 }
397
398 snprintf (filename, 256, "%s-%d-%s", "/tmp/wayland-shm", init, "XXXXXX");
333 399
334 fd = mkstemp (filename); 400 fd = mkstemp (filename);
335 if (fd < 0) { 401 if (fd < 0) {
336 fprintf (stderr, "open %s failed: %m\n", filename); 402 GST_ERROR_OBJECT (sink, "open %s failed:", filename);
337 exit (0); 403 exit (0);
338 } 404 }
339 405
340 stride = sink->width * 4; 406 stride = sink->video_width * 4;
341 size = stride * sink->height; 407 size = stride * sink->video_height;
342 408
343 if (ftruncate (fd, size) < 0) { 409 if (ftruncate (fd, size) < 0) {
344 fprintf (stderr, "ftruncate failed: %m\n"); 410 GST_ERROR_OBJECT (sink, "ftruncate failed:");
345 close (fd); 411 close (fd);
346 exit (0); 412 exit (0);
347 } 413 }
@@ -354,28 +420,102 @@ create_shm_buffer (GstWayLandSink * sink)
354 exit (0); 420 exit (0);
355 } 421 }
356 422
357 wbuffer = wl_shm_create_buffer (sink->display->shm, fd, 423 wbuffer->wbuffer = wl_shm_create_buffer (sink->display->shm, fd,
358 sink->width, sink->height, stride, sink->display->xrgb_visual); 424 sink->video_width, sink->video_height, stride,
425 sink->display->xrgb_visual);
359 426
360 close (fd); 427 close (fd);
361 428
362 sink->window->buffer = wbuffer; 429 GST_BUFFER_DATA (wbuffer) = data;
363 wl_surface_attach (sink->window->surface, sink->window->buffer, 0, 0); 430 GST_BUFFER_SIZE (wbuffer) = size;
364 sink->MapAddr = data; 431
432 return wbuffer;
433
434}
435
436static void
437gst_wayland_buffer_destroy (GstWaylandSink * sink, GstWlBuffer * buffer)
438{
439 if (buffer->wlsink) {
440 buffer->wlsink = NULL;
441 gst_object_unref (sink);
442 }
443
444 GST_MINI_OBJECT_CLASS (wlbuffer_parent_class)->finalize (GST_MINI_OBJECT
445 (buffer));
446}
447
448static void
449gst_wayland_bufferpool_clear (GstWaylandSink * sink)
450{
451 g_mutex_lock (sink->pool_lock);
452 while (sink->buffer_pool) {
453 GstWlBuffer *buffer = sink->buffer_pool->data;
454
455 sink->buffer_pool = g_slist_delete_link (sink->buffer_pool,
456 sink->buffer_pool);
457 gst_wayland_buffer_destroy (sink, buffer);
458 }
459 g_mutex_unlock (sink->pool_lock);
460}
461
462static GstFlowReturn
463gst_wayland_sink_buffer_alloc (GstBaseSink * bsink, guint64 offset, guint size,
464 GstCaps * caps, GstBuffer ** buf)
465{
466 GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
467 GstWlBuffer *buffer = NULL;
468 GstFlowReturn ret = GST_FLOW_OK;
469 GstStructure *structure = NULL;
470 GstCaps *desired_caps = NULL;
471
472 GST_LOG_OBJECT (sink, "a buffer of %u bytes was requested with caps "
473 "%" GST_PTR_FORMAT " and offset %" G_GUINT64_FORMAT, size, caps, offset);
474
475 desired_caps = gst_caps_copy (caps);
476 structure = gst_caps_get_structure (desired_caps, 0);
477
478 if (gst_structure_get_int (structure, "width", &sink->video_width) &&
479 gst_structure_get_int (structure, "height", &sink->video_height)) {
480 sink->bpp = size / sink->video_width / sink->video_height;
481 }
482
483 g_mutex_lock (sink->pool_lock);
484 while (sink->buffer_pool) {
485 buffer = (GstWlBuffer *) sink->buffer_pool->data;
486
487 if (buffer) {
488 sink->buffer_pool =
489 g_slist_delete_link (sink->buffer_pool, sink->buffer_pool);
490 } else {
491 break;
492 }
493 }
494
495 g_mutex_unlock (sink->pool_lock);
496
497 if (!buffer)
498 buffer = wayland_buffer_create (sink);
499
500 if (buffer)
501 gst_buffer_set_caps (GST_BUFFER (buffer), caps);
502
503 *buf = GST_BUFFER (buffer);
504
505 gst_caps_unref (desired_caps);
506
507 return ret;
365 508
366 return TRUE;
367} 509}
368 510
369static gboolean 511static gboolean
370gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) 512gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
371{ 513{
372 GstWayLandSink *sink = GST_WAYLAND_SINK (bsink); 514 GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
373 const GstStructure *structure; 515 const GstStructure *structure;
374 GstFlowReturn result = GST_FLOW_OK;
375 GstCaps *allowed_caps; 516 GstCaps *allowed_caps;
376 gboolean ret = TRUE; 517 gboolean ret = TRUE;
377 GstCaps *intersection; 518 GstCaps *intersection;
378 const GValue *fps;
379 519
380 GST_LOG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps); 520 GST_LOG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps);
381 521
@@ -394,8 +534,8 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
394 534
395 structure = gst_caps_get_structure (caps, 0); 535 structure = gst_caps_get_structure (caps, 0);
396 536
397 ret &= gst_structure_get_int (structure, "width", &sink->width); 537 ret &= gst_structure_get_int (structure, "width", &sink->video_width);
398 ret &= gst_structure_get_int (structure, "height", &sink->height); 538 ret &= gst_structure_get_int (structure, "height", &sink->video_height);
399 539
400 if (!ret) 540 if (!ret)
401 return FALSE; 541 return FALSE;
@@ -404,11 +544,6 @@ gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps)
404 544
405 gst_caps_unref (intersection); 545 gst_caps_unref (intersection);
406 546
407 if (!create_shm_buffer (sink)) {
408 GST_ERROR_OBJECT (sink, "Failed to create the wayland buffers..");
409 return FALSE;
410 }
411
412 return TRUE; 547 return TRUE;
413} 548}
414 549
@@ -429,7 +564,7 @@ static void
429redraw (struct wl_surface *surface, void *data, uint32_t time) 564redraw (struct wl_surface *surface, void *data, uint32_t time)
430{ 565{
431 566
432 GstWayLandSink *sink = (GstWayLandSink *) data; 567 GstWaylandSink *sink = (GstWaylandSink *) data;
433 g_mutex_lock (sink->wayland_lock); 568 g_mutex_lock (sink->wayland_lock);
434 569
435 sink->render_finish = TRUE; 570 sink->render_finish = TRUE;
@@ -438,12 +573,10 @@ redraw (struct wl_surface *surface, void *data, uint32_t time)
438} 573}
439 574
440static struct window * 575static struct window *
441create_window (GstWayLandSink * sink, struct display *display, int width, 576create_window (GstWaylandSink * sink, struct display *display, int width,
442 int height) 577 int height)
443{ 578{
444 struct window *window; 579 struct window *window;
445 struct wl_visual *visual;
446 void *data;
447 580
448 g_mutex_lock (sink->wayland_lock); 581 g_mutex_lock (sink->wayland_lock);
449 582
@@ -453,7 +586,7 @@ create_window (GstWayLandSink * sink, struct display *display, int width,
453 window->height = height; 586 window->height = height;
454 window->surface = wl_compositor_create_surface (display->compositor); 587 window->surface = wl_compositor_create_surface (display->compositor);
455 588
456 wl_shell_set_toplevel (display->shell, window->surface); 589 //wl_shell_set_toplevel (display->shell, window->surface);
457 590
458 g_mutex_unlock (sink->wayland_lock); 591 g_mutex_unlock (sink->wayland_lock);
459 return window; 592 return window;
@@ -463,7 +596,7 @@ create_window (GstWayLandSink * sink, struct display *display, int width,
463static gboolean 596static gboolean
464gst_wayland_sink_start (GstBaseSink * bsink) 597gst_wayland_sink_start (GstBaseSink * bsink)
465{ 598{
466 GstWayLandSink *sink = (GstWayLandSink *) bsink; 599 GstWaylandSink *sink = (GstWaylandSink *) bsink;
467 gboolean result = TRUE; 600 gboolean result = TRUE;
468 601
469 GST_DEBUG_OBJECT (sink, "start"); 602 GST_DEBUG_OBJECT (sink, "start");
@@ -477,42 +610,9 @@ gst_wayland_sink_start (GstBaseSink * bsink)
477} 610}
478 611
479static gboolean 612static gboolean
480gst_wayland_sink_unlock (GstBaseSink * bsink)
481{
482 GstWayLandSink *sink = (GstWayLandSink *) bsink;
483
484 GST_DEBUG_OBJECT (sink, "unlock");
485
486 g_mutex_lock (sink->buffer_lock);
487
488 sink->unlock = TRUE;
489
490 g_mutex_unlock (sink->buffer_lock);
491
492 return TRUE;
493}
494
495static gboolean
496gst_wayland_sink_unlock_stop (GstBaseSink * bsink)
497{
498 GstWayLandSink *sink = (GstWayLandSink *) bsink;
499
500 GST_DEBUG_OBJECT (sink, "unlock_stop");
501
502 g_mutex_lock (sink->buffer_lock);
503
504 sink->unlock = FALSE;
505
506 g_mutex_unlock (sink->buffer_lock);
507
508 return TRUE;
509}
510
511
512static gboolean
513gst_wayland_sink_stop (GstBaseSink * bsink) 613gst_wayland_sink_stop (GstBaseSink * bsink)
514{ 614{
515 GstWayLandSink *sink = (GstWayLandSink *) bsink; 615 GstWaylandSink *sink = (GstWaylandSink *) bsink;
516 616
517 GST_DEBUG_OBJECT (sink, "stop"); 617 GST_DEBUG_OBJECT (sink, "stop");
518 618
@@ -530,31 +630,67 @@ gst_wayland_sink_preroll (GstBaseSink * bsink, GstBuffer * buffer)
530static GstFlowReturn 630static GstFlowReturn
531gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer) 631gst_wayland_sink_render (GstBaseSink * bsink, GstBuffer * buffer)
532{ 632{
533 GstWayLandSink *sink = GST_WAYLAND_SINK (bsink); 633 GstWaylandSink *sink = GST_WAYLAND_SINK (bsink);
634 gboolean mem_cpy = TRUE;
635 GstVideoRectangle src, dst, res;
534 636
535 if (sink->render_finish) { 637 GST_LOG_OBJECT (sink,
536 GST_LOG_OBJECT (sink, 638 "render buffer %p, data = %p, timestamp = %" GST_TIME_FORMAT, buffer,
537 "render buffer %p, data = %p, timestamp = %" GST_TIME_FORMAT, buffer, 639 GST_BUFFER_DATA (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
538 GST_BUFFER_DATA (buffer),
539 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
540
541 /*Fixme: remove the memcpy and add memory allocation stuffs to buff_alloc */
542 guint8 *src = GST_BUFFER_DATA (buffer);
543 guint len = GST_BUFFER_SIZE (buffer) / sink->height;
544 640
545 /*for (i = 0; i < sink->height; i++) { 641 if (sink->render_finish) {
546 memcpy (data, src, len); 642 if (GST_IS_WLBUFFER (buffer)) {
547 src += len; 643 GstWlBuffer *tmp_buffer = (GstWlBuffer *) buffer;
548 data += len; 644
549 } */ 645 /* Does it have a waylandbuffer ? */
550 646 if (tmp_buffer->wbuffer) {
551 memcpy (sink->MapAddr, src, GST_BUFFER_SIZE (buffer)); 647 mem_cpy = FALSE;
648 GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we allocated "
649 "ourselves and it has a wayland buffer, no memcpy then", buffer);
650 sink->window->buffer = tmp_buffer->wbuffer;
651 } else {
652 /* No wayland buffer, that's a malloc */
653 GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we allocated "
654 "ourselves but it does not hold a wayland buffer", buffer);
655 }
656 } else {
657 /* Not our baby! */
658 GST_DEBUG_OBJECT (sink, "we have a buffer (%p) we did not allocate",
659 buffer);
660 }
661
662 if (mem_cpy) {
663
664 GstWlBuffer *wlbuf = wayland_buffer_create (sink);
665 /*Fixme: remove the memcpy and add memory allocation stuffs to buff_alloc */
666 /*guint8 *src = GST_BUFFER_DATA (buffer);
667 guint len = GST_BUFFER_SIZE (buffer) / sink->height;
668
669 for (i = 0; i < sink->height; i++) {
670 memcpy (data, src, len);
671 src += len;
672 data += len;
673 } */
674
675 memcpy (GST_BUFFER_DATA (wlbuf), GST_BUFFER_DATA (buffer),
676 GST_BUFFER_SIZE (buffer));
677 sink->window->buffer = wlbuf->wbuffer;
678 }
679
680 src.w = sink->video_width;
681 src.h = sink->video_height;
682 dst.w = sink->window->width;
683 dst.h = sink->window->height;
684
685 gst_video_sink_center_rect (src, dst, &res, FALSE);
552 686
553 sink->render_finish = FALSE; 687 sink->render_finish = FALSE;
554 688
555 wl_buffer_damage (sink->window->buffer, 0, 0, sink->width, sink->height); 689 wl_buffer_damage (sink->window->buffer, 0, 0, res.w, res.h);
690
691 wl_surface_attach (sink->window->surface, sink->window->buffer, 0, 0);
556 692
557 wl_surface_damage (sink->window->surface, 0, 0, sink->width, sink->height); 693 wl_surface_damage (sink->window->surface, 0, 0, res.w, res.h);
558 694
559 wl_display_frame_callback (sink->display->display, 695 wl_display_frame_callback (sink->display->display,
560 sink->window->surface, redraw, sink); 696 sink->window->surface, redraw, sink);
@@ -583,4 +719,4 @@ plugin_init (GstPlugin * plugin)
583GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, 719GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
584 GST_VERSION_MINOR, 720 GST_VERSION_MINOR,
585 "waylandsink", 721 "waylandsink",
586 "WayLand Video Sink", plugin_init, VERSION, "LGPL", "gst-wayland", "") 722 "Wayland Video Sink", plugin_init, VERSION, "LGPL", "gst-wayland", "")
diff --git a/ext/wayland/gstwaylandsink.h b/ext/wayland/gstwaylandsink.h
index 71d6cfc75..75c5a9ac8 100755
--- a/ext/wayland/gstwaylandsink.h
+++ b/ext/wayland/gstwaylandsink.h
@@ -26,20 +26,19 @@
26#include <gst/video/gstvideosink.h> 26#include <gst/video/gstvideosink.h>
27 27
28#include <wayland-client.h> 28#include <wayland-client.h>
29#include <wayland-egl.h>
30 29
31#define GST_TYPE_WAYLAND_SINK \ 30#define GST_TYPE_WAYLAND_SINK \
32 (gst_wayland_sink_get_type()) 31 (gst_wayland_sink_get_type())
33#define GST_WAYLAND_SINK(obj) \ 32#define GST_WAYLAND_SINK(obj) \
34 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WAYLAND_SINK,GstWayLandSink)) 33 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_WAYLAND_SINK,GstWaylandSink))
35#define GST_WAYLAND_SINK_CLASS(klass) \ 34#define GST_WAYLAND_SINK_CLASS(klass) \
36 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_WAYLAND_SINK,GstWayLandSinkClass)) 35 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_WAYLAND_SINK,GstWaylandSinkClass))
37#define GST_IS_WAYLAND_SINK(obj) \ 36#define GST_IS_WAYLAND_SINK(obj) \
38 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAYLAND_SINK)) 37 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_WAYLAND_SINK))
39#define GST_IS_WAYLAND_SINK_CLASS(klass) \ 38#define GST_IS_WAYLAND_SINK_CLASS(klass) \
40 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAYLAND_SINK)) 39 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_WAYLAND_SINK))
41#define GST_WAYLAND_SINK_GET_CLASS(inst) \ 40#define GST_WAYLAND_SINK_GET_CLASS(inst) \
42 (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_WAYLAND_SINK, GstWayLandSinkClass)) 41 (G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_WAYLAND_SINK, GstWaylandSinkClass))
43 42
44struct display 43struct display
45{ 44{
@@ -57,13 +56,26 @@ struct window
57 int width, height; 56 int width, height;
58 struct wl_surface *surface; 57 struct wl_surface *surface;
59 struct wl_buffer *buffer; 58 struct wl_buffer *buffer;
60 void *data;
61}; 59};
62 60
63typedef struct _GstWayLandSink GstWayLandSink; 61typedef struct _GstWaylandSink GstWaylandSink;
64typedef struct _GstWayLandSinkClass GstWayLandSinkClass; 62typedef struct _GstWaylandSinkClass GstWaylandSinkClass;
65 63
66struct _GstWayLandSink 64#define GST_TYPE_WLBUFFER (gst_wlbuffer_get_type())
65#define GST_IS_WLBUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_WLBUFFER))
66#define GST_WLBUFFER (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_WLBUFFER, GstWlBuffer))
67
68typedef struct _GstWlBuffer GstWlBuffer;
69
70struct _GstWlBuffer {
71 GstBuffer buffer; /* Extending GstBuffer */
72
73 struct wl_buffer *wbuffer;
74
75 GstWaylandSink *wlsink;
76};
77
78struct _GstWaylandSink
67{ 79{
68 80
69 GstVideoSink parent; 81 GstVideoSink parent;
@@ -73,30 +85,27 @@ struct _GstWayLandSink
73 struct display *display; 85 struct display *display;
74 struct window *window; 86 struct window *window;
75 87
76 GCond *buffer_cond; 88 GMutex *pool_lock;
77 GMutex *buffer_lock; 89 GSList *buffer_pool;
78 90
79 GCond *wayland_cond;
80 GMutex *wayland_lock; 91 GMutex *wayland_lock;
81 92
82 gboolean unlock; 93 gint video_width;
94 gint video_height;
95 guint bpp;
83 96
84 guint width, height, depth, size;
85
86 void *MapAddr;
87 gboolean render_finish; 97 gboolean render_finish;
88 98
89}; 99};
90 100
91struct _GstWayLandSinkClass 101struct _GstWaylandSinkClass
92{ 102{
93 GstVideoSinkClass parent; 103 GstVideoSinkClass parent;
94 104
95}; 105};
96 106
97GType 107GType gst_wayland_sink_get_type (void) G_GNUC_CONST;
98gst_wayland_sink_get_type (void) 108GType gst_dfbsurface_get_type (void);
99 G_GNUC_CONST;
100 109
101G_END_DECLS 110G_END_DECLS
102#endif /* __GST_WAYLAND_VIDEO_SINK_H__ */ 111#endif /* __GST_WAYLAND_VIDEO_SINK_H__ */