summaryrefslogtreecommitdiff
path: root/legacy/emotion/src/modules/xine/emotion_xine.c
diff options
context:
space:
mode:
authordoursse <doursse>2008-05-11 18:52:29 +0000
committerdoursse <doursse@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>2008-05-11 18:52:29 +0000
commitc014ed5267c18bdcd1449970d592972e89f7886f (patch)
tree16cb16d84a27be9c77594969c83a1ddab9e7fb49 /legacy/emotion/src/modules/xine/emotion_xine.c
parentd72b07f4aa8aac8b4466e5b05e3ddd158cd514b0 (diff)
put xine and gstreamer modules in their own subdir
SVN revision: 34539
Diffstat (limited to 'legacy/emotion/src/modules/xine/emotion_xine.c')
-rw-r--r--legacy/emotion/src/modules/xine/emotion_xine.c1633
1 files changed, 1633 insertions, 0 deletions
diff --git a/legacy/emotion/src/modules/xine/emotion_xine.c b/legacy/emotion/src/modules/xine/emotion_xine.c
new file mode 100644
index 0000000000..41624af87f
--- /dev/null
+++ b/legacy/emotion/src/modules/xine/emotion_xine.c
@@ -0,0 +1,1633 @@
1#include "Emotion.h"
2#include "emotion_private.h"
3#include "emotion_xine.h"
4
5/* module api */
6static unsigned char em_init (Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt);
7static int em_shutdown (void *ef);
8static unsigned char em_file_open (const char *file, Evas_Object *obj, void *ef);
9static void em_file_close (void *ef);
10static void em_play (void *ef, double pos);
11static void em_stop (void *ef);
12static void em_size_get (void *ef, int *w, int *h);
13static void em_pos_set (void *ef, double pos);
14static void em_vis_set (void *ef, Emotion_Vis vis);
15static double em_len_get (void *ef);
16static int em_fps_num_get (void *ef);
17static int em_fps_den_get (void *ef);
18static double em_fps_get (void *ef);
19static double em_pos_get (void *ef);
20static Emotion_Vis em_vis_get (void *ef);
21static double em_ratio_get (void *ef);
22static int em_seekable (void *ef);
23static void em_frame_done (void *ef);
24static Emotion_Format em_format_get (void *ef);
25static void em_video_data_size_get (void *ef, int *w, int *h);
26static int em_yuv_rows_get (void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows);
27static int em_bgra_data_get (void *ef, unsigned char **bgra_data);
28static void em_event_feed (void *ef, int event);
29static void em_event_mouse_button_feed (void *ef, int button, int x, int y);
30static void em_event_mouse_move_feed (void *ef, int x, int y);
31static int em_video_channel_count (void *ef);
32static void em_video_channel_set (void *ef, int channel);
33static int em_video_channel_get (void *ef);
34static const char *em_video_channel_name_get (void *ef, int channel);
35static void em_video_channel_mute_set (void *ef, int mute);
36static int em_video_channel_mute_get (void *ef);
37static int em_audio_channel_count (void *ef);
38static void em_audio_channel_set (void *ef, int channel);
39static int em_audio_channel_get (void *ef);
40static const char *em_audio_channel_name_get (void *ef, int channel);
41static void em_audio_channel_mute_set (void *ef, int mute);
42static int em_audio_channel_mute_get (void *ef);
43static void em_audio_channel_volume_set(void *ef, double vol);
44static double em_audio_channel_volume_get(void *ef);
45static int em_spu_channel_count (void *ef);
46static void em_spu_channel_set (void *ef, int channel);
47static int em_spu_channel_get (void *ef);
48static const char *em_spu_channel_name_get (void *ef, int channel);
49static void em_spu_channel_mute_set (void *ef, int mute);
50static int em_spu_channel_mute_get (void *ef);
51static int em_chapter_count (void *ef);
52static void em_chapter_set (void *ef, int chapter);
53static int em_chapter_get (void *ef);
54static const char *em_chapter_name_get (void *ef, int chapter);
55static void em_speed_set (void *ef, double speed);
56static double em_speed_get (void *ef);
57static int em_eject (void *ef);
58static const char *em_meta_get (void *ef, int meta);
59
60/* internal util calls */
61static void *_em_slave (void *par);
62static void _em_slave_event (void *data, int type, void *arg);
63static int _em_fd_active (void *data, Ecore_Fd_Handler *fdh);
64static void _em_event (void *data, const xine_event_t *event);
65static void _em_module_event (void *data, int type);
66static int _em_fd_ev_active (void *data, Ecore_Fd_Handler *fdh);
67//static int _em_timer (void *data);
68static void *_em_get_pos_len_th(void *par);
69static void _em_get_pos_len (Emotion_Xine_Video *ev);
70
71extern plugin_info_t emotion_xine_plugin_info[];
72
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.
79 */
80static void *
81_em_slave(void *par)
82{
83 Emotion_Xine_Video *ev;
84 void *buf[2];
85 int len;
86
87 ev = (Emotion_Xine_Video *)par;
88 while ((len = read(ev->fd_slave_read, buf, sizeof(buf))) > 0)
89 {
90 if (len == sizeof(buf))
91 {
92 Emotion_Xine_Event *eev;
93
94 ev = buf[0];
95 eev = buf[1];
96 switch (eev->mtype)
97 {
98 case 0: /* noop */
99 break;
100 case 1: /* init */
101 {
102 ev->decoder = xine_new();
103 xine_init(ev->decoder);
104 xine_register_plugins(ev->decoder, emotion_xine_plugin_info);
105 if (1)
106 {
107 xine_cfg_entry_t cf;
108 if (xine_config_lookup_entry(ev->decoder, "input.dvd_use_readahead", &cf))
109 {
110 cf.num_value = 1; // 0 or 1
111 xine_config_update_entry(ev->decoder, &cf);
112 }
113 }
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);
130 ev->opening = 0;
131 ev->play_ok = 1;
132 _em_module_event(ev, 1); /* event - open done */
133 }
134 break;
135 case 3: /* shutdown */
136 {
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)
142 {
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);
148 }
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");
156 while (ev->have_vo);
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);
163 close(ev->fd_write);
164 close(ev->fd_read);
165 close(ev->fd_ev_write);
166 close(ev->fd_ev_read);
167 close(ev->fd_slave_write);
168 close(ev->fd_slave_read);
169 ev->closing = 0;
170 if (eev->xine_event) free(eev->xine_event);
171 free(eev);
172 free(ev);
173 return NULL;
174 }
175 break;
176 case 2: /* file open */
177 {
178 int pos_stream = 0;
179 int pos_time = 0;
180 int length_time = 0;
181 uint32_t v;
182 char *file;
183
184 file = eev->xine_event;
185 printf("OPN STREAM %s\n", file);
186 if (xine_open(ev->stream, file))
187 {
188 if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time))
189 {
190 if (length_time == 0)
191 {
192 ev->pos = (double)pos_stream / 65535;
193 ev->len = 1.0;
194 ev->no_time = 1;
195 }
196 else
197 {
198 ev->pos = 0.0;
199 ev->len = (double)length_time / 1000.0;
200 }
201 }
202 else
203 {
204 ev->pos = 0.0;
205 ev->len = 1.0;
206 }
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);
210 ev->w = v;
211 v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HEIGHT);
212 ev->h = v;
213 v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO);
214 ev->ratio = (double)v / 10000.0;
215 ev->just_loaded = 1;
216 ev->get_poslen = 0;
217 }
218 _em_module_event(ev, 2); /* event - open done */
219 }
220 break;
221 case 11: /* file close */
222 {
223 printf("EX done %p\n", ev);
224 em_frame_done(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);
231 }
232 break;
233 case 4: /* play */
234 {
235 double pos;
236 int pos_stream, pos_time, length_time;
237
238 pos = *((double *)eev->xine_event);
239 if ((xine_get_param(ev->stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE) &&
240 (pos == ev->pos) &&
241 (!ev->just_loaded))
242 {
243 xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
244 }
245 else
246 {
247 if (ev->no_time)
248 xine_play(ev->stream, pos * 65535, 0);
249 else
250 xine_play(ev->stream, 0, pos * 1000);
251 }
252 ev->just_loaded = 0;
253
254 if (xine_get_pos_length(ev->stream,
255 &pos_stream,
256 &pos_time,
257 &length_time))
258 {
259 if (length_time == 0)
260 {
261 ev->pos = (double)pos_stream / 65535;
262 ev->len = 1.0;
263 ev->no_time = 1;
264 }
265 else
266 {
267 ev->pos = (double)pos_time / 1000.0;
268 ev->len = (double)length_time / 1000.0;
269 }
270 }
271 _em_module_event(ev, 4);
272 }
273 break;
274 case 5: /* stop */
275 {
276 xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
277 _em_module_event(ev, 5);
278 }
279 break;
280 case 6: /* seek */
281 {
282 double pos;
283
284 pos = *((double *)eev->xine_event);
285 if (ev->seeked_pos != ev->seek_to_pos)
286 {
287 if (ev->no_time)
288 xine_play(ev->stream, pos * 65535, 0);
289 else
290 xine_play(ev->stream, 0, pos * 1000);
291 if (!ev->play)
292 xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
293 ev->seeked_pos = ev->seek_to_pos;
294 }
295 _em_module_event(ev, 6);
296 }
297 break;
298 case 7: /* eject */
299 {
300 xine_eject(ev->stream);
301 _em_module_event(ev, 7);
302 }
303 break;
304 case 8: /* spu mute */
305 {
306 xine_set_param(ev->stream, XINE_PARAM_IGNORE_SPU, ev->spu_mute);
307 _em_module_event(ev, 8);
308 }
309 break;
310 case 9: /* channel */
311 {
312 xine_set_param(ev->stream, XINE_PARAM_SPU_CHANNEL, ev->spu_channel);
313 _em_module_event(ev, 9);
314 }
315 break;
316 case 10: /* vol */
317 {
318 double vol;
319
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);
325 }
326 break;
327 case 12: /* audio mute */
328 {
329 xine_set_param(ev->stream, XINE_PARAM_AUDIO_MUTE, ev->audio_mute);
330 }
331 break;
332 case 13: /* audio mute */
333 {
334 xine_set_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, ev->audio_channel);
335 }
336 break;
337 case 14: /* audio mute */
338 {
339 xine_set_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL, ev->video_channel);
340 }
341 break;
342 default:
343 break;
344 }
345 if (eev->xine_event) free(eev->xine_event);
346 free(eev);
347 }
348 }
349 return NULL;
350}
351static void
352_em_slave_event(void *data, int type, void *arg)
353{
354 void *buf[2];
355 Emotion_Xine_Event *new_ev;
356 Emotion_Xine_Video *ev;
357
358 ev = data;
359 new_ev = calloc(1, sizeof(Emotion_Xine_Event));
360 if (!new_ev) return;
361 new_ev->mtype = type;
362 new_ev->type = -1;
363 new_ev->xine_event = arg;
364 buf[0] = data;
365 buf[1] = new_ev;
366 write(ev->fd_slave_write, buf, sizeof(buf));
367}
368
369static unsigned char
370em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt)
371{
372 Emotion_Xine_Video *ev;
373 int fds[2];
374
375 if (!emotion_video) return 0;
376
377 ev = calloc(1, sizeof(Emotion_Xine_Video));
378 if (!ev) return 0;
379 ev->obj = obj;
380
381 if (pipe(fds) == 0)
382 {
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,
387 _em_fd_active, ev,
388 NULL, NULL);
389 ecore_main_fd_handler_active_set(ev->fd_handler, ECORE_FD_READ);
390 }
391 if (pipe(fds) == 0)
392 {
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);
399 }
400 if (pipe(fds) == 0)
401 {
402 ev->fd_slave_read = fds[0];
403 ev->fd_slave_write = fds[1];
404 fcntl(ev->fd_slave_write, F_SETFL, O_NONBLOCK);
405 }
406 ev->delete_me = 0;
407 ev->get_pos_thread_deleted = 0;
408 ev->opening = 1;
409 ev->play_ok = 0;
410
411 if (opt)
412 {
413 ev->opt_no_audio = opt->no_audio;
414 ev->opt_no_video = opt->no_video;
415 }
416
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);
420
421 pthread_create(&ev->slave_th, NULL, _em_slave, ev);
422 pthread_detach(ev->slave_th);
423 _em_slave_event(ev, 1, NULL);
424
425 *emotion_video = ev;
426 return 1;
427}
428
429static int
430em_shutdown(void *ef)
431{
432 Emotion_Xine_Video *ev;
433
434 ev = (Emotion_Xine_Video *)ef;
435 ev->closing = 1;
436 ev->delete_me = 1;
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);
440
441 ev->closing = 1;
442 _em_slave_event(ev, 3, NULL);
443 printf("EXM done %p\n", ev);
444 return 1;
445}
446
447static unsigned char
448em_file_open(const char *file, Evas_Object *obj, void *ef)
449{
450 Emotion_Xine_Video *ev;
451
452 ev = (Emotion_Xine_Video *)ef;
453 if (!ev) return 0;
454 _em_slave_event(ev, 2, strdup(file));
455 return 1;
456}
457
458static void
459em_file_close(void *ef)
460{
461 Emotion_Xine_Video *ev;
462
463 ev = (Emotion_Xine_Video *)ef;
464 if (!ev) return;
465 _em_slave_event(ev, 11, NULL);
466}
467
468static void
469em_play(void *ef, double pos)
470{
471 Emotion_Xine_Video *ev;
472 double *ppos;
473
474 ev = (Emotion_Xine_Video *)ef;
475 ev->play = 1;
476 ev->play_ok = 0;
477 ppos = malloc(sizeof(double));
478 *ppos = pos;
479 _em_slave_event(ev, 4, ppos);
480}
481
482static void
483em_stop(void *ef)
484{
485 Emotion_Xine_Video *ev;
486
487 ev = (Emotion_Xine_Video *)ef;
488 ev->play = 0;
489 ev->play_ok = 0;
490 _em_slave_event(ev, 5, NULL);
491}
492
493static void
494em_size_get(void *ef, int *w, int *h)
495{
496 Emotion_Xine_Video *ev;
497
498 ev = (Emotion_Xine_Video *)ef;
499 if (w) *w = ev->w;
500 if (h) *h = ev->h;
501}
502
503static void
504em_pos_set(void *ef, double pos)
505{
506 Emotion_Xine_Video *ev;
507 double *ppos;
508
509 ev = (Emotion_Xine_Video *)ef;
510 if (pos == ev->seek_to_pos) return;
511 ppos = malloc(sizeof(double));
512 *ppos = pos;
513 ev->seek_to_pos = pos;
514 _em_slave_event(ev, 6, ppos);
515}
516
517static void
518em_vis_set(void *ef,
519 Emotion_Vis vis)
520{
521 Emotion_Xine_Video *ev;
522
523 ev = (Emotion_Xine_Video *)ef;
524 if (ev->vis == vis) return;
525 ev->vis = vis;
526}
527
528static double
529em_len_get(void *ef)
530{
531 Emotion_Xine_Video *ev;
532
533 ev = (Emotion_Xine_Video *)ef;
534 return ev->len;
535}
536
537static int
538em_fps_num_get(void *ef)
539{
540 Emotion_Xine_Video *ev;
541
542 ev = (Emotion_Xine_Video *)ef;
543 return (int)(ev->fps * 10000.0);
544}
545
546static int
547em_fps_den_get(void *ef)
548{
549 Emotion_Xine_Video *ev;
550
551 ev = (Emotion_Xine_Video *)ef;
552 return 10000;
553}
554
555static double
556em_fps_get(void *ef)
557{
558 Emotion_Xine_Video *ev;
559
560 ev = (Emotion_Xine_Video *)ef;
561 return ev->fps;
562}
563
564static double
565em_pos_get(void *ef)
566{
567 Emotion_Xine_Video *ev;
568
569 ev = (Emotion_Xine_Video *)ef;
570 return ev->pos;
571}
572
573static Emotion_Vis
574em_vis_get(void *ef)
575{
576 Emotion_Xine_Video *ev;
577
578 ev = (Emotion_Xine_Video *)ef;
579
580 return ev->vis;
581}
582
583static double
584em_ratio_get(void *ef)
585{
586 Emotion_Xine_Video *ev;
587
588 ev = (Emotion_Xine_Video *)ef;
589 return ev->ratio;
590}
591
592static int
593em_video_handled(void *ef)
594{
595 Emotion_Xine_Video *ev;
596
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));
601}
602
603static int
604em_audio_handled(void *ef)
605{
606 Emotion_Xine_Video *ev;
607
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));
612}
613
614static int
615em_seekable(void *ef)
616{
617 Emotion_Xine_Video *ev;
618
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);
622}
623
624static void
625em_frame_done(void *ef)
626{
627 Emotion_Xine_Video *ev;
628
629 ev = (Emotion_Xine_Video *)ef;
630 if (ev->cur_frame)
631 {
632 ev->fq--;
633 if (ev->cur_frame->done_func)
634 ev->cur_frame->done_func(ev->cur_frame->done_data);
635 ev->cur_frame = NULL;
636 }
637}
638
639static Emotion_Format
640em_format_get(void *ef)
641{
642 Emotion_Xine_Video *ev;
643 volatile Emotion_Xine_Video_Frame *fr;
644
645 ev = (Emotion_Xine_Video *)ef;
646 fr = ev->cur_frame;
647 if (fr) return fr->format;
648 return EMOTION_FORMAT_YV12;
649}
650
651static void
652em_video_data_size_get(void *ef, int *w, int *h)
653{
654 Emotion_Xine_Video *ev;
655 volatile Emotion_Xine_Video_Frame *fr;
656
657 ev = (Emotion_Xine_Video *)ef;
658 fr = ev->cur_frame;
659 if (!fr)
660 {
661 if (w) *w = 0;
662 if (h) *h = 0;
663 return;
664 }
665 if (w) *w = fr->w;
666 if (h) *h = fr->h;
667}
668
669static int
670em_yuv_rows_get(void *ef, int w, int h, unsigned char **yrows, unsigned char **urows, unsigned char **vrows)
671{
672 Emotion_Xine_Video *ev;
673 volatile Emotion_Xine_Video_Frame *fr;
674
675 ev = (Emotion_Xine_Video *)ef;
676 fr = ev->cur_frame;
677 if (!fr) return 0;
678 if (fr->y)
679 {
680 int i;
681
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);
685 return 1;
686 }
687 return 0;
688}
689
690static int
691em_bgra_data_get(void *ef, unsigned char **bgra_data)
692{
693 Emotion_Xine_Video *ev;
694 volatile Emotion_Xine_Video_Frame *fr;
695
696 ev = (Emotion_Xine_Video *)ef;
697 fr = ev->cur_frame;
698 if (!fr) return 0;
699 if (fr->bgra_data)
700 {
701 *bgra_data = fr->bgra_data;
702 return 1;
703 }
704 return 0;
705}
706
707static void
708em_event_feed(void *ef, int event)
709{
710 Emotion_Xine_Video *ev;
711 xine_event_t xine_event;
712
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);
719 switch (event)
720 {
721 case EMOTION_EVENT_MENU1:
722 xine_event.type = XINE_EVENT_INPUT_MENU1;
723 break;
724 case EMOTION_EVENT_MENU2:
725 xine_event.type = XINE_EVENT_INPUT_MENU2;
726 break;
727 case EMOTION_EVENT_MENU3:
728 xine_event.type = XINE_EVENT_INPUT_MENU3;
729 break;
730 case EMOTION_EVENT_MENU4:
731 xine_event.type = XINE_EVENT_INPUT_MENU4;
732 break;
733 case EMOTION_EVENT_MENU5:
734 xine_event.type = XINE_EVENT_INPUT_MENU5;
735 break;
736 case EMOTION_EVENT_MENU6:
737 xine_event.type = XINE_EVENT_INPUT_MENU6;
738 break;
739 case EMOTION_EVENT_MENU7:
740 xine_event.type = XINE_EVENT_INPUT_MENU7;
741 break;
742 case EMOTION_EVENT_UP:
743 xine_event.type = XINE_EVENT_INPUT_UP;
744 break;
745 case EMOTION_EVENT_DOWN:
746 xine_event.type = XINE_EVENT_INPUT_DOWN;
747 break;
748 case EMOTION_EVENT_LEFT:
749 xine_event.type = XINE_EVENT_INPUT_LEFT;
750 break;
751 case EMOTION_EVENT_RIGHT:
752 xine_event.type = XINE_EVENT_INPUT_RIGHT;
753 break;
754 case EMOTION_EVENT_SELECT:
755 xine_event.type = XINE_EVENT_INPUT_SELECT;
756 break;
757 case EMOTION_EVENT_NEXT:
758 xine_event.type = XINE_EVENT_INPUT_NEXT;
759 break;
760 case EMOTION_EVENT_PREV:
761 xine_event.type = XINE_EVENT_INPUT_PREVIOUS;
762 break;
763 case EMOTION_EVENT_ANGLE_NEXT:
764 xine_event.type = XINE_EVENT_INPUT_ANGLE_NEXT;
765 break;
766 case EMOTION_EVENT_ANGLE_PREV:
767 xine_event.type = XINE_EVENT_INPUT_ANGLE_PREVIOUS;
768 break;
769 case EMOTION_EVENT_FORCE:
770 xine_event.type = XINE_EVENT_INPUT_BUTTON_FORCE;
771 break;
772 case EMOTION_EVENT_0:
773 xine_event.type = XINE_EVENT_INPUT_NUMBER_0;
774 break;
775 case EMOTION_EVENT_1:
776 xine_event.type = XINE_EVENT_INPUT_NUMBER_1;
777 break;
778 case EMOTION_EVENT_2:
779 xine_event.type = XINE_EVENT_INPUT_NUMBER_2;
780 break;
781 case EMOTION_EVENT_3:
782 xine_event.type = XINE_EVENT_INPUT_NUMBER_3;
783 break;
784 case EMOTION_EVENT_4:
785 xine_event.type = XINE_EVENT_INPUT_NUMBER_4;
786 break;
787 case EMOTION_EVENT_5:
788 xine_event.type = XINE_EVENT_INPUT_NUMBER_5;
789 break;
790 case EMOTION_EVENT_6:
791 xine_event.type = XINE_EVENT_INPUT_NUMBER_6;
792 break;
793 case EMOTION_EVENT_7:
794 xine_event.type = XINE_EVENT_INPUT_NUMBER_7;
795 break;
796 case EMOTION_EVENT_8:
797 xine_event.type = XINE_EVENT_INPUT_NUMBER_8;
798 break;
799 case EMOTION_EVENT_9:
800 xine_event.type = XINE_EVENT_INPUT_NUMBER_9;
801 break;
802 case EMOTION_EVENT_10:
803 xine_event.type = XINE_EVENT_INPUT_NUMBER_10_ADD;
804 break;
805 default:
806 return;
807 break;
808 }
809 xine_event_send(ev->stream, &xine_event);
810}
811
812static void
813em_event_mouse_button_feed(void *ef, int button, int x, int y)
814{
815 Emotion_Xine_Video *ev;
816 xine_event_t xine_event;
817 xine_input_data_t xine_input;
818
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;
825 xine_input.x = x;
826 xine_input.y = y;
827 xine_event.data = &xine_input;
828 xine_event.data_length = sizeof(xine_input);
829 xine_event_send(ev->stream, &xine_event);
830}
831
832static void
833em_event_mouse_move_feed(void *ef, int x, int y)
834{
835 Emotion_Xine_Video *ev;
836 xine_event_t xine_event;
837 xine_input_data_t xine_input;
838
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;
845 xine_input.x = x;
846 xine_input.y = y;
847 xine_event.data = &xine_input;
848 xine_event.data_length = sizeof(xine_input);
849 xine_event_send(ev->stream, &xine_event);
850}
851
852static int
853em_video_channel_count(void *ef)
854{
855 Emotion_Xine_Video *ev;
856 int v;
857
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);
861 if ((v < 1) &&
862 xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_VIDEO)) return 1;
863 return v;
864}
865
866static void
867em_video_channel_set(void *ef, int channel)
868{
869 Emotion_Xine_Video *ev;
870
871 ev = (Emotion_Xine_Video *)ef;
872 if (channel < 0) channel = 0;
873 ev->video_channel = channel;
874 _em_slave_event(ev, 14, NULL);
875}
876
877static int
878em_video_channel_get(void *ef)
879{
880 Emotion_Xine_Video *ev;
881
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);
885}
886
887static const char *
888em_video_channel_name_get(void *ef, int channel)
889{
890 Emotion_Xine_Video *ev;
891
892 ev = (Emotion_Xine_Video *)ef;
893 return NULL;
894}
895
896static void
897em_video_channel_mute_set(void *ef, int mute)
898{
899 Emotion_Xine_Video *ev;
900
901 ev = (Emotion_Xine_Video *)ef;
902 ev->video_mute = mute;
903}
904
905static int
906em_video_channel_mute_get(void *ef)
907{
908 Emotion_Xine_Video *ev;
909
910 ev = (Emotion_Xine_Video *)ef;
911 return ev->video_mute;
912}
913
914static int
915em_audio_channel_count(void *ef)
916{
917 Emotion_Xine_Video *ev;
918
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);
922}
923
924static void
925em_audio_channel_set(void *ef, int channel)
926{
927 Emotion_Xine_Video *ev;
928
929 ev = (Emotion_Xine_Video *)ef;
930 if (channel < -1) channel = -1;
931 ev->audio_channel = channel;
932 _em_slave_event(ev, 13, NULL);
933}
934
935static int
936em_audio_channel_get(void *ef)
937{
938 Emotion_Xine_Video *ev;
939
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);
943}
944
945static const char *
946em_audio_channel_name_get(void *ef, int channel)
947{
948 Emotion_Xine_Video *ev;
949 static char lang[XINE_LANG_MAX + 1];
950
951 ev = (Emotion_Xine_Video *)ef;
952 if (ev->opening) return NULL;
953 lang[0] = 0;
954 if (xine_get_audio_lang(ev->stream, channel, lang)) return lang;
955 return NULL;
956}
957
958static void
959em_audio_channel_mute_set(void *ef, int mute)
960{
961 Emotion_Xine_Video *ev;
962
963 ev = (Emotion_Xine_Video *)ef;
964 ev->audio_mute = mute;
965 _em_slave_event(ev, 12, NULL);
966}
967
968static int
969em_audio_channel_mute_get(void *ef)
970{
971 Emotion_Xine_Video *ev;
972
973 ev = (Emotion_Xine_Video *)ef;
974 return ev->audio_mute;
975}
976
977static void
978em_audio_channel_volume_set(void *ef, double vol)
979{
980 Emotion_Xine_Video *ev;
981 double *ppos;
982
983 ev = (Emotion_Xine_Video *)ef;
984 ppos = malloc(sizeof(double));
985 *ppos = vol;
986 _em_slave_event(ev, 10, ppos);
987}
988
989static double
990em_audio_channel_volume_get(void *ef)
991{
992 Emotion_Xine_Video *ev;
993
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;
997}
998
999static int
1000em_spu_channel_count(void *ef)
1001{
1002 Emotion_Xine_Video *ev;
1003
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);
1007}
1008
1009static void
1010em_spu_channel_set(void *ef, int channel)
1011{
1012 Emotion_Xine_Video *ev;
1013
1014 ev = (Emotion_Xine_Video *)ef;
1015 if (channel < 0) channel = 0;
1016 ev->spu_channel = channel;
1017 _em_slave_event(ev, 9, NULL);
1018}
1019
1020static int
1021em_spu_channel_get(void *ef)
1022{
1023 Emotion_Xine_Video *ev;
1024
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);
1028}
1029
1030static const char *
1031em_spu_channel_name_get(void *ef, int channel)
1032{
1033 Emotion_Xine_Video *ev;
1034 static char lang[XINE_LANG_MAX + 1];
1035
1036 ev = (Emotion_Xine_Video *)ef;
1037 if (ev->opening) return NULL;
1038 lang[0] = 0;
1039 if (xine_get_spu_lang(ev->stream, channel, lang)) return lang;
1040 return NULL;
1041}
1042
1043static void
1044em_spu_channel_mute_set(void *ef, int mute)
1045{
1046 Emotion_Xine_Video *ev;
1047
1048 ev = (Emotion_Xine_Video *)ef;
1049 ev->spu_mute = mute;
1050 _em_slave_event(ev, 8, NULL);
1051}
1052
1053static int
1054em_spu_channel_mute_get(void *ef)
1055{
1056 Emotion_Xine_Video *ev;
1057
1058 ev = (Emotion_Xine_Video *)ef;
1059 return ev->spu_mute;
1060}
1061
1062static int
1063em_chapter_count(void *ef)
1064{
1065 Emotion_Xine_Video *ev;
1066
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))
1070 return 99;
1071 return 0;
1072}
1073
1074static void
1075em_chapter_set(void *ef, int chapter)
1076{
1077 Emotion_Xine_Video *ev;
1078
1079 ev = (Emotion_Xine_Video *)ef;
1080}
1081
1082static int
1083em_chapter_get(void *ef)
1084{
1085 Emotion_Xine_Video *ev;
1086
1087 ev = (Emotion_Xine_Video *)ef;
1088 return 0;
1089}
1090
1091static const char *
1092em_chapter_name_get(void *ef, int chapter)
1093{
1094 Emotion_Xine_Video *ev;
1095
1096 ev = (Emotion_Xine_Video *)ef;
1097 return NULL;
1098}
1099
1100static void
1101em_speed_set(void *ef, double speed)
1102{
1103 Emotion_Xine_Video *ev;
1104
1105 ev = (Emotion_Xine_Video *)ef;
1106}
1107
1108static double
1109em_speed_get(void *ef)
1110{
1111 Emotion_Xine_Video *ev;
1112
1113 ev = (Emotion_Xine_Video *)ef;
1114 return 1.0;
1115}
1116
1117static int
1118em_eject(void *ef)
1119{
1120 Emotion_Xine_Video *ev;
1121
1122 ev = (Emotion_Xine_Video *)ef;
1123 _em_slave_event(ev, 7, NULL);
1124 return 1;
1125}
1126
1127static const char *
1128em_meta_get(void *ef, int meta)
1129{
1130 Emotion_Xine_Video *ev;
1131
1132 ev = (Emotion_Xine_Video *)ef;
1133 if ((ev->opening) || (!ev->play_ok)) return NULL;
1134 switch (meta)
1135 {
1136 case META_TRACK_TITLE:
1137 return xine_get_meta_info(ev->stream, XINE_META_INFO_TITLE);
1138 break;
1139 case META_TRACK_ARTIST:
1140 return xine_get_meta_info(ev->stream, XINE_META_INFO_ARTIST);
1141 break;
1142 case META_TRACK_GENRE:
1143 return xine_get_meta_info(ev->stream, XINE_META_INFO_GENRE);
1144 break;
1145 case META_TRACK_COMMENT:
1146 return xine_get_meta_info(ev->stream, XINE_META_INFO_COMMENT);
1147 break;
1148 case META_TRACK_ALBUM:
1149 return xine_get_meta_info(ev->stream, XINE_META_INFO_ALBUM);
1150 break;
1151 case META_TRACK_YEAR:
1152 return xine_get_meta_info(ev->stream, XINE_META_INFO_YEAR);
1153 break;
1154 case META_TRACK_DISCID:
1155 return xine_get_meta_info(ev->stream, XINE_META_INFO_CDINDEX_DISCID);
1156 break;
1157 default:
1158 break;
1159 }
1160 return NULL;
1161}
1162
1163static int
1164_em_fd_active(void *data, Ecore_Fd_Handler *fdh)
1165{
1166 void *buf;
1167 int fd, len;
1168 Emotion_Xine_Video_Frame *fr;
1169 Emotion_Xine_Video *ev;
1170
1171 ev = data;
1172 fd = ecore_main_fd_handler_fd_get(fdh);
1173 while ((len = read(fd, &buf, sizeof(buf))) > 0)
1174 {
1175 if (len == sizeof(buf))
1176 {
1177 fr = buf;
1178 ev = _emotion_video_get(fr->obj);
1179 if (ev)
1180 {
1181 em_frame_done(ev);
1182 ev->cur_frame = fr;
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)))
1186 {
1187 if (ev->video_mute) em_frame_done(ev);
1188 else _emotion_frame_new(fr->obj);
1189 }
1190 _emotion_frame_resize(fr->obj, fr->w, fr->h, fr->ratio);
1191 _emotion_video_pos_update(fr->obj, ev->pos, ev->len);
1192 }
1193 }
1194 }
1195 return 1;
1196}
1197
1198static void
1199_em_event(void *data, const xine_event_t *event)
1200{
1201 void *buf[2];
1202 Emotion_Xine_Event *new_ev;
1203 Emotion_Xine_Video *ev;
1204
1205 ev = data;
1206 new_ev = calloc(1, sizeof(Emotion_Xine_Event));
1207 if (!new_ev) return;
1208 new_ev->mtype = 0;
1209 new_ev->type = event->type;
1210 if (event->data)
1211 {
1212 new_ev->xine_event = malloc(event->data_length);
1213 if (!new_ev->xine_event)
1214 {
1215 free(new_ev);
1216 return;
1217 }
1218 memcpy(new_ev->xine_event, event->data, event->data_length);
1219 }
1220 buf[0] = data;
1221 buf[1] = new_ev;
1222 write(ev->fd_ev_write, buf, sizeof(buf));
1223}
1224
1225static void
1226_em_module_event(void *data, int type)
1227{
1228 void *buf[2];
1229 Emotion_Xine_Event *new_ev;
1230 Emotion_Xine_Video *ev;
1231
1232 ev = data;
1233 new_ev = calloc(1, sizeof(Emotion_Xine_Event));
1234 if (!new_ev) return;
1235 new_ev->mtype = type;
1236 new_ev->type = -1;
1237 buf[0] = data;
1238 buf[1] = new_ev;
1239 write(ev->fd_ev_write, buf, sizeof(buf));
1240}
1241
1242static int
1243_em_fd_ev_active(void *data, Ecore_Fd_Handler *fdh)
1244{
1245 Emotion_Xine_Video *ev;
1246 int fd, len;
1247 void *buf[2];
1248
1249 ev = data;
1250 fd = ecore_main_fd_handler_fd_get(fdh);
1251 while ((len = read(fd, buf, sizeof(buf))) > 0)
1252 {
1253 if (len == sizeof(buf))
1254 {
1255 Emotion_Xine_Event *eev;
1256
1257 ev = buf[0];
1258 eev = buf[1];
1259 if (eev->mtype != 0)
1260 {
1261 switch (eev->mtype)
1262 {
1263 case 1: /* init done */
1264 ev->play_ok = 1;
1265 break;
1266 case 2: /* open done */
1267 ev->play_ok = 1;
1268 break;
1269 case 3: /* shutdown done */
1270 ev->play_ok = 1;
1271 break;
1272 case 4: /* play done */
1273 ev->play_ok = 1;
1274 break;
1275 case 5: /* stop done */
1276 ev->play_ok = 1;
1277 break;
1278 case 6: /* seek done */
1279 ev->play_ok = 1;
1280 break;
1281 case 7: /* eject done */
1282 ev->play_ok = 1;
1283 break;
1284 case 8: /* spu mute done */
1285 ev->play_ok = 1;
1286 break;
1287 case 9: /* channel done */
1288 ev->play_ok = 1;
1289 break;
1290 case 10: /* volume done */
1291 ev->play_ok = 1;
1292 break;
1293 case 11: /* close done */
1294 ev->play_ok = 1;
1295 break;
1296 default:
1297 break;
1298 }
1299 }
1300 else
1301 {
1302 switch (eev->type)
1303 {
1304 case XINE_EVENT_UI_PLAYBACK_FINISHED:
1305 {
1306 ev->play = 0;
1307 _emotion_decode_stop(ev->obj);
1308 _emotion_playback_finished(ev->obj);
1309 }
1310 break;
1311 case XINE_EVENT_UI_CHANNELS_CHANGED:
1312 {
1313 _emotion_channels_change(ev->obj);
1314 }
1315 break;
1316 case XINE_EVENT_UI_SET_TITLE:
1317 {
1318 xine_ui_data_t *e;
1319
1320 e = (xine_ui_data_t *)eev->xine_event;
1321 _emotion_title_set(ev->obj, e->str);
1322 }
1323 break;
1324 case XINE_EVENT_FRAME_FORMAT_CHANGE:
1325 {
1326 xine_format_change_data_t *e;
1327
1328 e = (xine_format_change_data_t *)eev->xine_event;
1329 }
1330 break;
1331 case XINE_EVENT_UI_MESSAGE:
1332 {
1333 xine_ui_message_data_t *e;
1334
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
1339 }
1340 break;
1341 case XINE_EVENT_AUDIO_LEVEL:
1342 {
1343 xine_audio_level_data_t *e;
1344
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");
1348 // e->left (0->100)
1349 // e->right
1350 // e->mute
1351 }
1352 break;
1353 case XINE_EVENT_PROGRESS:
1354 {
1355 xine_progress_data_t *e;
1356
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);
1360 }
1361 break;
1362 case XINE_EVENT_MRL_REFERENCE:
1363 {
1364 xine_mrl_reference_data_t *e;
1365
1366 e = (xine_mrl_reference_data_t *)eev->xine_event;
1367 _emotion_file_ref_set(ev->obj, e->mrl, e->alternative);
1368 }
1369 break;
1370 case XINE_EVENT_UI_NUM_BUTTONS:
1371 {
1372 xine_ui_data_t *e;
1373
1374 e = (xine_ui_data_t *)eev->xine_event;
1375 _emotion_spu_button_num_set(ev->obj, e->num_buttons);
1376 }
1377 break;
1378 case XINE_EVENT_SPU_BUTTON:
1379 {
1380 xine_spu_button_t *e;
1381
1382 e = (xine_spu_button_t *)eev->xine_event;
1383 if (e->direction == 1)
1384 _emotion_spu_button_set(ev->obj, e->button);
1385 else
1386 _emotion_spu_button_set(ev->obj, -1);
1387 }
1388 break;
1389 case XINE_EVENT_DROPPED_FRAMES:
1390 {
1391 xine_dropped_frames_t *e;
1392
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
1397 }
1398 break;
1399 default:
1400 // printf("EV: unknown event type %i\n", eev->type);
1401 break;
1402 }
1403 }
1404 if (eev->xine_event) free(eev->xine_event);
1405 free(eev);
1406 }
1407 }
1408 return 1;
1409}
1410
1411static void *
1412_em_get_pos_len_th(void *par)
1413{
1414 Emotion_Xine_Video *ev;
1415
1416 ev = (Emotion_Xine_Video *)par;
1417
1418 for (;;)
1419 {
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));
1423 if (ev->get_poslen)
1424 {
1425 int pos_stream = 0;
1426 int pos_time = 0;
1427 int length_time = 0;
1428
1429 if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time))
1430 {
1431 if (length_time == 0)
1432 {
1433 ev->pos = (double)pos_stream / 65535;
1434 ev->len = 1.0;
1435 ev->no_time = 1;
1436 }
1437 else
1438 {
1439 ev->pos = (double)pos_time / 1000.0;
1440 ev->len = (double)length_time / 1000.0;
1441 ev->no_time = 0;
1442 }
1443 }
1444 ev->get_poslen = 0;
1445 //printf("get pos %3.3f\n", ev->pos);
1446 }
1447 if (ev->delete_me)
1448 {
1449 ev->get_pos_thread_deleted = 1;
1450 return NULL;
1451 }
1452 }
1453 return NULL;
1454}
1455
1456static void
1457_em_get_pos_len(Emotion_Xine_Video *ev)
1458{
1459 if (ev->get_poslen) return;
1460 ev->get_poslen = 1;
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));
1464}
1465
1466static Emotion_Video_Module em_module =
1467{
1468 em_init, /* init */
1469 em_shutdown, /* shutdown */
1470 em_file_open, /* file_open */
1471 em_file_close, /* file_close */
1472 em_play, /* play */
1473 em_stop, /* stop */
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 */
1523
1524 NULL /* handle */
1525};
1526
1527unsigned char
1528module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
1529{
1530 if (!module)
1531 return 0;
1532
1533 if (!em_module.init(obj, video, opt))
1534 return 0;
1535
1536 *module = &em_module;
1537 return 1;
1538}
1539
1540void
1541module_close(Emotion_Video_Module *module, void *video)
1542{
1543 em_module.shutdown(video);
1544}
1545
1546#if 0
1547void
1548em_debug(Emotion_Xine_Video *ev)
1549{
1550 int has_chapters = 0;
1551 int max_spu = 0;
1552 int max_audio = 0;
1553 int video_channels = 0;
1554 int video_streams = 0;
1555 int video_seekable = 0;
1556 char *title;
1557 char *comment;
1558 char *artist;
1559 char *genre;
1560 char *album;
1561 char *year;
1562 char *cdindex_discid;
1563 int video_channel = 0;
1564 int audio_channel = 0;
1565 int spu_channel = 0;
1566 int video_ratio = 0;
1567 int audio_mode = 0;
1568
1569// return;
1570 has_chapters = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_HAS_CHAPTERS);
1571 max_spu = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
1572 max_audio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
1573 video_channels = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_CHANNELS);
1574 video_streams = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_STREAMS);
1575 video_seekable = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_SEEKABLE);
1576 title = xine_get_meta_info(ev->stream, XINE_META_INFO_TITLE);
1577 comment = xine_get_meta_info(ev->stream, XINE_META_INFO_COMMENT);
1578 artist = xine_get_meta_info(ev->stream, XINE_META_INFO_ARTIST);
1579 genre = xine_get_meta_info(ev->stream, XINE_META_INFO_GENRE);
1580 album = xine_get_meta_info(ev->stream, XINE_META_INFO_ALBUM);
1581 year = xine_get_meta_info(ev->stream, XINE_META_INFO_YEAR);
1582 cdindex_discid = xine_get_meta_info(ev->stream, XINE_META_INFO_CDINDEX_DISCID);
1583 video_channel = xine_get_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL);
1584 audio_channel = xine_get_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
1585 spu_channel = xine_get_param(ev->stream, XINE_PARAM_SPU_CHANNEL);
1586 video_ratio = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO);
1587 audio_mode = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_AUDIO_MODE);
1588 printf("has_chapters = %i\n", has_chapters);
1589 printf("max_spu = %i\n", max_spu);
1590 printf("max_audio = %i\n", max_audio);
1591 printf("video_channels = %i\n", video_channels);
1592 printf("video_streams = %i\n", video_streams);
1593 printf("video_seekable = %i\n", video_seekable);
1594 printf("title = %s\n", title);
1595 printf("comment = %s\n", comment);
1596 printf("artist = %s\n", artist);
1597 printf("genre = %s\n", genre);
1598 printf("album = %s\n", album);
1599 printf("year = %s\n", year);
1600 printf("cdindex_discid = %s\n", cdindex_discid);
1601 printf("video_channel = %i\n", video_channel);
1602 printf("audio_channel = %i\n", audio_channel);
1603 printf("spu_channels = %i\n", spu_channel);
1604 printf("video_ratio = %i\n", video_ratio);
1605 printf("audio_mode = %i\n", audio_mode);
1606 {
1607 int i;
1608
1609 for (i = 0; i <= max_audio; i++)
1610 {
1611 char lang[XINE_LANG_MAX + 1];
1612
1613 lang[0] = 0;
1614 printf(" AUDIO %i = ", i);
1615 if (xine_get_audio_lang(ev->stream, i, lang))
1616 printf("%s\n", lang);
1617 else
1618 printf("NONE\n");
1619 }
1620 for (i = 0; i <= max_spu; i++)
1621 {
1622 char lang[XINE_LANG_MAX + 1];
1623
1624 lang[0] = 0;
1625 printf(" SPU %i = ", i);
1626 if (xine_get_spu_lang(ev->stream, i, lang))
1627 printf("%s\n", lang);
1628 else
1629 printf("NONE\n");
1630 }
1631 }
1632}
1633#endif