a5a061d64982f1a564c96edf924caac5ead10aad
[profile/ivi/emotion.git] / src / modules / emotion_gstreamer.c
1 #include <unistd.h>
2 #include <fcntl.h>
3
4 #include "Emotion.h"
5 #include "emotion_private.h"
6 #include "emotion_gstreamer.h"
7 #include "emotion_gstreamer_pipeline.h"
8
9
10 /* Callbacks to get the eos */
11 static int _eos_timer_fct (void *data);
12
13 static int   _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh);
14
15
16 /* Interface */
17
18 static unsigned char  em_init                     (Evas_Object     *obj,
19                                                    void           **emotion_video,
20                                                    Emotion_Module_Options *opt);
21
22 static int            em_shutdown                 (void           *video);
23
24 static unsigned char  em_file_open                (const char     *file,
25                                                    Evas_Object     *obj,
26                                                    void            *video);
27
28 static void           em_file_close               (void            *video);
29
30 static void           em_play                     (void            *video,
31                                                    double           pos);
32
33 static void           em_stop                     (void            *video);
34
35 static void           em_size_get                 (void            *video,
36                                                    int             *width,
37                                                    int             *height);
38
39 static void           em_pos_set                  (void            *video,
40                                                    double           pos);
41
42 static void           em_vis_set                  (void            *video,
43                                                    Emotion_Vis      vis);
44
45 static double         em_len_get                  (void            *video);
46
47 static int            em_fps_num_get              (void            *video);
48
49 static int            em_fps_den_get              (void            *video);
50
51 static double         em_fps_get                  (void            *video);
52
53 static double         em_pos_get                  (void            *video);
54
55 static Emotion_Vis    em_vis_get                  (void            *video);
56
57 static double         em_ratio_get                (void            *video);
58
59 static int            em_video_handled            (void            *video);
60
61 static int            em_audio_handled            (void            *video);
62
63 static int            em_seekable                 (void            *video);
64
65 static void           em_frame_done               (void            *video);
66
67 static Emotion_Format em_format_get               (void            *video);
68
69 static void           em_video_data_size_get      (void            *video,
70                                                    int             *w,
71                                                    int             *h);
72
73 static int            em_yuv_rows_get             (void            *video,
74                                                    int              w,
75                                                    int              h,
76                                                    unsigned char  **yrows,
77                                                    unsigned char  **urows,
78                                                    unsigned char  **vrows);
79
80 static int            em_bgra_data_get            (void            *video,
81                                                    unsigned char  **bgra_data);
82
83 static void           em_event_feed               (void            *video,
84                                                    int              event);
85
86 static void           em_event_mouse_button_feed  (void            *video,
87                                                    int              button,
88                                                    int              x,
89                                                    int              y);
90
91 static void           em_event_mouse_move_feed    (void            *video,
92                                                    int              x,
93                                                    int              y);
94
95 static int            em_video_channel_count      (void             *video);
96
97 static void           em_video_channel_set        (void             *video,
98                                                    int               channel);
99
100 static int            em_video_channel_get        (void             *video);
101
102 static const char    *em_video_channel_name_get   (void             *video,
103                                                    int               channel);
104
105 static void           em_video_channel_mute_set   (void             *video,
106                                                    int               mute);
107
108 static int            em_video_channel_mute_get   (void             *video);
109
110 static int            em_audio_channel_count      (void             *video);
111
112 static void           em_audio_channel_set        (void             *video,
113                                                    int               channel);
114
115 static int            em_audio_channel_get        (void             *video);
116
117 static const char    *em_audio_channel_name_get   (void             *video,
118                                                    int               channel);
119
120 static void           em_audio_channel_mute_set   (void             *video,
121                                                    int               mute);
122
123 static int            em_audio_channel_mute_get   (void             *video);
124
125 static void           em_audio_channel_volume_set (void             *video,
126                                                    double             vol);
127
128 static double         em_audio_channel_volume_get (void             *video);
129
130 static int            em_spu_channel_count        (void             *video);
131
132 static void           em_spu_channel_set          (void             *video,
133                                                    int               channel);
134
135 static int            em_spu_channel_get          (void             *video);
136
137 static const char    *em_spu_channel_name_get     (void             *video,
138                                                    int               channel);
139
140 static void           em_spu_channel_mute_set     (void             *video,
141                                                    int               mute);
142
143 static int            em_spu_channel_mute_get     (void             *video);
144
145 static int            em_chapter_count            (void             *video);
146
147 static void           em_chapter_set              (void             *video,
148                                                    int               chapter);
149
150 static int            em_chapter_get              (void             *video);
151
152 static const char    *em_chapter_name_get         (void             *video,
153                                                    int               chapter);
154
155 static void           em_speed_set                (void             *video,
156                                                    double            speed);
157
158 static double         em_speed_get                (void             *video);
159
160 static int            em_eject                    (void             *video);
161
162 static const char    *em_meta_get                 (void             *video,
163                                                    int               meta);
164
165 /* Module interface */
166
167 static Emotion_Video_Module em_module =
168 {
169    em_init, /* init */
170    em_shutdown, /* shutdown */
171    em_file_open, /* file_open */
172    em_file_close, /* file_close */
173    em_play, /* play */
174    em_stop, /* stop */
175    em_size_get, /* size_get */
176    em_pos_set, /* pos_set */
177    em_vis_set, /* vis_set */
178    em_len_get, /* len_get */
179    em_fps_num_get, /* fps_num_get */
180    em_fps_den_get, /* fps_den_get */
181    em_fps_get, /* fps_get */
182    em_pos_get, /* pos_get */
183    em_vis_get, /* vis_get */
184    em_ratio_get, /* ratio_get */
185    em_video_handled, /* video_handled */
186    em_audio_handled, /* audio_handled */
187    em_seekable, /* seekable */
188    em_frame_done, /* frame_done */
189    em_format_get, /* format_get */
190    em_video_data_size_get, /* video_data_size_get */
191    em_yuv_rows_get, /* yuv_rows_get */
192    em_bgra_data_get, /* bgra_data_get */
193    em_event_feed, /* event_feed */
194    em_event_mouse_button_feed, /* event_mouse_button_feed */
195    em_event_mouse_move_feed, /* event_mouse_move_feed */
196    em_video_channel_count, /* video_channel_count */
197    em_video_channel_set, /* video_channel_set */
198    em_video_channel_get, /* video_channel_get */
199    em_video_channel_name_get, /* video_channel_name_get */
200    em_video_channel_mute_set, /* video_channel_mute_set */
201    em_video_channel_mute_get, /* video_channel_mute_get */
202    em_audio_channel_count, /* audio_channel_count */
203    em_audio_channel_set, /* audio_channel_set */
204    em_audio_channel_get, /* audio_channel_get */
205    em_audio_channel_name_get, /* audio_channel_name_get */
206    em_audio_channel_mute_set, /* audio_channel_mute_set */
207    em_audio_channel_mute_get, /* audio_channel_mute_get */
208    em_audio_channel_volume_set, /* audio_channel_volume_set */
209    em_audio_channel_volume_get, /* audio_channel_volume_get */
210    em_spu_channel_count, /* spu_channel_count */
211    em_spu_channel_set, /* spu_channel_set */
212    em_spu_channel_get, /* spu_channel_get */
213    em_spu_channel_name_get, /* spu_channel_name_get */
214    em_spu_channel_mute_set, /* spu_channel_mute_set */
215    em_spu_channel_mute_get, /* spu_channel_mute_get */
216    em_chapter_count, /* chapter_count */
217    em_chapter_set, /* chapter_set */
218    em_chapter_get, /* chapter_get */
219    em_chapter_name_get, /* chapter_name_get */
220    em_speed_set, /* speed_set */
221    em_speed_get, /* speed_get */
222    em_eject, /* eject */
223    em_meta_get /* meta_get */
224 };
225
226 static unsigned char
227 em_init(Evas_Object  *obj,
228         void        **emotion_video,
229         Emotion_Module_Options *opt)
230 {
231    Emotion_Gstreamer_Video *ev;
232    GError                  *error;
233    int                      fds[2];
234
235    if (!emotion_video)
236       return 0;
237
238    printf ("Init gstreamer...\n");
239
240    ev = calloc(1, sizeof(Emotion_Gstreamer_Video));
241    if (!ev) return 0;
242
243    ev->obj = obj;
244    ev->obj_data = NULL;
245
246    /* Initialization of gstreamer */
247    if (!gst_init_check (NULL, NULL, &error))
248      goto failure_gstreamer;
249
250    ev->pipeline = gst_pipeline_new ("pipeline");
251    if (!ev->pipeline)
252      goto failure_pipeline;
253
254    ev->eos_bus = gst_pipeline_get_bus (GST_PIPELINE (ev->pipeline));
255    if (!ev->eos_bus)
256      goto failure_bus;
257
258    /* We allocate the sinks lists */
259    ev->video_sinks = ecore_list_new ();
260    if (!ev->video_sinks)
261      goto failure_video_sinks;
262    ecore_list_free_cb_set(ev->video_sinks, ECORE_FREE_CB(free));
263    ev->audio_sinks = ecore_list_new ();
264    if (!ev->audio_sinks)
265      goto failure_audio_sinks;
266    ecore_list_free_cb_set(ev->audio_sinks, ECORE_FREE_CB(free));
267
268    *emotion_video = ev;
269
270    /* Default values */
271    ev->ratio = 1.0;
272    ev->video_sink_nbr = 0;
273    ev->audio_sink_nbr = 0;
274    ev->vis = EMOTION_VIS_GOOM;
275
276    /* Create the file descriptors */
277    if (pipe(fds) == 0) {
278       ev->fd_ev_read = fds[0];
279       ev->fd_ev_write = fds[1];
280       fcntl(ev->fd_ev_read, F_SETFL, O_NONBLOCK);
281       ev->fd_ev_handler = ecore_main_fd_handler_add(ev->fd_ev_read,
282                                                     ECORE_FD_READ,
283                                                     _em_fd_ev_active,
284                                                     ev,
285                                                     NULL, NULL);
286       ecore_main_fd_handler_active_set(ev->fd_ev_handler, ECORE_FD_READ);
287    }
288    else
289      goto failure_pipe;
290
291    return 1;
292
293  failure_pipe:
294    ecore_list_destroy (ev->audio_sinks);
295  failure_audio_sinks:
296    ecore_list_destroy (ev->video_sinks);
297  failure_video_sinks:
298    gst_object_unref (GST_OBJECT (ev->eos_bus));
299  failure_bus:
300    /* this call is not really necessary */
301    gst_element_set_state (ev->pipeline, GST_STATE_NULL);
302    gst_object_unref (GST_OBJECT (ev->pipeline));
303  failure_pipeline:
304    gst_deinit ();
305  failure_gstreamer:
306    free (ev);
307
308    return 0;
309 }
310
311 static int
312 em_shutdown(void *video)
313 {
314    Emotion_Gstreamer_Video *ev;
315
316    ev = (Emotion_Gstreamer_Video *)video;
317    if (!ev)
318      return 0;
319
320    gst_element_set_state (ev->pipeline, GST_STATE_NULL);
321    gst_object_unref (GST_OBJECT (ev->pipeline));
322    gst_object_unref (GST_OBJECT (ev->eos_bus));
323    gst_deinit ();
324
325    ecore_list_destroy (ev->video_sinks);
326    ecore_list_destroy (ev->audio_sinks);
327
328    /* FIXME: and the evas object ? */
329
330    ecore_main_fd_handler_del(ev->fd_ev_handler);
331    close(ev->fd_ev_write);
332    close(ev->fd_ev_read);
333
334    free(ev);
335
336    return 1;
337 }
338
339 static unsigned char
340 em_file_open(const char   *file,
341              Evas_Object  *obj,
342              void         *video)
343 {
344    Emotion_Gstreamer_Video *ev;
345
346    ev = (Emotion_Gstreamer_Video *)video;
347
348    /* Evas Object */
349    ev->obj = obj;
350
351    /* CD Audio */
352    if (strstr (file,"cdda://")) {
353       const char  *device = NULL;
354       unsigned int track = 1;
355
356       device = file + strlen ("cdda://");
357       if (device[0] == '/') {
358          char *tmp;
359
360          if ((tmp = strchr (device, '?')) || (tmp = strchr (device, '#'))) {
361             sscanf (tmp + 1,"%d", &track);
362             tmp[0] = '\0';
363          }
364       }
365       else {
366          device = NULL;
367          sscanf (file,"cdda://%d", &track);
368       }
369       fprintf (stderr, "[Emotion] [gst] build CD Audio pipeline\n");
370       if (!(emotion_pipeline_cdda_build (ev, device, track))) {
371         fprintf (stderr, "[Emotion] [gst] error while building CD Audio pipeline\n");
372         return 0;
373       }
374    }
375    /* Dvd */
376    else if (strstr (file, "dvd://")) {
377
378       fprintf (stderr, "[Emotion] [gst] build DVD pipeline \n");
379       if (!(emotion_pipeline_dvd_build (ev, NULL))) {
380         fprintf (stderr, "[Emotion] [gst] error while building DVD pipeline\n");
381         return 0;
382       }
383    }
384    /* http */
385    else if (strstr (file, "http://")) {
386      fprintf (stderr, "[Emotion] [gst] build URI pipeline \n");
387      if (!(emotion_pipeline_uri_build (ev, file))) {
388        fprintf (stderr, "[Emotion] [gst] error while building URI pipeline\n");
389        return 0;
390      }
391    }
392    /* Normal media file */
393    else {
394       const char *filename;
395
396       filename = strstr (file, "file://")
397         ? file + strlen ("file://")
398         : file;
399
400       fprintf (stderr, "[Emotion] [gst] build file pipeline \n");
401       if (!(emotion_pipeline_file_build (ev, filename))) {
402         fprintf (stderr, "[Emotion] [gst] error while building File pipeline\n");
403         return 0;
404       }
405    }
406
407    ev->position = 0.0;
408
409    {
410       /* on recapitule : */
411      Emotion_Video_Sink *vsink;
412      Emotion_Audio_Sink *asink;
413
414      vsink = (Emotion_Video_Sink *)ecore_list_first_goto (ev->video_sinks);
415      if (vsink) {
416         g_print ("video : \n");
417         g_print ("  size   : %dx%d\n", vsink->width, vsink->height);
418         g_print ("  fps    : %d/%d\n", vsink->fps_num, vsink->fps_den);
419         g_print ("  fourcc : %" GST_FOURCC_FORMAT "\n", GST_FOURCC_ARGS (vsink->fourcc));
420         g_print ("  length : %" GST_TIME_FORMAT "\n\n",
421                  GST_TIME_ARGS ((guint64)(vsink->length_time * GST_SECOND)));
422      }
423
424      asink = (Emotion_Audio_Sink *)ecore_list_first_goto (ev->audio_sinks);
425      if (asink) {
426         g_print ("audio : \n");
427         g_print ("  chan   : %d\n", asink->channels);
428         g_print ("  rate   : %d\n", asink->samplerate);
429         g_print ("  length : %" GST_TIME_FORMAT "\n\n",
430                  GST_TIME_ARGS ((guint64)(asink->length_time * GST_SECOND)));
431      }
432    }
433
434    return 1;
435 }
436
437 static void
438 em_file_close(void *video)
439 {
440    Emotion_Gstreamer_Video *ev;
441    GstIterator             *iter;
442    gpointer                 data;
443    gboolean                 done;
444
445    ev = (Emotion_Gstreamer_Video *)video;
446    if (!ev)
447      return;
448
449    printf("EX pause end...\n");
450    if (!emotion_object_play_get(ev->obj))
451      {
452         printf("  ... unpause\n");
453         emotion_pipeline_pause (ev->pipeline);
454      }
455
456    printf("EX stop\n");
457    gst_element_set_state (ev->pipeline, GST_STATE_READY);
458
459    /* we remove all the elements in the pipeline */
460    iter = gst_bin_iterate_elements (GST_BIN (ev->pipeline));
461    done = FALSE;
462    while (!done) {
463      switch (gst_iterator_next (iter, &data)) {
464      case GST_ITERATOR_OK: {
465        GstElement *element;
466
467        element = GST_ELEMENT (data);
468        if (element) {
469          gst_bin_remove (GST_BIN (ev->pipeline), element);
470        }
471        break;
472      }
473      case GST_ITERATOR_RESYNC: {
474        GstElement *element;
475
476        element = GST_ELEMENT (data);
477        if (element) {
478          gst_bin_remove (GST_BIN (ev->pipeline), element);
479        }
480        gst_iterator_resync (iter);
481        break;
482      }
483      case GST_ITERATOR_ERROR:
484        printf("error iter\n");
485        done = TRUE;
486        break;
487      case GST_ITERATOR_DONE:
488        done = TRUE;
489        break;
490      }
491    }
492    gst_iterator_free (iter);
493
494    /* we clear the sink lists */
495    ecore_list_clear (ev->video_sinks);
496    ecore_list_clear (ev->audio_sinks);
497
498    /* shutdown eos */
499    if (ev->eos_timer) {
500      ecore_timer_del (ev->eos_timer);
501      ev->eos_timer = NULL;
502    }
503 }
504
505 static void
506 em_play(void   *video,
507         double  pos)
508 {
509    Emotion_Gstreamer_Video *ev;
510
511    ev = (Emotion_Gstreamer_Video *)video;
512    gst_element_set_state (ev->pipeline, GST_STATE_PLAYING);
513    ev->play = 1;
514
515    /* eos */
516    ev->eos_timer = ecore_timer_add (0.1, _eos_timer_fct, ev);
517 }
518
519 static void
520 em_stop(void *video)
521 {
522    Emotion_Gstreamer_Video *ev;
523
524    ev = (Emotion_Gstreamer_Video *)video;
525
526    gst_element_set_state (ev->pipeline, GST_STATE_PAUSED);
527    ev->play = 0;
528
529    /* shutdown eos */
530    if (ev->eos_timer) {
531      ecore_timer_del (ev->eos_timer);
532      ev->eos_timer = NULL;
533    }
534 }
535
536 static void
537 em_size_get(void  *video,
538             int   *width,
539             int   *height)
540 {
541    Emotion_Gstreamer_Video *ev;
542    Emotion_Video_Sink      *vsink;
543
544    ev = (Emotion_Gstreamer_Video *)video;
545
546    vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
547    if (vsink) {
548       if (width) *width = vsink->width;
549       if (height) *height = vsink->height;
550    }
551    else {
552       if (width) *width = 0;
553       if (height) *height = 0;
554    }
555 }
556
557 static void
558 em_pos_set(void   *video,
559            double  pos)
560 {
561    Emotion_Gstreamer_Video *ev;
562    Emotion_Video_Sink      *vsink;
563    Emotion_Audio_Sink      *asink;
564
565    ev = (Emotion_Gstreamer_Video *)video;
566
567    if (ev->seek_to_pos == pos) return;
568
569    vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
570    asink = (Emotion_Audio_Sink *)ecore_list_index_goto (ev->video_sinks, ev->audio_sink_nbr);
571
572    if (vsink) {
573       gst_element_seek(vsink->sink, 1.0,
574                        GST_FORMAT_TIME,
575                        GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
576                        GST_SEEK_TYPE_SET,
577                        (gint64)(pos * (double)GST_SECOND),
578                        GST_SEEK_TYPE_NONE,
579                        -1);
580    }
581    if (asink) {
582       gst_element_seek(asink->sink, 1.0,
583                        GST_FORMAT_TIME,
584                        GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
585                        GST_SEEK_TYPE_SET,
586                        (gint64)(pos * (double)GST_SECOND),
587                        GST_SEEK_TYPE_NONE,
588                        -1);
589    }
590    ev->seek_to_pos = pos;
591 }
592
593 static void
594 em_vis_set(void       *video,
595            Emotion_Vis vis)
596 {
597    Emotion_Gstreamer_Video *ev;
598
599    ev = (Emotion_Gstreamer_Video *)video;
600
601    if (ev->vis == vis) return;
602    ev->vis = vis;
603 }
604
605 static double
606 em_len_get(void *video)
607 {
608    Emotion_Gstreamer_Video *ev;
609    Emotion_Video_Sink      *vsink;
610
611    ev = (Emotion_Gstreamer_Video *)video;
612
613    vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
614    if (vsink)
615       return (double)vsink->length_time;
616
617    return 0.0;
618 }
619
620 static int
621 em_fps_num_get(void *video)
622 {
623    Emotion_Gstreamer_Video *ev;
624    Emotion_Video_Sink      *vsink;
625
626    ev = (Emotion_Gstreamer_Video *)video;
627
628    vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
629    if (vsink)
630       return vsink->fps_num;
631
632    return 0;
633 }
634
635 static int
636 em_fps_den_get(void *video)
637 {
638    Emotion_Gstreamer_Video *ev;
639    Emotion_Video_Sink      *vsink;
640
641    ev = (Emotion_Gstreamer_Video *)video;
642
643    vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
644    if (vsink)
645       return vsink->fps_den;
646
647    return 1;
648 }
649
650 static double
651 em_fps_get(void *video)
652 {
653    Emotion_Gstreamer_Video *ev;
654    Emotion_Video_Sink      *vsink;
655
656    ev = (Emotion_Gstreamer_Video *)video;
657
658    vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
659    if (vsink)
660       return (double)vsink->fps_num / (double)vsink->fps_den;
661
662    return 0.0;
663 }
664
665 static double
666 em_pos_get(void *video)
667 {
668    Emotion_Gstreamer_Video *ev;
669
670    ev = (Emotion_Gstreamer_Video *)video;
671
672    return ev->position;
673 }
674
675 static Emotion_Vis
676 em_vis_get(void *video)
677 {
678    Emotion_Gstreamer_Video *ev;
679
680    ev = (Emotion_Gstreamer_Video *)video;
681
682    return ev->vis;
683 }
684
685 static double
686 em_ratio_get(void *video)
687 {
688    Emotion_Gstreamer_Video *ev;
689
690    ev = (Emotion_Gstreamer_Video *)video;
691
692    return ev->ratio;
693 }
694
695 static int
696 em_video_handled(void *video)
697 {
698    Emotion_Gstreamer_Video *ev;
699
700    ev = (Emotion_Gstreamer_Video *)video;
701
702    if (ecore_list_empty_is (ev->video_sinks))
703      return 0;
704
705    return 1;
706 }
707
708 static int
709 em_audio_handled(void *video)
710 {
711    Emotion_Gstreamer_Video *ev;
712
713    ev = (Emotion_Gstreamer_Video *)video;
714
715    if (ecore_list_empty_is (ev->audio_sinks))
716      return 0;
717
718    return 1;
719 }
720
721 static int
722 em_seekable(void *video)
723 {
724    Emotion_Gstreamer_Video *ev;
725
726    ev = (Emotion_Gstreamer_Video *)video;
727
728    return 1;
729 }
730
731 static void
732 em_frame_done(void *video)
733 {
734    Emotion_Gstreamer_Video *ev;
735
736    ev = (Emotion_Gstreamer_Video *)video;
737 }
738
739 static Emotion_Format
740 em_format_get (void *video)
741 {
742    Emotion_Gstreamer_Video *ev;
743    Emotion_Video_Sink      *vsink;
744
745    ev = (Emotion_Gstreamer_Video *)video;
746
747    vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
748    if (vsink) {
749       switch (vsink->fourcc) {
750       case GST_MAKE_FOURCC ('I','4','2','0'):
751          return EMOTION_FORMAT_I420;
752       case GST_MAKE_FOURCC ('Y','V','1','2'):
753          return EMOTION_FORMAT_YV12;
754       case GST_MAKE_FOURCC ('Y','U','Y','2'):
755          return EMOTION_FORMAT_YUY2;
756       case GST_MAKE_FOURCC ('A','R','G','B'):
757          return EMOTION_FORMAT_BGRA;
758       default:
759          return EMOTION_FORMAT_NONE;
760       }
761    }
762    return EMOTION_FORMAT_NONE;
763 }
764
765 static void
766 em_video_data_size_get(void *video, int *w, int *h)
767 {
768    Emotion_Gstreamer_Video *ev;
769    Emotion_Video_Sink      *vsink;
770
771    ev = (Emotion_Gstreamer_Video *)video;
772
773    vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
774    if (vsink) {
775       *w = vsink->width;
776       *h = vsink->height;
777    }
778    else {
779       *w = 0;
780       *h = 0;
781    }
782 }
783
784 static int
785 em_yuv_rows_get(void           *video,
786                 int             w,
787                 int             h,
788                 unsigned char **yrows,
789                 unsigned char **urows,
790                 unsigned char **vrows)
791 {
792    Emotion_Gstreamer_Video *ev;
793    int                      i;
794
795    ev = (Emotion_Gstreamer_Video *)video;
796
797    if (ev->obj_data)
798      {
799        if (em_format_get(video) == EMOTION_FORMAT_I420) {
800          for (i = 0; i < h; i++)
801            yrows[i] = &ev->obj_data[i * w];
802
803          for (i = 0; i < (h / 2); i++)
804            urows[i] = &ev->obj_data[h * w + i * (w / 2) ];
805
806          for (i = 0; i < (h / 2); i++)
807            vrows[i] = &ev->obj_data[h * w + h * (w /4) + i * (w / 2)];
808        }
809        else if (em_format_get(video) == EMOTION_FORMAT_YV12) {
810          for (i = 0; i < h; i++)
811            yrows[i] = &ev->obj_data[i * w];
812
813          for (i = 0; i < (h / 2); i++)
814            vrows[i] = &ev->obj_data[h * w + i * (w / 2) ];
815
816          for (i = 0; i < (h / 2); i++)
817            urows[i] = &ev->obj_data[h * w + h * (w /4) + i * (w / 2)];
818        }
819        else
820          return 0;
821
822        return 1;
823      }
824
825    return 0;
826 }
827
828 static int
829 em_bgra_data_get(void *video, unsigned char **bgra_data)
830 {
831    Emotion_Gstreamer_Video *ev;
832
833    ev = (Emotion_Gstreamer_Video *)video;
834
835    if (ev->obj_data && em_format_get(video) == EMOTION_FORMAT_BGRA) {
836       *bgra_data = ev->obj_data;
837       return 1;
838    }
839    return 0;
840 }
841
842 static void
843 em_event_feed(void *video, int event)
844 {
845    Emotion_Gstreamer_Video *ev;
846
847    ev = (Emotion_Gstreamer_Video *)video;
848 }
849
850 static void
851 em_event_mouse_button_feed(void *video, int button, int x, int y)
852 {
853    Emotion_Gstreamer_Video *ev;
854
855    ev = (Emotion_Gstreamer_Video *)video;
856 }
857
858 static void
859 em_event_mouse_move_feed(void *video, int x, int y)
860 {
861    Emotion_Gstreamer_Video *ev;
862
863    ev = (Emotion_Gstreamer_Video *)video;
864 }
865
866 /* Video channels */
867 static int
868 em_video_channel_count(void *video)
869 {
870    Emotion_Gstreamer_Video *ev;
871
872    ev = (Emotion_Gstreamer_Video *)video;
873
874    return ecore_list_count(ev->video_sinks);
875 }
876
877 static void
878 em_video_channel_set(void *video,
879                      int   channel)
880 {
881    Emotion_Gstreamer_Video *ev;
882
883    ev = (Emotion_Gstreamer_Video *)video;
884
885    if (channel < 0) channel = 0;
886    /* FIXME: a faire... */
887 }
888
889 static int
890 em_video_channel_get(void *video)
891 {
892    Emotion_Gstreamer_Video *ev;
893
894    ev = (Emotion_Gstreamer_Video *)video;
895
896    return ev->video_sink_nbr;
897 }
898
899 static const char *
900 em_video_channel_name_get(void *video,
901                           int   channel)
902 {
903    Emotion_Gstreamer_Video *ev;
904
905    ev = (Emotion_Gstreamer_Video *)video;
906
907    return NULL;
908 }
909
910 static void
911 em_video_channel_mute_set(void *video,
912                           int   mute)
913 {
914    Emotion_Gstreamer_Video *ev;
915
916    ev = (Emotion_Gstreamer_Video *)video;
917
918    ev->video_mute = mute;
919 }
920
921 static int
922 em_video_channel_mute_get(void *video)
923 {
924    Emotion_Gstreamer_Video *ev;
925
926    ev = (Emotion_Gstreamer_Video *)video;
927
928    return ev->video_mute;
929 }
930
931 /* Audio channels */
932
933 static int
934 em_audio_channel_count(void *video)
935 {
936    Emotion_Gstreamer_Video *ev;
937
938    ev = (Emotion_Gstreamer_Video *)video;
939
940    return ecore_list_count(ev->audio_sinks);
941 }
942
943 static void
944 em_audio_channel_set(void *video,
945                      int   channel)
946 {
947    Emotion_Gstreamer_Video *ev;
948
949    ev = (Emotion_Gstreamer_Video *)video;
950
951    if (channel < -1) channel = -1;
952    /* FIXME: a faire... */
953 }
954
955 static int
956 em_audio_channel_get(void *video)
957 {
958    Emotion_Gstreamer_Video *ev;
959
960    ev = (Emotion_Gstreamer_Video *)video;
961
962    return ev->audio_sink_nbr;
963 }
964
965 static const char *
966 em_audio_channel_name_get(void *video,
967                           int   channel)
968 {
969    Emotion_Gstreamer_Video *ev;
970
971    ev = (Emotion_Gstreamer_Video *)video;
972
973    return NULL;
974 }
975
976 static void
977 em_audio_channel_mute_set(void *video,
978                           int   mute)
979 {
980    Emotion_Gstreamer_Video *ev;
981    GstElement              *volume;
982
983    ev = (Emotion_Gstreamer_Video *)video;
984
985    if (ev->audio_mute == mute)
986      return;
987
988    ev->audio_mute = mute;
989    volume = gst_bin_get_by_name (GST_BIN (ev->pipeline), "volume");
990    if (!volume) return;
991
992    if (mute)
993       g_object_set (G_OBJECT (volume), "volume", 0.0, NULL);
994    else
995       g_object_set (G_OBJECT (volume), "volume", ev->volume * 10.0, NULL);
996
997    gst_object_unref (volume);
998 }
999
1000 static int
1001 em_audio_channel_mute_get(void *video)
1002 {
1003    Emotion_Gstreamer_Video *ev;
1004
1005    ev = (Emotion_Gstreamer_Video *)video;
1006
1007    return ev->audio_mute;
1008 }
1009
1010 static void
1011 em_audio_channel_volume_set(void  *video,
1012                             double vol)
1013 {
1014    Emotion_Gstreamer_Video *ev;
1015    GstElement              *volume;
1016
1017    ev = (Emotion_Gstreamer_Video *)video;
1018
1019    if (vol < 0.0)
1020      vol = 0.0;
1021    if (vol > 1.0)
1022      vol = 1.0;
1023    ev->volume = vol;
1024    volume = gst_bin_get_by_name (GST_BIN (ev->pipeline), "volume");
1025    if (!volume) return;
1026    g_object_set (G_OBJECT (volume), "volume",
1027                  vol * 10.0, NULL);
1028    gst_object_unref (volume);
1029 }
1030
1031 static double
1032 em_audio_channel_volume_get(void *video)
1033 {
1034    Emotion_Gstreamer_Video *ev;
1035
1036    ev = (Emotion_Gstreamer_Video *)video;
1037
1038    return ev->volume;
1039 }
1040
1041 /* spu stuff */
1042
1043 static int
1044 em_spu_channel_count(void *video)
1045 {
1046    Emotion_Gstreamer_Video *ev;
1047
1048    ev = (Emotion_Gstreamer_Video *)video;
1049
1050    return 0;
1051 }
1052
1053 static void
1054 em_spu_channel_set(void *video, int channel)
1055 {
1056    Emotion_Gstreamer_Video *ev;
1057
1058    ev = (Emotion_Gstreamer_Video *)video;
1059 }
1060
1061 static int
1062 em_spu_channel_get(void *video)
1063 {
1064    Emotion_Gstreamer_Video *ev;
1065
1066    ev = (Emotion_Gstreamer_Video *)video;
1067
1068    return 1;
1069 }
1070
1071 static const char *
1072 em_spu_channel_name_get(void *video, int channel)
1073 {
1074    Emotion_Gstreamer_Video *ev;
1075
1076    ev = (Emotion_Gstreamer_Video *)video;
1077    return NULL;
1078 }
1079
1080 static void
1081 em_spu_channel_mute_set(void *video, int mute)
1082 {
1083    Emotion_Gstreamer_Video *ev;
1084
1085    ev = (Emotion_Gstreamer_Video *)video;
1086 }
1087
1088 static int
1089 em_spu_channel_mute_get(void *video)
1090 {
1091    Emotion_Gstreamer_Video *ev;
1092
1093    ev = (Emotion_Gstreamer_Video *)video;
1094
1095    return 0;
1096 }
1097
1098 static int
1099 em_chapter_count(void *video)
1100 {
1101    Emotion_Gstreamer_Video *ev;
1102
1103    ev = (Emotion_Gstreamer_Video *)video;
1104    return 0;
1105 }
1106
1107 static void
1108 em_chapter_set(void *video, int chapter)
1109 {
1110    Emotion_Gstreamer_Video *ev;
1111
1112    ev = (Emotion_Gstreamer_Video *)video;
1113 }
1114
1115 static int
1116 em_chapter_get(void *video)
1117 {
1118    Emotion_Gstreamer_Video *ev;
1119
1120    ev = (Emotion_Gstreamer_Video *)video;
1121
1122    return 0;
1123 }
1124
1125 static const char *
1126 em_chapter_name_get(void *video, int chapter)
1127 {
1128    Emotion_Gstreamer_Video *ev;
1129
1130    ev = (Emotion_Gstreamer_Video *)video;
1131
1132    return NULL;
1133 }
1134
1135 static void
1136 em_speed_set(void *video, double speed)
1137 {
1138    Emotion_Gstreamer_Video *ev;
1139
1140    ev = (Emotion_Gstreamer_Video *)video;
1141 }
1142
1143 static double
1144 em_speed_get(void *video)
1145 {
1146    Emotion_Gstreamer_Video *ev;
1147
1148    ev = (Emotion_Gstreamer_Video *)video;
1149
1150    return 1.0;
1151 }
1152
1153 static int
1154 em_eject(void *video)
1155 {
1156    Emotion_Gstreamer_Video *ev;
1157
1158    ev = (Emotion_Gstreamer_Video *)video;
1159
1160    return 1;
1161 }
1162
1163 static const char *
1164 em_meta_get(void *video, int meta)
1165 {
1166    Emotion_Gstreamer_Video *ev;
1167    GstBus                  *bus;
1168    gchar                   *str = NULL;
1169    gboolean                 done;
1170
1171    ev = (Emotion_Gstreamer_Video *)video;
1172    if (!ev) return NULL;
1173
1174    done = FALSE;
1175    bus = gst_element_get_bus (ev->pipeline);
1176    if (!bus) return NULL;
1177
1178    while (!done) {
1179       GstMessage *message;
1180
1181       message = gst_bus_pop (bus);
1182       if (message == NULL)
1183         /* All messages read, we're done */
1184          break;
1185
1186       switch (GST_MESSAGE_TYPE (message)) {
1187       case GST_MESSAGE_TAG: {
1188          GstTagList *new_tags;
1189
1190          gst_message_parse_tag (message, &new_tags);
1191
1192          switch (meta) {
1193          case META_TRACK_TITLE:
1194             gst_tag_list_get_string (new_tags, GST_TAG_TITLE, &str);
1195             if (str) done = TRUE;
1196             break;
1197          case META_TRACK_ARTIST:
1198             gst_tag_list_get_string (new_tags, GST_TAG_ARTIST, &str);
1199             if (str) done = TRUE;
1200             break;
1201          case META_TRACK_GENRE:
1202             gst_tag_list_get_string (new_tags, GST_TAG_GENRE, &str);
1203             if (str) done = TRUE;
1204             break;
1205          case META_TRACK_COMMENT:
1206             gst_tag_list_get_string (new_tags, GST_TAG_COMMENT, &str);
1207             if (str) done = TRUE;
1208             break;
1209          case META_TRACK_ALBUM:
1210             gst_tag_list_get_string (new_tags, GST_TAG_ALBUM, &str);
1211             if (str) done = TRUE;
1212             break;
1213          case META_TRACK_YEAR: {
1214             const GValue *date;
1215
1216             date = gst_tag_list_get_value_index (new_tags, GST_TAG_DATE, 0);
1217             if (date)
1218                str = g_strdup_value_contents (date);
1219             if (str) done = TRUE;
1220             break;
1221          }
1222          case META_TRACK_DISCID:
1223 #ifdef GST_TAG_CDDA_CDDB_DISCID
1224             gst_tag_list_get_string (new_tags, GST_TAG_CDDA_CDDB_DISCID, &str);
1225 #endif
1226             if (str) done = TRUE;
1227             break;
1228          case META_TRACK_COUNT: {
1229             int track_count;
1230
1231             track_count = emotion_pipeline_cdda_track_count_get (video);
1232             if (track_count > 0) {
1233                char buf[64];
1234
1235                g_snprintf (buf, 64, "%d", track_count);
1236                str = g_strdup (buf);
1237                done = TRUE;
1238             }
1239             break;
1240          }
1241          }
1242          break;
1243       }
1244       default:
1245          break;
1246       }
1247       gst_message_unref (message);
1248    }
1249
1250    gst_object_unref (GST_OBJECT (bus));
1251
1252    return str;
1253 }
1254
1255 unsigned char
1256 module_open(Evas_Object           *obj,
1257             Emotion_Video_Module **module,
1258             void                 **video,
1259             Emotion_Module_Options *opt)
1260 {
1261    if (!module)
1262       return 0;
1263
1264    if (!em_module.init(obj, video, opt))
1265       return 0;
1266
1267    *module = &em_module;
1268    return 1;
1269 }
1270
1271 void
1272 module_close(Emotion_Video_Module *module,
1273              void                 *video)
1274 {
1275    em_module.shutdown(video);
1276 }
1277
1278 static int
1279 _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh)
1280 {
1281    int fd;
1282    int len;
1283    void *buf[2];
1284    unsigned char *frame_data;
1285    Emotion_Gstreamer_Video *ev;
1286    GstBuffer  *buffer;
1287
1288    ev = data;
1289    fd = ecore_main_fd_handler_fd_get(fdh);
1290
1291    while ((len = read(fd, buf, sizeof(buf))) > 0)
1292      {
1293         if (len == sizeof(buf))
1294           {
1295              Emotion_Video_Sink *vsink;
1296
1297              frame_data = buf[0];
1298              buffer = buf[1];
1299              _emotion_frame_new(ev->obj);
1300              vsink = (Emotion_Video_Sink *)ecore_list_index_goto (ev->video_sinks, ev->video_sink_nbr);
1301              _emotion_video_pos_update(ev->obj, ev->position, vsink->length_time);
1302           }
1303      }
1304    return 1;
1305 }
1306
1307 int _eos_timer_fct (void *data)
1308 {
1309    Emotion_Gstreamer_Video *ev;
1310    GstMessage              *msg;
1311
1312    ev = (Emotion_Gstreamer_Video *)data;
1313    while ((msg = gst_bus_poll (ev->eos_bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS, 0))) {
1314      switch (GST_MESSAGE_TYPE(msg)) {
1315      case GST_MESSAGE_ERROR: {
1316        gchar *debug;
1317        GError *err;
1318
1319        gst_message_parse_error (msg, &err, &debug);
1320        g_free (debug);
1321
1322        g_print ("Error: %s\n", err->message);
1323        g_error_free (err);
1324
1325        break;
1326      }
1327      case GST_MESSAGE_EOS:
1328        if (ev->eos_timer)
1329          {
1330            ecore_timer_del(ev->eos_timer);
1331            ev->eos_timer = NULL;
1332          }
1333        ev->play = 0;
1334        _emotion_decode_stop(ev->obj);
1335        _emotion_playback_finished(ev->obj);
1336        break;
1337      default:
1338        break;
1339      }
1340      gst_message_unref (msg);
1341    }
1342    return 1;
1343 }