Initialize Tizen 2.3
[framework/multimedia/gst-plugins-ext0.10.git] / wearable / evasimagesink / src / gstevasimagesink.c
1 /*
2  * evasimagesink
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Sangchul Lee <sc11.lee@samsung.com>
7  *
8  * This library is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU Lesser General Public License as published by the
10  * Free Software Foundation; either version 2.1 of the License, or (at your option)
11  * any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but WITHOUT ANY
14  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16  * License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; if not, write to the Free Software Foundation, Inc., 51
20  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23
24 /**
25  * SECTION:element-evasimagesink
26  * Gstreamer Evas Video Sink - draw video on the given Evas Image Object
27  */
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32
33 #include <sys/types.h>
34 #include <gst/gst.h>
35 #include <gst/video/video.h>
36 #include <gst/video/gstvideosink.h>
37 #include <Evas.h>
38 #include <Ecore.h>
39 #include <Ecore_X.h>
40
41 #include "gstevasimagesink.h"
42
43 #define CAP_WIDTH "width"
44 #define CAP_HEIGHT "height"
45
46 GST_DEBUG_CATEGORY_STATIC (gst_evas_image_sink_debug);
47 #define GST_CAT_DEFAULT gst_evas_image_sink_debug
48
49 /* Enumerations */
50 enum
51 {
52         LAST_SIGNAL
53 };
54
55 enum
56 {
57         PROP_0,
58         PROP_EVAS_OBJECT,
59         PROP_EVAS_OBJECT_SHOW
60 };
61
62 enum
63 {
64         UPDATE_FALSE,
65         UPDATE_TRUE
66 };
67
68 #define COLOR_DEPTH 4
69 #define GL_X11_ENGINE "gl_x11"
70 #define DO_RENDER_FROM_FIMC 1
71 #define SIZE_FOR_UPDATE_VISIBILITY sizeof(gchar)
72
73 #define EVASIMAGESINK_SET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object, x_usr_data ) \
74 do \
75 { \
76         if (x_evas_image_object) { \
77                 evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event, x_usr_data); \
78                 evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event, x_usr_data); \
79         } \
80 }while(0)
81
82 #define EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object ) \
83 do \
84 { \
85         if (x_evas_image_object) { \
86                 evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_DEL, evas_callback_del_event); \
87                 evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_RESIZE, evas_callback_resize_event); \
88         } \
89 }while(0)
90
91 GMutex *instance_lock;
92 guint instance_lock_count;
93
94 static inline gboolean
95 is_evas_image_object (Evas_Object *obj)
96 {
97         const char *type;
98         if (!obj) {
99                 return FALSE;
100         }
101         type = evas_object_type_get (obj);
102         if (!type) {
103                 return FALSE;
104         }
105         if (strcmp (type, "image") == 0) {
106                 return TRUE;
107         }
108         return FALSE;
109 }
110
111 /* the capabilities of the inputs.
112  *
113  * BGRx format
114  */
115 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
116                 GST_PAD_SINK,
117                 GST_PAD_ALWAYS,
118                 GST_STATIC_CAPS (GST_VIDEO_CAPS_BGRx));
119
120 GST_BOILERPLATE (GstEvasImageSink, gst_evas_image_sink, GstVideoSink, GST_TYPE_VIDEO_SINK);
121
122 static void gst_evas_image_sink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
123 static void gst_evas_image_sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
124 static gboolean gst_evas_image_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps);
125 static GstFlowReturn gst_evas_image_sink_show_frame (GstVideoSink *video_sink, GstBuffer *buf);
126 static gboolean gst_evas_image_sink_event (GstBaseSink *sink, GstEvent *event);
127 static GstStateChangeReturn gst_evas_image_sink_change_state (GstElement *element, GstStateChange transition);
128 static void evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info);
129 static void evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info);
130
131 static void
132 gst_evas_image_sink_base_init (gpointer gclass)
133 {
134         GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
135
136         gst_element_class_set_details_simple (element_class,
137                 "EvasImageSink",
138                 "VideoSink",
139                 "Video sink element for evas image object",
140                 "Samsung Electronics <www.samsung.com>");
141
142         gst_element_class_add_pad_template (element_class,
143         gst_static_pad_template_get (&sink_factory));
144 }
145
146 static void
147 gst_evas_image_sink_class_init (GstEvasImageSinkClass *klass)
148 {
149         GObjectClass *gobject_class;
150         GstBaseSinkClass *gstbasesink_class;
151         GstVideoSinkClass *gstvideosink_class;
152         GstElementClass *gstelement_class;
153
154         gobject_class = (GObjectClass *) klass;
155         gstbasesink_class = GST_BASE_SINK_CLASS (klass);
156         gstvideosink_class = GST_VIDEO_SINK_CLASS (klass);
157         gstelement_class = (GstElementClass *) klass;
158
159         gobject_class->set_property = gst_evas_image_sink_set_property;
160         gobject_class->get_property = gst_evas_image_sink_get_property;
161
162         g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT,
163                 g_param_spec_pointer ("evas-object", "Destination Evas Object", "Destination evas image object", G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
164         g_object_class_install_property (gobject_class, PROP_EVAS_OBJECT_SHOW,
165                 g_param_spec_boolean ("visible", "Show Evas Object", "When disabled, evas object does not show", TRUE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
166
167         gstvideosink_class->show_frame = GST_DEBUG_FUNCPTR (gst_evas_image_sink_show_frame);
168         gstbasesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_evas_image_sink_set_caps);
169         gstbasesink_class->event = GST_DEBUG_FUNCPTR (gst_evas_image_sink_event);
170         gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_evas_image_sink_change_state);
171 }
172
173 static void
174 gst_evas_image_sink_fini (gpointer data, GObject *obj)
175 {
176         GST_DEBUG ("[ENTER]");
177
178         GstEvasImageSink *esink = GST_EVASIMAGESINK (obj);
179         if (!esink) {
180                 return;
181         }
182         if (esink->oldbuf) {
183                 gst_buffer_unref (esink->oldbuf);
184         }
185
186         if (esink->eo) {
187                 evas_object_image_data_set(esink->eo, NULL);
188         }
189
190         g_mutex_lock (instance_lock);
191         instance_lock_count--;
192         g_mutex_unlock (instance_lock);
193         if (instance_lock_count == 0) {
194                 g_mutex_free (instance_lock);
195                 instance_lock = NULL;
196         }
197
198         GST_DEBUG ("[LEAVE]");
199 }
200
201 static void
202 evas_image_sink_cb_pipe (void *data, void *buffer, unsigned int nbyte)
203 {
204         GstBuffer *buf;
205         GstEvasImageSink *esink = data;
206         void *img_data;
207
208         GST_DEBUG ("[ENTER]");
209
210         if (!esink || !esink->eo) {
211                 return;
212         }
213         if (nbyte == SIZE_FOR_UPDATE_VISIBILITY) {
214                 if(!esink->object_show) {
215                         evas_object_hide(esink->eo);
216                         GST_INFO ("object hide..");
217                 } else {
218                         evas_object_show(esink->eo);
219                         GST_INFO ("object show..");
220                 }
221                 GST_DEBUG ("[LEAVE]");
222                 return;
223         }
224         if (!buffer || nbyte != sizeof (GstBuffer *)) {
225                 return;
226         }
227         if (GST_STATE(esink) < GST_STATE_PAUSED) {
228                 GST_WARNING ("WRONG-STATE(%d) for rendering, skip this frame", GST_STATE(esink));
229                 return;
230         }
231
232         memcpy (&buf, buffer, sizeof (GstBuffer *));
233         if (!buf) {
234                 GST_ERROR ("There is no buffer");
235                 return;
236         }
237         if (esink->present_data_addr == -1) {
238                 /* if present_data_addr is -1, we don't use this member variable */
239         } else if (esink->present_data_addr != DO_RENDER_FROM_FIMC) {
240                 GST_WARNING ("skip rendering this buffer, present_data_addr:%d, DO_RENDER_FROM_FIMC:%d", esink->present_data_addr, DO_RENDER_FROM_FIMC);
241                 return;
242         }
243
244         MMTA_ACUM_ITEM_BEGIN("eavsimagesink _cb_pipe total", FALSE);
245
246         if ( !esink->is_evas_object_size_set && esink->w > 0 && esink->h > 0) {
247                         evas_object_image_size_set (esink->eo, esink->w, esink->h);
248                         GST_DEBUG("evas_object_image_size_set(), width(%d),height(%d)",esink->w,esink->h);
249                         esink->is_evas_object_size_set = TRUE;
250         }
251         if (esink->gl_zerocopy) {
252                 img_data = evas_object_image_data_get (esink->eo, EINA_TRUE);
253                 if (!img_data || !GST_BUFFER_DATA(buf)) {
254                         GST_WARNING ("Cannot get image data from evas object or cannot get gstbuffer data");
255                         evas_object_image_data_set(esink->eo, img_data);
256                 } else {
257                         GST_DEBUG ("img_data(%x), GST_BUFFER_DATA(buf):%x, esink->w(%d),esink->h(%d), esink->eo(%x)",img_data,GST_BUFFER_DATA(buf),esink->w,esink->h,esink->eo);
258                         __ta__("evasimagesink memcpy in _cb_pipe", memcpy (img_data, GST_BUFFER_DATA (buf), esink->w * esink->h * COLOR_DEPTH););
259                         evas_object_image_pixels_dirty_set (esink->eo, 1);
260                         evas_object_image_data_set(esink->eo, img_data);
261                 }
262                 gst_buffer_unref (buf);
263         } else {
264                 GST_DEBUG ("GST_BUFFER_DATA(buf):%x, esink->eo(%x)",GST_BUFFER_DATA(buf),esink->eo);
265                 evas_object_image_data_set (esink->eo, GST_BUFFER_DATA (buf));
266                 evas_object_image_pixels_dirty_set (esink->eo, 1);
267                 if (esink->oldbuf) {
268                         gst_buffer_unref(esink->oldbuf);
269                 }
270                 esink->oldbuf = buf;
271         }
272
273         MMTA_ACUM_ITEM_END("eavsimagesink _cb_pipe total", FALSE);
274
275         GST_DEBUG ("[LEAVE]");
276 }
277
278 static void
279 gst_evas_image_sink_init (GstEvasImageSink *esink, GstEvasImageSinkClass *gclass)
280 {
281         GST_DEBUG ("[ENTER]");
282
283         esink->eo = NULL;
284         esink->epipe = NULL;
285         esink->object_show = FALSE;
286         esink->update_visibility = UPDATE_FALSE;
287         esink->gl_zerocopy = FALSE;
288         esink->is_evas_object_size_set = FALSE;
289         esink->present_data_addr = -1;
290
291         if(!instance_lock) {
292                 instance_lock = g_mutex_new();
293         }
294         g_mutex_lock (instance_lock);
295         instance_lock_count++;
296         g_mutex_unlock (instance_lock);
297
298         g_object_weak_ref (G_OBJECT (esink), gst_evas_image_sink_fini, NULL);
299
300         GST_DEBUG ("[LEAVE]");
301 }
302
303 static void
304 evas_callback_del_event (void *data, Evas *e, Evas_Object *obj, void *event_info)
305 {
306         GST_DEBUG ("[ENTER]");
307
308         GstEvasImageSink *esink = data;
309         if (!esink) {
310                 return;
311         }
312
313         EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo);
314         if (esink->oldbuf) {
315                 gst_buffer_unref (esink->oldbuf);
316                 esink->oldbuf = NULL;
317         }
318
319         if (esink->eo) {
320                 evas_object_image_data_set(esink->eo, NULL);
321                 esink->eo = NULL;
322         }
323
324         GST_DEBUG ("[LEAVE]");
325 }
326
327 static void
328 evas_callback_resize_event (void *data, Evas *e, Evas_Object *obj, void *event_info)
329 {
330         int w = 0;
331         int h = 0;
332
333         GST_DEBUG ("[ENTER]");
334
335         GstEvasImageSink *esink = data;
336         if (!esink) {
337                 return;
338         }
339
340         evas_object_geometry_get(esink->eo, NULL, NULL, &w, &h);
341         if (!w || !h) {
342                 GST_WARNING ("evas object size (w:%d,h:%d) was not set",w,h);
343         } else {
344                 evas_object_image_fill_set(esink->eo, 0, 0, w, h);
345                 GST_DEBUG ("evas object fill set (w:%d,h:%d)",w,h);
346         }
347
348         GST_DEBUG ("[LEAVE]");
349 }
350
351 static int
352 evas_image_sink_get_size_from_caps (GstCaps *caps, int *w, int *h)
353 {
354         gboolean r;
355         int width, height;
356         GstStructure *s;
357
358         if (!caps || !w || !h) {
359                 return -1;
360         }
361         s = gst_caps_get_structure (caps, 0);
362         if (!s) {
363                 return -1;
364         }
365
366         r = gst_structure_get_int (s, CAP_WIDTH, &width);
367         if (r == FALSE) {
368                 return -1;
369         }
370
371         r = gst_structure_get_int (s, CAP_HEIGHT, &height);
372         if (r == FALSE) {
373                 return -1;
374         }
375
376         *w = width;
377         *h = height;
378         return 0;
379 }
380
381 static gboolean
382 is_zerocopy_supported (Evas *e)
383 {
384         Eina_List *engines, *l;
385         int cur_id;
386         int id;
387         char *name;
388
389         if (!e) {
390                 return FALSE;
391         }
392
393         engines = evas_render_method_list ();
394         if (!engines) {
395                 return FALSE;
396         }
397
398         cur_id = evas_output_method_get (e);
399
400         EINA_LIST_FOREACH (engines, l, name) {
401                 id = evas_render_method_lookup (name);
402                 if (name && id == cur_id) {
403                         if (!strcmp (name, GL_X11_ENGINE)) {
404                                 return TRUE;
405                         }
406                         break;
407                 }
408         }
409         return FALSE;
410 }
411
412 static int
413 evas_image_sink_event_parse_data (GstEvasImageSink *esink, GstEvent *event)
414 {
415         const GstStructure *st;
416         guint st_data_addr = 0;
417         gint st_data_width = 0;
418         gint st_data_height = 0;
419
420         g_return_val_if_fail (event != NULL, FALSE);
421         g_return_val_if_fail (esink != NULL, FALSE);
422
423         if (GST_EVENT_TYPE (event) != GST_EVENT_CUSTOM_DOWNSTREAM_OOB) {
424                 GST_WARNING ("it's not a custom downstream oob event");
425                 return -1;
426         }
427         st = gst_event_get_structure (event);
428         if (st == NULL || !gst_structure_has_name (st, "GstStructureForCustomEvent")) {
429                 GST_WARNING ("structure in a given event is not proper");
430                 return -1;
431         }
432         if (!gst_structure_get_uint (st, "data-addr", &st_data_addr)) {
433                 GST_WARNING ("parsing data-addr failed");
434                 return -1;
435         }
436         esink->present_data_addr = st_data_addr;
437
438         return 0;
439 }
440
441 static gboolean
442 gst_evas_image_sink_event (GstBaseSink *sink, GstEvent *event)
443 {
444         GstEvasImageSink *esink = GST_EVASIMAGESINK (sink);
445         GstMessage *msg;
446         gchar *str;
447
448         switch (GST_EVENT_TYPE (event)) {
449                 case GST_EVENT_FLUSH_START:
450                         GST_DEBUG ("GST_EVENT_FLUSH_START");
451                         break;
452                 case GST_EVENT_FLUSH_STOP:
453                         GST_DEBUG ("GST_EVENT_FLUSH_STOP");
454                         break;
455                 case GST_EVENT_EOS:
456                         GST_DEBUG ("GST_EVENT_EOS");
457                         break;
458                 case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
459                         if(!evas_image_sink_event_parse_data(esink, event)) {
460                                 GST_DEBUG ("GST_EVENT_CUSTOM_DOWNSTREAM_OOB, present_data_addr:%x",esink->present_data_addr);
461                         } else {
462                                 GST_ERROR ("evas_image_sink_event_parse_data() failed");
463                         }
464                         break;
465                 default:
466                         break;
467         }
468         if (GST_BASE_SINK_CLASS (parent_class)->event) {
469                 return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
470         } else {
471                 return TRUE;
472         }
473 }
474
475 static GstStateChangeReturn
476 gst_evas_image_sink_change_state (GstElement *element, GstStateChange transition)
477 {
478         GstStateChangeReturn ret_state = GST_STATE_CHANGE_SUCCESS;
479         GstEvasImageSink *esink = NULL;
480         esink = GST_EVASIMAGESINK(element);
481         int ret = 0;
482
483         if(!esink) {
484                 GST_ERROR("can not get evasimagesink from element");
485                 return GST_STATE_CHANGE_FAILURE;
486         }
487
488         switch (transition) {
489                 case GST_STATE_CHANGE_NULL_TO_READY:
490                         GST_INFO ("*** STATE_CHANGE_NULL_TO_READY ***");
491                         break;
492                 case GST_STATE_CHANGE_READY_TO_PAUSED:
493                         GST_INFO ("*** STATE_CHANGE_READY_TO_PAUSED ***");
494                         break;
495                 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
496                         GST_INFO ("*** STATE_CHANGE_PAUSED_TO_PLAYING ***");
497                         break;
498                 default:
499                         break;
500         }
501
502         ret_state = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
503
504         switch (transition) {
505                 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
506                         GST_INFO ("*** STATE_CHANGE_PLAYING_TO_PAUSED ***");
507                         break;
508                 case GST_STATE_CHANGE_PAUSED_TO_READY:
509                         GST_INFO ("*** STATE_CHANGE_PAUSED_TO_READY ***");
510                         break;
511                 case GST_STATE_CHANGE_READY_TO_NULL:
512                         GST_INFO ("*** STATE_CHANGE_READY_TO_NULL ***");
513                         EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo);
514                         if (esink->epipe) {
515                                 ecore_pipe_del (esink->epipe);
516                                 esink->epipe = NULL;
517                         }
518                         break;
519                 default:
520                         break;
521         }
522
523         return ret_state;
524 }
525
526 static void
527 gst_evas_image_sink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
528 {
529         GstEvasImageSink *esink = GST_EVASIMAGESINK (object);
530         Evas_Object *eo;
531
532         g_mutex_lock (instance_lock);
533
534         switch (prop_id) {
535         case PROP_EVAS_OBJECT:
536                 eo = g_value_get_pointer (value);
537                 if (is_evas_image_object (eo)) {
538                         if (eo != esink->eo) {
539                                 Eina_Bool r;
540
541                                 /* delete evas object callbacks registrated on a previous evas image object */
542                                 EVASIMAGESINK_UNSET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo);
543                                 esink->eo = eo;
544                                 /* add evas object callbacks on a new evas image object */
545                                 EVASIMAGESINK_SET_EVAS_OBJECT_EVENT_CALLBACK (esink->eo, esink);
546
547                                 esink->gl_zerocopy = is_zerocopy_supported (evas_object_evas_get (eo));
548                                 if (esink->gl_zerocopy) {
549                                         evas_object_image_content_hint_set (esink->eo, EVAS_IMAGE_CONTENT_HINT_DYNAMIC);
550                                         GST_DEBUG("Enable gl zerocopy");
551                                 }
552                                 GST_DEBUG("Evas Image Object(%x) is set",esink->eo);
553                                 esink->is_evas_object_size_set = FALSE;
554                                 esink->object_show = TRUE;
555                                 esink->update_visibility = UPDATE_TRUE;
556                                 if (esink->epipe) {
557                                         r = ecore_pipe_write (esink->epipe, &esink->update_visibility, SIZE_FOR_UPDATE_VISIBILITY);
558                                         if (r == EINA_FALSE)  {
559                                                 GST_WARNING ("Failed to ecore_pipe_write() for updating visibility\n");
560                                         }
561                                 }
562                         }
563                 } else {
564                         GST_ERROR ("Cannot set evas-object property: value is not an evas image object");
565                 }
566                 break;
567
568         case PROP_EVAS_OBJECT_SHOW:
569         {
570                 Eina_Bool r;
571                 esink->object_show = g_value_get_boolean (value);
572                 if( !is_evas_image_object(esink->eo) ) {
573                         GST_WARNING ("Cannot apply visible(show-object) property: cannot get an evas object\n");
574                         break;
575                 }
576                 esink->update_visibility = UPDATE_TRUE;
577                 if (esink->epipe) {
578                         r = ecore_pipe_write (esink->epipe, &esink->update_visibility, SIZE_FOR_UPDATE_VISIBILITY);
579                         if (r == EINA_FALSE)  {
580                                 GST_WARNING ("Failed to ecore_pipe_write() for updating visibility)\n");
581                         }
582                 }
583                 break;
584         }
585         default:
586                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
587                 break;
588         }
589
590         g_mutex_unlock (instance_lock);
591 }
592
593 static void
594 gst_evas_image_sink_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
595 {
596         GstEvasImageSink *esink = GST_EVASIMAGESINK (object);
597
598         switch (prop_id) {
599         case PROP_EVAS_OBJECT:
600                 g_value_set_pointer (value, esink->eo);
601                 break;
602         case PROP_EVAS_OBJECT_SHOW:
603                 g_value_set_boolean (value, esink->object_show);
604                 break;
605         default:
606                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
607                 break;
608         }
609 }
610
611 static gboolean
612 gst_evas_image_sink_set_caps (GstBaseSink *base_sink, GstCaps *caps)
613 {
614         int r;
615         int w, h;
616         GstEvasImageSink *esink = GST_EVASIMAGESINK (base_sink);
617
618         esink->is_evas_object_size_set = FALSE;
619         r = evas_image_sink_get_size_from_caps (caps, &w, &h);
620         if (!r) {
621                 esink->w = w;
622                 esink->h = h;
623                 GST_DEBUG ("set size w(%d), h(%d)", w, h);
624         }
625         return TRUE;
626 }
627
628 static GstFlowReturn
629 gst_evas_image_sink_show_frame (GstVideoSink *video_sink, GstBuffer *buf)
630 {
631         GstEvasImageSink *esink = GST_EVASIMAGESINK (video_sink);
632         Eina_Bool r;
633
634         g_mutex_lock (instance_lock);
635         if (esink->present_data_addr == -1) {
636                 /* if present_data_addr is -1, we don't use this member variable */
637         } else if (esink->present_data_addr != DO_RENDER_FROM_FIMC) {
638                 GST_WARNING ("skip rendering this buffer, present_data_addr:%d, DO_RENDER_FROM_FIMC:%d", esink->present_data_addr, DO_RENDER_FROM_FIMC);
639                 g_mutex_unlock (instance_lock);
640                 return GST_FLOW_OK;
641         }
642         if (!esink->epipe) {
643                 esink->epipe = ecore_pipe_add (evas_image_sink_cb_pipe, esink);
644                 if (!esink->epipe) {
645                         GST_ERROR ("ecore-pipe create failed");
646                         g_mutex_unlock (instance_lock);
647                         return GST_FLOW_ERROR;
648                 }
649         }
650         if (esink->object_show) {
651                 gst_buffer_ref (buf);
652                 __ta__("evasimagesink ecore_pipe_write", r = ecore_pipe_write (esink->epipe, &buf, sizeof (GstBuffer *)););
653                 if (r == EINA_FALSE)  {
654                         gst_buffer_unref (buf);
655                 }
656                 GST_DEBUG ("ecore_pipe_write() was called with GST_BUFFER_DATA(buf):%x", GST_BUFFER_DATA(buf));
657         } else {
658                 GST_DEBUG ("skip ecore_pipe_write()");
659         }
660         g_mutex_unlock (instance_lock);
661         return GST_FLOW_OK;
662 }
663
664 static gboolean
665 evas_image_sink_init (GstPlugin *evasimagesink)
666 {
667         GST_DEBUG_CATEGORY_INIT (gst_evas_image_sink_debug, "evasimagesink", 0, "Evas image object based videosink");
668
669         return gst_element_register (evasimagesink, "evasimagesink", GST_RANK_NONE, GST_TYPE_EVASIMAGESINK);
670 }
671
672 #ifndef PACKAGE
673 #define PACKAGE "gstevasimagesink-plugin-package"
674 #endif
675
676 GST_PLUGIN_DEFINE (
677         GST_VERSION_MAJOR,
678         GST_VERSION_MINOR,
679         "evasimagesink",
680         "Evas image object based videosink",
681         evas_image_sink_init,
682         VERSION,
683         "LGPL",
684         "Samsung Electronics Co",
685         "http://www.samsung.com/"
686 )