summaryrefslogtreecommitdiff
path: root/legacy/emotion
diff options
context:
space:
mode:
authordoursse <doursse>2006-02-04 13:43:13 +0000
committerdoursse <doursse@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>2006-02-04 13:43:13 +0000
commit7ecab55f5b806d03f15011a957ce59d7e7af0485 (patch)
tree92fc281ade6898e0a293f2dea21e58feac0c937d /legacy/emotion
parent5d0432137401c269d091d15963ca0595c9ab9aae (diff)
gstreamer 0.10 port. There's a problem with the seek, no evas sink yet
SVN revision: 20273
Diffstat (limited to '')
-rw-r--r--legacy/emotion/configure.in16
-rw-r--r--legacy/emotion/src/lib/emotion_private.h10
-rw-r--r--legacy/emotion/src/lib/emotion_smart.c4
-rw-r--r--legacy/emotion/src/modules/emotion_gstreamer.c1021
-rw-r--r--legacy/emotion/src/modules/emotion_gstreamer.h75
-rw-r--r--legacy/emotion/src/modules/emotion_xine.c24
-rw-r--r--legacy/emotion/src/modules/emotion_xine_vo_out.c4
7 files changed, 511 insertions, 643 deletions
diff --git a/legacy/emotion/configure.in b/legacy/emotion/configure.in
index a9c1eb599b..a1877df8ea 100644
--- a/legacy/emotion/configure.in
+++ b/legacy/emotion/configure.in
@@ -157,9 +157,9 @@ HAVE_GSTPLUG="no"
157if test "$enable_gstreamer" != "no" ; then 157if test "$enable_gstreamer" != "no" ; then
158 158
159 dnl Gstreamer version requirement 159 dnl Gstreamer version requirement
160 GST_REQS=0.8.10 160 GST_REQS=0.10.2
161 GSTPLUG_REQS=0.8.10 161 GSTPLUG_REQS=0.10.1
162 GST_MAJORMINOR=0.8 162 GST_MAJORMINOR=0.10
163 163
164 PKG_CHECK_MODULES(GST, \ 164 PKG_CHECK_MODULES(GST, \
165 gstreamer-$GST_MAJORMINOR >= $GST_REQS, 165 gstreamer-$GST_MAJORMINOR >= $GST_REQS,
@@ -167,14 +167,19 @@ if test "$enable_gstreamer" != "no" ; then
167 AC_MSG_RESULT($HAVE_GSTREAMER) 167 AC_MSG_RESULT($HAVE_GSTREAMER)
168 168
169 PKG_CHECK_MODULES(GSTPLUG, \ 169 PKG_CHECK_MODULES(GSTPLUG, \
170 gstreamer-plugins-$GST_MAJORMINOR >= $GSTPLUG_REQS, 170 gstreamer-plugins-base-$GST_MAJORMINOR >= $GSTPLUG_REQS,
171 HAVE_GSTPLUG="yes", HAVE_GSTPLUG="no") 171 HAVE_GSTPLUG="yes", HAVE_GSTPLUG="no")
172 AC_MSG_RESULT($HAVE_GSTPLUG) 172 AC_MSG_RESULT($HAVE_GSTPLUG)
173
174 AM_GST_ELEMENT_CHECK(
175 [ffmpeg],
176 [HAVE_GSTFFMPEG="yes"],
177 [HAVE_GSTFFMPEG="no"])
173fi 178fi
174if test "$enable_gstreamer$HAVE_GSTREAMER" = "yesno" ; then 179if test "$enable_gstreamer$HAVE_GSTREAMER" = "yesno" ; then
175 AC_MSG_ERROR(gstreamer not found) 180 AC_MSG_ERROR(gstreamer not found)
176fi 181fi
177if test "$HAVE_GSTPLUG" = "no" ; then 182if test "$HAVE_GSTPLUG" = "no" -o test "$HAVE_GSTFFMPEG" = "no"; then
178 if test "$HAVE_GSTREAMER" = "no" ; then 183 if test "$HAVE_GSTREAMER" = "no" ; then
179 GSTPLUG_MSG="no" 184 GSTPLUG_MSG="no"
180 else 185 else
@@ -230,6 +235,7 @@ echo " Modules:"
230echo " Xine...............: $HAVE_XINE" 235echo " Xine...............: $HAVE_XINE"
231echo " Gstreamer..........: $HAVE_GSTREAMER" 236echo " Gstreamer..........: $HAVE_GSTREAMER"
232echo " Gstreamer plugins..: $GSTPLUG_MSG" 237echo " Gstreamer plugins..: $GSTPLUG_MSG"
238echo " Gstreamer FFmpeg...: $HAVE_GSTFFMPEG"
233echo 239echo
234echo " Compilation..........: make" 240echo " Compilation..........: make"
235echo 241echo
diff --git a/legacy/emotion/src/lib/emotion_private.h b/legacy/emotion/src/lib/emotion_private.h
index 1b041fa622..4ad012caea 100644
--- a/legacy/emotion/src/lib/emotion_private.h
+++ b/legacy/emotion/src/lib/emotion_private.h
@@ -24,9 +24,11 @@ typedef struct _Emotion_Video_Module Emotion_Video_Module;
24 24
25enum _Emotion_Format 25enum _Emotion_Format
26{ 26{
27 EMOTION_YV12, 27 EMOTION_FORMAT_NONE,
28 EMOTION_YUY2, /* unused for now since evas does not support yuy2 format */ 28 EMOTION_FORMAT_I420,
29 EMOTION_BGRA 29 EMOTION_FORMAT_YV12,
30 EMOTION_FORMAT_YUY2, /* unused for now since evas does not support yuy2 format */
31 EMOTION_FORMAT_BGRA
30}; 32};
31 33
32struct _Emotion_Video_Module 34struct _Emotion_Video_Module
@@ -40,6 +42,8 @@ struct _Emotion_Video_Module
40 void (*size_get) (void *ef, int *w, int *h); 42 void (*size_get) (void *ef, int *w, int *h);
41 void (*pos_set) (void *ef, double pos); 43 void (*pos_set) (void *ef, double pos);
42 double (*len_get) (void *ef); 44 double (*len_get) (void *ef);
45 int (*fps_num_get) (void *ef);
46 int (*fps_den_get) (void *ef);
43 double (*fps_get) (void *ef); 47 double (*fps_get) (void *ef);
44 double (*pos_get) (void *ef); 48 double (*pos_get) (void *ef);
45 double (*ratio_get) (void *ef); 49 double (*ratio_get) (void *ef);
diff --git a/legacy/emotion/src/lib/emotion_smart.c b/legacy/emotion/src/lib/emotion_smart.c
index f66bb562a1..01326fea17 100644
--- a/legacy/emotion/src/lib/emotion_smart.c
+++ b/legacy/emotion/src/lib/emotion_smart.c
@@ -1003,7 +1003,7 @@ _pixels_get(void *data, Evas_Object *obj)
1003 ih = h; 1003 ih = h;
1004 } 1004 }
1005 format = sd->module->format_get(sd->video); 1005 format = sd->module->format_get(sd->video);
1006 if (format == EMOTION_YV12) 1006 if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420))
1007 { 1007 {
1008 unsigned char **rows; 1008 unsigned char **rows;
1009 Evas_Pixel_Import_Source ps; 1009 Evas_Pixel_Import_Source ps;
@@ -1029,7 +1029,7 @@ _pixels_get(void *data, Evas_Object *obj)
1029 evas_object_image_pixels_dirty_set(obj, 0); 1029 evas_object_image_pixels_dirty_set(obj, 0);
1030 free(ps.rows); 1030 free(ps.rows);
1031 } 1031 }
1032 else if (format == EMOTION_BGRA) 1032 else if (format == EMOTION_FORMAT_BGRA)
1033 { 1033 {
1034 unsigned char *bgra_data; 1034 unsigned char *bgra_data;
1035 if (sd->module->bgra_data_get(sd->video, &bgra_data)); 1035 if (sd->module->bgra_data_get(sd->video, &bgra_data));
diff --git a/legacy/emotion/src/modules/emotion_gstreamer.c b/legacy/emotion/src/modules/emotion_gstreamer.c
index 8cf3552bfa..074f50c16d 100644
--- a/legacy/emotion/src/modules/emotion_gstreamer.c
+++ b/legacy/emotion/src/modules/emotion_gstreamer.c
@@ -1,24 +1,13 @@
1#include <unistd.h> 1#include <unistd.h>
2#include <fcntl.h> 2#include <fcntl.h>
3#include <math.h>
4 3
5#include "Emotion.h" 4#include "Emotion.h"
6#include "emotion_private.h" 5#include "emotion_private.h"
7#include "emotion_gstreamer.h" 6#include "emotion_gstreamer.h"
8 7
9 8
10static Emotion_Gstreamer_Video *em_v;
11 9
12static int id_new_pad; 10/* Callbacks to handle errors and EOS */
13static int id_no_more_pad;
14static int count = 0;
15static int video_streams_count = 0;
16static int audio_streams_count = 0;
17
18
19static void _em_set_pipeline_info (Emotion_Gstreamer_Video *ev);
20
21/* Callbacks to get stream information */
22static void cb_end_of_stream (GstElement *thread, 11static void cb_end_of_stream (GstElement *thread,
23 gpointer data); 12 gpointer data);
24 13
@@ -30,28 +19,16 @@ static void cb_thread_error (GstElement *thread,
30 gchar *debug, 19 gchar *debug,
31 gpointer data); 20 gpointer data);
32 21
33static void cb_new_pad (GstElement *decodebin,
34 GstPad *pad,
35 gboolean last,
36 gpointer data);
37
38static void cb_no_more_pad (GstElement *decodebin,
39 gpointer data);
40
41static void cb_caps_video_set (GObject *obj,
42 GParamSpec *pspec,
43 gpointer data);
44
45static void cb_caps_audio_set (GObject *obj,
46 GParamSpec *pspec,
47 gpointer data);
48
49/* Callbacks to display the frame content */ 22/* Callbacks to display the frame content */
50 23
51static void cb_handoff (GstElement *fakesrc, 24static void cb_handoff (GstElement *fakesrc,
52 GstBuffer *buffer, 25 GstBuffer *buffer,
53 GstPad *pad, 26 GstPad *pad,
54 gpointer user_data); 27 gpointer user_data);
28static void new_decoded_pad_cb (GstElement *decodebin,
29 GstPad *new_pad,
30 gboolean last,
31 gpointer user_data);
55 32
56static int _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh); 33static int _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh);
57 34
@@ -73,10 +50,15 @@ static void em_size_get(void *video,
73static void em_pos_set(void *video, 50static void em_pos_set(void *video,
74 double pos); 51 double pos);
75static double em_len_get(void *video); 52static double em_len_get(void *video);
53static int em_fps_num_get(void *video);
54static int em_fps_den_get(void *video);
76static double em_fps_get(void *video); 55static double em_fps_get(void *video);
77static double em_pos_get(void *video); 56static double em_pos_get(void *video);
78static double em_ratio_get(void *video); 57static double em_ratio_get(void *video);
79 58
59static int em_video_handled(void *video);
60static int em_audio_handled(void *video);
61
80static int em_seekable(void *video); 62static int em_seekable(void *video);
81static void em_frame_done(void *video); 63static void em_frame_done(void *video);
82static Emotion_Format em_format_get(void *video); 64static Emotion_Format em_format_get(void *video);
@@ -126,13 +108,73 @@ static double em_speed_get(void *video);
126static int em_eject(void *video); 108static int em_eject(void *video);
127static const char *em_meta_get(void *video, int meta); 109static const char *em_meta_get(void *video, int meta);
128 110
111/* Module interface */
112
113static Emotion_Video_Module em_module =
114{
115 em_init, /* init */
116 em_shutdown, /* shutdown */
117 em_file_open, /* file_open */
118 em_file_close, /* file_close */
119 em_play, /* play */
120 em_stop, /* stop */
121 em_size_get, /* size_get */
122 em_pos_set, /* pos_set */
123 em_len_get, /* len_get */
124 em_fps_num_get, /* fps_num_get */
125 em_fps_den_get, /* fps_den_get */
126 em_fps_get, /* fps_get */
127 em_pos_get, /* pos_get */
128 em_ratio_get, /* ratio_get */
129 em_video_handled, /* video_handled */
130 em_audio_handled, /* audio_handled */
131 em_seekable, /* seekable */
132 em_frame_done, /* frame_done */
133 em_format_get, /* format_get */
134 em_video_data_size_get, /* video_data_size_get */
135 em_yuv_rows_get, /* yuv_rows_get */
136 em_bgra_data_get, /* bgra_data_get */
137 em_event_feed, /* event_feed */
138 em_event_mouse_button_feed, /* event_mouse_button_feed */
139 em_event_mouse_move_feed, /* event_mouse_move_feed */
140 em_video_channel_count, /* video_channel_count */
141 em_video_channel_set, /* video_channel_set */
142 em_video_channel_get, /* video_channel_get */
143 em_video_channel_name_get, /* video_channel_name_get */
144 em_video_channel_mute_set, /* video_channel_mute_set */
145 em_video_channel_mute_get, /* video_channel_mute_get */
146 em_audio_channel_count, /* audio_channel_count */
147 em_audio_channel_set, /* audio_channel_set */
148 em_audio_channel_get, /* audio_channel_get */
149 em_audio_channel_name_get, /* audio_channel_name_get */
150 em_audio_channel_mute_set, /* audio_channel_mute_set */
151 em_audio_channel_mute_get, /* audio_channel_mute_get */
152 em_audio_channel_volume_set, /* audio_channel_volume_set */
153 em_audio_channel_volume_get, /* audio_channel_volume_get */
154 em_spu_channel_count, /* spu_channel_count */
155 em_spu_channel_set, /* spu_channel_set */
156 em_spu_channel_get, /* spu_channel_get */
157 em_spu_channel_name_get, /* spu_channel_name_get */
158 em_spu_channel_mute_set, /* spu_channel_mute_set */
159 em_spu_channel_mute_get, /* spu_channel_mute_get */
160 em_chapter_count, /* chapter_count */
161 em_chapter_set, /* chapter_set */
162 em_chapter_get, /* chapter_get */
163 em_chapter_name_get, /* chapter_name_get */
164 em_speed_set, /* speed_set */
165 em_speed_get, /* speed_get */
166 em_eject, /* eject */
167 em_meta_get /* meta_get */
168};
129 169
130static unsigned char 170static unsigned char
131em_init(Evas_Object *obj, 171em_init(Evas_Object *obj,
132 void **emotion_video) 172 void **emotion_video)
133{ 173{
134 Emotion_Gstreamer_Video *ev; 174 Emotion_Gstreamer_Video *ev;
135 int fds[2]; 175 GstElement *filesrc;
176 GstElement *decodebin;
177 int fds[2];
136 178
137 if (!emotion_video) 179 if (!emotion_video)
138 return 0; 180 return 0;
@@ -144,29 +186,38 @@ em_init(Evas_Object *obj,
144 ev->obj = obj; 186 ev->obj = obj;
145 ev->obj_data = NULL; 187 ev->obj_data = NULL;
146 188
147 em_v = ev;
148
149 /* Initialization of gstreamer */ 189 /* Initialization of gstreamer */
150 gst_init (NULL, NULL); 190 gst_init (NULL, NULL);
151 191
152 /* Gstreamer pipeline */ 192 /* Gstreamer pipeline */
153 ev->pipeline = gst_thread_new ("pipeline"); 193 ev->pipeline = gst_pipeline_new ("pipeline");
154 g_signal_connect (ev->pipeline, "eos", G_CALLBACK (cb_end_of_stream), ev); 194/* g_signal_connect (ev->pipeline, "eos", G_CALLBACK (cb_end_of_stream), ev); */
155 g_signal_connect (ev->pipeline, "error", G_CALLBACK (cb_thread_error), ev); 195/* g_signal_connect (ev->pipeline, "error", G_CALLBACK (cb_thread_error), ev); */
196
197 filesrc = gst_element_factory_make ("filesrc", "filesrc");
198 if (!filesrc)
199 gst_object_unref (GST_OBJECT (ev->pipeline));
200
201 decodebin = gst_element_factory_make ("decodebin", "decodebin");
202 if (!decodebin)
203 gst_object_unref (GST_OBJECT (ev->pipeline));
204 g_signal_connect (decodebin, "new-decoded-pad",
205 G_CALLBACK (new_decoded_pad_cb), ev);
206
207 gst_bin_add_many (GST_BIN (ev->pipeline), filesrc, decodebin, NULL);
208 gst_element_link (filesrc, decodebin);
156 209
157 /* We allocate the sinks lists */ 210 /* We allocate the sinks lists */
158 ev->video_sinks = ecore_list_new (); 211 ev->video_sinks = ecore_list_new ();
212 ecore_list_set_free_cb(ev->video_sinks, ECORE_FREE_CB(free));
159 ev->audio_sinks = ecore_list_new (); 213 ev->audio_sinks = ecore_list_new ();
214 ecore_list_set_free_cb(ev->audio_sinks, ECORE_FREE_CB(free));
160 215
161 *emotion_video = ev; 216 *emotion_video = ev;
162 217
163 /* Default values */ 218 /* Default values */
164 ev->width = 1;
165 ev->height = 1;
166 ev->ratio = 1.0; 219 ev->ratio = 1.0;
167 220
168 ev->position = 0;
169
170 /* Create the file descriptors */ 221 /* Create the file descriptors */
171 if (pipe(fds) == 0) 222 if (pipe(fds) == 0)
172 { 223 {
@@ -194,6 +245,11 @@ em_shutdown(void *video)
194 gst_element_set_state (ev->pipeline, GST_STATE_NULL); 245 gst_element_set_state (ev->pipeline, GST_STATE_NULL);
195 gst_object_unref (GST_OBJECT (ev->pipeline)); 246 gst_object_unref (GST_OBJECT (ev->pipeline));
196 247
248 ecore_list_destroy (ev->video_sinks);
249 ecore_list_destroy (ev->audio_sinks);
250
251 /* FIXME: and the evas object ? */
252
197 ecore_main_fd_handler_del(ev->fd_ev_handler); 253 ecore_main_fd_handler_del(ev->fd_ev_handler);
198 close(ev->fd_ev_write); 254 close(ev->fd_ev_write);
199 close(ev->fd_ev_read); 255 close(ev->fd_ev_read);
@@ -210,7 +266,7 @@ em_file_open(const char *file,
210{ 266{
211 Emotion_Gstreamer_Video *ev; 267 Emotion_Gstreamer_Video *ev;
212 GstElement *filesrc; 268 GstElement *filesrc;
213 GstElement *decoder; 269 GstStateChangeReturn res;
214 270
215 ev = (Emotion_Gstreamer_Video *)video; 271 ev = (Emotion_Gstreamer_Video *)video;
216 printf ("Open file gstreamer...\n"); 272 printf ("Open file gstreamer...\n");
@@ -219,28 +275,115 @@ em_file_open(const char *file,
219 ev->obj = obj; 275 ev->obj = obj;
220 276
221 /* Gstreamer elements */ 277 /* Gstreamer elements */
222 filesrc = gst_element_factory_make ("filesrc", "source"); 278 filesrc = gst_bin_get_by_name (GST_BIN (ev->pipeline), "filesrc");
223 g_object_set (G_OBJECT (filesrc), "location", file, NULL); 279 g_object_set (G_OBJECT (filesrc), "location", file, NULL);
224 decoder = gst_element_factory_make ("decodebin", "decoder");
225 gst_bin_add_many (GST_BIN (ev->pipeline), filesrc, decoder, NULL);
226 gst_element_link (filesrc, decoder);
227
228 gst_element_set_state (ev->pipeline, GST_STATE_READY);
229
230 /* Set the callback to get the sinks */
231 id_new_pad = g_signal_connect (G_OBJECT (decoder),
232 "new-decoded-pad",
233 G_CALLBACK (cb_new_pad), ev);
234 id_no_more_pad = g_signal_connect (G_OBJECT (decoder),
235 "no-more-pads",
236 G_CALLBACK (cb_no_more_pad), ev);
237 /* Get the sinks */
238 printf ("get sinks\n");
239 gst_element_set_state (ev->pipeline, GST_STATE_PLAYING);
240 280
241 /* we set the streams to the first frame */ 281 res = gst_element_set_state (ev->pipeline, GST_STATE_PAUSED);
242/* ev->get_poslen = 0; */ 282 if (res == GST_STATE_CHANGE_FAILURE) {
243/* ev->seek_to = 0; */ 283 g_print ("Emotion-Gstreamer ERROR: could not pause\n");
284 gst_object_unref (GST_OBJECT (ev->pipeline));
285 return 0;
286 }
287 res = gst_element_get_state (ev->pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
288 if (res != GST_STATE_CHANGE_SUCCESS) {
289 g_print ("Emotion-Gstreamer ERROR: could not complete pause\n");
290 gst_object_unref (GST_OBJECT (ev->pipeline));
291 return 0;
292 }
293
294 /* We get the informations of streams */
295 ecore_list_goto_first (ev->video_sinks);
296 ecore_list_goto_first (ev->audio_sinks);
297 {
298 GstElement *decodebin;
299 GstIterator *it;
300 gpointer data;
301
302 decodebin = gst_bin_get_by_name (GST_BIN (ev->pipeline), "decodebin");
303 it = gst_element_iterate_src_pads (decodebin);
304 while (gst_iterator_next (it, &data) == GST_ITERATOR_OK) {
305 GstPad *pad;
306 GstCaps *caps;
307 gchar *str;
308
309 pad = GST_PAD (data);
310
311 caps = gst_pad_get_caps (pad);
312 str = gst_caps_to_string (caps);
313 g_print ("%s\n", str);
314 /* video stream */
315 if (g_str_has_prefix (str, "video/")) {
316 Emotion_Video_Sink *vsink;
317 GstStructure *structure;
318 const GValue *val;
319 GstQuery *query;
320
321 vsink = (Emotion_Video_Sink *)ecore_list_next (ev->video_sinks);
322 structure = gst_caps_get_structure (GST_CAPS (caps), 0);
323
324 gst_structure_get_int (structure, "width", &vsink->width);
325 gst_structure_get_int (structure, "height", &vsink->height);
326
327 val = gst_structure_get_value (structure, "framerate");
328 if (val) {
329 vsink->fps_num = gst_value_get_fraction_numerator (val);
330 vsink->fps_den = gst_value_get_fraction_denominator (val);
331 }
332 if (g_str_has_prefix(str, "video/x-raw-yuv")) {
333 val = gst_structure_get_value (structure, "format");
334 vsink->fourcc = gst_value_get_fourcc (val);
335 }
336 else if (g_str_has_prefix(str, "video/x-raw-rgb")) {
337 vsink->fourcc = GST_MAKE_FOURCC ('A','R','G','B');
338 }
339 else
340 vsink->fourcc = 0;
341
342 printf (" size : %dx%d\n", vsink->width, vsink->height);
343 printf (" framerate : %d/%d\n", vsink->fps_num, vsink->fps_den);
344 printf (" fourcc : %" GST_FOURCC_FORMAT "\n", GST_FOURCC_ARGS (vsink->fourcc));
345
346 query = gst_query_new_duration (GST_FORMAT_TIME);
347 if (gst_pad_query (pad, query)) {
348 gint64 time;
349
350 gst_query_parse_duration (query, NULL, &time);
351 g_print (" duration : %" GST_TIME_FORMAT "\n\n", GST_TIME_ARGS (time));
352 vsink->length_time = (double)time / (double)GST_SECOND;
353 }
354 gst_query_unref (query);
355 }
356 /* audio stream */
357 else if (g_str_has_prefix (str, "audio/")) {
358 Emotion_Audio_Sink *asink;
359 GstStructure *structure;
360 GstQuery *query;
361
362 asink = (Emotion_Audio_Sink *)ecore_list_next (ev->audio_sinks);
363
364 structure = gst_caps_get_structure (GST_CAPS (caps), 0);
365
366 gst_structure_get_int (structure, "channels", &asink->channels);
367 gst_structure_get_int (structure, "rate", &asink->samplerate);
368
369 query = gst_query_new_duration (GST_FORMAT_TIME);
370 if (gst_pad_query (pad, query)) {
371 gint64 time;
372
373 gst_query_parse_duration (query, NULL, &time);
374 g_print (" duration : %" GST_TIME_FORMAT "\n\n", GST_TIME_ARGS (time));
375 asink->length_time = (double)time / (double)GST_SECOND;
376 }
377 gst_query_unref (query);
378 }
379
380 g_free (str);
381 gst_object_unref (pad);
382 }
383 gst_iterator_free (it);
384 }
385
386 ev->position = 0.0;
244 387
245 return 1; 388 return 1;
246} 389}
@@ -254,16 +397,17 @@ em_file_close(void *video)
254 if (!ev) 397 if (!ev)
255 return; 398 return;
256 399
257
258 printf("EX pause end...\n"); 400 printf("EX pause end...\n");
259 if (!emotion_object_play_get(ev->obj)) 401 if (!emotion_object_play_get(ev->obj))
260 { 402 {
261 printf(" ... unpause\n"); 403 printf(" ... unpause\n");
262 /* FIXME: do something ? */ 404 gst_element_set_state (ev->pipeline, GST_STATE_PAUSED);
263 } 405 }
264 printf("EX stop\n"); 406 printf("EX stop\n");
265 if (ev->pipeline) 407 if (ev->pipeline)
266 gst_element_set_state (ev->pipeline, GST_STATE_READY); 408 gst_element_set_state (ev->pipeline, GST_STATE_READY);
409
410 /* FIXME: delete the pipeline completely ? */
267} 411}
268 412
269static void 413static void
@@ -274,6 +418,7 @@ em_play(void *video,
274 418
275 ev = (Emotion_Gstreamer_Video *)video; 419 ev = (Emotion_Gstreamer_Video *)video;
276 gst_element_set_state (ev->pipeline, GST_STATE_PLAYING); 420 gst_element_set_state (ev->pipeline, GST_STATE_PLAYING);
421 ev->play = 1;
277} 422}
278 423
279static void 424static void
@@ -293,10 +438,19 @@ em_size_get(void *video,
293 int *height) 438 int *height)
294{ 439{
295 Emotion_Gstreamer_Video *ev; 440 Emotion_Gstreamer_Video *ev;
441 Emotion_Video_Sink *vsink;
296 442
297 ev = (Emotion_Gstreamer_Video *)video; 443 ev = (Emotion_Gstreamer_Video *)video;
298 if (width) *width = ev->width; 444
299 if (height) *height = ev->height; 445 vsink = (Emotion_Video_Sink *)ecore_list_goto_index (ev->video_sinks, ev->video_sink_nbr);
446 if (vsink) {
447 if (width) *width = vsink->width;
448 if (height) *height = vsink->height;
449 }
450 else {
451 if (width) *width = 0;
452 if (height) *height = 0;
453 }
300} 454}
301 455
302static void 456static void
@@ -304,66 +458,95 @@ em_pos_set(void *video,
304 double pos) 458 double pos)
305{ 459{
306 Emotion_Gstreamer_Video *ev; 460 Emotion_Gstreamer_Video *ev;
307 GstElement *vsink = NULL; 461 Emotion_Video_Sink *vsink;
308 GstElement *asink = NULL; 462 Emotion_Audio_Sink *asink;
309 GstSeekType type;
310 guint64 time;
311 463
312 ev = (Emotion_Gstreamer_Video *)video; 464 ev = (Emotion_Gstreamer_Video *)video;
313 465
314 if (ev->seek_to_pos == pos) return; 466 if (ev->seek_to_pos == pos) return;
315 467
316 type = (GstSeekType)(GST_FORMAT_TIME | 468 vsink = (Emotion_Video_Sink *)ecore_list_goto_index (ev->video_sinks, ev->video_sink_nbr);
317 GST_SEEK_METHOD_SET | 469 asink = (Emotion_Audio_Sink *)ecore_list_goto_index (ev->video_sinks, ev->audio_sink_nbr);
318 GST_SEEK_FLAG_FLUSH); 470
319 471 if (vsink) {
320 if (ecore_list_current (ev->video_sinks)) 472 gst_element_seek(vsink->sink, 1.0,
321 vsink = ((Emotion_Video_Sink *)(ecore_list_current (ev->video_sinks)))->sink; 473 GST_FORMAT_TIME,
322 if (ecore_list_current (ev->audio_sinks)) 474 GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
323 asink = ((Emotion_Audio_Sink *)(ecore_list_current (ev->audio_sinks)))->sink; 475 GST_SEEK_TYPE_CUR,
476 (gint64)(pos * (double)GST_SECOND),
477 GST_SEEK_TYPE_NONE,
478 -1);
479 }
480 if (asink) {
481 gst_element_seek(asink->sink, 1.0,
482 GST_FORMAT_TIME,
483 GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
484 GST_SEEK_TYPE_CUR,
485 (gint64)(pos * (double)GST_SECOND),
486 GST_SEEK_TYPE_NONE,
487 -1);
488 }
489 ev->seek_to_pos = pos;
490}
324 491
492static double
493em_len_get(void *video)
494{
495 Emotion_Gstreamer_Video *ev;
496 Emotion_Video_Sink *vsink;
325 497
326 time = (guint64)(floor (pos)); 498 ev = (Emotion_Gstreamer_Video *)video;
327 499
500 vsink = (Emotion_Video_Sink *)ecore_list_goto_index (ev->video_sinks, ev->video_sink_nbr);
328 if (vsink) 501 if (vsink)
329 gst_element_seek(vsink, type, time); 502 return (double)vsink->length_time;
330 if (asink) 503
331 gst_element_seek(asink, type, time); 504 return 0.0;
332} 505}
333 506
334static double 507static int
335em_len_get(void *video) 508em_fps_num_get(void *video)
336{ 509{
337 Emotion_Gstreamer_Video *ev; 510 Emotion_Gstreamer_Video *ev;
338 Emotion_Video_Sink *vs; 511 Emotion_Video_Sink *vsink;
339 512
340 ev = (Emotion_Gstreamer_Video *)video; 513 ev = (Emotion_Gstreamer_Video *)video;
341 514
342 if (!ecore_list_is_empty(ev->video_sinks)) 515 vsink = (Emotion_Video_Sink *)ecore_list_goto_index (ev->video_sinks, ev->video_sink_nbr);
343 { 516 if (vsink)
344 vs = (Emotion_Video_Sink *)ecore_list_current(ev->video_sinks); 517 return vsink->fps_num;
345 return vs->length_time;
346 }
347 518
348 return 0; 519 return 0;
349} 520}
350 521
522static int
523em_fps_den_get(void *video)
524{
525 Emotion_Gstreamer_Video *ev;
526 Emotion_Video_Sink *vsink;
527
528 ev = (Emotion_Gstreamer_Video *)video;
529
530 vsink = (Emotion_Video_Sink *)ecore_list_goto_index (ev->video_sinks, ev->video_sink_nbr);
531 if (vsink)
532 return vsink->fps_den;
533
534 return 1;
535}
536
351static double 537static double
352em_fps_get(void *video) 538em_fps_get(void *video)
353{ 539{
354 Emotion_Gstreamer_Video *ev; 540 Emotion_Gstreamer_Video *ev;
355 Emotion_Video_Sink *vs; 541 Emotion_Video_Sink *vsink;
356 542
357 ev = (Emotion_Gstreamer_Video *)video; 543 ev = (Emotion_Gstreamer_Video *)video;
358 544
359 /* FIXME: Maybe we can just get the fps of the current stream */ 545 vsink = (Emotion_Video_Sink *)ecore_list_goto_index (ev->video_sinks, ev->video_sink_nbr);
360 if (!ecore_list_is_empty(ev->video_sinks)) 546 if (vsink)
361 { 547 return (double)vsink->fps_num / (double)vsink->fps_den;
362 vs = (Emotion_Video_Sink *)ecore_list_current(ev->video_sinks);
363 return vs->framerate;
364 }
365 548
366 return 0; 549 return 0.0;
367} 550}
368 551
369static double 552static double
@@ -373,7 +556,7 @@ em_pos_get(void *video)
373 556
374 ev = (Emotion_Gstreamer_Video *)video; 557 ev = (Emotion_Gstreamer_Video *)video;
375 558
376 return 0;//ev->pos; 559 return ev->position;
377} 560}
378 561
379static double 562static double
@@ -393,7 +576,10 @@ em_video_handled(void *video)
393 576
394 ev = (Emotion_Gstreamer_Video *)video; 577 ev = (Emotion_Gstreamer_Video *)video;
395 578
396 return 0; 579 if (ecore_list_is_empty (ev->video_sinks))
580 return 0;
581
582 return 1;
397} 583}
398 584
399static int 585static int
@@ -403,7 +589,10 @@ em_audio_handled(void *video)
403 589
404 ev = (Emotion_Gstreamer_Video *)video; 590 ev = (Emotion_Gstreamer_Video *)video;
405 591
406 return 0; 592 if (ecore_list_is_empty (ev->audio_sinks))
593 return 0;
594
595 return 1;
407} 596}
408 597
409static int 598static int
@@ -413,7 +602,7 @@ em_seekable(void *video)
413 602
414 ev = (Emotion_Gstreamer_Video *)video; 603 ev = (Emotion_Gstreamer_Video *)video;
415 604
416 return 0; 605 return 1;
417} 606}
418 607
419static void 608static void
@@ -428,21 +617,45 @@ static Emotion_Format
428em_format_get (void *video) 617em_format_get (void *video)
429{ 618{
430 Emotion_Gstreamer_Video *ev; 619 Emotion_Gstreamer_Video *ev;
620 Emotion_Video_Sink *vsink;
431 621
432 ev = (Emotion_Gstreamer_Video *)video; 622 ev = (Emotion_Gstreamer_Video *)video;
433 623
434 return EMOTION_YV12; 624 vsink = (Emotion_Video_Sink *)ecore_list_goto_index (ev->video_sinks, ev->video_sink_nbr);
625 if (vsink) {
626 switch (vsink->fourcc) {
627 case GST_MAKE_FOURCC ('I','4','2','0'):
628 return EMOTION_FORMAT_I420;
629 case GST_MAKE_FOURCC ('Y','V','1','2'):
630 return EMOTION_FORMAT_YV12;
631 case GST_MAKE_FOURCC ('Y','U','Y','2'):
632 return EMOTION_FORMAT_YUY2;
633 case GST_MAKE_FOURCC ('A','R','G','B'):
634 return EMOTION_FORMAT_BGRA;
635 default:
636 return EMOTION_FORMAT_NONE;
637 }
638 }
639 return EMOTION_FORMAT_NONE;
435} 640}
436 641
437static void 642static void
438em_video_data_size_get(void *video, int *w, int *h) 643em_video_data_size_get(void *video, int *w, int *h)
439{ 644{
440 Emotion_Gstreamer_Video *ev; 645 Emotion_Gstreamer_Video *ev;
646 Emotion_Video_Sink *vsink;
441 647
442 ev = (Emotion_Gstreamer_Video *)video; 648 ev = (Emotion_Gstreamer_Video *)video;
443 649
444 *w= ev->width; 650 vsink = (Emotion_Video_Sink *)ecore_list_goto_index (ev->video_sinks, ev->video_sink_nbr);
445 *h = ev->height; 651 if (vsink) {
652 *w = vsink->width;
653 *h = vsink->height;
654 }
655 else {
656 *w = 0;
657 *h = 0;
658 }
446} 659}
447 660
448static int 661static int
@@ -460,14 +673,28 @@ em_yuv_rows_get(void *video,
460 673
461 if (ev->obj_data) 674 if (ev->obj_data)
462 { 675 {
463 for (i = 0; i < h; i++) 676 if (em_format_get(video) == EMOTION_FORMAT_I420) {
464 yrows[i] = &ev->obj_data[i * w]; 677 for (i = 0; i < h; i++)
678 yrows[i] = &ev->obj_data[i * w];
679
680 for (i = 0; i < (h / 2); i++)
681 urows[i] = &ev->obj_data[h * w + i * (w / 2) ];
682
683 for (i = 0; i < (h / 2); i++)
684 vrows[i] = &ev->obj_data[h * w + h * (w /4) + i * (w / 2)];
685 }
686 else if (em_format_get(video) == EMOTION_FORMAT_YV12) {
687 for (i = 0; i < h; i++)
688 yrows[i] = &ev->obj_data[i * w];
465 689
466 for (i = 0; i < (h / 2); i++) 690 for (i = 0; i < (h / 2); i++)
467 urows[i] = &ev->obj_data[h * w + i * (w / 2) ]; 691 vrows[i] = &ev->obj_data[h * w + i * (w / 2) ];
468 692
469 for (i = 0; i < (h / 2); i++) 693 for (i = 0; i < (h / 2); i++)
470 vrows[i] = &ev->obj_data[h * w + h * (w /4) + i * (w / 2)]; 694 urows[i] = &ev->obj_data[h * w + h * (w /4) + i * (w / 2)];
695 }
696 else
697 return 0;
471 698
472 return 1; 699 return 1;
473 } 700 }
@@ -482,7 +709,11 @@ em_bgra_data_get(void *video, unsigned char **bgra_data)
482 709
483 ev = (Emotion_Gstreamer_Video *)video; 710 ev = (Emotion_Gstreamer_Video *)video;
484 711
485 return 1; 712 if (ev->obj_data && em_format_get(video) == EMOTION_FORMAT_BGRA) {
713 *bgra_data = ev->obj_data;
714 return 1;
715 }
716 return 0;
486} 717}
487 718
488static void 719static void
@@ -539,7 +770,7 @@ em_video_channel_get(void *video)
539 770
540 ev = (Emotion_Gstreamer_Video *)video; 771 ev = (Emotion_Gstreamer_Video *)video;
541 772
542 return ecore_list_index(ev->video_sinks); 773 return ev->video_sink_nbr;
543} 774}
544 775
545static const char * 776static const char *
@@ -604,7 +835,7 @@ em_audio_channel_get(void *video)
604 835
605 ev = (Emotion_Gstreamer_Video *)video; 836 ev = (Emotion_Gstreamer_Video *)video;
606 837
607 return ecore_list_index(ev->audio_sinks); 838 return ev->audio_sink_nbr;
608} 839}
609 840
610static const char * 841static const char *
@@ -800,63 +1031,6 @@ em_meta_get(void *video, int meta)
800 return NULL; 1031 return NULL;
801} 1032}
802 1033
803/* Module interface */
804
805static Emotion_Video_Module em_module =
806{
807 em_init, /* init */
808 em_shutdown, /* shutdown */
809 em_file_open, /* file_open */
810 em_file_close, /* file_close */
811 em_play, /* play */
812 em_stop, /* stop */
813 em_size_get, /* size_get */
814 em_pos_set, /* pos_set */
815 em_len_get, /* len_get */
816 em_fps_get, /* fps_get */
817 em_pos_get, /* pos_get */
818 em_ratio_get, /* ratio_get */
819 em_video_handled, /* video_handled */
820 em_audio_handled, /* audio_handled */
821 em_seekable, /* seekable */
822 em_frame_done, /* frame_done */
823 em_format_get, /* format_get */
824 em_video_data_size_get, /* video_data_size_get */
825 em_yuv_rows_get, /* yuv_rows_get */
826 em_bgra_data_get, /* bgra_data_get */
827 em_event_feed, /* event_feed */
828 em_event_mouse_button_feed, /* event_mouse_button_feed */
829 em_event_mouse_move_feed, /* event_mouse_move_feed */
830 em_video_channel_count, /* video_channel_count */
831 em_video_channel_set, /* video_channel_set */
832 em_video_channel_get, /* video_channel_get */
833 em_video_channel_name_get, /* video_channel_name_get */
834 em_video_channel_mute_set, /* video_channel_mute_set */
835 em_video_channel_mute_get, /* video_channel_mute_get */
836 em_audio_channel_count, /* audio_channel_count */
837 em_audio_channel_set, /* audio_channel_set */
838 em_audio_channel_get, /* audio_channel_get */
839 em_audio_channel_name_get, /* audio_channel_name_get */
840 em_audio_channel_mute_set, /* audio_channel_mute_set */
841 em_audio_channel_mute_get, /* audio_channel_mute_get */
842 em_audio_channel_volume_set, /* audio_channel_volume_set */
843 em_audio_channel_volume_get, /* audio_channel_volume_get */
844 em_spu_channel_count, /* spu_channel_count */
845 em_spu_channel_set, /* spu_channel_set */
846 em_spu_channel_get, /* spu_channel_get */
847 em_spu_channel_name_get, /* spu_channel_name_get */
848 em_spu_channel_mute_set, /* spu_channel_mute_set */
849 em_spu_channel_mute_get, /* spu_channel_mute_get */
850 em_chapter_count, /* chapter_count */
851 em_chapter_set, /* chapter_set */
852 em_chapter_get, /* chapter_get */
853 em_chapter_name_get, /* chapter_name_get */
854 em_speed_set, /* speed_set */
855 em_speed_get, /* speed_get */
856 em_eject, /* eject */
857 em_meta_get /* meta_get */
858};
859
860unsigned char 1034unsigned char
861module_open(Evas_Object *obj, 1035module_open(Evas_Object *obj,
862 Emotion_Video_Module **module, 1036 Emotion_Video_Module **module,
@@ -879,121 +1053,6 @@ module_close(Emotion_Video_Module *module,
879 em_module.shutdown(video); 1053 em_module.shutdown(video);
880} 1054}
881 1055
882#if 0
883void
884em_debug(Emotion_Xine_Video *ev)
885{
886 int has_chapters = 0;
887 int max_spu = 0;
888 int max_audio = 0;
889 int video_channels = 0;
890 int video_streams = 0;
891 int video_seekable = 0;
892 char *title;
893 char *comment;
894 char *artist;
895 char *genre;
896 char *album;
897 char *year;
898 char *cdindex_discid;
899 int video_channel = 0;
900 int audio_channel = 0;
901 int spu_channel = 0;
902 int video_ratio = 0;
903 int audio_mode = 0;
904
905// return;
906 has_chapters = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_CHAPTERS);
907 max_spu = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
908 max_audio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
909 video_channels = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_CHANNELS);
910 video_streams = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_STREAMS);
911 video_seekable = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_SEEKABLE);
912 title = xine_get_meta_info(ev->stream, XINE_META_INFO_TITLE);
913 comment = xine_get_meta_info(ev->stream, XINE_META_INFO_COMMENT);
914 artist = xine_get_meta_info(ev->stream, XINE_META_INFO_ARTIST);
915 genre = xine_get_meta_info(ev->stream, XINE_META_INFO_GENRE);
916 album = xine_get_meta_info(ev->stream, XINE_META_INFO_ALBUM);
917 year = xine_get_meta_info(ev->stream, XINE_META_INFO_YEAR);
918 cdindex_discid = xine_get_meta_info(ev->stream, XINE_META_INFO_CDINDEX_DISCID);
919 video_channel = xine_get_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL);
920 audio_channel = xine_get_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
921 spu_channel = xine_get_param(ev->stream, XINE_PARAM_SPU_CHANNEL);
922 video_ratio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO);
923 audio_mode = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_MODE);
924 printf("has_chapters = %i\n", has_chapters);
925 printf("max_spu = %i\n", max_spu);
926 printf("max_audio = %i\n", max_audio);
927 printf("video_channels = %i\n", video_channels);
928 printf("video_streams = %i\n", video_streams);
929 printf("video_seekable = %i\n", video_seekable);
930 printf("title = %s\n", title);
931 printf("comment = %s\n", comment);
932 printf("artist = %s\n", artist);
933 printf("genre = %s\n", genre);
934 printf("album = %s\n", album);
935 printf("year = %s\n", year);
936 printf("cdindex_discid = %s\n", cdindex_discid);
937 printf("video_channel = %i\n", video_channel);
938 printf("audio_channel = %i\n", audio_channel);
939 printf("spu_channels = %i\n", spu_channel);
940 printf("video_ratio = %i\n", video_ratio);
941 printf("audio_mode = %i\n", audio_mode);
942 {
943 int i;
944
945 for (i = 0; i <= max_audio; i++)
946 {
947 char lang[XINE_LANG_MAX + 1];
948
949 lang[0] = 0;
950 printf(" AUDIO %i = ", i);
951 if (xine_get_audio_lang(ev->stream, i, lang))
952 printf("%s\n", lang);
953 else
954 printf("NONE\n");
955 }
956 for (i = 0; i <= max_spu; i++)
957 {
958 char lang[XINE_LANG_MAX + 1];
959
960 lang[0] = 0;
961 printf(" SPU %i = ", i);
962 if (xine_get_spu_lang(ev->stream, i, lang))
963 printf("%s\n", lang);
964 else
965 printf("NONE\n");
966 }
967 }
968}
969#endif
970
971static void
972_em_set_pipeline_info (Emotion_Gstreamer_Video *ev)
973{
974 Emotion_Video_Sink *video_sink;
975 GstElement *misc;
976
977 video_sink = (Emotion_Video_Sink *)ecore_list_goto_first (ev->video_sinks);
978 ev->width = video_sink->width;
979 ev->height = video_sink->height;
980 ev->ratio = (double)ev->width / (double)ev->height;
981
982 _emotion_frame_new(ev->obj);
983 _emotion_frame_resize(ev->obj,
984 ev->width, ev->height, ev->ratio);
985
986 /* we set the streams to the first frame */
987 ev->get_poslen = 0;
988 ev->seek_to = 0;
989
990 /* we add hand-offs signal to display the video */
991 misc = video_sink->sink;
992
993 g_object_set (G_OBJECT (misc ),"signal-handoffs", TRUE, NULL);
994 g_signal_connect (misc, "handoff", G_CALLBACK (cb_handoff),ev);
995}
996
997 1056
998/* 1057/*
999 * Callbacks 1058 * Callbacks
@@ -1035,315 +1094,6 @@ cb_thread_error (GstElement *thread,
1035 g_idle_add ((GSourceFunc) cb_idle_eos, NULL); 1094 g_idle_add ((GSourceFunc) cb_idle_eos, NULL);
1036} 1095}
1037 1096
1038
1039/*
1040 * Add a sink to the pipeline when it is found by the decodebin
1041 * element.
1042 */
1043void
1044cb_new_pad (GstElement *decodebin,
1045 GstPad *pad,
1046 gboolean last,
1047 gpointer data)
1048{
1049 Emotion_Gstreamer_Video *ev;
1050 GstCaps *caps;
1051 GstStructure *str;
1052 const gchar *mimetype;
1053
1054 ev = (Emotion_Gstreamer_Video *)data;
1055
1056 caps = gst_pad_get_caps (pad);
1057 str = gst_caps_get_structure (caps, 0);
1058 mimetype = gst_structure_get_name (str);
1059
1060 /* test */
1061 printf ("\nNew Pad : %s\n", gst_structure_to_string (str));
1062 /* end test */
1063
1064 if (g_str_has_prefix (mimetype, "audio/"))
1065 {
1066 Emotion_Audio_Sink *asink;
1067
1068 GstElement *audio_thread;
1069 GstElement *audioqueue;
1070 GstElement *conv;
1071 GstElement *scale;
1072 GstPad *audiopad;
1073
1074 char buf[1024];
1075 char *namebin;
1076
1077 asink = (Emotion_Audio_Sink *)malloc (sizeof (Emotion_Audio_Sink));
1078 if (!asink)
1079 return;
1080 if (!ecore_list_append(ev->audio_sinks, asink))
1081 {
1082 free (asink);
1083 return;
1084 }
1085
1086 sprintf (buf, "audio_thread%d", ecore_list_nodes (ev->audio_sinks));
1087 namebin = strdup (buf);
1088 audio_thread = gst_thread_new (namebin);
1089 free (namebin);
1090 audioqueue = gst_element_factory_make ("queue", namebin);
1091 conv = gst_element_factory_make ("audioconvert", NULL);
1092 audiopad = gst_element_get_pad (conv, "sink");
1093 scale = gst_element_factory_make ("audioscale", NULL);
1094 if (audio_streams_count == 0)
1095 asink->sink = gst_element_factory_make ("alsasink", NULL);
1096 else
1097 asink->sink = gst_element_factory_make ("fakesink", NULL);
1098 gst_bin_add_many (GST_BIN (audio_thread),
1099 audioqueue, conv, scale, asink->sink, NULL);
1100 gst_element_link_many (audioqueue, conv, scale, asink->sink, NULL);
1101
1102
1103 /* Ghost pads for the thread */
1104 gst_element_add_ghost_pad (audio_thread,
1105 gst_element_get_pad (audioqueue,
1106 "sink"),
1107 "sink");
1108
1109 gst_pad_link (pad,
1110 gst_element_get_pad (audioqueue, "sink"));
1111
1112 /* We add the thread in the pipeline */
1113 gst_bin_add (GST_BIN (ev->pipeline), audio_thread);
1114 gst_bin_sync_children_state (GST_BIN (ev->pipeline));
1115
1116/* audiopad = gst_element_get_pad (ai->sink, "sink"); */
1117 audiopad = gst_element_get_pad (gst_pad_get_real_parent (pad),
1118 "src");
1119 g_signal_connect (audiopad, "notify::caps",
1120 G_CALLBACK (cb_caps_audio_set), asink);
1121
1122 audio_streams_count++;
1123 }
1124 else
1125 {
1126 if (g_str_has_prefix (mimetype, "video/"))
1127 {
1128 Emotion_Video_Sink *vsink;
1129
1130 GstElement *video_thread;
1131 GstElement *videoqueue;
1132 GstElement *vcs;
1133 GstPad *videopad;
1134
1135 char buf[1024];
1136 char *name;
1137
1138 vsink = (Emotion_Video_Sink *)malloc (sizeof (Emotion_Video_Sink));
1139 if (!ev->video_sinks)
1140 printf ("DIABOLIC !!!\n");
1141 if (!vsink)
1142 return;
1143 if (!ecore_list_append(ev->video_sinks, vsink))
1144 {
1145 free (vsink);
1146 return;
1147 }
1148 printf ("video, sink added\n");
1149
1150 sprintf (buf, "video_thread%d", ecore_list_nodes (ev->video_sinks));
1151 name = strdup (buf);
1152 video_thread = gst_thread_new (name);
1153 free (name);
1154 videoqueue = gst_element_factory_make ("queue", NULL);
1155 vcs = gst_element_factory_make ("ffmpegcolorspace", NULL);
1156 videopad = gst_element_get_pad (vcs, "sink");
1157 vsink->sink = gst_element_factory_make ("fakesink", NULL);
1158 g_object_set (G_OBJECT (vsink->sink), "sync", TRUE, NULL);
1159 gst_bin_add_many (GST_BIN (video_thread),
1160 videoqueue, vcs, vsink->sink, NULL);
1161 gst_element_link_many (videoqueue, vcs, vsink->sink, NULL);
1162
1163
1164 /* Ghost pads for the thread */
1165 gst_element_add_ghost_pad (video_thread,
1166 gst_element_get_pad (videoqueue,
1167 "sink"),
1168 "sink");
1169
1170 gst_pad_link (pad,
1171 gst_element_get_pad (videoqueue, "sink"));
1172
1173 /* We add the thread in the pipeline */
1174 gst_bin_add (GST_BIN (ev->pipeline), video_thread);
1175 gst_bin_sync_children_state (GST_BIN (ev->pipeline));
1176
1177 /* audiopad = gst_element_get_pad (ai->sink, "sink");
1178 */
1179 videopad = gst_element_get_pad (gst_pad_get_real_parent (pad),
1180 "src");
1181 g_signal_connect (videopad, "notify::caps",
1182 G_CALLBACK (cb_caps_video_set), vsink);
1183
1184 video_streams_count++;
1185 }
1186 else
1187 {
1188 printf ("Unknown stream type\n");
1189 }
1190 }
1191}
1192
1193/*
1194 * Stop the pipeline when there is no more streams to find.
1195 */
1196void
1197cb_no_more_pad (GstElement *decodebin,
1198 gpointer data)
1199{
1200 printf ("no more pads\n");
1201
1202 if (g_signal_handler_is_connected (G_OBJECT (decodebin), id_new_pad))
1203 g_signal_handler_disconnect (G_OBJECT (decodebin), id_new_pad);
1204 if (g_signal_handler_is_connected (G_OBJECT (decodebin), id_no_more_pad))
1205 g_signal_handler_disconnect (G_OBJECT (decodebin), id_no_more_pad);
1206}
1207
1208/*
1209 * Fill the informations for each video streams
1210 */
1211void
1212cb_caps_video_set (GObject *obj,
1213 GParamSpec *pspec,
1214 gpointer data)
1215{
1216 GstStructure *str;
1217 GstPad *pad = GST_PAD (obj);
1218 Emotion_Video_Sink *vsink;
1219
1220 if (!GST_PAD_CAPS (pad))
1221 return;
1222
1223 vsink = (Emotion_Video_Sink *)data;
1224
1225 str = gst_caps_get_structure (GST_PAD_CAPS (pad), 0);
1226 if (str)
1227 {
1228 gdouble framerate;
1229 const GValue *val;
1230 gint width;
1231 gint height;
1232
1233 if ((gst_structure_get_int (str, "width", &width)) &&
1234 (gst_structure_get_int (str, "height", &height)))
1235 {
1236 vsink->width = (unsigned int)width;
1237 vsink->height = (unsigned int)height;
1238 }
1239
1240 if (gst_structure_get_double (str, "framerate", &framerate))
1241 vsink->framerate = framerate;
1242
1243 val = gst_structure_get_value (str, "pixel-aspect-ratio");
1244 if (val)
1245 {
1246 vsink->par_num = (unsigned int)gst_value_get_fraction_numerator (val);
1247 vsink->par_den = (unsigned int)gst_value_get_fraction_denominator (val);
1248 }
1249 printf ("width : %d\n", width);
1250 printf ("height : %d\n", height);
1251 printf ("frame rate : %f\n", framerate);
1252
1253 {
1254 GstFormat fmt;
1255 gint64 len;
1256 GstElement *sink;
1257
1258 sink = vsink->sink;
1259 fmt = GST_FORMAT_TIME;
1260 if (gst_element_query (sink, GST_QUERY_TOTAL, &fmt, &len))
1261 {
1262 vsink->length_time = (unsigned long long)len;
1263
1264 fmt = GST_FORMAT_DEFAULT;
1265 if (gst_element_query (sink, GST_QUERY_TOTAL, &fmt, &len))
1266 vsink->length_frames = (unsigned long long)len;
1267 else
1268 vsink->length_frames = vsink->framerate *
1269 (double)vsink->length_time / 1000000000.0;
1270
1271 printf ("frame count : %lld\n", vsink->length_frames);
1272 count ++;
1273 printf ("video, count : %d, vsc : %d asc : %d\n",
1274 count, video_streams_count, audio_streams_count);
1275 if (count == video_streams_count + audio_streams_count)
1276 {
1277 _em_set_pipeline_info (em_v);
1278 }
1279 }
1280 }
1281 }
1282}
1283
1284/*
1285 * Fill the informations for each audio streams
1286 */
1287void
1288cb_caps_audio_set (GObject *obj,
1289 GParamSpec *pspec,
1290 gpointer data)
1291{
1292 GstStructure *str;
1293 GstPad *pad = GST_PAD (obj);
1294 Emotion_Audio_Sink *asink;
1295
1296 if (!GST_PAD_CAPS (pad))
1297 return;
1298
1299 asink = (Emotion_Audio_Sink *)data;
1300
1301 str = gst_caps_get_structure (GST_PAD_CAPS (pad), 0);
1302 if (str)
1303 {
1304 gint channels;
1305 gint samplerate;
1306
1307 if (gst_structure_get_int (str, "channels", &channels))
1308 asink->channels = (unsigned int)channels;
1309
1310 if (gst_structure_get_int (str, "rate", &samplerate))
1311 asink->samplerate = (unsigned int)samplerate;
1312
1313 printf ("channels : %d\n", channels);
1314 printf ("sample rate : %d\n", samplerate);
1315
1316 {
1317 GstFormat fmt;
1318 gint64 len;
1319 GstElement *sink;
1320
1321 sink = asink->sink;
1322 fmt = GST_FORMAT_TIME;
1323 if (gst_element_query (sink, GST_QUERY_TOTAL, &fmt, &len))
1324 {
1325 asink->length_time = (unsigned long long)len;
1326
1327 fmt = GST_FORMAT_DEFAULT;
1328 if (gst_element_query (sink, GST_QUERY_TOTAL, &fmt, &len))
1329 asink->length_samples = (unsigned long long)len;
1330 else
1331 asink->length_samples = asink->samplerate *
1332 (double)asink->length_time / 1000000000.0;
1333
1334 printf ("sample count : %lld\n", asink->length_samples);
1335 count ++;
1336 printf ("audio, count : %d, vsc : %d asc : %d\n",
1337 count, video_streams_count, audio_streams_count);
1338 if (count == video_streams_count + audio_streams_count)
1339 {
1340 _em_set_pipeline_info (em_v);
1341 }
1342 }
1343 }
1344 }
1345}
1346
1347/* Send the video frame to the evas object */ 1097/* Send the video frame to the evas object */
1348static void 1098static void
1349cb_handoff (GstElement *fakesrc, 1099cb_handoff (GstElement *fakesrc,
@@ -1351,10 +1101,12 @@ cb_handoff (GstElement *fakesrc,
1351 GstPad *pad, 1101 GstPad *pad,
1352 gpointer user_data) 1102 gpointer user_data)
1353{ 1103{
1104 GstQuery *query;
1354 void *buf[2]; 1105 void *buf[2];
1355 1106
1356 Emotion_Gstreamer_Video *ev = ( Emotion_Gstreamer_Video *) user_data; 1107 Emotion_Gstreamer_Video *ev = ( Emotion_Gstreamer_Video *) user_data;
1357 1108 if (!ev)
1109 return;
1358 1110
1359 if (!ev->obj_data) 1111 if (!ev->obj_data)
1360 ev->obj_data = (void*) malloc (GST_BUFFER_SIZE(buffer) * sizeof(void)); 1112 ev->obj_data = (void*) malloc (GST_BUFFER_SIZE(buffer) * sizeof(void));
@@ -1364,6 +1116,89 @@ cb_handoff (GstElement *fakesrc,
1364 buf[1] = buffer; 1116 buf[1] = buffer;
1365 write(ev->fd_ev_write, buf, sizeof(buf)); 1117 write(ev->fd_ev_write, buf, sizeof(buf));
1366 1118
1119 query = gst_query_new_position (GST_FORMAT_TIME);
1120 if (gst_pad_query (gst_pad_get_peer (pad), query)) {
1121 gint64 position;
1122
1123 gst_query_parse_position (query, NULL, &position);
1124 ev->position = (double)position / (double)GST_SECOND;
1125 }
1126 gst_query_unref (query);
1127}
1128
1129static void
1130new_decoded_pad_cb (GstElement *decodebin,
1131 GstPad *new_pad,
1132 gboolean last,
1133 gpointer user_data)
1134{
1135 Emotion_Gstreamer_Video *ev;
1136 GstCaps *caps;
1137 gchar *str;
1138
1139 ev = (Emotion_Gstreamer_Video *)user_data;
1140 caps = gst_pad_get_caps (new_pad);
1141 str = gst_caps_to_string (caps);
1142
1143 /* video stream */
1144 if (g_str_has_prefix (str, "video/")) {
1145 Emotion_Video_Sink *vsink;
1146 GstPad *videopad;
1147
1148 vsink = (Emotion_Video_Sink *)malloc (sizeof (Emotion_Video_Sink));
1149 if (!vsink) return;
1150 if (!ecore_list_append (ev->video_sinks, vsink)) {
1151 free(vsink);
1152 return;
1153 }
1154
1155 vsink->sink = gst_element_factory_make ("fakesink", NULL);
1156 gst_bin_add (GST_BIN (ev->pipeline), vsink->sink);
1157 videopad = gst_element_get_pad (vsink->sink, "sink");
1158 gst_pad_link(new_pad, videopad);
1159 if (ecore_list_nodes(ev->video_sinks) == 1) {
1160 ev->ratio = (double)vsink->width / (double)vsink->height;
1161 g_object_set (G_OBJECT (vsink->sink), "sync", TRUE, NULL);
1162 g_object_set (G_OBJECT (vsink->sink), "signal-handoffs", TRUE, NULL);
1163 g_signal_connect (G_OBJECT (vsink->sink),
1164 "handoff",
1165 G_CALLBACK (cb_handoff), ev);
1166 }
1167 gst_element_set_state (vsink->sink, GST_STATE_PAUSED);
1168 }
1169 /* audio stream */
1170 else if (g_str_has_prefix (str, "audio/")) {
1171 Emotion_Audio_Sink *asink;
1172 GstElement *audioqueue;
1173 GstElement *conv;
1174 GstElement *resample;
1175 GstPad *audiopad;
1176
1177 asink = (Emotion_Audio_Sink *)malloc (sizeof (Emotion_Audio_Sink));
1178 if (!asink) return;
1179 if (!ecore_list_append (ev->audio_sinks, asink)) {
1180 free(asink);
1181 return;
1182 }
1183
1184 g_print ("node # %d\n", ecore_list_nodes(ev->audio_sinks));
1185 audioqueue = gst_element_factory_make ("queue", NULL);
1186 conv = gst_element_factory_make ("audioconvert", NULL);
1187 resample = gst_element_factory_make ("audioresample", NULL);
1188 if (ecore_list_nodes(ev->audio_sinks) == 1)
1189 asink->sink = gst_element_factory_make ("alsasink", NULL);
1190 else
1191 asink->sink = gst_element_factory_make ("fakesink", NULL);
1192 gst_bin_add_many (GST_BIN (ev->pipeline),
1193 audioqueue, conv, resample, asink->sink, NULL);
1194 gst_element_link_many (audioqueue, conv, resample, asink->sink, NULL);
1195 audiopad = gst_element_get_pad (audioqueue, "sink");
1196 gst_pad_link(new_pad, audiopad);
1197 gst_element_set_state (audioqueue, GST_STATE_PAUSED);
1198 gst_element_set_state (conv, GST_STATE_PAUSED);
1199 gst_element_set_state (resample, GST_STATE_PAUSED);
1200 gst_element_set_state (asink->sink, GST_STATE_PAUSED);
1201 }
1367} 1202}
1368 1203
1369static int 1204static int
diff --git a/legacy/emotion/src/modules/emotion_gstreamer.h b/legacy/emotion/src/modules/emotion_gstreamer.h
index 4b725bb362..cf106c3b55 100644
--- a/legacy/emotion/src/modules/emotion_gstreamer.h
+++ b/legacy/emotion/src/modules/emotion_gstreamer.h
@@ -1,33 +1,33 @@
1#ifndef __EMOTION_GSTREAMER_H__ 1#ifndef __EMOTION_GSTREAMER_H__
2#define __EMOTION_GSTREAMER_H__ 2#define __EMOTION_GSTREAMER_H__
3 3
4
4#include <Ecore_Data.h> 5#include <Ecore_Data.h>
5 6
6#include <gst/gst.h> 7#include <gst/gst.h>
7 8
9
8typedef struct _Emotion_Video_Sink Emotion_Video_Sink; 10typedef struct _Emotion_Video_Sink Emotion_Video_Sink;
9 11
10struct _Emotion_Video_Sink 12struct _Emotion_Video_Sink
11{ 13{
12 GstElement *sink; 14 GstElement *sink;
13 unsigned long long length_time; 15 gdouble length_time;
14 unsigned long long length_frames; 16 gint width;
15 unsigned int width; 17 gint height;
16 unsigned int height; 18 gint fps_num;
17 unsigned int par_num; 19 gint fps_den;
18 unsigned int par_den; 20 guint32 fourcc;
19 double framerate;
20}; 21};
21 22
22typedef struct _Emotion_Audio_Sink Emotion_Audio_Sink; 23typedef struct _Emotion_Audio_Sink Emotion_Audio_Sink;
23 24
24struct _Emotion_Audio_Sink 25struct _Emotion_Audio_Sink
25{ 26{
26 GstElement *sink; 27 GstElement *sink;
27 unsigned long long length_time; 28 gdouble length_time;
28 unsigned long long length_samples; 29 gint channels;
29 unsigned int channels; 30 gint samplerate;
30 unsigned int samplerate;
31}; 31};
32 32
33typedef struct _Emotion_Gstreamer_Video Emotion_Gstreamer_Video; 33typedef struct _Emotion_Gstreamer_Video Emotion_Gstreamer_Video;
@@ -35,42 +35,43 @@ typedef struct _Emotion_Gstreamer_Video Emotion_Gstreamer_Video;
35struct _Emotion_Gstreamer_Video 35struct _Emotion_Gstreamer_Video
36{ 36{
37 /* Gstreamer elements */ 37 /* Gstreamer elements */
38 GstElement *pipeline; 38 GstElement *pipeline;
39 39
40 /* Sinks */ 40 /* Sinks */
41 Ecore_List *video_sinks; 41 Ecore_List *video_sinks;
42 Ecore_List *audio_sinks; 42 Ecore_List *audio_sinks;
43
44 int video_sink_nbr;
45 int audio_sink_nbr;
43 46
44 /* Evas object */ 47 /* Evas object */
45 Evas_Object *obj; 48 Evas_Object *obj;
46 unsigned char *obj_data; 49 unsigned char *obj_data;
47 50
48 /* Characteristics */ 51 /* Characteristics of stream */
49 int position; 52 int position;
50 int width; 53 double ratio;
51 int height;
52 double ratio;
53 54
54 volatile int seek_to; 55 volatile int seek_to;
55 volatile int get_poslen; 56 volatile int get_poslen;
56 volatile double seek_to_pos; 57 volatile double seek_to_pos;
57 58
58 int fd_ev_read; 59 int fd_ev_read;
59 int fd_ev_write; 60 int fd_ev_write;
60 Ecore_Fd_Handler *fd_ev_handler; 61 Ecore_Fd_Handler *fd_ev_handler;
61 62
62 63
63 unsigned char play : 1; 64 unsigned char play : 1;
64 unsigned char video_mute : 1; 65 unsigned char video_mute : 1;
65 unsigned char audio_mute : 1; 66 unsigned char audio_mute : 1;
66}; 67};
67 68
68unsigned char module_open (Evas_Object *obj, 69unsigned char module_open (Evas_Object *obj,
69 Emotion_Video_Module **module, 70 Emotion_Video_Module **module,
70 void **video); 71 void **video);
71 72
72void module_close (Emotion_Video_Module *module, 73void module_close (Emotion_Video_Module *module,
73 void *video); 74 void *video);
74 75
75 76
76#endif /* __EMOTION_GSTREAMER_H__ */ 77#endif /* __EMOTION_GSTREAMER_H__ */
diff --git a/legacy/emotion/src/modules/emotion_xine.c b/legacy/emotion/src/modules/emotion_xine.c
index a909dcfbac..eb387a4f20 100644
--- a/legacy/emotion/src/modules/emotion_xine.c
+++ b/legacy/emotion/src/modules/emotion_xine.c
@@ -11,6 +11,8 @@ static void em_stop(void *ef);
11static void em_size_get(void *ef, int *w, int *h); 11static void em_size_get(void *ef, int *w, int *h);
12static void em_pos_set(void *ef, double pos); 12static void em_pos_set(void *ef, double pos);
13static double em_len_get(void *ef); 13static double em_len_get(void *ef);
14static int em_fps_num_get(void *ef);
15static int em_fps_den_get(void *ef);
14static double em_fps_get(void *ef); 16static double em_fps_get(void *ef);
15static double em_pos_get(void *ef); 17static double em_pos_get(void *ef);
16static double em_ratio_get(void *ef); 18static double em_ratio_get(void *ef);
@@ -483,6 +485,24 @@ em_len_get(void *ef)
483 return ev->len; 485 return ev->len;
484} 486}
485 487
488static int
489em_fps_num_get(void *ef)
490{
491 Emotion_Xine_Video *ev;
492
493 ev = (Emotion_Xine_Video *)ef;
494 return (int)(ev->fps * 10000.0);
495}
496
497static int
498em_fps_den_get(void *ef)
499{
500 Emotion_Xine_Video *ev;
501
502 ev = (Emotion_Xine_Video *)ef;
503 return 10000;
504}
505
486static double 506static double
487em_fps_get(void *ef) 507em_fps_get(void *ef)
488{ 508{
@@ -563,7 +583,7 @@ static Emotion_Format em_format_get(void *ef)
563 583
564 if (fr) 584 if (fr)
565 return fr->format; 585 return fr->format;
566 return EMOTION_YV12; 586 return EMOTION_FORMAT_YV12;
567} 587}
568 588
569static void 589static void
@@ -1370,6 +1390,8 @@ static Emotion_Video_Module em_module =
1370 em_size_get, /* size_get */ 1390 em_size_get, /* size_get */
1371 em_pos_set, /* pos_set */ 1391 em_pos_set, /* pos_set */
1372 em_len_get, /* len_get */ 1392 em_len_get, /* len_get */
1393 em_fps_num_get, /* fps_num_get */
1394 em_fps_den_get, /* fps_den_get */
1373 em_fps_get, /* fps_get */ 1395 em_fps_get, /* fps_get */
1374 em_pos_get, /* pos_get */ 1396 em_pos_get, /* pos_get */
1375 em_ratio_get, /* ratio_get */ 1397 em_ratio_get, /* ratio_get */
diff --git a/legacy/emotion/src/modules/emotion_xine_vo_out.c b/legacy/emotion/src/modules/emotion_xine_vo_out.c
index 13a400a6f1..d25efb81a9 100644
--- a/legacy/emotion/src/modules/emotion_xine_vo_out.c
+++ b/legacy/emotion/src/modules/emotion_xine_vo_out.c
@@ -361,7 +361,7 @@ _emotion_frame_format_update(vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint3
361 { 361 {
362 int y_size, uv_size; 362 int y_size, uv_size;
363 363
364 fr->frame.format = EMOTION_YV12; 364 fr->frame.format = EMOTION_FORMAT_YV12;
365 fr->vo_frame.pitches[0] = 8 * ((width + 7) / 8); 365 fr->vo_frame.pitches[0] = 8 * ((width + 7) / 8);
366 fr->vo_frame.pitches[1] = 8 * ((width + 15) / 16); 366 fr->vo_frame.pitches[1] = 8 * ((width + 15) / 16);
367 fr->vo_frame.pitches[2] = 8 * ((width + 15) / 16); 367 fr->vo_frame.pitches[2] = 8 * ((width + 15) / 16);
@@ -387,7 +387,7 @@ _emotion_frame_format_update(vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint3
387 break; 387 break;
388 case XINE_IMGFMT_YUY2: 388 case XINE_IMGFMT_YUY2:
389 { 389 {
390 fr->frame.format = EMOTION_BGRA; 390 fr->frame.format = EMOTION_FORMAT_BGRA;
391 fr->vo_frame.pitches[0] = 8 * ((width + 3) / 4); 391 fr->vo_frame.pitches[0] = 8 * ((width + 3) / 4);
392 fr->vo_frame.pitches[1] = 0; 392 fr->vo_frame.pitches[1] = 0;
393 fr->vo_frame.pitches[2] = 0; 393 fr->vo_frame.pitches[2] = 0;