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 */
230 _emotion_object_extension_can_play_generic_get, /* play_get */
234 static Emotion_Video_Stream *
235 emotion_video_stream_new(Emotion_Gstreamer_Video *ev)
237 Emotion_Video_Stream *vstream;
239 if (!ev) return NULL;
241 vstream = (Emotion_Video_Stream *)calloc(1, sizeof(Emotion_Video_Stream));
242 if (!vstream) return NULL;
244 ev->video_streams = eina_list_append(ev->video_streams, vstream);
245 if (eina_error_get())
254 emotion_video_stream_free(Emotion_Gstreamer_Video *ev, Emotion_Video_Stream *vstream)
256 if (!ev || !vstream) return;
258 ev->video_streams = eina_list_remove(ev->video_streams, vstream);
263 emotion_visualization_element_name_get(Emotion_Vis visualisation)
265 switch (visualisation)
267 case EMOTION_VIS_NONE:
269 case EMOTION_VIS_GOOM:
271 case EMOTION_VIS_LIBVISUAL_BUMPSCOPE:
272 return "libvisual_bumpscope";
273 case EMOTION_VIS_LIBVISUAL_CORONA:
274 return "libvisual_corona";
275 case EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES:
276 return "libvisual_dancingparticles";
277 case EMOTION_VIS_LIBVISUAL_GDKPIXBUF:
278 return "libvisual_gdkpixbuf";
279 case EMOTION_VIS_LIBVISUAL_G_FORCE:
280 return "libvisual_G-Force";
281 case EMOTION_VIS_LIBVISUAL_GOOM:
282 return "libvisual_goom";
283 case EMOTION_VIS_LIBVISUAL_INFINITE:
284 return "libvisual_infinite";
285 case EMOTION_VIS_LIBVISUAL_JAKDAW:
286 return "libvisual_jakdaw";
287 case EMOTION_VIS_LIBVISUAL_JESS:
288 return "libvisual_jess";
289 case EMOTION_VIS_LIBVISUAL_LV_ANALYSER:
290 return "libvisual_lv_analyzer";
291 case EMOTION_VIS_LIBVISUAL_LV_FLOWER:
292 return "libvisual_lv_flower";
293 case EMOTION_VIS_LIBVISUAL_LV_GLTEST:
294 return "libvisual_lv_gltest";
295 case EMOTION_VIS_LIBVISUAL_LV_SCOPE:
296 return "libvisual_lv_scope";
297 case EMOTION_VIS_LIBVISUAL_MADSPIN:
298 return "libvisual_madspin";
299 case EMOTION_VIS_LIBVISUAL_NEBULUS:
300 return "libvisual_nebulus";
301 case EMOTION_VIS_LIBVISUAL_OINKSIE:
302 return "libvisual_oinksie";
303 case EMOTION_VIS_LIBVISUAL_PLASMA:
304 return "libvisual_plazma";
311 em_init(Evas_Object *obj,
312 void **emotion_video,
313 Emotion_Module_Options *opt __UNUSED__)
315 Emotion_Gstreamer_Video *ev;
321 ev = calloc(1, sizeof(Emotion_Gstreamer_Video));
326 /* Initialization of gstreamer */
327 if (!gst_init_check(NULL, NULL, &error))
332 ev->vis = EMOTION_VIS_NONE;
346 em_shutdown(void *video)
348 Emotion_Gstreamer_Video *ev;
349 Emotion_Audio_Stream *astream;
350 Emotion_Video_Stream *vstream;
352 ev = (Emotion_Gstreamer_Video *)video;
358 gst_element_set_state(ev->pipeline, GST_STATE_NULL);
359 gst_object_unref(ev->pipeline);
363 EINA_LIST_FREE(ev->audio_streams, astream)
365 EINA_LIST_FREE(ev->video_streams, vstream)
375 em_file_open(const char *file,
379 Emotion_Gstreamer_Video *ev;
380 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 uri = sbuf ? eina_strbuf_string_get(sbuf) : file;
411 DBG("setting file to '%s'", uri);
412 ev->pipeline = gstreamer_video_sink_new(ev, obj, uri);
413 if (sbuf) eina_strbuf_free(sbuf);
418 ev->eos_bus = gst_pipeline_get_bus(GST_PIPELINE(ev->pipeline));
421 ERR("could not get the bus");
430 g_object_get(G_OBJECT(ev->pipeline),
431 "n-audio", &ev->audio_stream_nbr,
432 "n-video", &ev->video_stream_nbr,
435 if ((ev->video_stream_nbr == 0) && (ev->audio_stream_nbr == 0))
437 ERR("No audio nor video stream found");
438 gst_object_unref(ev->pipeline);
445 for (i = 0; i < ev->video_stream_nbr; i++)
447 Emotion_Video_Stream *vstream;
450 GstStructure *structure;
455 gdouble length_time = 0.0;
462 g_signal_emit_by_name(ev->pipeline, "get-video-pad", i, &pad);
466 caps = gst_pad_get_negotiated_caps(pad);
469 structure = gst_caps_get_structure(caps, 0);
470 str = gst_caps_to_string(caps);
472 if (!gst_structure_get_int(structure, "width", &width))
474 if (!gst_structure_get_int(structure, "height", &height))
476 if (!gst_structure_get_fraction(structure, "framerate", &fps_num, &fps_den))
479 if (g_str_has_prefix(str, "video/x-raw-yuv"))
481 val = gst_structure_get_value(structure, "format");
482 fourcc = gst_value_get_fourcc(val);
484 else if (g_str_has_prefix(str, "video/x-raw-rgb"))
485 fourcc = GST_MAKE_FOURCC('A', 'R', 'G', 'B');
489 query = gst_query_new_duration(GST_FORMAT_TIME);
490 if (gst_pad_peer_query(pad, query))
494 gst_query_parse_duration(query, NULL, &t);
495 length_time = (double)t / (double)GST_SECOND;
500 vstream = emotion_video_stream_new(ev);
501 if (!vstream) goto unref_query_v;
503 vstream->length_time = length_time;
504 vstream->width = width;
505 vstream->height = height;
506 vstream->fps_num = fps_num;
507 vstream->fps_den = fps_den;
508 vstream->fourcc = fourcc;
512 gst_query_unref(query);
514 gst_caps_unref(caps);
516 gst_object_unref(pad);
521 for (i = 0; i < ev->audio_stream_nbr; i++)
523 Emotion_Audio_Stream *astream;
526 GstStructure *structure;
529 gdouble length_time = 0.0;
533 g_signal_emit_by_name(ev->pipeline, "get-audio-pad", i, &pad);
537 caps = gst_pad_get_negotiated_caps(pad);
540 structure = gst_caps_get_structure(caps, 0);
542 if (!gst_structure_get_int(structure, "channels", &channels))
544 if (!gst_structure_get_int(structure, "rate", &samplerate))
547 query = gst_query_new_duration(GST_FORMAT_TIME);
548 if (gst_pad_peer_query(pad, query))
552 gst_query_parse_duration(query, NULL, &t);
553 length_time = (double)t / (double)GST_SECOND;
558 astream = calloc(1, sizeof(Emotion_Audio_Stream));
559 if (!astream) continue;
560 ev->audio_streams = eina_list_append(ev->audio_streams, astream);
561 if (eina_error_get())
567 astream->length_time = length_time;
568 astream->channels = channels;
569 astream->samplerate = samplerate;
572 gst_query_unref(query);
574 gst_caps_unref(caps);
576 gst_object_unref(pad);
579 /* Visualization sink */
581 if (ev->video_stream_nbr == 0)
583 GstElement *vis = NULL;
584 Emotion_Video_Stream *vstream;
585 Emotion_Audio_Stream *astream;
587 const char *vis_name;
589 if (!(vis_name = emotion_visualization_element_name_get(ev->vis)))
591 ERR("pb vis name %d\n", ev->vis);
595 astream = eina_list_data_get(ev->audio_streams);
597 vis = gst_element_factory_make(vis_name, "vissink");
598 vstream = emotion_video_stream_new(ev);
602 DBG("could not create visualization stream");
604 vstream->length_time = astream->length_time;
605 vstream->width = 320;
606 vstream->height = 200;
607 vstream->fps_num = 25;
608 vstream->fps_den = 1;
609 vstream->fourcc = GST_MAKE_FOURCC('A', 'R', 'G', 'B');
611 g_object_set(G_OBJECT(ev->pipeline), "vis-plugin", vis, NULL);
612 g_object_get(G_OBJECT(ev->pipeline), "flags", &flags, NULL);
614 g_object_set(G_OBJECT(ev->pipeline), "flags", flags, NULL);
619 ev->video_stream_nbr = eina_list_count(ev->video_streams);
620 ev->audio_stream_nbr = eina_list_count(ev->audio_streams);
622 if (ev->video_stream_nbr == 1)
624 Emotion_Video_Stream *vstream;
626 vstream = eina_list_data_get(ev->video_streams);
627 ev->ratio = (double)vstream->width / (double)vstream->height;
628 _emotion_frame_resize(ev->obj, vstream->width, vstream->height, ev->ratio);
632 /* on recapitule : */
633 Emotion_Video_Stream *vstream;
634 Emotion_Audio_Stream *astream;
636 vstream = eina_list_data_get(ev->video_streams);
639 DBG("video size=%dx%d, fps=%d/%d, "
640 "fourcc=%"GST_FOURCC_FORMAT", length=%"GST_TIME_FORMAT,
641 vstream->width, vstream->height, vstream->fps_num, vstream->fps_den,
642 GST_FOURCC_ARGS(vstream->fourcc),
643 GST_TIME_ARGS((guint64)(vstream->length_time * GST_SECOND)));
646 astream = eina_list_data_get(ev->audio_streams);
649 DBG("audio channels=%d, rate=%d, length=%"GST_TIME_FORMAT,
650 astream->channels, astream->samplerate,
651 GST_TIME_ARGS((guint64)(astream->length_time * GST_SECOND)));
656 _free_metadata(ev->metadata);
657 ev->metadata = calloc(1, sizeof(Emotion_Gstreamer_Metadata));
659 em_audio_channel_volume_set(ev, ev->volume);
662 _emotion_open_done(ev->obj);
668 em_file_close(void *video)
670 Emotion_Gstreamer_Video *ev;
671 Emotion_Audio_Stream *astream;
672 Emotion_Video_Stream *vstream;
674 ev = (Emotion_Gstreamer_Video *)video;
680 gst_object_unref(GST_OBJECT(ev->eos_bus));
684 /* we clear the stream lists */
685 EINA_LIST_FREE(ev->audio_streams, astream)
687 EINA_LIST_FREE(ev->video_streams, vstream)
693 ecore_timer_del(ev->eos_timer);
694 ev->eos_timer = NULL;
699 _free_metadata(ev->metadata);
706 double pos __UNUSED__)
708 Emotion_Gstreamer_Video *ev;
710 ev = (Emotion_Gstreamer_Video *)video;
711 gst_element_set_state(ev->pipeline, GST_STATE_PLAYING);
713 ev->play_started = 1;
716 ev->eos_timer = ecore_timer_add(0.1, _eos_timer_fct, ev);
722 Emotion_Gstreamer_Video *ev;
724 ev = (Emotion_Gstreamer_Video *)video;
729 ecore_timer_del(ev->eos_timer);
730 ev->eos_timer = NULL;
733 gst_element_set_state(ev->pipeline, GST_STATE_PAUSED);
738 em_size_get(void *video,
742 Emotion_Gstreamer_Video *ev;
743 Emotion_Video_Stream *vstream;
745 ev = (Emotion_Gstreamer_Video *)video;
747 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
750 if (width) *width = vstream->width;
751 if (height) *height = vstream->height;
755 if (width) *width = 0;
756 if (height) *height = 0;
761 em_pos_set(void *video,
764 Emotion_Gstreamer_Video *ev;
767 ev = (Emotion_Gstreamer_Video *)video;
769 res = gst_element_seek(ev->pipeline, 1.0,
771 GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
773 (gint64)(pos * (double)GST_SECOND),
774 GST_SEEK_TYPE_NONE, -1);
778 em_len_get(void *video)
780 Emotion_Gstreamer_Video *ev;
781 Emotion_Video_Stream *vstream;
782 Emotion_Audio_Stream *astream;
789 fmt = GST_FORMAT_TIME;
790 ret = gst_element_query_duration(ev->pipeline, &fmt, &val);
794 if (fmt != GST_FORMAT_TIME)
796 DBG("requrested duration in time, but got %s instead.",
797 gst_format_get_name(fmt));
804 return val / 1000000000.0;
807 EINA_LIST_FOREACH(ev->audio_streams, l, astream)
808 if (astream->length_time >= 0)
809 return astream->length_time;
811 EINA_LIST_FOREACH(ev->video_streams, l, vstream)
812 if (vstream->length_time >= 0)
813 return vstream->length_time;
819 em_fps_num_get(void *video)
821 Emotion_Gstreamer_Video *ev;
822 Emotion_Video_Stream *vstream;
824 ev = (Emotion_Gstreamer_Video *)video;
826 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
828 return vstream->fps_num;
834 em_fps_den_get(void *video)
836 Emotion_Gstreamer_Video *ev;
837 Emotion_Video_Stream *vstream;
839 ev = (Emotion_Gstreamer_Video *)video;
841 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
843 return vstream->fps_den;
849 em_fps_get(void *video)
851 Emotion_Gstreamer_Video *ev;
852 Emotion_Video_Stream *vstream;
854 ev = (Emotion_Gstreamer_Video *)video;
856 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
858 return (double)vstream->fps_num / (double)vstream->fps_den;
864 em_pos_get(void *video)
866 Emotion_Gstreamer_Video *ev;
872 fmt = GST_FORMAT_TIME;
873 ret = gst_element_query_position(ev->pipeline, &fmt, &val);
877 if (fmt != GST_FORMAT_TIME)
879 ERR("requrested position in time, but got %s instead.",
880 gst_format_get_name(fmt));
884 ev->position = val / 1000000000.0;
889 em_vis_set(void *video,
892 Emotion_Gstreamer_Video *ev;
894 ev = (Emotion_Gstreamer_Video *)video;
896 if (ev->vis == vis) return;
901 em_vis_get(void *video)
903 Emotion_Gstreamer_Video *ev;
905 ev = (Emotion_Gstreamer_Video *)video;
911 em_vis_supported(void *ef __UNUSED__, Emotion_Vis vis)
914 GstElementFactory *factory;
916 if (vis == EMOTION_VIS_NONE)
919 name = emotion_visualization_element_name_get(vis);
923 factory = gst_element_factory_find(name);
927 gst_object_unref(factory);
932 em_ratio_get(void *video)
934 Emotion_Gstreamer_Video *ev;
936 ev = (Emotion_Gstreamer_Video *)video;
942 em_video_handled(void *video)
944 Emotion_Gstreamer_Video *ev;
946 ev = (Emotion_Gstreamer_Video *)video;
948 if (!eina_list_count(ev->video_streams))
955 em_audio_handled(void *video)
957 Emotion_Gstreamer_Video *ev;
959 ev = (Emotion_Gstreamer_Video *)video;
961 if (!eina_list_count(ev->audio_streams))
968 em_seekable(void *video __UNUSED__)
974 em_frame_done(void *video __UNUSED__)
978 static Emotion_Format
979 em_format_get(void *video)
981 Emotion_Gstreamer_Video *ev;
982 Emotion_Video_Stream *vstream;
984 ev = (Emotion_Gstreamer_Video *)video;
986 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
989 switch (vstream->fourcc)
991 case GST_MAKE_FOURCC('I', '4', '2', '0'):
992 return EMOTION_FORMAT_I420;
993 case GST_MAKE_FOURCC('Y', 'V', '1', '2'):
994 return EMOTION_FORMAT_YV12;
995 case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'):
996 return EMOTION_FORMAT_YUY2;
997 case GST_MAKE_FOURCC('A', 'R', 'G', 'B'):
998 return EMOTION_FORMAT_BGRA;
1000 return EMOTION_FORMAT_NONE;
1003 return EMOTION_FORMAT_NONE;
1007 em_video_data_size_get(void *video, int *w, int *h)
1009 Emotion_Gstreamer_Video *ev;
1010 Emotion_Video_Stream *vstream;
1012 ev = (Emotion_Gstreamer_Video *)video;
1014 vstream = (Emotion_Video_Stream *)eina_list_nth(ev->video_streams, ev->video_stream_nbr - 1);
1017 *w = vstream->width;
1018 *h = vstream->height;
1028 em_yuv_rows_get(void *video __UNUSED__,
1031 unsigned char **yrows __UNUSED__,
1032 unsigned char **urows __UNUSED__,
1033 unsigned char **vrows __UNUSED__)
1039 em_bgra_data_get(void *video __UNUSED__, unsigned char **bgra_data __UNUSED__)
1045 em_event_feed(void *video __UNUSED__, int event __UNUSED__)
1050 em_event_mouse_button_feed(void *video __UNUSED__, int button __UNUSED__, int x __UNUSED__, int y __UNUSED__)
1055 em_event_mouse_move_feed(void *video __UNUSED__, int x __UNUSED__, int y __UNUSED__)
1059 /* Video channels */
1061 em_video_channel_count(void *video)
1063 Emotion_Gstreamer_Video *ev;
1065 ev = (Emotion_Gstreamer_Video *)video;
1067 return eina_list_count(ev->video_streams);
1071 em_video_channel_set(void *video __UNUSED__,
1072 int channel __UNUSED__)
1075 Emotion_Gstreamer_Video *ev;
1077 ev = (Emotion_Gstreamer_Video *)video;
1079 if (channel < 0) channel = 0;
1081 /* FIXME: a faire... */
1085 em_video_channel_get(void *video)
1087 Emotion_Gstreamer_Video *ev;
1089 ev = (Emotion_Gstreamer_Video *)video;
1091 return ev->video_stream_nbr;
1095 em_video_channel_name_get(void *video __UNUSED__,
1096 int channel __UNUSED__)
1102 em_video_channel_mute_set(void *video,
1105 Emotion_Gstreamer_Video *ev;
1107 ev = (Emotion_Gstreamer_Video *)video;
1109 ev->video_mute = mute;
1113 em_video_channel_mute_get(void *video)
1115 Emotion_Gstreamer_Video *ev;
1117 ev = (Emotion_Gstreamer_Video *)video;
1119 return ev->video_mute;
1122 /* Audio channels */
1125 em_audio_channel_count(void *video)
1127 Emotion_Gstreamer_Video *ev;
1129 ev = (Emotion_Gstreamer_Video *)video;
1131 return eina_list_count(ev->audio_streams);
1135 em_audio_channel_set(void *video __UNUSED__,
1136 int channel __UNUSED__)
1139 Emotion_Gstreamer_Video *ev;
1141 ev = (Emotion_Gstreamer_Video *)video;
1143 if (channel < -1) channel = -1;
1145 /* FIXME: a faire... */
1149 em_audio_channel_get(void *video)
1151 Emotion_Gstreamer_Video *ev;
1153 ev = (Emotion_Gstreamer_Video *)video;
1155 return ev->audio_stream_nbr;
1159 em_audio_channel_name_get(void *video __UNUSED__,
1160 int channel __UNUSED__)
1165 #define GST_PLAY_FLAG_AUDIO (1 << 1)
1168 em_audio_channel_mute_set(void *video,
1171 Emotion_Gstreamer_Video *ev;
1174 ev = (Emotion_Gstreamer_Video *)video;
1176 if (ev->audio_mute == mute)
1179 ev->audio_mute = mute;
1181 g_object_set(G_OBJECT(ev->pipeline), "mute", !!mute, NULL);
1182 /* This code should stop the decoding of only the audio stream, but everything stop :"( */
1183 /* g_object_get(G_OBJECT(ev->pipeline), "flags", &flags, NULL); */
1185 /* flags &= ~GST_PLAY_FLAG_AUDIO; */
1187 /* flags |= GST_PLAY_FLAG_AUDIO; */
1188 /* g_object_set(G_OBJECT(ev->pipeline), "flags", flags, NULL); */
1189 /* g_object_get(G_OBJECT(ev->pipeline), "flags", &flags, NULL); */
1190 /* fprintf(stderr, "flags-n: %x\n", flags); */
1194 em_audio_channel_mute_get(void *video)
1196 Emotion_Gstreamer_Video *ev;
1198 ev = (Emotion_Gstreamer_Video *)video;
1200 return ev->audio_mute;
1204 em_audio_channel_volume_set(void *video,
1207 Emotion_Gstreamer_Video *ev;
1209 ev = (Emotion_Gstreamer_Video *)video;
1216 g_object_set(G_OBJECT(ev->pipeline), "volume", vol, NULL);
1220 em_audio_channel_volume_get(void *video)
1222 Emotion_Gstreamer_Video *ev;
1224 ev = (Emotion_Gstreamer_Video *)video;
1232 em_spu_channel_count(void *video __UNUSED__)
1238 em_spu_channel_set(void *video __UNUSED__, int channel __UNUSED__)
1243 em_spu_channel_get(void *video __UNUSED__)
1249 em_spu_channel_name_get(void *video __UNUSED__, int channel __UNUSED__)
1255 em_spu_channel_mute_set(void *video __UNUSED__, int mute __UNUSED__)
1260 em_spu_channel_mute_get(void *video __UNUSED__)
1266 em_chapter_count(void *video __UNUSED__)
1272 em_chapter_set(void *video __UNUSED__, int chapter __UNUSED__)
1277 em_chapter_get(void *video __UNUSED__)
1283 em_chapter_name_get(void *video __UNUSED__, int chapter __UNUSED__)
1289 em_speed_set(void *video __UNUSED__, double speed __UNUSED__)
1294 em_speed_get(void *video __UNUSED__)
1300 em_eject(void *video __UNUSED__)
1306 em_meta_get(void *video, int meta)
1308 Emotion_Gstreamer_Video *ev;
1309 const char *str = NULL;
1311 ev = (Emotion_Gstreamer_Video *)video;
1313 if (!ev || !ev->metadata) return NULL;
1316 case META_TRACK_TITLE:
1317 str = ev->metadata->title;
1319 case META_TRACK_ARTIST:
1320 str = ev->metadata->artist;
1322 case META_TRACK_ALBUM:
1323 str = ev->metadata->album;
1325 case META_TRACK_YEAR:
1326 str = ev->metadata->year;
1328 case META_TRACK_GENRE:
1329 str = ev->metadata->genre;
1331 case META_TRACK_COMMENT:
1332 str = ev->metadata->comment;
1334 case META_TRACK_DISCID:
1335 str = ev->metadata->disc_id;
1345 module_open(Evas_Object *obj,
1346 const Emotion_Video_Module **module,
1348 Emotion_Module_Options *opt)
1353 if (_emotion_gstreamer_log_domain < 0)
1355 eina_threads_init();
1356 eina_log_threads_enable();
1357 _emotion_gstreamer_log_domain = eina_log_domain_register
1358 ("emotion-gstreamer", EINA_COLOR_LIGHTCYAN);
1359 if (_emotion_gstreamer_log_domain < 0)
1361 EINA_LOG_CRIT("Could not register log domain 'emotion-gstreamer'");
1366 if (!em_module.init(obj, video, opt))
1369 eina_threads_init();
1371 *module = &em_module;
1376 module_close(Emotion_Video_Module *module __UNUSED__,
1379 em_module.shutdown(video);
1381 eina_threads_shutdown();
1385 gstreamer_module_init(void)
1389 if (!gst_init_check(0, NULL, &error))
1391 EINA_LOG_CRIT("Could not init GStreamer");
1395 if (gst_plugin_register_static(GST_VERSION_MAJOR, GST_VERSION_MINOR,
1397 "video sink plugin for Emotion",
1398 gstreamer_plugin_init,
1403 "http://www.enlightenment.org/") == FALSE)
1405 EINA_LOG_CRIT("Could not load static gstreamer video sink for Emotion.");
1409 return _emotion_module_register("gstreamer", module_open, module_close);
1413 gstreamer_module_shutdown(void)
1415 _emotion_module_unregister("gstreamer");
1420 #ifndef EMOTION_STATIC_BUILD_GSTREAMER
1422 EINA_MODULE_INIT(gstreamer_module_init);
1423 EINA_MODULE_SHUTDOWN(gstreamer_module_shutdown);
1428 _for_each_tag(GstTagList const* list,
1432 Emotion_Gstreamer_Video *ev;
1437 ev = (Emotion_Gstreamer_Video*)data;
1439 if (!ev || !ev->metadata) return;
1441 count = gst_tag_list_get_tag_size(list, tag);
1443 for (i = 0; i < count; i++)
1445 if (!strcmp(tag, GST_TAG_TITLE))
1448 if (ev->metadata->title) g_free(ev->metadata->title);
1449 if (gst_tag_list_get_string(list, GST_TAG_TITLE, &str))
1450 ev->metadata->title = str;
1452 ev->metadata->title = NULL;
1455 if (!strcmp(tag, GST_TAG_ALBUM))
1458 if (ev->metadata->album) g_free(ev->metadata->album);
1459 if (gst_tag_list_get_string(list, GST_TAG_ALBUM, &str))
1460 ev->metadata->album = str;
1462 ev->metadata->album = NULL;
1465 if (!strcmp(tag, GST_TAG_ARTIST))
1468 if (ev->metadata->artist) g_free( ev->metadata->artist);
1469 if (gst_tag_list_get_string(list, GST_TAG_ARTIST, &str))
1470 ev->metadata->artist = str;
1472 ev->metadata->artist = NULL;
1475 if (!strcmp(tag, GST_TAG_GENRE))
1478 if (ev->metadata->genre) g_free( ev->metadata->genre);
1479 if (gst_tag_list_get_string(list, GST_TAG_GENRE, &str))
1480 ev->metadata->genre = str;
1482 ev->metadata->genre = NULL;
1485 if (!strcmp(tag, GST_TAG_COMMENT))
1488 if (ev->metadata->comment) g_free(ev->metadata->comment);
1489 if (gst_tag_list_get_string(list, GST_TAG_COMMENT, &str))
1490 ev->metadata->comment = str;
1492 ev->metadata->comment = NULL;
1495 if (!strcmp(tag, GST_TAG_DATE))
1499 if (ev->metadata->year) g_free(ev->metadata->year);
1500 date = gst_tag_list_get_value_index(list, GST_TAG_DATE, 0);
1502 str = g_strdup_value_contents(date);
1505 ev->metadata->year = str;
1509 if (!strcmp(tag, GST_TAG_TRACK_NUMBER))
1512 const GValue *track;
1513 if (ev->metadata->count) g_free( ev->metadata->count);
1514 track = gst_tag_list_get_value_index(list, GST_TAG_TRACK_NUMBER, 0);
1516 str = g_strdup_value_contents(track);
1519 ev->metadata->count = str;
1523 #ifdef GST_TAG_CDDA_CDDB_DISCID
1524 if (!strcmp(tag, GST_TAG_CDDA_CDDB_DISCID))
1527 const GValue *discid;
1528 if (ev->metadata->disc_id) g_free(ev->metadata->disc_id);
1529 discid = gst_tag_list_get_value_index(list, GST_TAG_CDDA_CDDB_DISCID, 0);
1531 str = g_strdup_value_contents(discid);
1534 ev->metadata->disc_id = str;
1543 _free_metadata(Emotion_Gstreamer_Metadata *m)
1547 if (m->title) g_free(m->title);
1548 if (m->album) g_free(m->album);
1549 if (m->artist) g_free(m->artist);
1550 if (m->genre) g_free(m->genre);
1551 if (m->comment) g_free(m->comment);
1552 if (m->year) g_free(m->year);
1553 if (m->count) g_free(m->count);
1554 if (m->disc_id) g_free(m->disc_id);
1560 _eos_timer_fct(void *data)
1562 Emotion_Gstreamer_Video *ev;
1565 ev = (Emotion_Gstreamer_Video *)data;
1566 if (ev->play_started)
1568 _emotion_playback_started(ev->obj);
1569 ev->play_started = 0;
1571 while ((msg = gst_bus_poll(ev->eos_bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_TAG | GST_MESSAGE_ASYNC_DONE, 0)))
1573 switch (GST_MESSAGE_TYPE(msg))
1575 case GST_MESSAGE_ERROR:
1580 gst_message_parse_error(msg, &err, &debug);
1583 ERR("Error: %s", err->message);
1588 case GST_MESSAGE_EOS:
1591 ecore_timer_del(ev->eos_timer);
1592 ev->eos_timer = NULL;
1595 _emotion_decode_stop(ev->obj);
1596 _emotion_playback_finished(ev->obj);
1598 case GST_MESSAGE_TAG:
1600 GstTagList *new_tags;
1601 gst_message_parse_tag(msg, &new_tags);
1604 gst_tag_list_foreach(new_tags, (GstTagForeachFunc)_for_each_tag, ev);
1605 gst_tag_list_free(new_tags);
1609 case GST_MESSAGE_ASYNC_DONE:
1610 _emotion_seek_done(ev->obj);
1613 ERR("bus say: %s [%i]\n",
1614 GST_MESSAGE_SRC_NAME(msg),
1615 GST_MESSAGE_TYPE(msg));
1618 gst_message_unref(msg);