summaryrefslogtreecommitdiff
path: root/legacy/emotion/src/modules/gstreamer/emotion_sink.c
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2011-10-04 11:14:58 +0000
committerCedric BAIL <cedric.bail@free.fr>2011-10-04 11:14:58 +0000
commit35c9a8f56c4fb60c6932ad647eaa6a0b419a4841 (patch)
tree4e479dd3144b1edc643e972e92aa0bd119349608 /legacy/emotion/src/modules/gstreamer/emotion_sink.c
parent4376c4f99592e2ecb49dde2d7f351d4e45c9e8b3 (diff)
emotion: make Xv work.
NOTE: we need the help of the window manager to make this really work. So for the moment, it half work. As soon as I hack E17, the Xv fast path for Emotion will only work when used with E17 and it will fallback to canvas inlined rendering in other case. SVN revision: 63802
Diffstat (limited to '')
-rw-r--r--legacy/emotion/src/modules/gstreamer/emotion_sink.c126
1 files changed, 101 insertions, 25 deletions
diff --git a/legacy/emotion/src/modules/gstreamer/emotion_sink.c b/legacy/emotion/src/modules/gstreamer/emotion_sink.c
index 2f4ef5f355..f2273b7980 100644
--- a/legacy/emotion/src/modules/gstreamer/emotion_sink.c
+++ b/legacy/emotion/src/modules/gstreamer/emotion_sink.c
@@ -730,6 +730,12 @@ evas_video_sink_samsung_main_render(void *data)
730 evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height); 730 evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height);
731 evas_object_image_pixels_dirty_set(priv->o, 0); 731 evas_object_image_pixels_dirty_set(priv->o, 0);
732 732
733 if (!preroll && send->ev->play_started)
734 {
735 _emotion_playback_started(send->ev->obj);
736 send->ev->play_started = 0;
737 }
738
733 _emotion_frame_new(send->ev->obj); 739 _emotion_frame_new(send->ev->obj);
734 740
735 vstream = eina_list_nth(send->ev->video_streams, send->ev->video_stream_nbr - 1); 741 vstream = eina_list_nth(send->ev->video_streams, send->ev->video_stream_nbr - 1);
@@ -790,6 +796,7 @@ evas_video_sink_main_render(void *data)
790 if (ev->send) 796 if (ev->send)
791 emotion_gstreamer_buffer_free(ev->send); 797 emotion_gstreamer_buffer_free(ev->send);
792 ev->send = send; 798 ev->send = send;
799 evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height);
793 goto exit_stream; 800 goto exit_stream;
794 } 801 }
795 802
@@ -812,6 +819,12 @@ evas_video_sink_main_render(void *data)
812 evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height); 819 evas_object_image_data_update_add(priv->o, 0, 0, priv->width, priv->height);
813 evas_object_image_pixels_dirty_set(priv->o, 0); 820 evas_object_image_pixels_dirty_set(priv->o, 0);
814 821
822 if (!preroll && ev->play_started)
823 {
824 _emotion_playback_started(ev->obj);
825 ev->play_started = 0;
826 }
827
815 _emotion_frame_new(ev->obj); 828 _emotion_frame_new(ev->obj);
816 829
817 gst_element_query_position(ev->pipeline, &fmt, &pos); 830 gst_element_query_position(ev->pipeline, &fmt, &pos);
@@ -944,10 +957,17 @@ static void
944_emotion_gstreamer_pause(void *data, Ecore_Thread *thread) 957_emotion_gstreamer_pause(void *data, Ecore_Thread *thread)
945{ 958{
946 Emotion_Gstreamer_Video *ev = data; 959 Emotion_Gstreamer_Video *ev = data;
960 gboolean res;
947 961
948 if (ecore_thread_check(thread) || !ev->pipeline) return ; 962 if (ecore_thread_check(thread) || !ev->pipeline) return ;
949 963
950 gst_element_set_state(ev->pipeline, GST_STATE_PAUSED); 964 gst_element_set_state(ev->pipeline, GST_STATE_PAUSED);
965 res = gst_element_get_state(ev->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
966 if (res == GST_STATE_CHANGE_NO_PREROLL)
967 {
968 gst_element_set_state(ev->pipeline, GST_STATE_PLAYING);
969 gst_element_get_state(ev->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
970 }
951} 971}
952 972
953static void 973static void
@@ -1009,19 +1029,51 @@ _video_move(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *s
1009{ 1029{
1010 Emotion_Gstreamer_Video *ev = data; 1030 Emotion_Gstreamer_Video *ev = data;
1011 1031
1032 fprintf(stderr, "move: %i, %i\n", x, y);
1012 ecore_x_window_move(ev->win, x, y); 1033 ecore_x_window_move(ev->win, x, y);
1013} 1034}
1014 1035
1036#if 0
1037/* Much better idea to always feed the XvImageSink and let him handle optimizing the rendering as we do */
1038static void
1039_block_pad_unlink_cb(GstPad *pad, gboolean blocked, gpointer user_data)
1040{
1041 if (blocked)
1042 {
1043 Emotion_Gstreamer_Video *ev = user_data;
1044 GstEvent *gev;
1045
1046 gst_pad_unlink(ev->teepad, ev->xvpad);
1047 gev = gst_event_new_eos();
1048 gst_pad_send_event(ev->xvpad, gev);
1049 gst_pad_set_blocked_async(pad, FALSE, _block_pad_unlink_cb, NULL);
1050 }
1051}
1052
1053static void
1054_block_pad_link_cb(GstPad *pad, gboolean blocked, gpointer user_data)
1055{
1056 if (blocked)
1057 {
1058 Emotion_Gstreamer_Video *ev = user_data;
1059
1060 gst_pad_link(ev->teepad, ev->xvpad);
1061 if (ev->play)
1062 gst_element_set_state(ev->xvsink, GST_STATE_PLAYING);
1063 else
1064 gst_element_set_state(ev->xvsink, GST_STATE_PAUSED);
1065 gst_pad_set_blocked_async(pad, FALSE, _block_pad_link_cb, NULL);
1066 }
1067}
1068#endif
1069
1015static void 1070static void
1016_video_show(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__) 1071_video_show(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *surface __UNUSED__)
1017{ 1072{
1018 Emotion_Gstreamer_Video *ev = data; 1073 Emotion_Gstreamer_Video *ev = data;
1019 1074
1020 fprintf(stderr, "show xwin %i\n", ev->win);
1021
1022 ecore_x_window_show(ev->win); 1075 ecore_x_window_show(ev->win);
1023 gst_pad_link(ev->teepad, ev->xvpad); 1076 /* gst_pad_set_blocked_async(ev->teepad, TRUE, _block_pad_link_cb, ev); */
1024 ev->linked = EINA_TRUE;
1025} 1077}
1026 1078
1027static void 1079static void
@@ -1029,11 +1081,8 @@ _video_hide(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface *s
1029{ 1081{
1030 Emotion_Gstreamer_Video *ev = data; 1082 Emotion_Gstreamer_Video *ev = data;
1031 1083
1032 fprintf(stderr, "hide xwin: %i\n", ev->win);
1033
1034 ecore_x_window_hide(ev->win); 1084 ecore_x_window_hide(ev->win);
1035 gst_pad_unlink(ev->teepad, ev->xvpad); 1085 /* gst_pad_set_blocked_async(ev->teepad, TRUE, _block_pad_unlink_cb, ev); */
1036 ev->linked = EINA_FALSE;
1037} 1086}
1038 1087
1039static void 1088static void
@@ -1101,8 +1150,6 @@ gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
1101 goto unref_pipeline; 1150 goto unref_pipeline;
1102 } 1151 }
1103 1152
1104 fprintf(stderr, "priority: %i\n", ev->priority);
1105
1106#if defined HAVE_ECORE_X && defined HAVE_XOVERLAY_H 1153#if defined HAVE_ECORE_X && defined HAVE_XOVERLAY_H
1107 engines = evas_render_method_list(); 1154 engines = evas_render_method_list();
1108 1155
@@ -1113,25 +1160,41 @@ gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
1113 Ecore_Evas *ee; 1160 Ecore_Evas *ee;
1114 Evas_Coord x, y, w, h; 1161 Evas_Coord x, y, w, h;
1115 Ecore_X_Window win; 1162 Ecore_X_Window win;
1163 Ecore_X_Window parent;
1116 1164
1117 evas_object_geometry_get(obj, &x, &y, &w, &h); 1165 evas_object_geometry_get(obj, &x, &y, &w, &h);
1118 1166
1119 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj)); 1167 ee = ecore_evas_ecore_evas_get(evas_object_evas_get(obj));
1120 1168
1121 if (w < 1) w = 1; 1169 if (w < 4) w = 4;
1122 if (h < 1) h = 1; 1170 if (h < 2) h = 2;
1171
1172 /* Here we really need to have the help of the window manager, this code will change when we update E17. */
1173 parent = (Ecore_X_Window) ecore_evas_window_get(ee);
1174 fprintf(stderr, "parent: %x\n", parent);
1123 1175
1124 win = ecore_x_window_new((Ecore_X_Window) ecore_evas_window_get(ee), x, y, w, h); 1176 win = ecore_x_window_override_new(0, x, y, w, h);
1177 fprintf(stderr, "creating window: %x [%i, %i, %i, %i]\n", win, x, y, w, h);
1125 if (win) 1178 if (win)
1126 { 1179 {
1180 ecore_x_window_show(win);
1127 xvsink = gst_element_factory_make("xvimagesink", NULL); 1181 xvsink = gst_element_factory_make("xvimagesink", NULL);
1128 if (xvsink) 1182 if (xvsink)
1129 { 1183 {
1184 Ecore_X_Atom atom;
1185
1130 gst_x_overlay_set_window_handle(GST_X_OVERLAY(xvsink), win); 1186 gst_x_overlay_set_window_handle(GST_X_OVERLAY(xvsink), win);
1131 ev->win = win; 1187 ev->win = win;
1188
1189 atom = ecore_x_atom_get("enlightenment.video");
1190 if (atom)
1191 {
1192 ecore_x_window_prop_card32_set(win, atom, &parent, 1);
1193 }
1132 } 1194 }
1133 else 1195 else
1134 { 1196 {
1197 fprintf(stderr, "destroying win: %x\n", win);
1135 ecore_x_window_free(win); 1198 ecore_x_window_free(win);
1136 } 1199 }
1137 } 1200 }
@@ -1161,7 +1224,7 @@ gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
1161 goto unref_pipeline; 1224 goto unref_pipeline;
1162 } 1225 }
1163 1226
1164 gst_bin_add_many(GST_BIN(bin), tee, queue, esink, xvsink, NULL); 1227 gst_bin_add_many(GST_BIN(bin), tee, queue, esink, NULL);
1165 gst_element_link_many(queue, esink, NULL); 1228 gst_element_link_many(queue, esink, NULL);
1166 1229
1167 /* link both sink to GstTee */ 1230 /* link both sink to GstTee */
@@ -1173,23 +1236,36 @@ gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
1173 1236
1174 if (xvsink) 1237 if (xvsink)
1175 { 1238 {
1239 GstElement *fakeeos;
1240
1176 queue = gst_element_factory_make("queue", NULL); 1241 queue = gst_element_factory_make("queue", NULL);
1177 if (queue) 1242 fakeeos = GST_ELEMENT(GST_BIN(g_object_new(GST_TYPE_FAKEEOS_BIN, "name", "eosbin", NULL)));
1243 if (queue && fakeeos)
1178 { 1244 {
1179 gst_bin_add_many(GST_BIN(bin), queue, NULL); 1245 GstPad *queue_pad;
1180 gst_element_link_many(queue, xvsink, NULL); 1246
1247 gst_bin_add_many(GST_BIN(bin), fakeeos, NULL);
1248
1249 gst_bin_add_many(GST_BIN(fakeeos), queue, xvsink, NULL);
1250 gst_element_link_many(queue, xvsink, NULL);
1251 queue_pad = gst_element_get_pad(queue, "sink");
1252 gst_element_add_pad(fakeeos, gst_ghost_pad_new("sink", queue_pad));
1253
1254 pad = gst_element_get_pad(fakeeos, "sink");
1255 teepad = gst_element_get_request_pad(tee, "src%d");
1256 gst_pad_link(teepad, pad);
1181 1257
1182 pad = gst_element_get_pad(queue, "sink"); 1258 xvsink = fakeeos;
1183 teepad = gst_element_get_request_pad(tee, "src%d");
1184 gst_pad_link(teepad, pad);
1185 1259
1186 ev->teepad = teepad; 1260 ev->teepad = teepad;
1187 ev->xvpad = pad; 1261 ev->xvpad = pad;
1188 } 1262 }
1189 else 1263 else
1190 { 1264 {
1191 gst_object_unref(xvsink); 1265 if (fakeeos) gst_object_unref(fakeeos);
1192 xvsink = NULL; 1266 if (queue) gst_object_unref(queue);
1267 gst_object_unref(xvsink);
1268 xvsink = NULL;
1193 } 1269 }
1194 } 1270 }
1195 1271
@@ -1230,10 +1306,10 @@ gstreamer_video_sink_new(Emotion_Gstreamer_Video *ev,
1230 } 1306 }
1231 1307
1232 eina_stringshare_replace(&ev->uri, uri); 1308 eina_stringshare_replace(&ev->uri, uri);
1233 ev->linked = EINA_TRUE;
1234 ev->pipeline = playbin; 1309 ev->pipeline = playbin;
1235 ev->sink = bin; 1310 ev->sink = bin;
1236 ev->esink = esink; 1311 ev->esink = esink;
1312 ev->xvsink = xvsink;
1237 ev->tee = tee; 1313 ev->tee = tee;
1238 ev->threads = eina_list_append(ev->threads, 1314 ev->threads = eina_list_append(ev->threads,
1239 ecore_thread_run(_emotion_gstreamer_pause, 1315 ecore_thread_run(_emotion_gstreamer_pause,