6179d183e16785e8bbbbf28a643a3f21b05e87a8
[profile/ivi/emotion.git] / src / modules / vlc / emotion_vlc.c
1 /* 
2  * SICMA AERO SEAT
3  * code@ife-sit.info
4  */
5
6 #ifdef HAVE_CONFIG_H
7 # include "config.h"
8 #endif
9 #include <sys/types.h>
10 #include <unistd.h>
11 #include <Evas.h>
12 #ifdef HAVE_EVAS_SOFWARE_X11
13 # include <Evas_Engine_Software_X11.h>
14 #endif
15 #ifdef HAVE_EVAS_OPENGL_X11
16 # include <Evas_Engine_GL_X11.h>
17 #endif
18
19 #include "Emotion.h"
20 #include "emotion_private.h"
21 #include "emotion_vlc.h"
22
23 /* internal util calls */
24 static void *_em_lock          (void *par);
25 static void  _em_unlock        (void *par);
26 static void  _em_event         (const libvlc_event_t *event, void* data);
27 static void  _em_resize        (Emotion_Vlc_Video *ev, int x,  int y);
28 static Eina_Bool _em_fd_active (Emotion_Vlc_Video *ev, Ecore_Fd_Handler *fdh);
29 static int   _em_reload_vlc    (Emotion_Vlc_Video *ev);
30 void*        _em_slave_thread  (void * t);
31
32 void * _em_slave_thread(void * t)
33 {
34         int event;
35         pthread_detach(pthread_self());
36         Emotion_Vlc_Video *ev=  (Emotion_Vlc_Video*)t;
37         while(read(ev->fd_slave_read, &event,  sizeof(int)) > 0)        {
38                 switch(event)   {
39                         case VLC_RESIZE:
40                                 _em_resize(ev, -1, -1);
41                         break;
42                         case VLC_CHANGE_VOL:
43                                 _emotion_audio_level_change(ev->obj);
44                         break;
45                         default:
46                         break;
47                 }
48         }
49         fprintf(stderr,"BYE BYE");
50         return NULL;
51 }
52
53 static unsigned char em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt)
54 {
55         Emotion_Vlc_Video *ev;
56         Emotion_Vlc_Video_Frame *ef;
57         int fds[2], x, y;
58         int event = VLC_NEW_FRAME;
59         pthread_t t_id;
60         x = WIDTH;
61         y = HEIGHT;
62
63
64         if (!emotion_video) return 0;
65
66         ev = (Emotion_Vlc_Video*)calloc(1, sizeof(Emotion_Vlc_Video));
67         ASSERT_EV(ev) return 0;
68         memset(ev, 0, sizeof(Emotion_Vlc_Video));
69
70         ef = (Emotion_Vlc_Video_Frame*)calloc(1, sizeof(Emotion_Vlc_Video_Frame));
71         if (!ef) return 0;
72         memset(ef, 0, sizeof(Emotion_Vlc_Video_Frame));
73
74         /* init internal frames */
75         if(ef->frame_A) {
76                 free(ef->frame_A);
77         }
78         if(ef->frame_B) {
79                 free(ef->frame_B);
80         }
81         ef->frame_A = (char*)malloc(x*y*sizeof(char)*4);
82         ef->frame_B = (char*)malloc(x*y*sizeof(char)*4);
83         memset(ef->frame_A, 0x00, x*y*sizeof(char)*4);
84         memset(ef->frame_B, 0x00, x*y*sizeof(char)*4);
85         ef->frame = ef->frame_A;
86
87         /* update size in object */
88         ev->w = x;
89         ev->h = y;
90         ev->ratio = (double)x/(double)y;
91
92         ev->cur_frame = ef;
93
94         if(pipe(fds) == 0)
95         {
96                 ev->fd_read = fds[0];
97                 ev->fd_write = fds[1];
98                 fcntl(ev->fd_read, F_SETFL, O_NONBLOCK);
99                 ev->fd_handler = ecore_main_fd_handler_add(ev->fd_read, ECORE_FD_READ, (Ecore_Fd_Cb)_em_fd_active, ev, NULL, NULL);
100                 ecore_main_fd_handler_active_set(ev->fd_handler, ECORE_FD_READ);
101         }
102
103         if (pipe(fds) == 0)
104         {
105                 ev->fd_slave_read = fds[0];
106                 ev->fd_slave_write = fds[1];
107                 fcntl(ev->fd_slave_write, F_SETFL, O_NONBLOCK);
108         }
109         ev->obj = obj;
110
111         ev->delete_me = 0;
112         ev->opening = 1;
113         ev->play_ok = 0;
114         ev->video_mute = 1;
115
116         if (opt)
117         {
118                 ev->opt_no_audio = opt->no_audio;
119                 ev->opt_no_video = opt->no_video;
120         }
121
122
123         /* init libvlc */
124         int vlc_argc = 0;
125         char const *vlc_argv[] =
126         {
127                 "-q",
128                 //"-vvvvv",
129                 "--ignore-config"
130         };
131         vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
132         sprintf(ev->clock, "%lld", (long long int)(intptr_t)_em_lock);
133         sprintf(ev->cunlock, "%lld", (long long int)(intptr_t)_em_unlock);
134         sprintf(ev->cdata, "%lld", (long long int)(intptr_t)ev);
135         sprintf(ev->width, "%d", WIDTH);
136         sprintf(ev->height, "%d", HEIGHT);
137         sprintf(ev->pitch, "%d", 4*WIDTH);
138
139         ev->vlc_player = libvlc_new(vlc_argc, vlc_argv);
140
141         if(ev->vlc_player)      {
142                 ev->play_ok = 1;
143         }
144
145         pthread_mutex_init(&ef->frame_copy_lock, NULL);
146         pthread_create(&t_id, NULL, _em_slave_thread, ev);
147
148         ev->opening = 0;
149         write(ev->fd_write, &event, sizeof(void *));
150
151         *emotion_video = ev;
152         return 1;
153 }
154
155 static int em_shutdown(void *ef)
156 {
157         Emotion_Vlc_Video *ev;
158         Emotion_Vlc_Video_Frame *evvf;
159
160         ev = (Emotion_Vlc_Video *)ef;
161         evvf = ev->cur_frame;
162
163         ASSERT_EV_VLC(ev) return 0;
164         libvlc_release(ev->vlc_player);
165         ev->vlc_player = NULL;
166
167         ev->closing = 0;
168
169         ecore_main_fd_handler_del(ev->fd_handler);
170
171         if(evvf)        {
172                 if(evvf->frame_A)       {
173                         free(evvf->frame_A);
174                 }
175                 if(evvf->frame_B)       {
176                         free(evvf->frame_B);
177                 }
178                 pthread_mutex_destroy(&(evvf->frame_copy_lock));
179                 free(evvf);
180         }
181         close(ev->fd_write);
182         close(ev->fd_read);
183         close(ev->fd_slave_write);
184         close(ev->fd_slave_read);
185
186         return 1;
187 }
188
189 static unsigned char em_file_open(const char *file, Evas_Object *obj, void *ef)
190 {
191         Emotion_Vlc_Video *ev;
192         int i, method;
193  Evas *e;
194  Eina_List *methods, *l;
195  char *name;
196 #ifndef _WIN32
197  uint32_t xid;
198 #endif
199         ev = (Emotion_Vlc_Video *)ef;
200         ASSERT_EV(ev) return 0;
201         ASSERT_EV_VLC(ev) return 0;
202
203         ev->vlc_m = libvlc_media_new_path(ev->vlc_player, file);
204         ASSERT_EV_M(ev) return 0;
205         ev->vlc_mp = libvlc_media_player_new_from_media(ev->vlc_m);
206         libvlc_media_release(ev->vlc_m); 
207         ev->vlc_m = NULL;
208         ASSERT_EV_MP(ev) return 0;
209
210    e = evas_object_evas_get(obj);
211    method = evas_output_method_get(e);
212    methods = evas_render_method_list();
213    EINA_LIST_FOREACH(methods, l, name)
214      if (evas_render_method_lookup(name) == method) break;
215
216 #ifdef _WIN32 /* NOT IMPLEMENTED YET */
217   libvlc_media_player_set_hwnd(ev->vlc_mp, (void*)xid);
218 #else
219 #ifdef HAVE_EVAS_SOFWARE_X11
220    if (!strcmp(name, "software_x11"))
221      {
222         Evas_Engine_Info_Software_X11 *einfo;
223         einfo = (Evas_Engine_Info_Software_X11*)evas_engine_info_get(e);
224         xid = einfo->info.drawable;
225      }
226 #endif
227 #ifdef HAVE_EVAS_OPENGL_X11
228    if (!strcmp(name, "gl_x11"))
229      {
230         Evas_Engine_Info_GL_X11 *einfo;
231         einfo = (Evas_Engine_Info_GL_X11*)evas_engine_info_get(e);
232         xid = einfo->info.drawable;
233      }
234 #endif
235    if (strcmp(name, "software_x11") && strcmp(name, "gl_x11")) /* FIXME */
236      {
237         fprintf(stderr, "FATAL: engine unsupported!\n");
238         exit(1);
239      }
240   libvlc_media_player_set_xwindow(ev->vlc_mp, xid);
241 #endif
242
243         ev->vlc_evtmngr = libvlc_media_player_event_manager (ev->vlc_mp);
244
245         for(i = EVENT_BEG_ID; i<EVENT_BEG_ID+NB_EVENTS; i++)    {
246                 libvlc_event_attach(ev->vlc_evtmngr, (libvlc_event_type_t)i, _em_event, ev);
247         }
248
249         if(ev->filename)        {
250                 free(ev->filename);
251                 ev->filename = NULL;
252         }
253         ev->filename = strdup(file);
254
255         /* set properties to video object */
256         ev->just_loaded = 1;
257    evas_render_method_list_free(methods);
258         return 1;
259 }
260
261 static void em_file_close(void *ef)
262 {
263         Emotion_Vlc_Video *ev;
264         int i;
265
266         ev = (Emotion_Vlc_Video *)ef;
267         ASSERT_EV(ev) return;
268         ASSERT_EV_MP(ev) return;
269
270         for(i = EVENT_BEG_ID; i<EVENT_BEG_ID+NB_EVENTS; i++)    {
271                 libvlc_event_detach(ev->vlc_evtmngr, (libvlc_event_type_t)i, _em_event, ev);
272         }
273         libvlc_media_player_stop(ev->vlc_mp);
274         libvlc_media_player_release(ev->vlc_mp);
275         ev->vlc_mp = NULL;
276         if(ev->filename)        {
277                 free(ev->filename);
278                 ev->filename = NULL;
279         }
280 }
281
282 static void em_play(void *ef, double pos)
283 {
284         Emotion_Vlc_Video *ev;
285
286         ev = (Emotion_Vlc_Video *)ef;
287         ASSERT_EV(ev) return;
288         ASSERT_EV_MP(ev) return;
289
290         ev->play = 1;
291         ev->play_ok = 0;
292
293         if(pos != ev->pos)      {
294                 libvlc_media_player_set_time(ev->vlc_mp, (libvlc_time_t)(pos*1000));
295         }
296         
297         libvlc_media_player_play(ev->vlc_mp);
298
299         ev->just_loaded = 0;
300 }
301
302 static void em_stop(void *ef)
303 {
304         Emotion_Vlc_Video *ev;
305
306         ev = (Emotion_Vlc_Video *)ef;
307         ASSERT_EV(ev) return;
308         ASSERT_EV_MP(ev) return;
309
310         ev->play = 0;
311         ev->play_ok = 0;
312         libvlc_media_player_pause(ev->vlc_mp);
313 }
314
315 static void em_size_get(void *ef, int *w, int *h)
316 {
317         Emotion_Vlc_Video *ev;
318         Emotion_Vlc_Video_Frame *fr;
319
320         ev = (Emotion_Vlc_Video *)ef;
321         ASSERT_EV(ev) return;
322         fr = ev->cur_frame;
323
324         pthread_mutex_lock(&fr->frame_copy_lock);
325         if(w) *w = ev->w;
326         if(h) *h = ev->h;
327         pthread_mutex_unlock(&fr->frame_copy_lock);
328 }
329
330 static void em_pos_set(void *ef, double pos)
331 {
332         Emotion_Vlc_Video *ev;
333
334         ev = (Emotion_Vlc_Video *)ef;
335         ASSERT_EV(ev) return;
336         ASSERT_EV_MP(ev) return;
337         libvlc_media_player_set_time(ev->vlc_mp, (libvlc_time_t)(pos*1000));
338 }
339
340 static double em_len_get(void *ef)
341 {
342         Emotion_Vlc_Video *ev;
343         ASSERT_EV(ev) return 0;
344
345         ev = (Emotion_Vlc_Video *)ef;
346         return ev->len;
347 }
348
349 static int em_fps_num_get(void *ef)
350 {
351         Emotion_Vlc_Video *ev;
352
353         ASSERT_EV(ev) return 0;
354         ev = (Emotion_Vlc_Video *)ef;
355         return (int)(ev->fps * 1000.0);
356 }
357
358 static int em_fps_den_get(void *ef)
359 {
360         Emotion_Vlc_Video *ev;
361
362         return 1000;
363 }
364
365 static double em_fps_get(void *ef)
366 {
367         Emotion_Vlc_Video *ev;
368
369         ASSERT_EV(ev) return 0;
370         ev = (Emotion_Vlc_Video *)ef;
371         return ev->fps;
372 }
373
374 static double em_pos_get(void *ef)
375 {
376         Emotion_Vlc_Video *ev;
377
378         ASSERT_EV(ev) return 0;
379         ev = (Emotion_Vlc_Video *)ef;
380         return ev->pos;
381 }
382
383 static void em_vis_set(void *ef, Emotion_Vis vis)
384 {
385         Emotion_Vlc_Video *ev;
386
387         ev = (Emotion_Vlc_Video *)ef;
388         ASSERT_EV(ev) return;
389         if (ev->vis == vis) return;
390         ev->vis = vis;
391 }
392
393 static Emotion_Vis em_vis_get(void *ef)
394 {
395         Emotion_Vlc_Video *ev;
396
397         ev = (Emotion_Vlc_Video *)ef;
398         return ev->vis;
399 }
400
401 static Eina_Bool em_vis_supported(void *ef, Emotion_Vis vis)
402 {
403         Emotion_Vlc_Video *ev;
404
405         ev = (Emotion_Vlc_Video *)ef;
406         return EINA_FALSE;
407 }
408
409 static double em_ratio_get(void *ef)
410 {
411         double ratio;
412         Emotion_Vlc_Video *ev;
413         Emotion_Vlc_Video_Frame *fr;
414
415         ASSERT_EV(ev) return 0;
416         ev = (Emotion_Vlc_Video *)ef;
417         fr = ev->cur_frame;
418         pthread_mutex_lock(&fr->frame_copy_lock);
419         ratio = ev->ratio;
420         pthread_mutex_unlock(&fr->frame_copy_lock);
421         return ratio;
422 }
423
424 static int em_video_handled(void *ef)
425 {
426         int ret = 0;
427         Emotion_Vlc_Video *ev;
428
429         ASSERT_EV(ev) return 0;
430         ASSERT_EV_MP(ev) return 0;
431         ev = (Emotion_Vlc_Video *)ef;
432         if (ev->opening || (!ev->play_ok)) return 0;
433
434         ret = libvlc_media_player_has_vout(ev->vlc_mp);
435         return ret;
436 }
437
438 static int em_audio_handled(void *ef)
439 {
440         Emotion_Vlc_Video *ev;
441
442         ev = (Emotion_Vlc_Video *)ef;
443         ASSERT_EV(ev) return 0;
444         if (ev->opening || (!ev->play_ok)) return 0;
445         return 1;
446 }
447
448 static int em_seekable(void *ef)
449 {
450         int ret = 0;
451         Emotion_Vlc_Video *ev;
452
453         ev = (Emotion_Vlc_Video *)ef;
454         ASSERT_EV(ev) return 0;
455         ASSERT_EV_MP(ev) return 0;
456         if (ev->opening || (!ev->play_ok)) return 0;
457         ret = libvlc_media_player_is_seekable(ev->vlc_mp);
458         return ret;
459 }
460
461 static void em_frame_done(void *ef)
462 {
463         return;
464 }
465
466 static Emotion_Format em_format_get(void *ef)
467 {
468         Emotion_Vlc_Video *ev;
469
470         return EMOTION_FORMAT_BGRA;
471 }
472
473 static void em_video_data_size_get(void *ef, int *w, int *h)
474 {
475         Emotion_Vlc_Video *ev;
476
477         ev = (Emotion_Vlc_Video *)ef;
478         ASSERT_EV(ev) return;
479         if (w) *w = ev->w;
480         if (h) *h = ev->h;
481 }
482
483 static int em_yuv_rows_get(void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows)
484 {
485    Emotion_Vlc_Video *ev;
486    volatile Emotion_Vlc_Video_Frame *fr;
487    
488    ev = (Emotion_Vlc_Video *)ef;
489    fr = ev->cur_frame;
490    if (!fr) return 0;
491    if (fr->frame_A)
492      {
493         int i;
494         
495         // FIXME: this is wrong. see xine/gst modules
496         for (i = 0; i < h; i++) yrows[i] = fr->frame_A + (i * w);
497         for (i = 0; i < (h / 2); i++) urows[i] = fr->frame_A + (i * w);
498         for (i = 0; i < (h / 2); i++) vrows[i] = fr->frame_A + (i * w);
499         return 1;
500      }
501    return 0;
502 }
503
504 static int em_bgra_data_get(void *ef, unsigned char **bgra_data)
505 {
506         Emotion_Vlc_Video *ev;
507         Emotion_Vlc_Video_Frame *fr;
508
509         ev = (Emotion_Vlc_Video *)ef;
510         ASSERT_EV(ev) return 0;
511         fr = ev->cur_frame;
512         if (!fr) return 0;
513         if (fr->frame)
514         {
515                 /* wait for frame to be ready */
516                 pthread_mutex_lock(&fr->frame_copy_lock);
517                 /* send cur frame to emotion */
518                 *bgra_data = fr->frame;
519
520                 /* switch frames */
521                 if(fr->frame == fr->frame_A)    {
522                         fr->frame = fr->frame_B;
523                 } else {
524                         fr->frame = fr->frame_A;
525                 }
526
527                 /* unlock both frames */
528                 pthread_mutex_unlock(&fr->frame_copy_lock);
529                 return 1;
530         }
531         return 0;
532 }
533
534 static void _em_resize(Emotion_Vlc_Video *ev, int x,  int y)
535 {
536         int i;
537         int event;
538         int vlc_argc = 0;
539         unsigned int tmp;
540         char const *vlc_argv[] =
541         {
542                 "-q",
543                 //"-vvvvv",
544                 "--ignore-config",
545                 "--vout", "vmem",
546                 "--vmem-width", ev->width,
547                 "--vmem-height", ev->height,
548                 "--vmem-pitch", ev->pitch,
549                 "--vmem-chroma", "RV32",
550                 "--vmem-lock", ev->clock,
551                 "--vmem-unlock", ev->cunlock,
552                 "--vmem-data", ev->cdata,
553         };
554         Emotion_Vlc_Video_Frame *fr;
555
556         ASSERT_EV(ev)   return;
557         ASSERT_EV_VLC(ev) return;
558         fr = ev->cur_frame;
559
560         /* We look for new size if not specified */
561         if ((x == -1) || (y == -1))
562           if (!libvlc_video_get_size(ev->vlc_mp, tmp, &x, &y)) return;
563
564         /* stop vlc if necessary */
565         if(ev->filename)        {       
566                 libvlc_media_player_stop(ev->vlc_mp);
567                 libvlc_media_player_release(ev->vlc_mp);
568         }
569
570         /* update size in object */
571         ev->w = x;
572         ev->h = y;
573         ev->ratio = (double)x/(double)y;
574
575         /* we need to restart vlc */
576         libvlc_release(ev->vlc_player);
577         vlc_argc = sizeof(vlc_argv) / sizeof(*vlc_argv);
578         sprintf(ev->clock, "%lld", (long long int)(intptr_t)_em_lock);
579         sprintf(ev->cunlock, "%lld", (long long int)(intptr_t)_em_unlock);
580         sprintf(ev->cdata, "%lld", (long long int)(intptr_t)ev);
581         sprintf(ev->width, "%d", ev->w);
582         sprintf(ev->height, "%d", ev->h);
583         sprintf(ev->pitch, "%d", 4*ev->w);
584         ev->vlc_player = libvlc_new(vlc_argc, vlc_argv);
585
586         pthread_mutex_lock(&fr->frame_copy_lock);
587
588         if(ev->filename)        {       
589                 /* relaunch media and mediaplayer */
590                 ev->vlc_m = libvlc_media_new_path(ev->vlc_player, ev->filename);
591                 ASSERT_EV_M(ev) return;
592                 ev->vlc_mp = libvlc_media_player_new_from_media(ev->vlc_m);
593                 libvlc_media_release(ev->vlc_m); 
594                 ev->vlc_m = NULL;
595                 ASSERT_EV_MP(ev) return;
596
597                 ev->vlc_evtmngr = libvlc_media_player_event_manager (ev->vlc_mp);
598
599                 for(i = EVENT_BEG_ID; i<EVENT_BEG_ID+NB_EVENTS; i++)    {
600                         libvlc_event_attach(ev->vlc_evtmngr, (libvlc_event_type_t)i, _em_event, ev);
601                 }
602         }
603
604         /* resize frames */
605         if(fr->frame_A) {
606                 free(fr->frame_A);
607         }
608         if(fr->frame_B) {
609                 free(fr->frame_B);
610         }
611         fr->frame_A = malloc(ev->w*ev->h*sizeof(char)*4);
612         fr->frame_B = malloc(ev->w*ev->h*sizeof(char)*4);
613         memset(fr->frame_A, 0xFF, x*y*sizeof(char)*4);
614         memset(fr->frame_B, 0xFF, x*y*sizeof(char)*4);
615         fr->frame = fr->frame_A;
616
617         /* notify a new frame is available */
618         event = VLC_RESIZE;
619         write(ev->fd_write, &event, sizeof(void *));
620
621         pthread_mutex_unlock(&fr->frame_copy_lock);
622
623         /* unlock both frames */
624         if(ev->filename)        {       
625                 libvlc_media_player_play(ev->vlc_mp);
626         }
627
628         /* activate display */
629         ev->video_mute = 0;
630 }
631
632 static Eina_Bool _em_fd_active(Emotion_Vlc_Video *ev, Ecore_Fd_Handler *fdh)
633 {
634         /* this only used for ecore notification */
635         /* every other internal event should be done in _em_slave_thread */
636         int event;
637         int fd, len;
638         Emotion_Vlc_Video_Frame *fr;
639
640         fd = ecore_main_fd_handler_fd_get(fdh);
641         while((len = read(fd, &event, sizeof(int))) > 0) {
642                 if(len == sizeof(int)) {
643                         switch(event)   {
644                                 case VLC_NEW_FRAME:
645                                         ASSERT_EV(ev)   return EINA_TRUE;
646                                         _emotion_frame_new(ev->obj);
647                                 break;
648                                 case VLC_RESIZE:
649                                         ASSERT_EV(ev)   return EINA_TRUE;
650                                         _emotion_frame_resize(ev->obj, ev->w, ev->h, ev->ratio);
651                                 break;
652                                 default:
653                                 break;
654                         }
655                 }
656         }
657         return EINA_TRUE;
658 }
659
660
661 /* STUB */
662 static void em_event_feed(void *ef, int event)
663 {
664         Emotion_Vlc_Video *ev;
665
666         ev = (Emotion_Vlc_Video *)ef;
667         if ((ev->opening) || (!ev->play_ok)) return;
668
669         switch (event)
670         {
671                 case EMOTION_EVENT_MENU1:
672                         break;
673                 case EMOTION_EVENT_MENU2:
674                         break;
675                 case EMOTION_EVENT_MENU3:
676                         break;
677                 case EMOTION_EVENT_MENU4:
678                         break;
679                 case EMOTION_EVENT_MENU5:
680                         break;
681                 case EMOTION_EVENT_MENU6:
682                         break;
683                 case EMOTION_EVENT_MENU7:
684                         break;
685                 case EMOTION_EVENT_UP:
686                         break;
687                 case EMOTION_EVENT_DOWN:
688                         break;
689                 case EMOTION_EVENT_LEFT:
690                         break;
691                 case EMOTION_EVENT_RIGHT:
692                         break;
693                 case EMOTION_EVENT_SELECT:
694                         break;
695                 case EMOTION_EVENT_NEXT:
696                         break;
697                 case EMOTION_EVENT_PREV:
698                         break;
699                 case EMOTION_EVENT_ANGLE_NEXT:
700                         break;
701                 case EMOTION_EVENT_ANGLE_PREV:
702                         break;
703                 case EMOTION_EVENT_FORCE:
704                         break;
705                 case EMOTION_EVENT_0:
706                         break;
707                 case EMOTION_EVENT_1:
708                         break;
709                 case EMOTION_EVENT_2:
710                         break;
711                 case EMOTION_EVENT_3:
712                         break;
713                 case EMOTION_EVENT_4:
714                         break;
715                 case EMOTION_EVENT_5:
716                         break;
717                 case EMOTION_EVENT_6:
718                         break;
719                 case EMOTION_EVENT_7:
720                         break;
721                 case EMOTION_EVENT_8:
722                         break;
723                 case EMOTION_EVENT_9:
724                         break;
725                 case EMOTION_EVENT_10:
726                         break;
727                 default:
728                         return;
729                         break;
730         }
731 }
732
733 /* STUB */
734 static void em_event_mouse_button_feed(void *ef, int button, int x, int y)
735 {
736         Emotion_Vlc_Video *ev;
737
738         ev = (Emotion_Vlc_Video *)ef;
739         if ((ev->opening) || (!ev->play_ok)) return;
740 }
741
742 /* STUB */
743 static void em_event_mouse_move_feed(void *ef, int x, int y)
744 {
745         Emotion_Vlc_Video *ev;
746
747         ev = (Emotion_Vlc_Video *)ef;
748         if ((ev->opening) || (!ev->play_ok)) return;
749 }
750
751 static int em_video_channel_count(void *ef)
752 {
753         int ret  = 0;
754         Emotion_Vlc_Video *ev;
755         ev = (Emotion_Vlc_Video *)ef; 
756         ASSERT_EV(ev) return 0;
757         ASSERT_EV_MP(ev) return 0;
758         if (ev->opening || (!ev->play_ok)) return 0;
759         ret = libvlc_media_player_has_vout(ev->vlc_mp);
760         return ret;
761 }
762
763 /* STUB */
764 static void em_video_channel_set(void *ef, int channel)
765 {
766         return;
767 }
768
769 /* STUB */
770 static int em_video_channel_get(void *ef)
771 {
772         return 1;
773 }
774
775 /* STUB */
776 static const char * em_video_channel_name_get(void *ef, int channel)
777 {
778         Emotion_Vlc_Video *ev;
779         return NULL;
780 }
781
782 static void em_video_channel_mute_set(void *ef, int mute)
783 {
784         Emotion_Vlc_Video *ev;
785         ev = (Emotion_Vlc_Video*)ef;
786         ASSERT_EV(ev)   return;
787         ev->video_mute = mute;
788 }
789
790 static int em_video_channel_mute_get(void *ef)
791 {
792         Emotion_Vlc_Video *ev;
793         ev = (Emotion_Vlc_Video*)ef;
794         ASSERT_EV(ev)   return;
795         return ev->video_mute;
796 }
797
798 /* STUB */
799 static int em_audio_channel_count(void *ef)
800 {
801         return -1;
802 }
803
804 static void em_audio_channel_set(void *ef, int channel)
805 {
806         Emotion_Vlc_Video *ev;
807
808         ev = (Emotion_Vlc_Video *)ef;
809         ASSERT_EV(ev) return;
810         ASSERT_EV_VLC(ev) return;
811         if (channel < -1) channel = -1;
812         ev->audio_channel = channel;
813         libvlc_audio_set_channel(ev->vlc_mp, channel);
814 }
815
816 static int em_audio_channel_get(void *ef)
817 {
818         int ret = 0;
819         Emotion_Vlc_Video *ev;
820
821         ev = (Emotion_Vlc_Video *)ef;
822         ASSERT_EV(ev) return 0;
823         ASSERT_EV_VLC(ev) return 0;
824         if (ev->opening || (!ev->play_ok)) return 0;
825         ret = libvlc_audio_get_channel(ev->vlc_mp);
826         return ret;
827 }
828
829 /* STUB */
830 static const char * em_audio_channel_name_get(void *ef, int channel)
831 {
832         return NULL;
833 }
834
835 static void em_audio_channel_mute_set(void *ef, int mute)
836 {
837         Emotion_Vlc_Video *ev;
838
839         ev = (Emotion_Vlc_Video *)ef;
840         ASSERT_EV(ev) return;
841         ASSERT_EV_VLC(ev) return;
842         ev->audio_mute = mute;
843         libvlc_audio_set_mute(ev->vlc_mp, (int)(ev->audio_mute));
844 }
845
846 static int em_audio_channel_mute_get(void *ef)
847 {
848         Emotion_Vlc_Video *ev;
849
850         ev = (Emotion_Vlc_Video *)ef;
851         ASSERT_EV(ev) return 0;
852         return ev->audio_mute;
853 }
854
855 static void em_audio_channel_volume_set(void *ef, double vol)
856 {
857         int event = VLC_CHANGE_VOL;
858         Emotion_Vlc_Video *ev;
859
860         ev = (Emotion_Vlc_Video *)ef;
861         ASSERT_EV(ev) return;
862         ASSERT_EV_VLC(ev) return;
863
864         if (vol < 0.0) vol = 0.0;
865         if (vol > 1.0) vol = 1.0;
866         libvlc_audio_set_volume(ev->vlc_mp, (int)(vol * 200));
867         write(ev->fd_slave_write, &event, sizeof(void *));
868 }
869
870 static double em_audio_channel_volume_get(void *ef)
871 {
872         int vol;
873         Emotion_Vlc_Video *ev;
874
875         ev = (Emotion_Vlc_Video *)ef;
876         ASSERT_EV(ev) return;
877         ASSERT_EV_VLC(ev) return;
878         if (ev->opening || (!ev->play_ok)) return 0;
879         vol = libvlc_audio_get_volume(ev->vlc_mp);
880         return (double)(vol/200.0);
881 }
882
883 /* STUB */
884 static int em_spu_channel_count(void *ef)
885 {
886         return 0;
887 }
888
889 static void em_spu_channel_set(void *ef, int channel)
890 {
891         Emotion_Vlc_Video *ev;
892
893         ev = (Emotion_Vlc_Video *)ef;
894         ASSERT_EV(ev) return;
895         ASSERT_EV_MP(ev) return;
896         if (channel < 0) channel = 0;
897         ev->spu_channel = channel;
898         libvlc_video_set_spu(ev->vlc_mp, ev->spu_channel);
899 }
900
901 static int em_spu_channel_get(void *ef)
902 {
903         int num = 0;
904         Emotion_Vlc_Video *ev;
905
906         ev = (Emotion_Vlc_Video *)ef;
907         ASSERT_EV(ev) return 0;
908         ASSERT_EV_MP(ev) return 0;
909         if (ev->opening || (!ev->play_ok)) return 0;
910         num = libvlc_video_get_spu(ev->vlc_mp);
911         return num;
912 }
913
914 /* STUB */
915 static const char * em_spu_channel_name_get(void *ef, int channel)
916 {
917         return NULL;
918 }
919
920 /* STUB */
921 static void em_spu_channel_mute_set(void *ef, int mute)
922 {
923         return;
924 }
925
926 /* STUB */
927 static int em_spu_channel_mute_get(void *ef)
928 {
929         return 0;
930 }
931
932 static int em_chapter_count(void *ef)
933 {
934         int num = 0;
935         Emotion_Vlc_Video *ev;
936
937         ev = (Emotion_Vlc_Video *)ef;
938         ASSERT_EV(ev) return 0;
939         ASSERT_EV_MP(ev) return 0;
940         if (ev->opening || (!ev->play_ok)) return 0;
941         num = libvlc_media_player_get_chapter_count(ev->vlc_mp);
942         return num;
943 }
944
945 static void em_chapter_set(void *ef, int chapter)
946 {
947         Emotion_Vlc_Video *ev;
948
949         ev = (Emotion_Vlc_Video *)ef;
950         ASSERT_EV(ev) return;
951         ASSERT_EV_MP(ev) return ;
952         libvlc_media_player_set_chapter(ev->vlc_mp, chapter);
953 }
954
955 static int em_chapter_get(void *ef)
956 {
957         int num = 0;
958         Emotion_Vlc_Video *ev;
959
960         ev = (Emotion_Vlc_Video *)ef;
961         ASSERT_EV(ev) return 0;
962         ASSERT_EV_MP(ev) return 0;
963         num = libvlc_media_player_get_chapter(ev->vlc_mp);
964         return num;
965 }
966
967 /* STUB */
968 static const char * em_chapter_name_get(void *ef, int chapter)
969 {
970         return NULL;
971 }
972
973 static void em_speed_set(void *ef, double speed)
974 {
975         Emotion_Vlc_Video *ev;
976
977         ev = (Emotion_Vlc_Video *)ef;
978         ASSERT_EV(ev) return;
979         ASSERT_EV_MP(ev) return;
980         libvlc_media_player_set_rate(ev->vlc_mp, speed);
981 }
982
983 static double em_speed_get(void *ef)
984 {
985         float speed = 0;
986         Emotion_Vlc_Video *ev;
987
988         ev = (Emotion_Vlc_Video *)ef;
989         ASSERT_EV(ev) return 0;
990         ASSERT_EV_MP(ev) return 0;
991         speed = libvlc_media_player_get_rate(ev->vlc_mp);
992         return (double)speed;
993 }
994
995 static int em_eject(void *ef)
996 {
997         Emotion_Vlc_Video *ev;
998
999         ev = (Emotion_Vlc_Video *)ef;
1000         if (system("eject"))
1001           fprintf(stderr, "Eject failed!\n");
1002         return 1;
1003 }
1004
1005 static const char * em_meta_get(void *ef, int meta)
1006 {
1007         char * meta_data = NULL;
1008         Emotion_Vlc_Video *ev;
1009
1010         ev = (Emotion_Vlc_Video *)ef;
1011         ASSERT_EV(ev)   return NULL;
1012         ASSERT_EV_M(ev) return NULL;
1013         if ((ev->opening) || (!ev->play_ok)) return NULL;
1014         switch (meta)
1015         {
1016                 case META_TRACK_TITLE:
1017                         meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Title);
1018                         break;
1019                 case META_TRACK_ARTIST:
1020                         meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Artist);
1021                         break;
1022                 case META_TRACK_GENRE:
1023                         meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Genre);
1024                         break;
1025                 case META_TRACK_COMMENT:
1026                         meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Description);
1027                         break;
1028                 case META_TRACK_ALBUM:
1029                         meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Album);
1030                         break;
1031                 case META_TRACK_YEAR:
1032                         meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_Date);
1033                         break;
1034                 case META_TRACK_DISCID:
1035                         meta_data = libvlc_media_get_meta(ev->vlc_m, libvlc_meta_TrackID);
1036                         break;
1037                 default:
1038                         break;
1039         }
1040         return meta_data;
1041 }
1042
1043 static void _em_event(const libvlc_event_t *event, void *data)
1044 {
1045         Emotion_Vlc_Event *new_ev;
1046         Emotion_Vlc_Video *ev;
1047
1048         ev = data;
1049         ASSERT_EV(ev)   return;
1050         switch (event->type) {
1051                 case libvlc_MediaPlayerTimeChanged: {
1052                                 libvlc_time_t pos = event->u.media_player_time_changed.new_time;
1053                                 double time = (pos / 1000000.f);
1054                                 _emotion_video_pos_update(ev->obj, time, 0);
1055                                 ev->pos = time;
1056                                 if(ev->len == 0)        {
1057                                         pos = libvlc_media_player_get_length(ev->vlc_mp);
1058                                         ev->len = (double)(pos / 1000.0);
1059                                 }
1060                         }
1061                 case libvlc_MediaPlayerPlaying: {
1062                                 int x, y;
1063                                 unsigned int tmp;
1064                                 float fps = 0;
1065                                 float pos = 0;
1066                                 float total_pos = 0;
1067                                 libvlc_time_t time = 0;
1068                                 libvlc_time_t total_time = 0;
1069
1070                                 /* get video properties */
1071                                 total_time = libvlc_media_player_get_length(ev->vlc_mp);
1072                                 fps = libvlc_media_player_get_fps(ev->vlc_mp);
1073                                 libvlc_video_get_size(ev->vlc_mp, tmp, &x, &y);
1074                                 /* set them to object */
1075                                 if(ev->fps == 0)        {
1076                                         ev->fps = fps;
1077                                 }
1078                                 if(ev->len == 0)        {
1079                                         ev->len = (double)(total_time / 1000.0);
1080                                 }
1081                                 if((x != 0) && (y != 0))        {
1082                                         if((ev->w != x)||(ev->h != y))  {
1083                                                 int event;
1084                                                 event = VLC_RESIZE;
1085                                                 write(ev->fd_slave_write, &event, sizeof(void *));
1086                                         }
1087                                 }
1088                         } break;
1089                 case libvlc_MediaPlayerEndReached: {
1090                                 ev->play = 0;
1091                                 _emotion_decode_stop(ev->obj);
1092                                 _emotion_playback_finished(ev->obj);
1093                         } break;
1094                 default:
1095                         break;
1096         }
1097 }
1098
1099 static void *_em_lock(void *par)
1100 {
1101         Emotion_Vlc_Video *ev;
1102         Emotion_Vlc_Video_Frame *evvf; 
1103
1104         /* get current frame */
1105         ev = (Emotion_Vlc_Video*)par;
1106         evvf = ev->cur_frame;
1107
1108         /* lock current frame */
1109         pthread_mutex_lock(&(evvf->frame_copy_lock));
1110         
1111         /* send current frame address to vlc */
1112         return evvf->frame;
1113 }
1114
1115 static void  _em_unlock(void *par)
1116 {
1117         float p = 0;
1118         int ret;
1119         int event;
1120         Emotion_Vlc_Video *ev;
1121         Emotion_Vlc_Video_Frame *evvf; 
1122
1123         /* get current frame */
1124         ev = (Emotion_Vlc_Video*)par;
1125         evvf = ev->cur_frame;
1126
1127         /* notify a new frame is available */
1128         event = VLC_NEW_FRAME;
1129         
1130         if(ev->video_mute == 0) {
1131                 ret = write(ev->fd_write, &event, sizeof(void *));
1132         }
1133         pthread_mutex_unlock(&(evvf->frame_copy_lock));
1134
1135         return;
1136 }
1137
1138 static Emotion_Video_Module em_module =
1139 {
1140         em_init, /* init */
1141         em_shutdown, /* shutdown */
1142         em_file_open, /* file_open */
1143         em_file_close, /* file_close */
1144         em_play, /* play */
1145         em_stop, /* stop */
1146         em_size_get, /* size_get */
1147         em_pos_set, /* pos_set */
1148         em_len_get, /* len_get */
1149         em_fps_num_get, /* fps_num_get */
1150         em_fps_den_get, /* fps_den_get */
1151         em_fps_get, /* fps_get */
1152         em_pos_get, /* pos_get */
1153         em_vis_set, /* vis_set */
1154         em_vis_get, /* vis_get */
1155         em_vis_supported, /* vis_supported */
1156         em_ratio_get, /* ratio_get */
1157         em_video_handled, /* video_handled */
1158         em_audio_handled, /* audio_handled */
1159         em_seekable, /* seekable */
1160         em_frame_done, /* frame_done */
1161         em_format_get, /* format_get */
1162         em_video_data_size_get, /* video_data_size_get */
1163         em_yuv_rows_get, /* yuv_rows_get */
1164         em_bgra_data_get, /* bgra_data_get */
1165         em_event_feed, /* event_feed */
1166         em_event_mouse_button_feed, /* event_mouse_button_feed */
1167         em_event_mouse_move_feed, /* event_mouse_move_feed */
1168         em_video_channel_count, /* video_channel_count */
1169         em_video_channel_set, /* video_channel_set */
1170         em_video_channel_get, /* video_channel_get */
1171         em_video_channel_name_get, /* video_channel_name_get */
1172         em_video_channel_mute_set, /* video_channel_mute_set */
1173         em_video_channel_mute_get, /* video_channel_mute_get */
1174         em_audio_channel_count, /* audio_channel_count */
1175         em_audio_channel_set, /* audio_channel_set */
1176         em_audio_channel_get, /* audio_channel_get */
1177         em_audio_channel_name_get, /* audio_channel_name_get */
1178         em_audio_channel_mute_set, /* audio_channel_mute_set */
1179         em_audio_channel_mute_get, /* audio_channel_mute_get */
1180         em_audio_channel_volume_set, /* audio_channel_volume_set */
1181         em_audio_channel_volume_get, /* audio_channel_volume_get */
1182         em_spu_channel_count, /* spu_channel_count */
1183         em_spu_channel_set, /* spu_channel_set */
1184         em_spu_channel_get, /* spu_channel_get */
1185         em_spu_channel_name_get, /* spu_channel_name_get */
1186         em_spu_channel_mute_set, /* spu_channel_mute_set */
1187         em_spu_channel_mute_get, /* spu_channel_mute_get */
1188         em_chapter_count, /* chapter_count */
1189         em_chapter_set, /* chapter_set */
1190         em_chapter_get, /* chapter_get */
1191         em_chapter_name_get, /* chapter_name_get */
1192         em_speed_set, /* speed_set */
1193         em_speed_get, /* speed_get */
1194         em_eject, /* eject */
1195         em_meta_get, /* meta_get */
1196        _emotion_object_extension_can_play_generic_get, /* can_play_get */
1197
1198         NULL /* handle */
1199 };
1200
1201 static Eina_Bool module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
1202 {
1203         if (!module)    {
1204                 return EINA_FALSE;
1205         }
1206
1207         if (!em_module.init(obj, video, opt))   {
1208                 return EINA_FALSE;
1209         }
1210
1211         *module = &em_module;
1212
1213         return EINA_TRUE;
1214 }
1215
1216 static void module_close(Emotion_Video_Module *module, void *video)
1217 {
1218         em_module.shutdown(video);
1219 }
1220
1221
1222 Eina_Bool
1223 vlc_module_init(void)
1224 {
1225    return _emotion_module_register("vlc", module_open, module_close);
1226 }
1227
1228 void
1229 vlc_module_shutdown(void)
1230 {
1231    _emotion_module_unregister("vlc");
1232 }
1233
1234 #ifndef EMOTION_STATIC_BUILD_VLC
1235
1236 EINA_MODULE_INIT(vlc_module_init);
1237 EINA_MODULE_SHUTDOWN(vlc_module_shutdown);
1238
1239 #endif
1240