2 #include "emotion_private.h"
3 #include "emotion_xine.h"
6 static unsigned char em_init (Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt);
7 static int em_shutdown (void *ef);
8 static unsigned char em_file_open (const char *file, Evas_Object *obj, void *ef);
9 static void em_file_close (void *ef);
10 static void em_play (void *ef, double pos);
11 static void em_stop (void *ef);
12 static void em_size_get (void *ef, int *w, int *h);
13 static void em_pos_set (void *ef, double pos);
14 static void em_vis_set (void *ef, Emotion_Vis vis);
15 static double em_len_get (void *ef);
16 static int em_fps_num_get (void *ef);
17 static int em_fps_den_get (void *ef);
18 static double em_fps_get (void *ef);
19 static double em_pos_get (void *ef);
20 static Emotion_Vis em_vis_get (void *ef);
21 static double em_ratio_get (void *ef);
22 static int em_seekable (void *ef);
23 static void em_frame_done (void *ef);
24 static Emotion_Format em_format_get (void *ef);
25 static void em_video_data_size_get (void *ef, int *w, int *h);
26 static int em_yuv_rows_get (void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows);
27 static int em_bgra_data_get (void *ef, unsigned char **bgra_data);
28 static void em_event_feed (void *ef, int event);
29 static void em_event_mouse_button_feed (void *ef, int button, int x, int y);
30 static void em_event_mouse_move_feed (void *ef, int x, int y);
31 static int em_video_channel_count (void *ef);
32 static void em_video_channel_set (void *ef, int channel);
33 static int em_video_channel_get (void *ef);
34 static const char *em_video_channel_name_get (void *ef, int channel);
35 static void em_video_channel_mute_set (void *ef, int mute);
36 static int em_video_channel_mute_get (void *ef);
37 static int em_audio_channel_count (void *ef);
38 static void em_audio_channel_set (void *ef, int channel);
39 static int em_audio_channel_get (void *ef);
40 static const char *em_audio_channel_name_get (void *ef, int channel);
41 static void em_audio_channel_mute_set (void *ef, int mute);
42 static int em_audio_channel_mute_get (void *ef);
43 static void em_audio_channel_volume_set(void *ef, double vol);
44 static double em_audio_channel_volume_get(void *ef);
45 static int em_spu_channel_count (void *ef);
46 static void em_spu_channel_set (void *ef, int channel);
47 static int em_spu_channel_get (void *ef);
48 static const char *em_spu_channel_name_get (void *ef, int channel);
49 static void em_spu_channel_mute_set (void *ef, int mute);
50 static int em_spu_channel_mute_get (void *ef);
51 static int em_chapter_count (void *ef);
52 static void em_chapter_set (void *ef, int chapter);
53 static int em_chapter_get (void *ef);
54 static const char *em_chapter_name_get (void *ef, int chapter);
55 static void em_speed_set (void *ef, double speed);
56 static double em_speed_get (void *ef);
57 static int em_eject (void *ef);
58 static const char *em_meta_get (void *ef, int meta);
60 /* internal util calls */
61 static void *_em_slave (void *par);
62 static void _em_slave_event (void *data, int type, void *arg);
63 static int _em_fd_active (void *data, Ecore_Fd_Handler *fdh);
64 static void _em_event (void *data, const xine_event_t *event);
65 static void _em_module_event (void *data, int type);
66 static int _em_fd_ev_active (void *data, Ecore_Fd_Handler *fdh);
67 //static int _em_timer (void *data);
68 static void *_em_get_pos_len_th(void *par);
69 static void _em_get_pos_len (Emotion_Xine_Video *ev);
71 extern plugin_info_t emotion_xine_plugin_info[];
73 /* this is a slave controller thread for the xine module - libxine loves
74 * to deadlock, internally stall and otherwise have unpredictable behavior
75 * if we use the main process thread for many things - so a lot will be
76 * farmed off to this slave. its job is to handle opening, closing, file
77 * opening, recoder init etc. and all sorts of things can that often block.
78 * anything this thread needs to return, it will return via the event pipe.
83 Emotion_Xine_Video *ev;
87 ev = (Emotion_Xine_Video *)par;
88 while ((len = read(ev->fd_slave_read, buf, sizeof(buf))) > 0)
90 if (len == sizeof(buf))
92 Emotion_Xine_Event *eev;
102 ev->decoder = xine_new();
103 xine_init(ev->decoder);
104 xine_register_plugins(ev->decoder, emotion_xine_plugin_info);
108 if (xine_config_lookup_entry(ev->decoder, "input.dvd_use_readahead", &cf))
110 cf.num_value = 1; // 0 or 1
111 xine_config_update_entry(ev->decoder, &cf);
114 printf("OPEN VIDEO PLUGIN...\n");
115 if (!ev->opt_no_video)
116 ev->video = xine_open_video_driver(ev->decoder, "emotion",
117 XINE_VISUAL_TYPE_NONE, ev);
118 printf("RESULT: xine_open_video_driver() = %p\n", ev->video);
119 // Let xine autodetect the best audio output driver
120 if (!ev->opt_no_audio)
121 ev->audio = xine_open_audio_driver(ev->decoder, NULL, ev);
122 // ev->audio = xine_open_audio_driver(ev->decoder, "oss", ev);
123 // dont use alsa - alsa has oss emulation.
124 // ev->audio = xine_open_audio_driver(ev->decoder, "alsa", ev);
125 // ev->audio = xine_open_audio_driver(ev->decoder, "arts", ev);
126 // ev->audio = xine_open_audio_driver(ev->decoder, "esd", ev);
127 ev->stream = xine_stream_new(ev->decoder, ev->audio, ev->video);
128 ev->queue = xine_event_new_queue(ev->stream);
129 xine_event_create_listener_thread(ev->queue, _em_event, ev);
132 _em_module_event(ev, 1); /* event - open done */
135 case 3: /* shutdown */
137 _em_module_event(ev, 3);
138 printf("EX shutdown stop\n");
139 xine_stop(ev->stream);
140 // pthread_mutex_lock(&(ev->get_pos_len_mutex));
141 if (!ev->get_pos_thread_deleted)
143 printf("closing get_pos thread, %p\n", ev);
144 pthread_mutex_lock(&(ev->get_pos_len_mutex));
145 pthread_cond_broadcast(&(ev->get_pos_len_cond));
146 pthread_mutex_unlock(&(ev->get_pos_len_mutex));
147 while (ev->get_poslen);
149 printf("EX dispose %p\n", ev);
150 xine_dispose(ev->stream);
151 printf("EX dispose evq %p\n", ev);
152 xine_event_dispose_queue(ev->queue);
153 printf("EX close video drv %p\n", ev);
154 if (ev->video) xine_close_video_driver(ev->decoder, ev->video);
155 printf("EX wait for vo to go\n");
157 printf("EX vo gone\n");
158 printf("EX close audio drv %p\n", ev);
159 if (ev->audio) xine_close_audio_driver(ev->decoder, ev->audio);
160 printf("EX xine exit %p\n", ev);
161 xine_exit(ev->decoder);
162 printf("EX DONE %p\n", ev);
165 close(ev->fd_ev_write);
166 close(ev->fd_ev_read);
167 close(ev->fd_slave_write);
168 close(ev->fd_slave_read);
170 if (eev->xine_event) free(eev->xine_event);
176 case 2: /* file open */
184 file = eev->xine_event;
185 printf("OPN STREAM %s\n", file);
186 if (xine_open(ev->stream, file))
188 if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time))
190 if (length_time == 0)
192 ev->pos = (double)pos_stream / 65535;
199 ev->len = (double)length_time / 1000.0;
207 v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_FRAME_DURATION);
208 if (v > 0) ev->fps = 90000.0 / (double)v;
209 v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_WIDTH);
211 v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HEIGHT);
213 v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO);
214 ev->ratio = (double)v / 10000.0;
218 _em_module_event(ev, 2); /* event - open done */
221 case 11: /* file close */
223 printf("EX done %p\n", ev);
225 printf("EX stop %p\n", ev);
226 xine_stop(ev->stream);
227 printf("EX close %p\n", ev);
228 xine_close(ev->stream);
229 printf("EX close done %p\n", ev);
230 _em_module_event(ev, 11);
236 int pos_stream, pos_time, length_time;
238 pos = *((double *)eev->xine_event);
239 if ((xine_get_param(ev->stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE) &&
243 xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
248 xine_play(ev->stream, pos * 65535, 0);
250 xine_play(ev->stream, 0, pos * 1000);
254 if (xine_get_pos_length(ev->stream,
259 if (length_time == 0)
261 ev->pos = (double)pos_stream / 65535;
267 ev->pos = (double)pos_time / 1000.0;
268 ev->len = (double)length_time / 1000.0;
271 _em_module_event(ev, 4);
276 xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
277 _em_module_event(ev, 5);
284 pos = *((double *)eev->xine_event);
285 if (ev->seeked_pos != ev->seek_to_pos)
288 xine_play(ev->stream, pos * 65535, 0);
290 xine_play(ev->stream, 0, pos * 1000);
292 xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
293 ev->seeked_pos = ev->seek_to_pos;
295 _em_module_event(ev, 6);
300 xine_eject(ev->stream);
301 _em_module_event(ev, 7);
304 case 8: /* spu mute */
306 xine_set_param(ev->stream, XINE_PARAM_IGNORE_SPU, ev->spu_mute);
307 _em_module_event(ev, 8);
310 case 9: /* channel */
312 xine_set_param(ev->stream, XINE_PARAM_SPU_CHANNEL, ev->spu_channel);
313 _em_module_event(ev, 9);
320 vol = *((double *)eev->xine_event);
321 if (vol < 0.0) vol = 0.0;
322 if (vol > 1.0) vol = 1.0;
323 xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, vol * 100);
324 _em_module_event(ev, 10);
327 case 12: /* audio mute */
329 xine_set_param(ev->stream, XINE_PARAM_AUDIO_MUTE, ev->audio_mute);
332 case 13: /* audio mute */
334 xine_set_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, ev->audio_channel);
337 case 14: /* audio mute */
339 xine_set_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL, ev->video_channel);
345 if (eev->xine_event) free(eev->xine_event);
352 _em_slave_event(void *data, int type, void *arg)
355 Emotion_Xine_Event *new_ev;
356 Emotion_Xine_Video *ev;
359 new_ev = calloc(1, sizeof(Emotion_Xine_Event));
361 new_ev->mtype = type;
363 new_ev->xine_event = arg;
366 write(ev->fd_slave_write, buf, sizeof(buf));
370 em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt)
372 Emotion_Xine_Video *ev;
375 if (!emotion_video) return 0;
377 ev = calloc(1, sizeof(Emotion_Xine_Video));
383 ev->fd_read = fds[0];
384 ev->fd_write = fds[1];
385 fcntl(ev->fd_read, F_SETFL, O_NONBLOCK);
386 ev->fd_handler = ecore_main_fd_handler_add(ev->fd_read, ECORE_FD_READ,
389 ecore_main_fd_handler_active_set(ev->fd_handler, ECORE_FD_READ);
393 ev->fd_ev_read = fds[0];
394 ev->fd_ev_write = fds[1];
395 fcntl(ev->fd_ev_read, F_SETFL, O_NONBLOCK);
396 ev->fd_ev_handler = ecore_main_fd_handler_add(ev->fd_ev_read,
397 ECORE_FD_READ, _em_fd_ev_active, ev, NULL, NULL);
398 ecore_main_fd_handler_active_set(ev->fd_ev_handler, ECORE_FD_READ);
402 ev->fd_slave_read = fds[0];
403 ev->fd_slave_write = fds[1];
404 fcntl(ev->fd_slave_write, F_SETFL, O_NONBLOCK);
407 ev->get_pos_thread_deleted = 0;
413 ev->opt_no_audio = opt->no_audio;
414 ev->opt_no_video = opt->no_video;
417 pthread_cond_init(&(ev->get_pos_len_cond), NULL);
418 pthread_mutex_init(&(ev->get_pos_len_mutex), NULL);
419 pthread_create(&ev->get_pos_len_th, NULL, _em_get_pos_len_th, ev);
421 pthread_create(&ev->slave_th, NULL, _em_slave, ev);
422 pthread_detach(ev->slave_th);
423 _em_slave_event(ev, 1, NULL);
430 em_shutdown(void *ef)
432 Emotion_Xine_Video *ev;
434 ev = (Emotion_Xine_Video *)ef;
437 printf("EXM del fds %p\n", ev);
438 ecore_main_fd_handler_del(ev->fd_handler);
439 ecore_main_fd_handler_del(ev->fd_ev_handler);
442 _em_slave_event(ev, 3, NULL);
443 printf("EXM done %p\n", ev);
448 em_file_open(const char *file, Evas_Object *obj, void *ef)
450 Emotion_Xine_Video *ev;
452 ev = (Emotion_Xine_Video *)ef;
454 _em_slave_event(ev, 2, strdup(file));
459 em_file_close(void *ef)
461 Emotion_Xine_Video *ev;
463 ev = (Emotion_Xine_Video *)ef;
465 _em_slave_event(ev, 11, NULL);
469 em_play(void *ef, double pos)
471 Emotion_Xine_Video *ev;
474 ev = (Emotion_Xine_Video *)ef;
477 ppos = malloc(sizeof(double));
479 _em_slave_event(ev, 4, ppos);
485 Emotion_Xine_Video *ev;
487 ev = (Emotion_Xine_Video *)ef;
490 _em_slave_event(ev, 5, NULL);
494 em_size_get(void *ef, int *w, int *h)
496 Emotion_Xine_Video *ev;
498 ev = (Emotion_Xine_Video *)ef;
504 em_pos_set(void *ef, double pos)
506 Emotion_Xine_Video *ev;
509 ev = (Emotion_Xine_Video *)ef;
510 if (pos == ev->seek_to_pos) return;
511 ppos = malloc(sizeof(double));
513 ev->seek_to_pos = pos;
514 _em_slave_event(ev, 6, ppos);
521 Emotion_Xine_Video *ev;
523 ev = (Emotion_Xine_Video *)ef;
524 if (ev->vis == vis) return;
531 Emotion_Xine_Video *ev;
533 ev = (Emotion_Xine_Video *)ef;
538 em_fps_num_get(void *ef)
540 Emotion_Xine_Video *ev;
542 ev = (Emotion_Xine_Video *)ef;
543 return (int)(ev->fps * 10000.0);
547 em_fps_den_get(void *ef)
549 Emotion_Xine_Video *ev;
551 ev = (Emotion_Xine_Video *)ef;
558 Emotion_Xine_Video *ev;
560 ev = (Emotion_Xine_Video *)ef;
567 Emotion_Xine_Video *ev;
569 ev = (Emotion_Xine_Video *)ef;
576 Emotion_Xine_Video *ev;
578 ev = (Emotion_Xine_Video *)ef;
584 em_ratio_get(void *ef)
586 Emotion_Xine_Video *ev;
588 ev = (Emotion_Xine_Video *)ef;
593 em_video_handled(void *ef)
595 Emotion_Xine_Video *ev;
597 ev = (Emotion_Xine_Video *)ef;
598 if (ev->opening || (!ev->play_ok)) return 0;
599 return (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO) &&
600 xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HANDLED));
604 em_audio_handled(void *ef)
606 Emotion_Xine_Video *ev;
608 ev = (Emotion_Xine_Video *)ef;
609 if (ev->opening || (!ev->play_ok)) return 0;
610 return (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_AUDIO) &&
611 xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_HANDLED));
615 em_seekable(void *ef)
617 Emotion_Xine_Video *ev;
619 ev = (Emotion_Xine_Video *)ef;
620 if (ev->opening || (!ev->play_ok)) return 0;
621 return xine_get_stream_info(ev->stream, XINE_STREAM_INFO_SEEKABLE);
625 em_frame_done(void *ef)
627 Emotion_Xine_Video *ev;
629 ev = (Emotion_Xine_Video *)ef;
633 if (ev->cur_frame->done_func)
634 ev->cur_frame->done_func(ev->cur_frame->done_data);
635 ev->cur_frame = NULL;
639 static Emotion_Format
640 em_format_get(void *ef)
642 Emotion_Xine_Video *ev;
643 volatile Emotion_Xine_Video_Frame *fr;
645 ev = (Emotion_Xine_Video *)ef;
647 if (fr) return fr->format;
648 return EMOTION_FORMAT_YV12;
652 em_video_data_size_get(void *ef, int *w, int *h)
654 Emotion_Xine_Video *ev;
655 volatile Emotion_Xine_Video_Frame *fr;
657 ev = (Emotion_Xine_Video *)ef;
670 em_yuv_rows_get(void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows)
672 Emotion_Xine_Video *ev;
673 volatile Emotion_Xine_Video_Frame *fr;
675 ev = (Emotion_Xine_Video *)ef;
682 for (i = 0; i < h; i++) yrows[i] = fr->y + (i * fr->y_stride);
683 for (i = 0; i < (h / 2); i++) urows[i] = fr->u + (i * fr->u_stride);
684 for (i = 0; i < (h / 2); i++) vrows[i] = fr->v + (i * fr->v_stride);
691 em_bgra_data_get(void *ef, unsigned char **bgra_data)
693 Emotion_Xine_Video *ev;
694 volatile Emotion_Xine_Video_Frame *fr;
696 ev = (Emotion_Xine_Video *)ef;
701 *bgra_data = fr->bgra_data;
708 em_event_feed(void *ef, int event)
710 Emotion_Xine_Video *ev;
711 xine_event_t xine_event;
713 ev = (Emotion_Xine_Video *)ef;
714 if ((ev->opening) || (!ev->play_ok)) return;
715 xine_event.data_length = 0;
716 xine_event.data = NULL;
717 xine_event.stream = ev->stream;
718 gettimeofday(&xine_event.tv, NULL);
721 case EMOTION_EVENT_MENU1:
722 xine_event.type = XINE_EVENT_INPUT_MENU1;
724 case EMOTION_EVENT_MENU2:
725 xine_event.type = XINE_EVENT_INPUT_MENU2;
727 case EMOTION_EVENT_MENU3:
728 xine_event.type = XINE_EVENT_INPUT_MENU3;
730 case EMOTION_EVENT_MENU4:
731 xine_event.type = XINE_EVENT_INPUT_MENU4;
733 case EMOTION_EVENT_MENU5:
734 xine_event.type = XINE_EVENT_INPUT_MENU5;
736 case EMOTION_EVENT_MENU6:
737 xine_event.type = XINE_EVENT_INPUT_MENU6;
739 case EMOTION_EVENT_MENU7:
740 xine_event.type = XINE_EVENT_INPUT_MENU7;
742 case EMOTION_EVENT_UP:
743 xine_event.type = XINE_EVENT_INPUT_UP;
745 case EMOTION_EVENT_DOWN:
746 xine_event.type = XINE_EVENT_INPUT_DOWN;
748 case EMOTION_EVENT_LEFT:
749 xine_event.type = XINE_EVENT_INPUT_LEFT;
751 case EMOTION_EVENT_RIGHT:
752 xine_event.type = XINE_EVENT_INPUT_RIGHT;
754 case EMOTION_EVENT_SELECT:
755 xine_event.type = XINE_EVENT_INPUT_SELECT;
757 case EMOTION_EVENT_NEXT:
758 xine_event.type = XINE_EVENT_INPUT_NEXT;
760 case EMOTION_EVENT_PREV:
761 xine_event.type = XINE_EVENT_INPUT_PREVIOUS;
763 case EMOTION_EVENT_ANGLE_NEXT:
764 xine_event.type = XINE_EVENT_INPUT_ANGLE_NEXT;
766 case EMOTION_EVENT_ANGLE_PREV:
767 xine_event.type = XINE_EVENT_INPUT_ANGLE_PREVIOUS;
769 case EMOTION_EVENT_FORCE:
770 xine_event.type = XINE_EVENT_INPUT_BUTTON_FORCE;
772 case EMOTION_EVENT_0:
773 xine_event.type = XINE_EVENT_INPUT_NUMBER_0;
775 case EMOTION_EVENT_1:
776 xine_event.type = XINE_EVENT_INPUT_NUMBER_1;
778 case EMOTION_EVENT_2:
779 xine_event.type = XINE_EVENT_INPUT_NUMBER_2;
781 case EMOTION_EVENT_3:
782 xine_event.type = XINE_EVENT_INPUT_NUMBER_3;
784 case EMOTION_EVENT_4:
785 xine_event.type = XINE_EVENT_INPUT_NUMBER_4;
787 case EMOTION_EVENT_5:
788 xine_event.type = XINE_EVENT_INPUT_NUMBER_5;
790 case EMOTION_EVENT_6:
791 xine_event.type = XINE_EVENT_INPUT_NUMBER_6;
793 case EMOTION_EVENT_7:
794 xine_event.type = XINE_EVENT_INPUT_NUMBER_7;
796 case EMOTION_EVENT_8:
797 xine_event.type = XINE_EVENT_INPUT_NUMBER_8;
799 case EMOTION_EVENT_9:
800 xine_event.type = XINE_EVENT_INPUT_NUMBER_9;
802 case EMOTION_EVENT_10:
803 xine_event.type = XINE_EVENT_INPUT_NUMBER_10_ADD;
809 xine_event_send(ev->stream, &xine_event);
813 em_event_mouse_button_feed(void *ef, int button, int x, int y)
815 Emotion_Xine_Video *ev;
816 xine_event_t xine_event;
817 xine_input_data_t xine_input;
819 ev = (Emotion_Xine_Video *)ef;
820 if ((ev->opening) || (!ev->play_ok)) return;
821 xine_event.stream = ev->stream;
822 gettimeofday(&xine_event.tv, NULL);
823 xine_event.type = XINE_EVENT_INPUT_MOUSE_BUTTON;
824 xine_input.button = 1;
827 xine_event.data = &xine_input;
828 xine_event.data_length = sizeof(xine_input);
829 xine_event_send(ev->stream, &xine_event);
833 em_event_mouse_move_feed(void *ef, int x, int y)
835 Emotion_Xine_Video *ev;
836 xine_event_t xine_event;
837 xine_input_data_t xine_input;
839 ev = (Emotion_Xine_Video *)ef;
840 if ((ev->opening) || (!ev->play_ok)) return;
841 xine_event.stream = ev->stream;
842 gettimeofday(&xine_event.tv, NULL);
843 xine_event.type = XINE_EVENT_INPUT_MOUSE_MOVE;
844 xine_input.button = 0;
847 xine_event.data = &xine_input;
848 xine_event.data_length = sizeof(xine_input);
849 xine_event_send(ev->stream, &xine_event);
853 em_video_channel_count(void *ef)
855 Emotion_Xine_Video *ev;
858 ev = (Emotion_Xine_Video *)ef;
859 if (ev->opening || (!ev->play_ok)) return 0;
860 v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_CHANNELS);
862 xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO)) return 1;
867 em_video_channel_set(void *ef, int channel)
869 Emotion_Xine_Video *ev;
871 ev = (Emotion_Xine_Video *)ef;
872 if (channel < 0) channel = 0;
873 ev->video_channel = channel;
874 _em_slave_event(ev, 14, NULL);
878 em_video_channel_get(void *ef)
880 Emotion_Xine_Video *ev;
882 ev = (Emotion_Xine_Video *)ef;
883 if (ev->opening || (!ev->play_ok)) return 0;
884 return xine_get_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL);
888 em_video_channel_name_get(void *ef, int channel)
890 Emotion_Xine_Video *ev;
892 ev = (Emotion_Xine_Video *)ef;
897 em_video_channel_mute_set(void *ef, int mute)
899 Emotion_Xine_Video *ev;
901 ev = (Emotion_Xine_Video *)ef;
902 ev->video_mute = mute;
906 em_video_channel_mute_get(void *ef)
908 Emotion_Xine_Video *ev;
910 ev = (Emotion_Xine_Video *)ef;
911 return ev->video_mute;
915 em_audio_channel_count(void *ef)
917 Emotion_Xine_Video *ev;
919 ev = (Emotion_Xine_Video *)ef;
920 if (ev->opening || (!ev->play_ok)) return 0;
921 return xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
925 em_audio_channel_set(void *ef, int channel)
927 Emotion_Xine_Video *ev;
929 ev = (Emotion_Xine_Video *)ef;
930 if (channel < -1) channel = -1;
931 ev->audio_channel = channel;
932 _em_slave_event(ev, 13, NULL);
936 em_audio_channel_get(void *ef)
938 Emotion_Xine_Video *ev;
940 ev = (Emotion_Xine_Video *)ef;
941 if (ev->opening || (!ev->play_ok)) return 0;
942 return xine_get_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
946 em_audio_channel_name_get(void *ef, int channel)
948 Emotion_Xine_Video *ev;
949 static char lang[XINE_LANG_MAX + 1];
951 ev = (Emotion_Xine_Video *)ef;
952 if (ev->opening) return NULL;
954 if (xine_get_audio_lang(ev->stream, channel, lang)) return lang;
959 em_audio_channel_mute_set(void *ef, int mute)
961 Emotion_Xine_Video *ev;
963 ev = (Emotion_Xine_Video *)ef;
964 ev->audio_mute = mute;
965 _em_slave_event(ev, 12, NULL);
969 em_audio_channel_mute_get(void *ef)
971 Emotion_Xine_Video *ev;
973 ev = (Emotion_Xine_Video *)ef;
974 return ev->audio_mute;
978 em_audio_channel_volume_set(void *ef, double vol)
980 Emotion_Xine_Video *ev;
983 ev = (Emotion_Xine_Video *)ef;
984 ppos = malloc(sizeof(double));
986 _em_slave_event(ev, 10, ppos);
990 em_audio_channel_volume_get(void *ef)
992 Emotion_Xine_Video *ev;
994 ev = (Emotion_Xine_Video *)ef;
995 if (ev->opening || (!ev->play_ok)) return 0;
996 return (double)xine_get_param(ev->stream, XINE_PARAM_AUDIO_VOLUME) / 100.0;
1000 em_spu_channel_count(void *ef)
1002 Emotion_Xine_Video *ev;
1004 ev = (Emotion_Xine_Video *)ef;
1005 if (ev->opening || (!ev->play_ok)) return 0;
1006 return xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
1010 em_spu_channel_set(void *ef, int channel)
1012 Emotion_Xine_Video *ev;
1014 ev = (Emotion_Xine_Video *)ef;
1015 if (channel < 0) channel = 0;
1016 ev->spu_channel = channel;
1017 _em_slave_event(ev, 9, NULL);
1021 em_spu_channel_get(void *ef)
1023 Emotion_Xine_Video *ev;
1025 ev = (Emotion_Xine_Video *)ef;
1026 if (ev->opening || (!ev->play_ok)) return 0;
1027 return xine_get_param(ev->stream, XINE_PARAM_SPU_CHANNEL);
1031 em_spu_channel_name_get(void *ef, int channel)
1033 Emotion_Xine_Video *ev;
1034 static char lang[XINE_LANG_MAX + 1];
1036 ev = (Emotion_Xine_Video *)ef;
1037 if (ev->opening) return NULL;
1039 if (xine_get_spu_lang(ev->stream, channel, lang)) return lang;
1044 em_spu_channel_mute_set(void *ef, int mute)
1046 Emotion_Xine_Video *ev;
1048 ev = (Emotion_Xine_Video *)ef;
1049 ev->spu_mute = mute;
1050 _em_slave_event(ev, 8, NULL);
1054 em_spu_channel_mute_get(void *ef)
1056 Emotion_Xine_Video *ev;
1058 ev = (Emotion_Xine_Video *)ef;
1059 return ev->spu_mute;
1063 em_chapter_count(void *ef)
1065 Emotion_Xine_Video *ev;
1067 ev = (Emotion_Xine_Video *)ef;
1068 if (ev->opening || (!ev->play_ok)) return 0;
1069 if (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_CHAPTERS))
1075 em_chapter_set(void *ef, int chapter)
1077 Emotion_Xine_Video *ev;
1079 ev = (Emotion_Xine_Video *)ef;
1083 em_chapter_get(void *ef)
1085 Emotion_Xine_Video *ev;
1087 ev = (Emotion_Xine_Video *)ef;
1092 em_chapter_name_get(void *ef, int chapter)
1094 Emotion_Xine_Video *ev;
1096 ev = (Emotion_Xine_Video *)ef;
1101 em_speed_set(void *ef, double speed)
1103 Emotion_Xine_Video *ev;
1105 ev = (Emotion_Xine_Video *)ef;
1109 em_speed_get(void *ef)
1111 Emotion_Xine_Video *ev;
1113 ev = (Emotion_Xine_Video *)ef;
1120 Emotion_Xine_Video *ev;
1122 ev = (Emotion_Xine_Video *)ef;
1123 _em_slave_event(ev, 7, NULL);
1128 em_meta_get(void *ef, int meta)
1130 Emotion_Xine_Video *ev;
1132 ev = (Emotion_Xine_Video *)ef;
1133 if ((ev->opening) || (!ev->play_ok)) return NULL;
1136 case META_TRACK_TITLE:
1137 return xine_get_meta_info(ev->stream, XINE_META_INFO_TITLE);
1139 case META_TRACK_ARTIST:
1140 return xine_get_meta_info(ev->stream, XINE_META_INFO_ARTIST);
1142 case META_TRACK_GENRE:
1143 return xine_get_meta_info(ev->stream, XINE_META_INFO_GENRE);
1145 case META_TRACK_COMMENT:
1146 return xine_get_meta_info(ev->stream, XINE_META_INFO_COMMENT);
1148 case META_TRACK_ALBUM:
1149 return xine_get_meta_info(ev->stream, XINE_META_INFO_ALBUM);
1151 case META_TRACK_YEAR:
1152 return xine_get_meta_info(ev->stream, XINE_META_INFO_YEAR);
1154 case META_TRACK_DISCID:
1155 return xine_get_meta_info(ev->stream, XINE_META_INFO_CDINDEX_DISCID);
1164 _em_fd_active(void *data, Ecore_Fd_Handler *fdh)
1168 Emotion_Xine_Video_Frame *fr;
1169 Emotion_Xine_Video *ev;
1172 fd = ecore_main_fd_handler_fd_get(fdh);
1173 while ((len = read(fd, &buf, sizeof(buf))) > 0)
1175 if (len == sizeof(buf))
1178 ev = _emotion_video_get(fr->obj);
1183 _em_get_pos_len(ev);
1184 if ((xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO)) &&
1185 (xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HANDLED)))
1187 if (ev->video_mute) em_frame_done(ev);
1188 else _emotion_frame_new(fr->obj);
1190 _emotion_frame_resize(fr->obj, fr->w, fr->h, fr->ratio);
1191 _emotion_video_pos_update(fr->obj, ev->pos, ev->len);
1199 _em_event(void *data, const xine_event_t *event)
1202 Emotion_Xine_Event *new_ev;
1203 Emotion_Xine_Video *ev;
1206 new_ev = calloc(1, sizeof(Emotion_Xine_Event));
1207 if (!new_ev) return;
1209 new_ev->type = event->type;
1212 new_ev->xine_event = malloc(event->data_length);
1213 if (!new_ev->xine_event)
1218 memcpy(new_ev->xine_event, event->data, event->data_length);
1222 write(ev->fd_ev_write, buf, sizeof(buf));
1226 _em_module_event(void *data, int type)
1229 Emotion_Xine_Event *new_ev;
1230 Emotion_Xine_Video *ev;
1233 new_ev = calloc(1, sizeof(Emotion_Xine_Event));
1234 if (!new_ev) return;
1235 new_ev->mtype = type;
1239 write(ev->fd_ev_write, buf, sizeof(buf));
1243 _em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh)
1245 Emotion_Xine_Video *ev;
1250 fd = ecore_main_fd_handler_fd_get(fdh);
1251 while ((len = read(fd, buf, sizeof(buf))) > 0)
1253 if (len == sizeof(buf))
1255 Emotion_Xine_Event *eev;
1259 if (eev->mtype != 0)
1263 case 1: /* init done */
1266 case 2: /* open done */
1269 case 3: /* shutdown done */
1272 case 4: /* play done */
1275 case 5: /* stop done */
1278 case 6: /* seek done */
1281 case 7: /* eject done */
1284 case 8: /* spu mute done */
1287 case 9: /* channel done */
1290 case 10: /* volume done */
1293 case 11: /* close done */
1304 case XINE_EVENT_UI_PLAYBACK_FINISHED:
1307 _emotion_decode_stop(ev->obj);
1308 _emotion_playback_finished(ev->obj);
1311 case XINE_EVENT_UI_CHANNELS_CHANGED:
1313 _emotion_channels_change(ev->obj);
1316 case XINE_EVENT_UI_SET_TITLE:
1320 e = (xine_ui_data_t *)eev->xine_event;
1321 _emotion_title_set(ev->obj, e->str);
1324 case XINE_EVENT_FRAME_FORMAT_CHANGE:
1326 xine_format_change_data_t *e;
1328 e = (xine_format_change_data_t *)eev->xine_event;
1331 case XINE_EVENT_UI_MESSAGE:
1333 xine_ui_message_data_t *e;
1335 e = (xine_ui_message_data_t *)eev->xine_event;
1336 printf("EV: UI Message [FIXME: break this out to emotion api]\n");
1337 // e->type = error type(XINE_MSG_NO_ERROR, XINE_MSG_GENERAL_WARNING, XINE_MSG_UNKNOWN_HOST etc.)
1338 // e->messages is a list of messages DOUBLE null terminated
1341 case XINE_EVENT_AUDIO_LEVEL:
1343 xine_audio_level_data_t *e;
1345 e = (xine_audio_level_data_t *)eev->xine_event;
1346 _emotion_audio_level_change(ev->obj);
1347 printf("EV: Audio Level [FIXME: break this out to emotion api]\n");
1353 case XINE_EVENT_PROGRESS:
1355 xine_progress_data_t *e;
1357 e = (xine_progress_data_t *)eev->xine_event;
1358 printf("PROGRESS: %i\n", e->percent);
1359 _emotion_progress_set(ev->obj, (char *)e->description, (double)e->percent / 100.0);
1362 case XINE_EVENT_MRL_REFERENCE:
1364 xine_mrl_reference_data_t *e;
1366 e = (xine_mrl_reference_data_t *)eev->xine_event;
1367 _emotion_file_ref_set(ev->obj, e->mrl, e->alternative);
1370 case XINE_EVENT_UI_NUM_BUTTONS:
1374 e = (xine_ui_data_t *)eev->xine_event;
1375 _emotion_spu_button_num_set(ev->obj, e->num_buttons);
1378 case XINE_EVENT_SPU_BUTTON:
1380 xine_spu_button_t *e;
1382 e = (xine_spu_button_t *)eev->xine_event;
1383 if (e->direction == 1)
1384 _emotion_spu_button_set(ev->obj, e->button);
1386 _emotion_spu_button_set(ev->obj, -1);
1389 case XINE_EVENT_DROPPED_FRAMES:
1391 xine_dropped_frames_t *e;
1393 e = (xine_dropped_frames_t *)eev->xine_event;
1394 printf("EV: Dropped Frames (skipped %i) (discarded %i) [FIXME: break this out to the emotion api]\n", e->skipped_frames, e->discarded_frames);
1395 // e->skipped_frames = % frames skipped * 10
1396 // e->discarded_frames = % frames skipped * 10
1400 // printf("EV: unknown event type %i\n", eev->type);
1404 if (eev->xine_event) free(eev->xine_event);
1412 _em_get_pos_len_th(void *par)
1414 Emotion_Xine_Video *ev;
1416 ev = (Emotion_Xine_Video *)par;
1420 pthread_mutex_lock(&(ev->get_pos_len_mutex));
1421 pthread_cond_wait(&(ev->get_pos_len_cond), &(ev->get_pos_len_mutex));
1422 pthread_mutex_unlock(&(ev->get_pos_len_mutex));
1427 int length_time = 0;
1429 if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time))
1431 if (length_time == 0)
1433 ev->pos = (double)pos_stream / 65535;
1439 ev->pos = (double)pos_time / 1000.0;
1440 ev->len = (double)length_time / 1000.0;
1445 //printf("get pos %3.3f\n", ev->pos);
1449 ev->get_pos_thread_deleted = 1;
1457 _em_get_pos_len(Emotion_Xine_Video *ev)
1459 if (ev->get_poslen) return;
1461 pthread_mutex_lock(&(ev->get_pos_len_mutex));
1462 pthread_cond_broadcast(&(ev->get_pos_len_cond));
1463 pthread_mutex_unlock(&(ev->get_pos_len_mutex));
1466 const static Emotion_Video_Module em_module =
1469 em_shutdown, /* shutdown */
1470 em_file_open, /* file_open */
1471 em_file_close, /* file_close */
1474 em_size_get, /* size_get */
1475 em_pos_set, /* pos_set */
1476 em_vis_set, /* vis_set */
1477 em_len_get, /* len_get */
1478 em_fps_num_get, /* fps_num_get */
1479 em_fps_den_get, /* fps_den_get */
1480 em_fps_get, /* fps_get */
1481 em_pos_get, /* pos_get */
1482 em_vis_get, /* vis_get */
1483 em_ratio_get, /* ratio_get */
1484 em_video_handled, /* video_handled */
1485 em_audio_handled, /* audio_handled */
1486 em_seekable, /* seekable */
1487 em_frame_done, /* frame_done */
1488 em_format_get, /* format_get */
1489 em_video_data_size_get, /* video_data_size_get */
1490 em_yuv_rows_get, /* yuv_rows_get */
1491 em_bgra_data_get, /* bgra_data_get */
1492 em_event_feed, /* event_feed */
1493 em_event_mouse_button_feed, /* event_mouse_button_feed */
1494 em_event_mouse_move_feed, /* event_mouse_move_feed */
1495 em_video_channel_count, /* video_channel_count */
1496 em_video_channel_set, /* video_channel_set */
1497 em_video_channel_get, /* video_channel_get */
1498 em_video_channel_name_get, /* video_channel_name_get */
1499 em_video_channel_mute_set, /* video_channel_mute_set */
1500 em_video_channel_mute_get, /* video_channel_mute_get */
1501 em_audio_channel_count, /* audio_channel_count */
1502 em_audio_channel_set, /* audio_channel_set */
1503 em_audio_channel_get, /* audio_channel_get */
1504 em_audio_channel_name_get, /* audio_channel_name_get */
1505 em_audio_channel_mute_set, /* audio_channel_mute_set */
1506 em_audio_channel_mute_get, /* audio_channel_mute_get */
1507 em_audio_channel_volume_set, /* audio_channel_volume_set */
1508 em_audio_channel_volume_get, /* audio_channel_volume_get */
1509 em_spu_channel_count, /* spu_channel_count */
1510 em_spu_channel_set, /* spu_channel_set */
1511 em_spu_channel_get, /* spu_channel_get */
1512 em_spu_channel_name_get, /* spu_channel_name_get */
1513 em_spu_channel_mute_set, /* spu_channel_mute_set */
1514 em_spu_channel_mute_get, /* spu_channel_mute_get */
1515 em_chapter_count, /* chapter_count */
1516 em_chapter_set, /* chapter_set */
1517 em_chapter_get, /* chapter_get */
1518 em_chapter_name_get, /* chapter_name_get */
1519 em_speed_set, /* speed_set */
1520 em_speed_get, /* speed_get */
1521 em_eject, /* eject */
1522 em_meta_get /* meta_get */
1526 module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
1531 if (!em_module.init(obj, video, opt))
1534 *module = &em_module;
1539 module_close(Emotion_Video_Module *module, void *video)
1541 em_module.shutdown(video);
1546 em_debug(Emotion_Xine_Video *ev)
1548 int has_chapters = 0;
1551 int video_channels = 0;
1552 int video_streams = 0;
1553 int video_seekable = 0;
1560 char *cdindex_discid;
1561 int video_channel = 0;
1562 int audio_channel = 0;
1563 int spu_channel = 0;
1564 int video_ratio = 0;
1568 has_chapters = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_CHAPTERS);
1569 max_spu = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
1570 max_audio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
1571 video_channels = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_CHANNELS);
1572 video_streams = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_STREAMS);
1573 video_seekable = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_SEEKABLE);
1574 title = xine_get_meta_info(ev->stream, XINE_META_INFO_TITLE);
1575 comment = xine_get_meta_info(ev->stream, XINE_META_INFO_COMMENT);
1576 artist = xine_get_meta_info(ev->stream, XINE_META_INFO_ARTIST);
1577 genre = xine_get_meta_info(ev->stream, XINE_META_INFO_GENRE);
1578 album = xine_get_meta_info(ev->stream, XINE_META_INFO_ALBUM);
1579 year = xine_get_meta_info(ev->stream, XINE_META_INFO_YEAR);
1580 cdindex_discid = xine_get_meta_info(ev->stream, XINE_META_INFO_CDINDEX_DISCID);
1581 video_channel = xine_get_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL);
1582 audio_channel = xine_get_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
1583 spu_channel = xine_get_param(ev->stream, XINE_PARAM_SPU_CHANNEL);
1584 video_ratio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO);
1585 audio_mode = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_MODE);
1586 printf("has_chapters = %i\n", has_chapters);
1587 printf("max_spu = %i\n", max_spu);
1588 printf("max_audio = %i\n", max_audio);
1589 printf("video_channels = %i\n", video_channels);
1590 printf("video_streams = %i\n", video_streams);
1591 printf("video_seekable = %i\n", video_seekable);
1592 printf("title = %s\n", title);
1593 printf("comment = %s\n", comment);
1594 printf("artist = %s\n", artist);
1595 printf("genre = %s\n", genre);
1596 printf("album = %s\n", album);
1597 printf("year = %s\n", year);
1598 printf("cdindex_discid = %s\n", cdindex_discid);
1599 printf("video_channel = %i\n", video_channel);
1600 printf("audio_channel = %i\n", audio_channel);
1601 printf("spu_channels = %i\n", spu_channel);
1602 printf("video_ratio = %i\n", video_ratio);
1603 printf("audio_mode = %i\n", audio_mode);
1607 for (i = 0; i <= max_audio; i++)
1609 char lang[XINE_LANG_MAX + 1];
1612 printf(" AUDIO %i = ", i);
1613 if (xine_get_audio_lang(ev->stream, i, lang))
1614 printf("%s\n", lang);
1618 for (i = 0; i <= max_spu; i++)
1620 char lang[XINE_LANG_MAX + 1];
1623 printf(" SPU %i = ", i);
1624 if (xine_get_spu_lang(ev->stream, i, lang))
1625 printf("%s\n", lang);