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