6 #include "emotion_private.h"
7 #include "emotion_gstreamer.h"
10 int _emotion_gstreamer_log_domain = -1;
12 /* Callbacks to get the eos */
13 static Eina_Bool _eos_timer_fct (void *data);
14 static void _for_each_tag (GstTagList const* list, gchar const* tag, void *data);
15 static void _free_metadata (Emotion_Gstreamer_Metadata *m);
19 static unsigned char em_init (Evas_Object *obj,
21 Emotion_Module_Options *opt);
23 static int em_shutdown (void *video);
25 static unsigned char em_file_open (const char *file,
29 static void em_file_close (void *video);
31 static void em_play (void *video,
34 static void em_stop (void *video);
36 static void em_size_get (void *video,
40 static void em_pos_set (void *video,
44 static double em_len_get (void *video);
46 static int em_fps_num_get (void *video);
48 static int em_fps_den_get (void *video);
50 static double em_fps_get (void *video);
52 static double em_pos_get (void *video);
54 static void em_vis_set (void *video,
57 static Emotion_Vis em_vis_get (void *video);
59 static Eina_Bool em_vis_supported (void *video,
62 static double em_ratio_get (void *video);
64 static int em_video_handled (void *video);
66 static int em_audio_handled (void *video);
68 static int em_seekable (void *video);
70 static void em_frame_done (void *video);
72 static Emotion_Format em_format_get (void *video);
74 static void em_video_data_size_get (void *video,
78 static int em_yuv_rows_get (void *video,
81 unsigned char **yrows,
82 unsigned char **urows,
83 unsigned char **vrows);
85 static int em_bgra_data_get (void *video,
86 unsigned char **bgra_data);
88 static void em_event_feed (void *video,
91 static void em_event_mouse_button_feed (void *video,
96 static void em_event_mouse_move_feed (void *video,
100 static int em_video_channel_count (void *video);
102 static void em_video_channel_set (void *video,
105 static int em_video_channel_get (void *video);
107 static const char *em_video_channel_name_get (void *video,
110 static void em_video_channel_mute_set (void *video,
113 static int em_video_channel_mute_get (void *video);
115 static int em_audio_channel_count (void *video);
117 static void em_audio_channel_set (void *video,
120 static int em_audio_channel_get (void *video);
122 static const char *em_audio_channel_name_get (void *video,
125 static void em_audio_channel_mute_set (void *video,
128 static int em_audio_channel_mute_get (void *video);
130 static void em_audio_channel_volume_set (void *video,
133 static double em_audio_channel_volume_get (void *video);
135 static int em_spu_channel_count (void *video);
137 static void em_spu_channel_set (void *video,
140 static int em_spu_channel_get (void *video);
142 static const char *em_spu_channel_name_get (void *video,
145 static void em_spu_channel_mute_set (void *video,
148 static int em_spu_channel_mute_get (void *video);
150 static int em_chapter_count (void *video);
152 static void em_chapter_set (void *video,
155 static int em_chapter_get (void *video);
157 static const char *em_chapter_name_get (void *video,
160 static void em_speed_set (void *video,
163 static double em_speed_get (void *video);
165 static int em_eject (void *video);
167 static const char *em_meta_get (void *video,
170 /* Module interface */
172 static Emotion_Video_Module em_module =
175 em_shutdown, /* shutdown */
176 em_file_open, /* file_open */
177 em_file_close, /* file_close */
180 em_size_get, /* size_get */
181 em_pos_set, /* pos_set */
182 em_len_get, /* len_get */
183 em_fps_num_get, /* fps_num_get */
184 em_fps_den_get, /* fps_den_get */
185 em_fps_get, /* fps_get */
186 em_pos_get, /* pos_get */
187 em_vis_set, /* vis_set */
188 em_vis_get, /* vis_get */
189 em_vis_supported, /* vis_supported */
190 em_ratio_get, /* ratio_get */
191 em_video_handled, /* video_handled */
192 em_audio_handled, /* audio_handled */
193 em_seekable, /* seekable */
194 em_frame_done, /* frame_done */
195 em_format_get, /* format_get */
196 em_video_data_size_get, /* video_data_size_get */
197 em_yuv_rows_get, /* yuv_rows_get */
198 em_bgra_data_get, /* bgra_data_get */
199 em_event_feed, /* event_feed */
200 em_event_mouse_button_feed, /* event_mouse_button_feed */
201 em_event_mouse_move_feed, /* event_mouse_move_feed */
202 em_video_channel_count, /* video_channel_count */
203 em_video_channel_set, /* video_channel_set */
204 em_video_channel_get, /* video_channel_get */
205 em_video_channel_name_get, /* video_channel_name_get */
206 em_video_channel_mute_set, /* video_channel_mute_set */
207 em_video_channel_mute_get, /* video_channel_mute_get */
208 em_audio_channel_count, /* audio_channel_count */
209 em_audio_channel_set, /* audio_channel_set */
210 em_audio_channel_get, /* audio_channel_get */
211 em_audio_channel_name_get, /* audio_channel_name_get */
212 em_audio_channel_mute_set, /* audio_channel_mute_set */
213 em_audio_channel_mute_get, /* audio_channel_mute_get */
214 em_audio_channel_volume_set, /* audio_channel_volume_set */
215 em_audio_channel_volume_get, /* audio_channel_volume_get */
216 em_spu_channel_count, /* spu_channel_count */
217 em_spu_channel_set, /* spu_channel_set */
218 em_spu_channel_get, /* spu_channel_get */
219 em_spu_channel_name_get, /* spu_channel_name_get */
220 em_spu_channel_mute_set, /* spu_channel_mute_set */
221 em_spu_channel_mute_get, /* spu_channel_mute_get */
222 em_chapter_count, /* chapter_count */
223 em_chapter_set, /* chapter_set */
224 em_chapter_get, /* chapter_get */
225 em_chapter_name_get, /* chapter_name_get */
226 em_speed_set, /* speed_set */
227 em_speed_get, /* speed_get */
228 em_eject, /* eject */
229 em_meta_get, /* meta_get */
233 static Emotion_Video_Stream *
234 emotion_video_stream_new(Emotion_Gstreamer_Video *ev)
236 Emotion_Video_Stream *vstream;
238 if (!ev) return NULL;
240 vstream = (Emotion_Video_Stream *)calloc(1, sizeof(Emotion_Video_Stream));
241 if (!vstream) return NULL;
243 ev->video_streams = eina_list_append(ev->video_streams, vstream);
244 if (eina_error_get())
253 emotion_video_stream_free(Emotion_Gstreamer_Video *ev, Emotion_Video_Stream *vstream)
255 if (!ev || !vstream) return;
257 ev->video_streams = eina_list_remove(ev->video_streams, vstream);
262 emotion_visualization_element_name_get(Emotion_Vis visualisation)
264 switch (visualisation)
266 case EMOTION_VIS_NONE:
268 case EMOTION_VIS_GOOM:
270 case EMOTION_VIS_LIBVISUAL_BUMPSCOPE:
271 return "libvisual_bumpscope";
272 case EMOTION_VIS_LIBVISUAL_CORONA:
273 return "libvisual_corona";
274 case EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES:
275 return "libvisual_dancingparticles";
276 case EMOTION_VIS_LIBVISUAL_GDKPIXBUF:
277 return "libvisual_gdkpixbuf";
278 case EMOTION_VIS_LIBVISUAL_G_FORCE:
279 return "libvisual_G-Force";
280 case EMOTION_VIS_LIBVISUAL_GOOM:
281 return "libvisual_goom";
282 case EMOTION_VIS_LIBVISUAL_INFINITE:
283 return "libvisual_infinite";
284 case EMOTION_VIS_LIBVISUAL_JAKDAW:
285 return "libvisual_jakdaw";
286 case EMOTION_VIS_LIBVISUAL_JESS:
287 return "libvisual_jess";
288 case EMOTION_VIS_LIBVISUAL_LV_ANALYSER:
289 return "libvisual_lv_analyzer";
290 case EMOTION_VIS_LIBVISUAL_LV_FLOWER:
291 return "libvisual_lv_flower";
292 case EMOTION_VIS_LIBVISUAL_LV_GLTEST:
293 return "libvisual_lv_gltest";
294 case EMOTION_VIS_LIBVISUAL_LV_SCOPE:
295 return "libvisual_lv_scope";
296 case EMOTION_VIS_LIBVISUAL_MADSPIN:
297 return "libvisual_madspin";
298 case EMOTION_VIS_LIBVISUAL_NEBULUS:
299 return "libvisual_nebulus";
300 case EMOTION_VIS_LIBVISUAL_OINKSIE:
301 return "libvisual_oinksie";
302 case EMOTION_VIS_LIBVISUAL_PLASMA:
303 return "libvisual_plazma";
310 em_init(Evas_Object *obj,
311 void **emotion_video,
312 Emotion_Module_Options *opt __UNUSED__)
314 Emotion_Gstreamer_Video *ev;
320 ev = calloc(1, sizeof(Emotion_Gstreamer_Video));
325 /* Initialization of gstreamer */
326 if (!gst_init_check(NULL, NULL, &error))
331 ev->vis = EMOTION_VIS_NONE;
345 em_shutdown(void *video)
347 Emotion_Gstreamer_Video *ev;
348 Emotion_Audio_Stream *astream;
349 Emotion_Video_Stream *vstream;
351 ev = (Emotion_Gstreamer_Video *)video;
357 gst_element_set_state(ev->pipeline, GST_STATE_NULL);
358 gst_object_unref(ev->pipeline);
362 EINA_LIST_FREE(ev->audio_streams, astream)
364 EINA_LIST_FREE(ev->video_streams, vstream)
374 em_file_open(const char *file,
378 Emotion_Gstreamer_Video *ev;
379 Eina_Strbuf *sbuf = NULL;
384 ev = (Emotion_Gstreamer_Video *)video;
386 if (!file) return EINA_FALSE;
387 if (strstr(file, "://") == NULL)
389 sbuf = eina_strbuf_new();
390 eina_strbuf_append(sbuf, "file://");
391 if (strncmp(file, "./", 2) == 0)
393 if (strstr(file, ":/") != NULL)
394 { /* We absolutely need file:///C:/ under Windows, so adding it here */
395 eina_strbuf_append(sbuf, "/");
397 else if (*file != '/')
401 if (getcwd(tmp, PATH_MAX))
403 eina_strbuf_append(sbuf, tmp);
404 eina_strbuf_append(sbuf, "/");
407 eina_strbuf_append(sbuf, file);
410 start = ecore_time_get();
411 uri = sbuf ? eina_strbuf_string_get(sbuf) : file;
412 DBG("setting file to '%s'", uri);
413 ev->pipeline = gstreamer_video_sink_new(ev, obj, uri);
414 if (sbuf) eina_strbuf_free(sbuf);
415 end = ecore_time_get();
416 DBG("Pipeline creation: %f", end - start);
421 start = ecore_time_get();
422 ev->eos_bus = gst_pipeline_get_bus(GST_PIPELINE(ev->pipeline));
425 ERR("could not get the bus");
428 end = ecore_time_get();
429 DBG("Get the bus: %f", end - start);
436 g_object_get(G_OBJECT(ev->pipeline),
437 "n-audio", &ev->audio_stream_nbr,
438 "n-video", &ev->video_stream_nbr,
441 if ((ev->video_stream_nbr == 0) && (ev->audio_stream_nbr == 0))
443 ERR("No audio nor video stream found");
444 gst_object_unref(ev->pipeline);
451 start = ecore_time_get();
452 for (i = 0; i < ev->video_stream_nbr; i++)
454 Emotion_Video_Stream *vstream;
457 GstStructure *structure;
462 gdouble length_time = 0.0;
469 g_signal_emit_by_name(ev->pipeline, "get-video-pad", i, &pad);
473 caps = gst_pad_get_negotiated_caps(pad);
476 structure = gst_caps_get_structure(caps, 0);
477 str = gst_caps_to_string(caps);
479 if (!gst_structure_get_int(structure, "width", &width))
481 if (!gst_structure_get_int(structure, "height", &height))
483 if (!gst_structure_get_fraction(structure, "framerate", &fps_num, &fps_den))
486 if (g_str_has_prefix(str, "video/x-raw-yuv"))
488 val = gst_structure_get_value(structure, "format");
489 fourcc = gst_value_get_fourcc(val);
491 else if (g_str_has_prefix(str, "video/x-raw-rgb"))
492 fourcc = GST_MAKE_FOURCC('A', 'R', 'G', 'B');
496 query = gst_query_new_duration(GST_FORMAT_TIME);
497 if (gst_pad_peer_query(pad, query))
501 gst_query_parse_duration(query, NULL, &t);
502 length_time = (double)t / (double)GST_SECOND;
507 vstream = emotion_video_stream_new(ev);
508 if (!vstream) goto unref_query_v;
510 vstream->length_time = length_time;
511 vstream->width = width;
512 vstream->height = height;
513 vstream->fps_num = fps_num;
514 vstream->fps_den = fps_den;
515 vstream->fourcc = fourcc;
519 gst_query_unref(query);
521 gst_caps_unref(caps);
523 gst_object_unref(pad);
525 end = ecore_time_get();
526 DBG("Get video streams: %f", end - start);
530 start = ecore_time_get();
531 for (i = 0; i < ev->audio_stream_nbr; i++)
533 Emotion_Audio_Stream *astream;
536 GstStructure *structure;
539 gdouble length_time = 0.0;
543 g_signal_emit_by_name(ev->pipeline, "get-audio-pad", i, &pad);
547 caps = gst_pad_get_negotiated_caps(pad);
550 structure = gst_caps_get_structure(caps, 0);
552 if (!gst_structure_get_int(structure, "channels", &channels))
554 if (!gst_structure_get_int(structure, "rate", &samplerate))
557 query = gst_query_new_duration(GST_FORMAT_TIME);
558 if (gst_pad_peer_query(pad, query))
562 gst_query_parse_duration(query, NULL, &t);
563 length_time = (double)t / (double)GST_SECOND;
568 astream = calloc(1, sizeof(Emotion_Audio_Stream));
569 if (!astream) continue;
570 ev->audio_streams = eina_list_append(ev->audio_streams, astream);
571 if (eina_error_get())
577 astream->length_time = length_time;
578 astream->channels = channels;
579 astream->samplerate = samplerate;
582 gst_query_unref(query);
584 gst_caps_unref(caps);
586 gst_object_unref(pad);
588 end = ecore_time_get();
589 DBG("Get audio streams: %f", end - start);
591 /* Visualization sink */
593 start = ecore_time_get();
594 if (ev->video_stream_nbr == 0)
596 GstElement *vis = NULL;
597 Emotion_Video_Stream *vstream;
598 Emotion_Audio_Stream *astream;
600 const char *vis_name;
602 if (!(vis_name = emotion_visualization_element_name_get(ev->vis)))
604 ERR("pb vis name %d\n", ev->vis);
608 astream = eina_list_data_get(ev->audio_streams);
610 vis = gst_element_factory_make(vis_name, "vissink");
611 vstream = emotion_video_stream_new(ev);
615 DBG("could not create visualization stream");
617 vstream->length_time = astream->length_time;
618 vstream->width = 320;
619 vstream->height = 200;
620 vstream->fps_num = 25;
621 vstream->fps_den = 1;
622 vstream->fourcc = GST_MAKE_FOURCC('A', 'R', 'G', 'B');
624 g_object_set(G_OBJECT(ev->pipeline), "vis-plugin", vis, NULL);
625 g_object_get(G_OBJECT(ev->pipeline), "flags", &flags, NULL);
627 g_object_set(G_OBJECT(ev->pipeline), "flags", flags, NULL);
629 end = ecore_time_get();
630 DBG("Get visualization streams: %f", end - start);
634 ev->video_stream_nbr = eina_list_count(ev->video_streams);
635 ev->audio_stream_nbr = eina_list_count(ev->audio_streams);
637 if (ev->video_stream_nbr == 1)
639 Emotion_Video_Stream *vstream;
641 vstream = eina_list_data_get(ev->video_streams);
642 ev->ratio = (double)vstream->width / (double)vstream->height;
643 _emotion_frame_resize(ev->obj, vstream->width, vstream->height, ev->ratio);
647 /* on recapitule : */
648 Emotion_Video_Stream *vstream;
649 Emotion_Audio_Stream *astream;
651 vstream = eina_list_data_get(ev->video_streams);
654 DBG("video size=%dx%d, fps=%d/%d, "
655 "fourcc=%"GST_FOURCC_FORMAT", length=%"GST_TIME_FORMAT,
656 vstream->width, vstream->height, vstream->fps_num, vstream->fps_den,
657 GST_FOURCC_ARGS(vstream->fourcc),
658 GST_TIME_ARGS((guint64)(vstream->length_time * GST_SECOND)));
661 astream = eina_list_data_get(ev->audio_streams);
664 DBG("audio channels=%d, rate=%d, length=%"GST_TIME_FORMAT,
665 astream->channels, astream->samplerate,
666 GST_TIME_ARGS((guint64)(astream->length_time * GST_SECOND)));
671 _free_metadata(ev->metadata);
672 ev->metadata = calloc(1, sizeof(Emotion_Gstreamer_Metadata));
674 start = ecore_time_get();
675 em_audio_channel_volume_set(ev, ev->volume);
678 _emotion_open_done(ev->obj);
679 end = ecore_time_get();
680 DBG("Last stuff: %f", end - start);
686 em_file_close(void *video)
688 Emotion_Gstreamer_Video *ev;
689 Emotion_Audio_Stream *astream;
690 Emotion_Video_Stream *vstream;
692 ev = (Emotion_Gstreamer_Video *)video;
698 gst_object_unref(GST_OBJECT(ev->eos_bus));
702 /* we clear the stream lists */
703 EINA_LIST_FREE(ev->audio_streams, astream)
705 EINA_LIST_FREE(ev->video_streams, vstream)
711 ecore_timer_del(ev->eos_timer);
712 ev->eos_timer = NULL;
717 _free_metadata(ev->metadata);
724 double pos __UNUSED__)
726 Emotion_Gstreamer_Video *ev;
728 ev = (Emotion_Gstreamer_Video *)video;
729 gst_element_set_state(ev->pipeline, GST_STATE_PLAYING);
731 ev->play_started = 1;
734 ev->eos_timer = ecore_timer_add(0.1, _eos_timer_fct, ev);
740 Emotion_Gstreamer_Video *ev;
742 ev = (Emotion_Gstreamer_Video *)video;
747 ecore_timer_del(ev->eos_timer);
748 ev->eos_timer = NULL;
751 gst_element_set_state(ev->pipeline, GST_STATE_PAUSED);
756 em_size_get(void *video,
760 Emotion_Gstreamer_Video *ev;
761 Emotion_Video_Stream *vstream;
763 ev = (Emotion_Gstreamer_Video *)video;
765 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
768 if (width) *width = vstream->width;
769 if (height) *height = vstream->height;
773 if (width) *width = 0;
774 if (height) *height = 0;
779 em_pos_set(void *video,
782 Emotion_Gstreamer_Video *ev;
785 ev = (Emotion_Gstreamer_Video *)video;
787 res = gst_element_seek(ev->pipeline, 1.0,
789 GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
791 (gint64)(pos * (double)GST_SECOND),
792 GST_SEEK_TYPE_NONE, -1);
796 em_len_get(void *video)
798 Emotion_Gstreamer_Video *ev;
799 Emotion_Video_Stream *vstream;
800 Emotion_Audio_Stream *astream;
807 fmt = GST_FORMAT_TIME;
808 ret = gst_element_query_duration(ev->pipeline, &fmt, &val);
812 if (fmt != GST_FORMAT_TIME)
814 DBG("requrested duration in time, but got %s instead.",
815 gst_format_get_name(fmt));
822 return val / 1000000000.0;
825 EINA_LIST_FOREACH(ev->audio_streams, l, astream)
826 if (astream->length_time >= 0)
827 return astream->length_time;
829 EINA_LIST_FOREACH(ev->video_streams, l, vstream)
830 if (vstream->length_time >= 0)
831 return vstream->length_time;
837 em_fps_num_get(void *video)
839 Emotion_Gstreamer_Video *ev;
840 Emotion_Video_Stream *vstream;
842 ev = (Emotion_Gstreamer_Video *)video;
844 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
846 return vstream->fps_num;
852 em_fps_den_get(void *video)
854 Emotion_Gstreamer_Video *ev;
855 Emotion_Video_Stream *vstream;
857 ev = (Emotion_Gstreamer_Video *)video;
859 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
861 return vstream->fps_den;
867 em_fps_get(void *video)
869 Emotion_Gstreamer_Video *ev;
870 Emotion_Video_Stream *vstream;
872 ev = (Emotion_Gstreamer_Video *)video;
874 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
876 return (double)vstream->fps_num / (double)vstream->fps_den;
882 em_pos_get(void *video)
884 Emotion_Gstreamer_Video *ev;
890 fmt = GST_FORMAT_TIME;
891 ret = gst_element_query_position(ev->pipeline, &fmt, &val);
895 if (fmt != GST_FORMAT_TIME)
897 ERR("requrested position in time, but got %s instead.",
898 gst_format_get_name(fmt));
902 ev->position = val / 1000000000.0;
907 em_vis_set(void *video,
910 Emotion_Gstreamer_Video *ev;
912 ev = (Emotion_Gstreamer_Video *)video;
914 if (ev->vis == vis) return;
919 em_vis_get(void *video)
921 Emotion_Gstreamer_Video *ev;
923 ev = (Emotion_Gstreamer_Video *)video;
929 em_vis_supported(void *ef __UNUSED__, Emotion_Vis vis)
932 GstElementFactory *factory;
934 if (vis == EMOTION_VIS_NONE)
937 name = emotion_visualization_element_name_get(vis);
941 factory = gst_element_factory_find(name);
945 gst_object_unref(factory);
950 em_ratio_get(void *video)
952 Emotion_Gstreamer_Video *ev;
954 ev = (Emotion_Gstreamer_Video *)video;
960 em_video_handled(void *video)
962 Emotion_Gstreamer_Video *ev;
964 ev = (Emotion_Gstreamer_Video *)video;
966 if (!eina_list_count(ev->video_streams))
973 em_audio_handled(void *video)
975 Emotion_Gstreamer_Video *ev;
977 ev = (Emotion_Gstreamer_Video *)video;
979 if (!eina_list_count(ev->audio_streams))
986 em_seekable(void *video __UNUSED__)
992 em_frame_done(void *video __UNUSED__)
996 static Emotion_Format
997 em_format_get(void *video)
999 Emotion_Gstreamer_Video *ev;
1000 Emotion_Video_Stream *vstream;
1002 ev = (Emotion_Gstreamer_Video *)video;
1004 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
1007 switch (vstream->fourcc)
1009 case GST_MAKE_FOURCC('I', '4', '2', '0'):
1010 return EMOTION_FORMAT_I420;
1011 case GST_MAKE_FOURCC('Y', 'V', '1', '2'):
1012 return EMOTION_FORMAT_YV12;
1013 case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'):
1014 return EMOTION_FORMAT_YUY2;
1015 case GST_MAKE_FOURCC('A', 'R', 'G', 'B'):
1016 return EMOTION_FORMAT_BGRA;
1018 return EMOTION_FORMAT_NONE;
1021 return EMOTION_FORMAT_NONE;
1025 em_video_data_size_get(void *video, int *w, int *h)
1027 Emotion_Gstreamer_Video *ev;
1028 Emotion_Video_Stream *vstream;
1030 ev = (Emotion_Gstreamer_Video *)video;
1032 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
1035 *w = vstream->width;
1036 *h = vstream->height;
1046 em_yuv_rows_get(void *video __UNUSED__,
1049 unsigned char **yrows __UNUSED__,
1050 unsigned char **urows __UNUSED__,
1051 unsigned char **vrows __UNUSED__)
1057 em_bgra_data_get(void *video __UNUSED__, unsigned char **bgra_data __UNUSED__)
1063 em_event_feed(void *video __UNUSED__, int event __UNUSED__)
1068 em_event_mouse_button_feed(void *video __UNUSED__, int button __UNUSED__, int x __UNUSED__, int y __UNUSED__)
1073 em_event_mouse_move_feed(void *video __UNUSED__, int x __UNUSED__, int y __UNUSED__)
1077 /* Video channels */
1079 em_video_channel_count(void *video)
1081 Emotion_Gstreamer_Video *ev;
1083 ev = (Emotion_Gstreamer_Video *)video;
1085 return eina_list_count(ev->video_streams);
1089 em_video_channel_set(void *video __UNUSED__,
1090 int channel __UNUSED__)
1093 Emotion_Gstreamer_Video *ev;
1095 ev = (Emotion_Gstreamer_Video *)video;
1097 if (channel < 0) channel = 0;
1099 /* FIXME: a faire... */
1103 em_video_channel_get(void *video)
1105 Emotion_Gstreamer_Video *ev;
1107 ev = (Emotion_Gstreamer_Video *)video;
1109 return ev->video_stream_nbr;
1113 em_video_channel_name_get(void *video __UNUSED__,
1114 int channel __UNUSED__)
1120 em_video_channel_mute_set(void *video,
1123 Emotion_Gstreamer_Video *ev;
1125 ev = (Emotion_Gstreamer_Video *)video;
1127 ev->video_mute = mute;
1131 em_video_channel_mute_get(void *video)
1133 Emotion_Gstreamer_Video *ev;
1135 ev = (Emotion_Gstreamer_Video *)video;
1137 return ev->video_mute;
1140 /* Audio channels */
1143 em_audio_channel_count(void *video)
1145 Emotion_Gstreamer_Video *ev;
1147 ev = (Emotion_Gstreamer_Video *)video;
1149 return eina_list_count(ev->audio_streams);
1153 em_audio_channel_set(void *video __UNUSED__,
1154 int channel __UNUSED__)
1157 Emotion_Gstreamer_Video *ev;
1159 ev = (Emotion_Gstreamer_Video *)video;
1161 if (channel < -1) channel = -1;
1163 /* FIXME: a faire... */
1167 em_audio_channel_get(void *video)
1169 Emotion_Gstreamer_Video *ev;
1171 ev = (Emotion_Gstreamer_Video *)video;
1173 return ev->audio_stream_nbr;
1177 em_audio_channel_name_get(void *video __UNUSED__,
1178 int channel __UNUSED__)
1183 #define GST_PLAY_FLAG_AUDIO (1 << 1)
1186 em_audio_channel_mute_set(void *video,
1189 Emotion_Gstreamer_Video *ev;
1192 ev = (Emotion_Gstreamer_Video *)video;
1194 if (ev->audio_mute == mute)
1197 ev->audio_mute = mute;
1199 g_object_set(G_OBJECT(ev->pipeline), "mute", !!mute, NULL);
1200 /* This code should stop the decoding of only the audio stream, but everything stop :"( */
1201 /* g_object_get(G_OBJECT(ev->pipeline), "flags", &flags, NULL); */
1203 /* flags &= ~GST_PLAY_FLAG_AUDIO; */
1205 /* flags |= GST_PLAY_FLAG_AUDIO; */
1206 /* g_object_set(G_OBJECT(ev->pipeline), "flags", flags, NULL); */
1207 /* g_object_get(G_OBJECT(ev->pipeline), "flags", &flags, NULL); */
1208 /* fprintf(stderr, "flags-n: %x\n", flags); */
1212 em_audio_channel_mute_get(void *video)
1214 Emotion_Gstreamer_Video *ev;
1216 ev = (Emotion_Gstreamer_Video *)video;
1218 return ev->audio_mute;
1222 em_audio_channel_volume_set(void *video,
1225 Emotion_Gstreamer_Video *ev;
1227 ev = (Emotion_Gstreamer_Video *)video;
1234 g_object_set(G_OBJECT(ev->pipeline), "volume", vol, NULL);
1238 em_audio_channel_volume_get(void *video)
1240 Emotion_Gstreamer_Video *ev;
1242 ev = (Emotion_Gstreamer_Video *)video;
1250 em_spu_channel_count(void *video __UNUSED__)
1256 em_spu_channel_set(void *video __UNUSED__, int channel __UNUSED__)
1261 em_spu_channel_get(void *video __UNUSED__)
1267 em_spu_channel_name_get(void *video __UNUSED__, int channel __UNUSED__)
1273 em_spu_channel_mute_set(void *video __UNUSED__, int mute __UNUSED__)
1278 em_spu_channel_mute_get(void *video __UNUSED__)
1284 em_chapter_count(void *video __UNUSED__)
1290 em_chapter_set(void *video __UNUSED__, int chapter __UNUSED__)
1295 em_chapter_get(void *video __UNUSED__)
1301 em_chapter_name_get(void *video __UNUSED__, int chapter __UNUSED__)
1307 em_speed_set(void *video __UNUSED__, double speed __UNUSED__)
1312 em_speed_get(void *video __UNUSED__)
1318 em_eject(void *video __UNUSED__)
1324 em_meta_get(void *video, int meta)
1326 Emotion_Gstreamer_Video *ev;
1327 const char *str = NULL;
1329 ev = (Emotion_Gstreamer_Video *)video;
1331 if (!ev || !ev->metadata) return NULL;
1334 case META_TRACK_TITLE:
1335 str = ev->metadata->title;
1337 case META_TRACK_ARTIST:
1338 str = ev->metadata->artist;
1340 case META_TRACK_ALBUM:
1341 str = ev->metadata->album;
1343 case META_TRACK_YEAR:
1344 str = ev->metadata->year;
1346 case META_TRACK_GENRE:
1347 str = ev->metadata->genre;
1349 case META_TRACK_COMMENT:
1350 str = ev->metadata->comment;
1352 case META_TRACK_DISCID:
1353 str = ev->metadata->disc_id;
1363 module_open(Evas_Object *obj,
1364 const Emotion_Video_Module **module,
1366 Emotion_Module_Options *opt)
1371 if (_emotion_gstreamer_log_domain < 0)
1373 eina_threads_init();
1374 eina_log_threads_enable();
1375 _emotion_gstreamer_log_domain = eina_log_domain_register
1376 ("emotion-gstreamer", EINA_COLOR_LIGHTCYAN);
1377 if (_emotion_gstreamer_log_domain < 0)
1379 EINA_LOG_CRIT("Could not register log domain 'emotion-gstreamer'");
1384 if (!em_module.init(obj, video, opt))
1387 eina_threads_init();
1389 *module = &em_module;
1394 module_close(Emotion_Video_Module *module __UNUSED__,
1397 em_module.shutdown(video);
1399 eina_threads_shutdown();
1403 gstreamer_module_init(void)
1407 if (!gst_init_check(0, NULL, &error))
1409 EINA_LOG_CRIT("Could not init GStreamer");
1413 if (gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR,
1415 "video sink plugin for Emotion",
1416 gstreamer_plugin_init,
1421 "http://www.enlightenment.org/") == FALSE)
1423 EINA_LOG_CRIT("Could not load static gstreamer video sink for Emotion.");
1427 return _emotion_module_register("gstreamer", module_open, module_close);
1431 gstreamer_module_shutdown(void)
1433 _emotion_module_unregister("gstreamer");
1438 #ifndef EMOTION_STATIC_BUILD_GSTREAMER
1440 EINA_MODULE_INIT(gstreamer_module_init);
1441 EINA_MODULE_SHUTDOWN(gstreamer_module_shutdown);
1446 _for_each_tag(GstTagList const* list,
1450 Emotion_Gstreamer_Video *ev;
1455 ev = (Emotion_Gstreamer_Video*)data;
1457 if (!ev || !ev->metadata) return;
1459 count = gst_tag_list_get_tag_size(list, tag);
1461 for (i = 0; i < count; i++)
1463 if (!strcmp(tag, GST_TAG_TITLE))
1466 if (ev->metadata->title) g_free(ev->metadata->title);
1467 if (gst_tag_list_get_string(list, GST_TAG_TITLE, &str))
1468 ev->metadata->title = str;
1470 ev->metadata->title = NULL;
1473 if (!strcmp(tag, GST_TAG_ALBUM))
1476 if (ev->metadata->album) g_free(ev->metadata->album);
1477 if (gst_tag_list_get_string(list, GST_TAG_ALBUM, &str))
1478 ev->metadata->album = str;
1480 ev->metadata->album = NULL;
1483 if (!strcmp(tag, GST_TAG_ARTIST))
1486 if (ev->metadata->artist) g_free( ev->metadata->artist);
1487 if (gst_tag_list_get_string(list, GST_TAG_ARTIST, &str))
1488 ev->metadata->artist = str;
1490 ev->metadata->artist = NULL;
1493 if (!strcmp(tag, GST_TAG_GENRE))
1496 if (ev->metadata->genre) g_free( ev->metadata->genre);
1497 if (gst_tag_list_get_string(list, GST_TAG_GENRE, &str))
1498 ev->metadata->genre = str;
1500 ev->metadata->genre = NULL;
1503 if (!strcmp(tag, GST_TAG_COMMENT))
1506 if (ev->metadata->comment) g_free(ev->metadata->comment);
1507 if (gst_tag_list_get_string(list, GST_TAG_COMMENT, &str))
1508 ev->metadata->comment = str;
1510 ev->metadata->comment = NULL;
1513 if (!strcmp(tag, GST_TAG_DATE))
1517 if (ev->metadata->year) g_free(ev->metadata->year);
1518 date = gst_tag_list_get_value_index(list, GST_TAG_DATE, 0);
1520 str = g_strdup_value_contents(date);
1523 ev->metadata->year = str;
1527 if (!strcmp(tag, GST_TAG_TRACK_NUMBER))
1530 const GValue *track;
1531 if (ev->metadata->count) g_free( ev->metadata->count);
1532 track = gst_tag_list_get_value_index(list, GST_TAG_TRACK_NUMBER, 0);
1534 str = g_strdup_value_contents(track);
1537 ev->metadata->count = str;
1541 #ifdef GST_TAG_CDDA_CDDB_DISCID
1542 if (!strcmp(tag, GST_TAG_CDDA_CDDB_DISCID))
1545 const GValue *discid;
1546 if (ev->metadata->disc_id) g_free(ev->metadata->disc_id);
1547 discid = gst_tag_list_get_value_index(list, GST_TAG_CDDA_CDDB_DISCID, 0);
1549 str = g_strdup_value_contents(discid);
1552 ev->metadata->disc_id = str;
1561 _free_metadata(Emotion_Gstreamer_Metadata *m)
1565 if (m->title) g_free(m->title);
1566 if (m->album) g_free(m->album);
1567 if (m->artist) g_free(m->artist);
1568 if (m->genre) g_free(m->genre);
1569 if (m->comment) g_free(m->comment);
1570 if (m->year) g_free(m->year);
1571 if (m->count) g_free(m->count);
1572 if (m->disc_id) g_free(m->disc_id);
1578 _eos_timer_fct(void *data)
1580 Emotion_Gstreamer_Video *ev;
1583 ev = (Emotion_Gstreamer_Video *)data;
1584 if (ev->play_started)
1586 _emotion_playback_started(ev->obj);
1587 ev->play_started = 0;
1589 while ((msg = gst_bus_poll(ev->eos_bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_TAG | GST_MESSAGE_ASYNC_DONE, 0)))
1591 switch (GST_MESSAGE_TYPE(msg))
1593 case GST_MESSAGE_ERROR:
1598 gst_message_parse_error(msg, &err, &debug);
1601 ERR("Error: %s", err->message);
1606 case GST_MESSAGE_EOS:
1609 ecore_timer_del(ev->eos_timer);
1610 ev->eos_timer = NULL;
1613 _emotion_decode_stop(ev->obj);
1614 _emotion_playback_finished(ev->obj);
1616 case GST_MESSAGE_TAG:
1618 GstTagList *new_tags;
1619 gst_message_parse_tag(msg, &new_tags);
1622 gst_tag_list_foreach(new_tags, (GstTagForeachFunc)_for_each_tag, ev);
1623 gst_tag_list_free(new_tags);
1627 case GST_MESSAGE_ASYNC_DONE:
1628 _emotion_seek_done(ev->obj);
1631 ERR("bus say: %s [%i]\n",
1632 GST_MESSAGE_SRC_NAME(msg),
1633 GST_MESSAGE_TYPE(msg));
1636 gst_message_unref(msg);