summaryrefslogtreecommitdiff
path: root/legacy/emotion
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2012-07-05 12:40:56 +0000
committerCedric BAIL <cedric.bail@free.fr>2012-07-05 12:40:56 +0000
commit8f38e5e4e62391e5649bbfe970c3d15ef3705a0b (patch)
tree64c0a83cfe49e6b3c2debc30fbc276b5d98adca1 /legacy/emotion
parent1c08b5899eaac1b10a8e7bf5fdb592449ef107a9 (diff)
emotion: let work around embedded device limitation.
NOTE: I am going to accept more of this work around. So if you preferred device doesn't come with a proper nice implementation of gstreamer, let's start working around in emotion :'( SVN revision: 73340
Diffstat (limited to 'legacy/emotion')
-rw-r--r--legacy/emotion/AUTHORS1
-rw-r--r--legacy/emotion/ChangeLog3
-rw-r--r--legacy/emotion/NEWS1
-rw-r--r--legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c75
-rw-r--r--legacy/emotion/src/modules/gstreamer/emotion_gstreamer.h8
-rw-r--r--legacy/emotion/src/modules/gstreamer/emotion_sink.c79
6 files changed, 156 insertions, 11 deletions
diff --git a/legacy/emotion/AUTHORS b/legacy/emotion/AUTHORS
index c683782f43..c2579a8e4e 100644
--- a/legacy/emotion/AUTHORS
+++ b/legacy/emotion/AUTHORS
@@ -7,3 +7,4 @@ Rafael Antognolli <antognolli@profusion.mobi>
7Jérôme Pinot <ngc891@gmail.com> 7Jérôme Pinot <ngc891@gmail.com>
8Pierre Le Magourou <pierre.lemagourou@openwide.fr> 8Pierre Le Magourou <pierre.lemagourou@openwide.fr>
9Hugo Camboulive <hugo.camboulive@zodiacaerospace.com> 9Hugo Camboulive <hugo.camboulive@zodiacaerospace.com>
10Sohyun Kim <anna1014.kim@samsung.com>
diff --git a/legacy/emotion/ChangeLog b/legacy/emotion/ChangeLog
index 4169f7d53a..9329acf180 100644
--- a/legacy/emotion/ChangeLog
+++ b/legacy/emotion/ChangeLog
@@ -29,3 +29,6 @@
292012-07-03 Cedric Bail 292012-07-03 Cedric Bail
30 30
31 * Track pending object for proper shutdown. 31 * Track pending object for proper shutdown.
322012-06-05 Sohyun Kim
33
34 * Add fimcconvert element to resize and convert color using fimc on device
diff --git a/legacy/emotion/NEWS b/legacy/emotion/NEWS
index 5fffba7213..fa32d20257 100644
--- a/legacy/emotion/NEWS
+++ b/legacy/emotion/NEWS
@@ -8,6 +8,7 @@ Additions:
8 - Implement SPU switch for generic/vlc. 8 - Implement SPU switch for generic/vlc.
9 - Sync rendering with Ecore_Animator. 9 - Sync rendering with Ecore_Animator.
10 - Track pending object for proper shutdown. 10 - Track pending object for proper shutdown.
11 - Start handling embedded hardware customization.
11 12
12Fixes: 13Fixes:
13 - build out of tree. 14 - build out of tree.
diff --git a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c
index 38abf57dd2..3383ce9863 100644
--- a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c
+++ b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c
@@ -422,11 +422,16 @@ em_cleanup(Emotion_Gstreamer_Video *ev)
422 ev->pipeline = NULL; 422 ev->pipeline = NULL;
423 ev->sink = NULL; 423 ev->sink = NULL;
424 424
425 if (ev->teepad) gst_object_unref(ev->teepad); 425 if (ev->eteepad) gst_object_unref(ev->eteepad);
426 ev->teepad = NULL; 426 ev->eteepad = NULL;
427 if (ev->xvteepad) gst_object_unref(ev->xvteepad);
428 ev->xvteepad = NULL;
427 if (ev->xvpad) gst_object_unref(ev->xvpad); 429 if (ev->xvpad) gst_object_unref(ev->xvpad);
428 ev->xvpad = NULL; 430 ev->xvpad = NULL;
429 431
432 ev->src_width = 0;
433 ev->src_height = 0;
434
430#ifdef HAVE_ECORE_X 435#ifdef HAVE_ECORE_X
431 fprintf(stderr, "destroying window: %i\n", ev->win); 436 fprintf(stderr, "destroying window: %i\n", ev->win);
432 if (ev->win) ecore_x_window_free(ev->win); 437 if (ev->win) ecore_x_window_free(ev->win);
@@ -1604,6 +1609,58 @@ _em_restart_stream(void *data)
1604 return ECORE_CALLBACK_CANCEL; 1609 return ECORE_CALLBACK_CANCEL;
1605} 1610}
1606 1611
1612static Eina_Bool
1613_video_size_get(GstElement *elem, int *width, int *height)
1614{
1615 GstIterator *itr = NULL;
1616 GstCaps *caps;
1617 GstStructure *str;
1618 gpointer pad;
1619 Eina_Bool ret = EINA_FALSE;
1620
1621 itr = gst_element_iterate_src_pads(elem);
1622 while(gst_iterator_next(itr, &pad) && !ret)
1623 {
1624 caps = gst_pad_get_caps(GST_PAD(pad));
1625 str = gst_caps_get_structure(caps, 0);
1626 if (g_strrstr(gst_structure_get_name(str), "video"))
1627 {
1628 if (gst_structure_get_int(str, "width", width) && gst_structure_get_int(str, "height", height))
1629 ret = EINA_TRUE;
1630 }
1631 gst_caps_unref(caps);
1632 gst_object_unref(pad);
1633 }
1634 gst_iterator_free(itr);
1635
1636 return ret;
1637}
1638
1639static void
1640_no_more_pads(GstElement *decodebin, gpointer data)
1641{
1642 GstIterator *itr = NULL;
1643 gpointer elem;
1644 Emotion_Gstreamer_Video *ev = data;
1645
1646 itr = gst_bin_iterate_elements(GST_BIN(decodebin));
1647 while(gst_iterator_next(itr, &elem))
1648 {
1649 if(_video_size_get(GST_ELEMENT(elem), &ev->src_width, &ev->src_height))
1650 {
1651 double ratio;
1652
1653 ratio = (double)ev->src_width / (double)ev->src_height;
1654 _emotion_frame_resize(ev->obj, ev->src_width, ev->src_height, ratio);
1655
1656 gst_object_unref(elem);
1657 break;
1658 }
1659 gst_object_unref(elem);
1660 }
1661 gst_iterator_free(itr);
1662}
1663
1607static void 1664static void
1608_eos_main_fct(void *data) 1665_eos_main_fct(void *data)
1609{ 1666{
@@ -1650,6 +1707,13 @@ _eos_main_fct(void *data)
1650 break; 1707 break;
1651 case GST_MESSAGE_STREAM_STATUS: 1708 case GST_MESSAGE_STREAM_STATUS:
1652 break; 1709 break;
1710 case GST_MESSAGE_STATE_CHANGED:
1711 if (!ev->delete_me)
1712 {
1713 if (!g_signal_handlers_disconnect_by_func(msg->src, _no_more_pads, ev))
1714 g_signal_connect(msg->src, "no-more-pads", G_CALLBACK(_no_more_pads), ev);
1715 }
1716 break;
1653 case GST_MESSAGE_ERROR: 1717 case GST_MESSAGE_ERROR:
1654 em_cleanup(ev); 1718 em_cleanup(ev);
1655 1719
@@ -1704,6 +1768,13 @@ _eos_sync_fct(GstBus *bus __UNUSED__, GstMessage *msg, gpointer data)
1704 GST_OBJECT_NAME(msg->src), 1768 GST_OBJECT_NAME(msg->src),
1705 gst_element_state_get_name(old_state), 1769 gst_element_state_get_name(old_state),
1706 gst_element_state_get_name(new_state)); 1770 gst_element_state_get_name(new_state));
1771
1772 if (!strncmp(GST_OBJECT_NAME(msg->src), "decodebin", 9) && !strcmp(gst_element_state_get_name(new_state), "READY"))
1773 {
1774 send = emotion_gstreamer_message_alloc(ev, msg);
1775
1776 if (send) ecore_main_loop_thread_safe_call_async(_eos_main_fct, send);
1777 }
1707 break; 1778 break;
1708 } 1779 }
1709 case GST_MESSAGE_ERROR: 1780 case GST_MESSAGE_ERROR:
diff --git a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.h b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.h
index 25a718076c..9c7455d208 100644
--- a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.h
+++ b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.h
@@ -55,7 +55,10 @@ struct _Emotion_Gstreamer_Video
55 GstElement *esink; 55 GstElement *esink;
56 GstElement *xvsink; 56 GstElement *xvsink;
57 GstElement *tee; 57 GstElement *tee;
58 GstPad *teepad; 58 GstElement *convert;
59
60 GstPad *eteepad;
61 GstPad *xvteepad;
59 GstPad *xvpad; 62 GstPad *xvpad;
60 Eina_List *threads; 63 Eina_List *threads;
61 64
@@ -121,6 +124,9 @@ struct _Emotion_Gstreamer_Video
121 Eina_Bool kill_buffer : 1; 124 Eina_Bool kill_buffer : 1;
122 Eina_Bool stream : 1; 125 Eina_Bool stream : 1;
123 Eina_Bool priority : 1; 126 Eina_Bool priority : 1;
127
128 int src_width;
129 int src_height;
124}; 130};
125 131
126struct _EvasVideoSink { 132struct _EvasVideoSink {
diff --git a/legacy/emotion/src/modules/gstreamer/emotion_sink.c b/legacy/emotion/src/modules/gstreamer/emotion_sink.c
index 85739bd360..6fe26f80af 100644
--- a/legacy/emotion/src/modules/gstreamer/emotion_sink.c
+++ b/legacy/emotion/src/modules/gstreamer/emotion_sink.c
@@ -895,7 +895,7 @@ _block_pad_unlink_cb(GstPad *pad, gboolean blocked, gpointer user_data)
895 Emotion_Gstreamer_Video *ev = user_data; 895 Emotion_Gstreamer_Video *ev = user_data;
896 GstEvent *gev; 896 GstEvent *gev;
897 897
898 gst_pad_unlink(ev->teepad, ev->xvpad); 898 gst_pad_unlink(ev->xvteepad, ev->xvpad);
899 gev = gst_event_new_eos(); 899 gev = gst_event_new_eos();
900 gst_pad_send_event(ev->xvpad, gev); 900 gst_pad_send_event(ev->xvpad, gev);
901 gst_pad_set_blocked_async(pad, FALSE, _block_pad_unlink_cb, NULL); 901 gst_pad_set_blocked_async(pad, FALSE, _block_pad_unlink_cb, NULL);
@@ -909,7 +909,7 @@ _block_pad_link_cb(GstPad *pad, gboolean blocked, gpointer user_data)
909 { 909 {
910 Emotion_Gstreamer_Video *ev = user_data; 910 Emotion_Gstreamer_Video *ev = user_data;
911 911
912 gst_pad_link(ev->teepad, ev->xvpad); 912 gst_pad_link(ev->xvteepad, ev->xvpad);
913 if (ev->play) 913 if (ev->play)
914 gst_element_set_state(ev->xvsink, GST_STATE_PLAYING); 914 gst_element_set_state(ev->xvsink, GST_STATE_PLAYING);
915 else 915 else
@@ -928,7 +928,7 @@ _video_show(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *s
928 fprintf(stderr, "show xv\n"); 928 fprintf(stderr, "show xv\n");
929 ecore_x_window_show(ev->win); 929 ecore_x_window_show(ev->win);
930#endif 930#endif
931 /* gst_pad_set_blocked_async(ev->teepad, TRUE, _block_pad_link_cb, ev); */ 931 /* gst_pad_set_blocked_async(ev->xvteepad, TRUE, _block_pad_link_cb, ev); */
932} 932}
933 933
934static void 934static void
@@ -940,7 +940,7 @@ _video_hide(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *s
940 fprintf(stderr, "hide xv\n"); 940 fprintf(stderr, "hide xv\n");
941 ecore_x_window_hide(ev->win); 941 ecore_x_window_hide(ev->win);
942#endif 942#endif
943 /* gst_pad_set_blocked_async(ev->teepad, TRUE, _block_pad_unlink_cb, ev); */ 943 /* gst_pad_set_blocked_async(ev->xvteepad, TRUE, _block_pad_unlink_cb, ev); */
944} 944}
945 945
946static void 946static void
@@ -957,6 +957,67 @@ _video_update_pixels(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_S
957 evas_video_sink_main_render(send); 957 evas_video_sink_main_render(send);
958} 958}
959 959
960static void
961_image_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
962{
963 Emotion_Gstreamer_Video *ev = data;
964 Evas_Coord width, height;
965 int image_area, src_area;
966 double ratio;
967
968 evas_object_geometry_get(obj, NULL, NULL, &width, &height);
969 image_area = width * height;
970 src_area = ev->src_width * ev->src_height;
971 ratio = (double)image_area / (double)src_area;
972
973 // when an image is much smaller than original video size,
974 // add fimcconvert element to the pipeline
975 if (ratio < 0.8 && !ev->priority && !ev->convert)
976 {
977 GstElementFactory *cfactory = NULL;
978
979 cfactory = gst_element_factory_find("fimcconvert");
980 if (cfactory)
981 {
982 GstElement *convert = NULL;
983
984 convert = gst_element_factory_create(cfactory, NULL);
985 if (convert)
986 {
987 GstElement *queue = NULL;
988 GstPad *pad, *teepad;
989
990 queue = gst_bin_get_by_name(GST_BIN(ev->sink), "equeue");
991 gst_element_unlink(ev->tee, queue);
992 gst_element_release_request_pad(ev->tee, ev->eteepad);
993 gst_object_unref(ev->eteepad);
994
995 gst_bin_add(GST_BIN(ev->sink), convert);
996 gst_element_link_many(ev->tee, convert, queue, NULL);
997 pad = gst_element_get_pad(convert, "sink");
998 teepad = gst_element_get_request_pad(ev->tee, "src%d");
999 gst_pad_link(teepad, pad);
1000 gst_object_unref(pad);
1001
1002 g_object_set(G_OBJECT(convert), "src-width", width, NULL);
1003 g_object_set(G_OBJECT(convert), "src-height", height, NULL);
1004 g_object_set(G_OBJECT(convert), "qos", TRUE, NULL);
1005 gst_element_sync_state_with_parent(convert);
1006
1007 ev->eteepad = teepad;
1008 ev->convert = convert;
1009 }
1010 }
1011 }
1012 // TODO: when an image is resized(e.g rotation), set size again to fimcconvert
1013 // TODO: fimcconvert has an issue about resetting
1014 //else if (ev->convert)
1015 // {
1016 // g_object_set(G_OBJECT(ev->convert), "src-width", w, NULL);
1017 // g_object_set(G_OBJECT(ev->convert), "src-height", h, NULL);
1018 // }
1019}
1020
960GstElement * 1021GstElement *
961gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev, 1022gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
962 Evas_Object *o, 1023 Evas_Object *o,
@@ -1115,9 +1176,10 @@ gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
1115 g_object_set(G_OBJECT(esink), "ev", ev, NULL); 1176 g_object_set(G_OBJECT(esink), "ev", ev, NULL);
1116 1177
1117 evas_object_image_pixels_get_callback_set(obj, NULL, NULL); 1178 evas_object_image_pixels_get_callback_set(obj, NULL, NULL);
1179 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _image_resize, ev);
1118 1180
1119 /* We need queue to force each video sink to be in its own thread */ 1181 /* We need queue to force each video sink to be in its own thread */
1120 queue = gst_element_factory_make("queue", NULL); 1182 queue = gst_element_factory_make("queue", "equeue");
1121 if (!queue) 1183 if (!queue)
1122 { 1184 {
1123 ERR("Unable to create 'queue' GstElement."); 1185 ERR("Unable to create 'queue' GstElement.");
@@ -1132,13 +1194,14 @@ gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
1132 teepad = gst_element_get_request_pad(tee, "src%d"); 1194 teepad = gst_element_get_request_pad(tee, "src%d");
1133 gst_pad_link(teepad, pad); 1195 gst_pad_link(teepad, pad);
1134 gst_object_unref(pad); 1196 gst_object_unref(pad);
1135 gst_object_unref(teepad); 1197
1198 ev->eteepad = teepad;
1136 1199
1137 if (xvsink) 1200 if (xvsink)
1138 { 1201 {
1139 GstElement *fakeeos; 1202 GstElement *fakeeos;
1140 1203
1141 queue = gst_element_factory_make("queue", NULL); 1204 queue = gst_element_factory_make("queue", "xvqueue");
1142 fakeeos = GST_ELEMENT(GST_BIN(g_object_new(GST_TYPE_FAKEEOS_BIN, "name", "eosbin", NULL))); 1205 fakeeos = GST_ELEMENT(GST_BIN(g_object_new(GST_TYPE_FAKEEOS_BIN, "name", "eosbin", NULL)));
1143 if (queue && fakeeos) 1206 if (queue && fakeeos)
1144 { 1207 {
@@ -1157,7 +1220,7 @@ gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
1157 1220
1158 xvsink = fakeeos; 1221 xvsink = fakeeos;
1159 1222
1160 ev->teepad = teepad; 1223 ev->xvteepad = teepad;
1161 ev->xvpad = pad; 1224 ev->xvpad = pad;
1162 } 1225 }
1163 else 1226 else