Emotion: Add __UNUSED__ where needed
[profile/ivi/emotion.git] / src / modules / generic / emotion_generic.c
1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4 #include <sys/mman.h>
5 #include <sys/stat.h>
6 #include <sys/time.h>
7 #include <sys/types.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <Eina.h>
11 #include <Evas.h>
12
13 #include "Emotion.h"
14 #include "emotion_private.h"
15 #include "emotion_generic.h"
16
17 static Eina_Prefix *pfx = NULL;
18
19 static int _emotion_generic_log_domain = -1;
20 #define DBG(...) EINA_LOG_DOM_DBG(_emotion_generic_log_domain, __VA_ARGS__)
21 #define INF(...) EINA_LOG_DOM_INFO(_emotion_generic_log_domain, __VA_ARGS__)
22 #define WRN(...) EINA_LOG_DOM_WARN(_emotion_generic_log_domain, __VA_ARGS__)
23 #define ERR(...) EINA_LOG_DOM_ERR(_emotion_generic_log_domain, __VA_ARGS__)
24 #define CRITICAL(...) EINA_LOG_DOM_CRIT(_emotion_generic_log_domain, __VA_ARGS__)
25
26
27 struct _default_players {
28    const char *name;
29    const char *cmdline;
30 };
31
32 static struct _default_players players[] = {
33 #ifdef EMOTION_BUILD_VLC
34        { "vlc", "em_generic_vlc" },
35 #endif
36        { NULL, NULL }
37 };
38
39 static const char *
40 _get_player(const char *name)
41 {
42    const char *selected_name = NULL;
43    const char *libdir = eina_prefix_lib_get(pfx);
44    static char buf[PATH_MAX];
45    int i;
46
47    if (name)
48      {
49         for (i = 0; players[i].name; i++)
50           {
51              if (!strcmp(players[i].name, name))
52                {
53                   selected_name = players[i].cmdline;
54                   break;
55                }
56           }
57      }
58
59    if ((!selected_name) && (name))
60      selected_name = name;
61
62    if (selected_name)
63      {
64         const char *cmd;
65
66         if (selected_name[0] == '/') cmd = selected_name;
67         else
68           {
69              snprintf(buf, sizeof(buf), "%s/emotion/utils/%s",
70                       libdir, selected_name);
71              cmd = buf;
72           }
73
74         DBG("Try generic player '%s'", cmd);
75         if (access(cmd, R_OK | X_OK) == 0)
76           {
77              INF("Using generic player '%s'", cmd);
78              return cmd;
79           }
80      }
81
82    for (i = 0; players[i].name; i++)
83      {
84         snprintf(buf, sizeof(buf), "%s/emotion/utils/%s",
85                  libdir, players[i].cmdline);
86         DBG("Try generic player '%s'", buf);
87         if (access(buf, R_OK | X_OK) == 0)
88           {
89              INF("Using fallback player '%s'", buf);
90              return buf;
91           }
92      }
93
94    ERR("no generic player found, given name='%s'", name ? name : "");
95    return NULL;
96 }
97
98 static void
99 _player_send_cmd(Emotion_Generic_Video *ev, int cmd)
100 {
101    if (cmd >= EM_CMD_LAST)
102      {
103         ERR("invalid command to player.");
104         return;
105      }
106    ecore_exe_send(ev->player.exe, &cmd, sizeof(cmd));
107 }
108
109 static void
110 _player_send_int(Emotion_Generic_Video *ev, int number)
111 {
112    ecore_exe_send(ev->player.exe, &number, sizeof(number));
113 }
114
115 static void
116 _player_send_float(Emotion_Generic_Video *ev, float number)
117 {
118    ecore_exe_send(ev->player.exe, &number, sizeof(number));
119 }
120
121 static void
122 _player_send_str(Emotion_Generic_Video *ev, const char *str, Eina_Bool stringshared)
123 {
124    int len;
125
126    if (stringshared)
127      len = eina_stringshare_strlen(str) + 1;
128    else
129      len = strlen(str) + 1;
130    ecore_exe_send(ev->player.exe, &len, sizeof(len));
131    ecore_exe_send(ev->player.exe, str, len);
132 }
133
134 static Eina_Bool
135 _create_shm_data(Emotion_Generic_Video *ev, const char *shmname)
136 {
137    int shmfd;
138    int npages;
139    size_t size;
140    Emotion_Generic_Video_Shared *vs;
141
142    shmfd = shm_open(shmname, O_CREAT | O_RDWR | O_TRUNC, 0777);
143    size = 3 * (ev->w * ev->h * DEFAULTPITCH) + sizeof(*vs);
144
145    npages = (int)(size / getpagesize()) + 1;
146    size = npages * getpagesize();
147
148    if (ftruncate(shmfd, size))
149      {
150         ERR("error when allocating shared memory (size = %zd): "
151             "%s", size, strerror(errno));
152         return EINA_FALSE;
153      }
154    vs = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0);
155    if (vs == MAP_FAILED)
156      {
157         ERR("error when mapping shared memory.\n");
158         return EINA_FALSE;
159      }
160
161    vs->size = size;
162    vs->width = ev->w;
163    vs->height = ev->h;
164    vs->pitch = DEFAULTPITCH;
165    vs->frame.emotion = 0;
166    vs->frame.player = 1;
167    vs->frame.last = 2;
168    vs->frame.next = 2;
169    sem_init(&vs->lock, 1, 1);
170    ev->frame.frames[0] = (unsigned char *)vs + sizeof(*vs);
171    ev->frame.frames[1] = (unsigned char *)vs + sizeof(*vs) + vs->height * vs->width * vs->pitch;
172    ev->frame.frames[2] = (unsigned char *)vs + sizeof(*vs) + 2 * vs->height * vs->width * vs->pitch;
173
174    if (ev->shared)
175      munmap(ev->shared, ev->shared->size);
176    ev->shared = vs;
177
178    return EINA_TRUE;
179 }
180
181 static void
182 _player_new_frame(Emotion_Generic_Video *ev)
183 {
184    if (!ev->drop++)
185      _emotion_frame_new(ev->obj);
186 }
187
188 static void
189 _player_file_set_done(Emotion_Generic_Video *ev)
190 {
191    if (!_create_shm_data(ev, ev->shmname))
192      {
193         ERR("could not create shared memory.");
194         return;
195      }
196    _player_send_cmd(ev, EM_CMD_FILE_SET_DONE);
197 }
198
199 static void
200 _file_open(Emotion_Generic_Video *ev)
201 {
202    INF("Opening file: %s", ev->filename);
203    ev->w = DEFAULTWIDTH;
204    ev->h = DEFAULTHEIGHT;
205    ev->ratio = (double)DEFAULTWIDTH / DEFAULTHEIGHT;
206    ev->speed = 1.0;
207    ev->len = 0;
208    ev->drop = 0;
209
210    if (!ev->ready)
211      return;
212    _player_send_cmd(ev, EM_CMD_FILE_SET);
213    _player_send_str(ev, ev->filename, EINA_TRUE);
214 }
215
216 static void
217 _player_ready(Emotion_Generic_Video *ev)
218 {
219    INF("received: player ready.");
220
221    ev->initializing = EINA_FALSE;
222    ev->ready = EINA_TRUE;
223
224    if (!ev->filename)
225      return;
226
227    _file_open(ev);
228 }
229
230 #define RCV_CMD_PARAM(src, param) \
231    memcpy(&(param), (src), sizeof((param))); \
232    (src) = (char *)(src) + sizeof((param));
233
234 #define RCV_CMD_STR(src, buf, len) \
235    RCV_CMD_PARAM((src), (len)); \
236    memcpy((buf), (src), (len)); \
237    (src) = (char *)(src) + len;
238
239 static int
240 _player_int_read(Emotion_Generic_Video *ev __UNUSED__, void **data)
241 {
242    int number;
243    memcpy(&number, *data, sizeof(number));
244    *data = (char *)(*data) + sizeof(number);
245
246    return number;
247 }
248
249 static void
250 _player_frame_resize(Emotion_Generic_Video *ev, void *line)
251 {
252    int w, h;
253    RCV_CMD_PARAM(line, w);
254    RCV_CMD_PARAM(line, h);
255
256    INF("received frame resize: %dx%d", w, h);
257    ev->w = w;
258    ev->h = h;
259    ev->ratio = (float)w / h;
260
261    if (ev->opening)
262      return;
263
264    _emotion_frame_resize(ev->obj, ev->w, ev->h, ev->ratio);
265 }
266
267 static void
268 _player_length_changed(Emotion_Generic_Video *ev, void *line)
269 {
270    float length;
271    RCV_CMD_PARAM(line, length);
272
273    INF("received length changed: %0.3f", length);
274
275    ev->len = length;
276    _emotion_video_pos_update(ev->obj, ev->pos, ev->len);
277 }
278
279 static void
280 _player_position_changed(Emotion_Generic_Video *ev, void *line)
281 {
282    float position;
283    RCV_CMD_PARAM(line, position);
284
285    INF("received position changed: %0.3f", position);
286
287    ev->pos = position;
288    _emotion_video_pos_update(ev->obj, ev->pos, ev->len);
289
290    if (ev->len == 0)
291      return;
292
293    float progress = ev->pos / ev->len;
294    char buf[16];
295    snprintf(buf, sizeof(buf), "%0.1f%%", progress * 100);
296
297    _emotion_progress_set(ev->obj, buf, progress);
298 }
299
300 static void
301 _player_seekable_changed(Emotion_Generic_Video *ev, void *line)
302 {
303    int seekable;
304    RCV_CMD_PARAM(line, seekable);
305
306    INF("received seekable changed: %d", seekable);
307
308    seekable = !!seekable;
309
310    ev->seekable = seekable;
311 }
312
313 static void
314 _player_volume(Emotion_Generic_Video *ev, void *line)
315 {
316    float vol, oldvol;
317    RCV_CMD_PARAM(line, vol);
318
319    INF("received volume: %0.3f", vol);
320
321    oldvol = ev->volume;
322    ev->volume = vol;
323    if (vol != oldvol && !ev->opening)
324      _emotion_audio_level_change(ev->obj);
325 }
326
327 static void
328 _player_audio_mute(Emotion_Generic_Video *ev, void *line)
329 {
330    int mute;
331    RCV_CMD_PARAM(line, mute);
332
333    INF("received audio mute: %d", mute);
334
335    ev->audio_mute = !!mute;
336 }
337
338 static void
339 _audio_channels_free(Emotion_Generic_Video *ev)
340 {
341    int i;
342    for (i = 0; i < ev->audio_channels_count; i++)
343      eina_stringshare_del(ev->audio_channels[i].name);
344    free(ev->audio_channels);
345    ev->audio_channels_count = 0;
346 }
347
348 static void
349 _player_audio_tracks_info(Emotion_Generic_Video *ev, void *line)
350 {
351    int track_current, tracks_count;
352    int i;
353
354    if (ev->audio_channels_count)
355      _audio_channels_free(ev);
356
357    RCV_CMD_PARAM(line, track_current);
358    RCV_CMD_PARAM(line, tracks_count);
359    INF("video with %d audio tracks (current = %d):", tracks_count, track_current);
360    ev->audio_channels = calloc(
361       tracks_count, sizeof(Emotion_Generic_Audio_Channel));
362    ev->audio_channels_count = tracks_count;
363    ev->audio_channel_current = track_current;
364    for (i = 0; i < tracks_count; i++)
365      {
366         int tid, len;
367         char buf[PATH_MAX];
368         RCV_CMD_PARAM(line, tid);
369         RCV_CMD_STR(line, buf, len);
370         ev->audio_channels[i].id = tid;
371         ev->audio_channels[i].name = eina_stringshare_add_length(buf, len);
372         INF("\t%d: %s", tid, buf);
373      }
374 }
375
376 static void
377 _player_file_closed(Emotion_Generic_Video *ev)
378 {
379    INF("Closed previous file.");
380    sem_destroy(&ev->shared->lock);
381
382    ev->closing = EINA_FALSE;
383
384    if (ev->opening)
385      _file_open(ev);
386 }
387
388 static void
389 _player_open_done(Emotion_Generic_Video *ev)
390 {
391    ev->opening = EINA_FALSE;
392    shm_unlink(ev->shmname);
393    _emotion_open_done(ev->obj);
394
395    if (ev->play)
396      {
397         _player_send_cmd(ev, EM_CMD_PLAY);
398         _player_send_float(ev, ev->pos);
399      }
400
401    INF("Open done");
402 }
403
404 static void
405 _player_read_cmd(Emotion_Generic_Video *ev, void *line, int size __UNUSED__)
406 {
407    int type;
408    RCV_CMD_PARAM(line, type);
409
410    switch (type) {
411       case EM_RESULT_INIT:
412          _player_ready(ev);
413          break;
414       case EM_RESULT_FRAME_NEW:
415          _player_new_frame(ev);
416          break;
417       case EM_RESULT_FILE_SET:
418          _player_file_set_done(ev);
419          break;
420       case EM_RESULT_FILE_SET_DONE:
421          _player_open_done(ev);
422          break;
423       case EM_RESULT_FILE_CLOSE:
424          _player_file_closed(ev);
425          break;
426       case EM_RESULT_PLAYBACK_STOPPED:
427          _emotion_playback_finished(ev->obj);
428          break;
429       case EM_RESULT_FRAME_SIZE:
430          _player_frame_resize(ev, line);
431          break;
432       case EM_RESULT_LENGTH_CHANGED:
433          _player_length_changed(ev, line);
434          break;
435       case EM_RESULT_POSITION_CHANGED:
436          _player_position_changed(ev, line);
437          break;
438       case EM_RESULT_SEEKABLE_CHANGED:
439          _player_seekable_changed(ev, line);
440          break;
441       case EM_RESULT_AUDIO_TRACK_INFO:
442          _player_audio_tracks_info(ev, line);
443          break;
444       default:
445          WRN("received wrong command: %d", type);
446    };
447 }
448
449 #undef RCV_CMD_PARAM
450
451 static Eina_Bool
452 _player_data_cb(void *data, int type __UNUSED__, void *event)
453 {
454    Ecore_Exe_Event_Data *ev = event;
455    Emotion_Generic_Video *evideo = data;
456    int psize;
457    char *pdata;
458    int i;
459
460    if (ev->exe != evideo->player.exe)
461      {
462         ERR("slave != ev->exe");
463         return ECORE_CALLBACK_DONE;
464      }
465
466    if (ev->size < 4)
467      {
468         ERR("invalid command: missing bytes.");
469         return ECORE_CALLBACK_DONE;
470      }
471
472    for (i = 0; ev->lines[i].line; i++)
473      _player_read_cmd(evideo, ev->lines[i].line, ev->lines[i].size);
474
475    return ECORE_CALLBACK_DONE;
476 }
477
478 static Eina_Bool
479 _player_add_cb(void *data, int type __UNUSED__, void *event)
480 {
481    Ecore_Exe_Event_Add *event_add = event;
482    Ecore_Exe *player = event_add->exe;
483    Emotion_Generic_Video *ev = data;
484
485    if (ev->player.exe != player)
486      {
487         ERR("ev->player != player.");
488         return ECORE_CALLBACK_DONE;
489      }
490
491    _player_send_cmd(ev, EM_CMD_INIT);
492    _player_send_str(ev, ev->shmname, EINA_TRUE);
493
494    return ECORE_CALLBACK_DONE;
495 }
496
497 static Eina_Bool
498 _player_del_cb(void *data, int type __UNUSED__, void *event __UNUSED__)
499 {
500    Ecore_Exe_Event_Del *event_del = event;
501    Ecore_Exe *player = event_del->exe;
502    Emotion_Generic_Video *ev = data;
503    ERR("player died.");
504
505    ev->player.exe = NULL;
506    ev->ready = EINA_FALSE;
507    _emotion_decode_stop(ev->obj);
508
509    return ECORE_CALLBACK_DONE;
510 }
511
512 static Eina_Bool
513 _fork_and_exec(Evas_Object *obj __UNUSED__, Emotion_Generic_Video *ev)
514 {
515    char shmname[256];
516    struct timeval tv;
517
518    gettimeofday(&tv, NULL);
519    snprintf(shmname, sizeof(shmname), "/em-generic-shm_%d_%d",
520             (int)tv.tv_sec, (int)tv.tv_usec);
521
522    ev->shmname = eina_stringshare_add(shmname);
523
524    ev->player_add = ecore_event_handler_add(
525       ECORE_EXE_EVENT_ADD, _player_add_cb, ev);
526    ev->player_del = ecore_event_handler_add(
527       ECORE_EXE_EVENT_DEL, _player_del_cb, ev);
528    ev->player_data = ecore_event_handler_add(
529       ECORE_EXE_EVENT_DATA, _player_data_cb, ev);
530
531    ev->player.exe = ecore_exe_pipe_run(
532       ev->cmdline,
533       ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
534       ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_NOT_LEADER,
535       ev);
536
537    if (!ev->player.exe)
538      {
539         ERR("could not start player.");
540         return EINA_FALSE;
541      }
542
543    ev->initializing = EINA_TRUE;
544
545    return EINA_TRUE;
546 }
547
548 static unsigned char
549 em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt)
550 {
551    Emotion_Generic_Video *ev;
552    const char *player;
553
554    if (!emotion_video) return 0;
555    player = _get_player(opt ? opt->player : NULL);
556    if (!player) return 0;
557
558    ev = (Emotion_Generic_Video *)calloc(1, sizeof(*ev));
559    if (!ev) return 0;
560
561    ev->speed = 1.0;
562    ev->volume = 0.5;
563    ev->audio_mute = EINA_FALSE;
564
565    ev->obj = obj;
566    ev->cmdline = eina_stringshare_add(player);
567    *emotion_video = ev;
568
569    return _fork_and_exec(obj, ev);
570 }
571
572 static int
573 em_shutdown(void *data)
574 {
575    Emotion_Generic_Video *ev = data;
576
577    if (!ev) return 0;
578
579    if (ev->player.exe)
580      {
581         ecore_exe_terminate(ev->player.exe);
582         ecore_exe_free(ev->player.exe);
583         ev->player.exe = NULL;
584      }
585
586    if (ev->shared)
587      munmap(ev->shared, ev->shared->size);
588
589    _audio_channels_free(ev);
590
591    eina_stringshare_del(ev->cmdline);
592    eina_stringshare_del(ev->shmname);
593
594    ecore_event_handler_del(ev->player_add);
595    ecore_event_handler_del(ev->player_data);
596    ecore_event_handler_del(ev->player_del);
597
598    return 1;
599 }
600
601 static unsigned char
602 em_file_open(const char *file, Evas_Object *obj __UNUSED__, void *data)
603 {
604    Emotion_Generic_Video *ev = data;
605    INF("file set: %s", file);
606    if (!ev) return 0;
607
608    ev->pos = 0;
609    ev->opening = EINA_TRUE;
610
611    eina_stringshare_replace(&ev->filename, file);
612
613    if (!ev->closing)
614      _file_open(ev);
615
616    return 1;
617 }
618
619 static void
620 em_file_close(void *data)
621 {
622    Emotion_Generic_Video *ev = data;
623
624    if (!ev) return;
625    INF("file close: %s", ev->filename);
626
627    if (!ev->filename)
628      return;
629
630    _player_send_cmd(ev, EM_CMD_FILE_CLOSE);
631    ev->closing = EINA_TRUE;
632 }
633
634 static Emotion_Format
635 em_format_get(void *ef __UNUSED__)
636 {
637    return EMOTION_FORMAT_BGRA;
638 }
639
640 static void
641 em_video_data_size_get(void *data, int *w, int *h)
642 {
643    Emotion_Generic_Video *ev = data;
644
645    if (!ev) return;
646    if (w) *w = ev->w;
647    if (h) *h = ev->h;
648 }
649
650 static void
651 em_play(void *data, double pos)
652 {
653    Emotion_Generic_Video *ev = data;
654
655    if (!ev)
656      return;
657
658    ev->play = EINA_TRUE;
659    INF("play: %0.3f", pos);
660
661    if (ev->initializing || ev->opening)
662      return;
663
664    if (ev->ready)
665      {
666         _player_send_cmd(ev, EM_CMD_PLAY);
667         _player_send_float(ev, ev->pos);
668         return;
669      }
670
671    ev->player.exe = ecore_exe_pipe_run(
672       ev->cmdline,
673       ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
674       ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_NOT_LEADER,
675       ev);
676
677    if (!ev->player.exe)
678      ERR("could not start player.");
679 }
680
681 static void
682 em_stop(void *data)
683 {
684    Emotion_Generic_Video *ev = data;
685
686    if (!ev)
687      return;
688
689    ev->play = EINA_FALSE;
690
691    if (!ev->ready)
692      return;
693
694    _player_send_cmd(ev, EM_CMD_STOP);
695    _emotion_decode_stop(ev->obj);
696 }
697
698 static void
699 em_size_get(void *data, int *w, int *h)
700 {
701    Emotion_Generic_Video *ev = data;
702    if(w) *w = ev->w;
703    if(h) *h = ev->h;
704 }
705
706 static void
707 em_pos_set(void *data, double pos)
708 {
709    Emotion_Generic_Video *ev = data;
710    float position = pos;
711    _player_send_cmd(ev, EM_CMD_POSITION_SET);
712    _player_send_float(ev, position);
713    _emotion_seek_done(ev->obj);
714 }
715
716 static double
717 em_len_get(void *data)
718 {
719    Emotion_Generic_Video *ev = data;
720    return ev->len;
721 }
722
723 static int
724 em_fps_num_get(void *data)
725 {
726    Emotion_Generic_Video *ev = data;
727    return (int)(ev->fps * 1000.0);
728 }
729
730 static int
731 em_fps_den_get(void *ef __UNUSED__)
732 {
733    return 1000;
734 }
735
736 static double
737 em_fps_get(void *data)
738 {
739    Emotion_Generic_Video *ev = data;
740    return ev->fps;
741 }
742
743 static double
744 em_pos_get(void *data)
745 {
746    Emotion_Generic_Video *ev = data;
747    return ev->pos;
748 }
749
750 static void
751 em_vis_set(void *ef __UNUSED__, Emotion_Vis vis __UNUSED__)
752 {
753 }
754
755 static Emotion_Vis
756 em_vis_get(void *data)
757 {
758    Emotion_Generic_Video *ev = data;
759    return ev->vis;
760 }
761
762 static Eina_Bool
763 em_vis_supported(void *ef __UNUSED__, Emotion_Vis vis __UNUSED__)
764 {
765    return EINA_FALSE;
766 }
767
768 static double
769 em_ratio_get(void *data)
770 {
771    Emotion_Generic_Video *ev = data;
772    return ev->ratio;
773 }
774
775 static int em_video_handled(void *ef __UNUSED__)
776 {
777    fprintf(stderr, "video handled!\n");
778    return 1;
779 }
780
781 static int em_audio_handled(void *ef __UNUSED__)
782 {
783    fprintf(stderr, "audio handled!\n");
784    return 1;
785 }
786
787 static int em_seekable(void *data)
788 {
789    Emotion_Generic_Video *ev = data;
790    return ev->seekable;
791 }
792
793 static void em_frame_done(void *ef __UNUSED__)
794 {
795 }
796
797 static int
798 em_yuv_rows_get(void *data __UNUSED__, int w __UNUSED__, int h __UNUSED__, unsigned char **yrows __UNUSED__, unsigned char **urows __UNUSED__, unsigned char **vrows __UNUSED__)
799 {
800    Emotion_Generic_Video *ev;
801    volatile Emotion_Generic_Video_Shared *vs;
802    return 0;
803 }
804
805 static int
806 em_bgra_data_get(void *data, unsigned char **bgra_data)
807 {
808    Emotion_Generic_Video *ev = data;
809
810    if (!ev || ev->opening || ev->closing)
811      return 0;
812
813    // lock frame here
814    sem_wait(&ev->shared->lock);
815
816    // send current frame to emotion
817    if (ev->shared->frame.emotion != ev->shared->frame.last)
818      {
819         ev->shared->frame.next = ev->shared->frame.emotion;
820         ev->shared->frame.emotion = ev->shared->frame.last;
821      }
822    *bgra_data = ev->frame.frames[ev->shared->frame.emotion];
823
824    // unlock frame here
825    sem_post(&ev->shared->lock);
826    ev->drop = 0;
827
828    return 1;
829 }
830
831 static void
832 em_event_feed(void *ef __UNUSED__, int event __UNUSED__)
833 {
834 }
835
836 static void
837 em_event_mouse_button_feed(void *ef __UNUSED__, int button __UNUSED__, int x __UNUSED__, int y __UNUSED__)
838 {
839 }
840
841 static void
842 em_event_mouse_move_feed(void *ef __UNUSED__, int x __UNUSED__, int y __UNUSED__)
843 {
844 }
845
846 static int
847 em_video_channel_count(void *ef __UNUSED__)
848 {
849    int ret  = 0;
850    return ret;
851 }
852
853 static void
854 em_video_channel_set(void *ef __UNUSED__, int channel __UNUSED__)
855 {
856 }
857
858 static int
859 em_video_channel_get(void *ef __UNUSED__)
860 {
861    return 1;
862 }
863
864 static const char *
865 em_video_channel_name_get(void *ef __UNUSED__, int channel __UNUSED__)
866 {
867    return NULL;
868 }
869
870 static void
871 em_video_channel_mute_set(void *ef __UNUSED__, int mute __UNUSED__)
872 {
873 }
874
875 static int
876 em_video_channel_mute_get(void *data)
877 {
878    Emotion_Generic_Video *ev = data;
879    return ev->video_mute;
880 }
881
882 static int
883 em_audio_channel_count(void *data)
884 {
885    Emotion_Generic_Video *ev = data;
886    return ev->audio_channels_count;
887 }
888
889 static void
890 em_audio_channel_set(void *data, int channel)
891 {
892    Emotion_Generic_Video *ev = data;
893    int i;
894
895    for (i = 0; i < ev->audio_channels_count; i++)
896      {
897         if (ev->audio_channels[i].id == channel)
898           {
899              _player_send_cmd(ev, EM_CMD_AUDIO_TRACK_SET);
900              _player_send_int(ev, channel);
901              break;
902           }
903      }
904 }
905
906 static int
907 em_audio_channel_get(void *data)
908 {
909    Emotion_Generic_Video *ev = data;
910    return ev->audio_channel_current;
911 }
912
913 static const char *
914 em_audio_channel_name_get(void *data, int channel)
915 {
916    Emotion_Generic_Video *ev = data;
917    int i;
918
919    for (i = 0; i < ev->audio_channels_count; i++)
920      {
921         if (ev->audio_channels[i].id == channel)
922           return ev->audio_channels[i].name;
923      }
924
925    return NULL;
926 }
927
928 static void
929 em_audio_channel_mute_set(void *data, int mute)
930 {
931    Emotion_Generic_Video *ev = data;
932    _player_send_cmd(ev, EM_CMD_AUDIO_MUTE_SET);
933    _player_send_int(ev, mute);
934    ev->audio_mute = !!mute;
935 }
936
937 static int
938 em_audio_channel_mute_get(void *data)
939 {
940    Emotion_Generic_Video *ev = data;
941    return ev->audio_mute;
942 }
943
944 static void
945 em_audio_channel_volume_set(void *data, double vol)
946 {
947    Emotion_Generic_Video *ev = data;
948    float fvol;
949
950    if (vol > 1.0) vol = 1.0;
951    if (vol < 0.0) vol = 0.0;
952
953    fvol = vol;
954    _player_send_cmd(ev, EM_CMD_VOLUME_SET);
955    _player_send_float(ev, fvol);
956
957    ev->volume = vol;
958 }
959
960 static double
961 em_audio_channel_volume_get(void *data)
962 {
963    Emotion_Generic_Video *ev = data;
964    return ev->volume;
965 }
966
967 static int
968 em_spu_channel_count(void *ef __UNUSED__)
969 {
970    return 0;
971 }
972
973 static void
974 em_spu_channel_set(void *ef __UNUSED__, int channel __UNUSED__)
975 {
976 }
977
978 static int
979 em_spu_channel_get(void *ef __UNUSED__)
980 {
981    int num = 0;
982    return num;
983 }
984
985 static const char *
986 em_spu_channel_name_get(void *ef __UNUSED__, int channel __UNUSED__)
987 {
988    return NULL;
989 }
990
991 static void
992 em_spu_channel_mute_set(void *ef __UNUSED__, int mute __UNUSED__)
993 {
994    return;
995 }
996
997 static int
998 em_spu_channel_mute_get(void *ef __UNUSED__)
999 {
1000    return 0;
1001 }
1002
1003 static int
1004 em_chapter_count(void *ef __UNUSED__)
1005 {
1006    int num = 0;
1007    return num;
1008 }
1009
1010 static void
1011 em_chapter_set(void *ef __UNUSED__, int chapter __UNUSED__)
1012 {
1013 }
1014
1015 static int
1016 em_chapter_get(void *ef __UNUSED__)
1017 {
1018    int num = 0;
1019    return num;
1020 }
1021
1022 static const char *
1023 em_chapter_name_get(void *ef __UNUSED__, int chapter __UNUSED__)
1024 {
1025    return NULL;
1026 }
1027
1028 static void
1029 em_speed_set(void *data, double speed)
1030 {
1031    Emotion_Generic_Video *ev = data;
1032    float rate = speed;
1033
1034    _player_send_cmd(ev, EM_CMD_SPEED_SET);
1035    _player_send_float(ev, rate);
1036
1037    ev->speed = rate;
1038 }
1039
1040 static double
1041 em_speed_get(void *data)
1042 {
1043    Emotion_Generic_Video *ev = data;
1044    return (double)ev->speed;
1045 }
1046
1047 static int
1048 em_eject(void *ef __UNUSED__)
1049 {
1050    return 1;
1051 }
1052
1053 static const char *
1054 em_meta_get(void *ef __UNUSED__, int meta __UNUSED__)
1055 {
1056    char * meta_data = NULL;
1057    return meta_data;
1058 }
1059
1060 static Emotion_Video_Module em_module =
1061 {
1062    em_init, /* init */
1063    em_shutdown, /* shutdown */
1064    em_file_open, /* file_open */
1065    em_file_close, /* file_close */
1066    em_play, /* play */
1067    em_stop, /* stop */
1068    em_size_get, /* size_get */
1069    em_pos_set, /* pos_set */
1070    em_len_get, /* len_get */
1071    em_fps_num_get, /* fps_num_get */
1072    em_fps_den_get, /* fps_den_get */
1073    em_fps_get, /* fps_get */
1074    em_pos_get, /* pos_get */
1075    em_vis_set, /* vis_set */
1076    em_vis_get, /* vis_get */
1077    em_vis_supported, /* vis_supported */
1078    em_ratio_get, /* ratio_get */
1079    em_video_handled, /* video_handled */
1080    em_audio_handled, /* audio_handled */
1081    em_seekable, /* seekable */
1082    em_frame_done, /* frame_done */
1083    em_format_get, /* format_get */
1084    em_video_data_size_get, /* video_data_size_get */
1085    em_yuv_rows_get, /* yuv_rows_get */
1086    em_bgra_data_get, /* bgra_data_get */
1087    em_event_feed, /* event_feed */
1088    em_event_mouse_button_feed, /* event_mouse_button_feed */
1089    em_event_mouse_move_feed, /* event_mouse_move_feed */
1090    em_video_channel_count, /* video_channel_count */
1091    em_video_channel_set, /* video_channel_set */
1092    em_video_channel_get, /* video_channel_get */
1093    em_video_channel_name_get, /* video_channel_name_get */
1094    em_video_channel_mute_set, /* video_channel_mute_set */
1095    em_video_channel_mute_get, /* video_channel_mute_get */
1096    em_audio_channel_count, /* audio_channel_count */
1097    em_audio_channel_set, /* audio_channel_set */
1098    em_audio_channel_get, /* audio_channel_get */
1099    em_audio_channel_name_get, /* audio_channel_name_get */
1100    em_audio_channel_mute_set, /* audio_channel_mute_set */
1101    em_audio_channel_mute_get, /* audio_channel_mute_get */
1102    em_audio_channel_volume_set, /* audio_channel_volume_set */
1103    em_audio_channel_volume_get, /* audio_channel_volume_get */
1104    em_spu_channel_count, /* spu_channel_count */
1105    em_spu_channel_set, /* spu_channel_set */
1106    em_spu_channel_get, /* spu_channel_get */
1107    em_spu_channel_name_get, /* spu_channel_name_get */
1108    em_spu_channel_mute_set, /* spu_channel_mute_set */
1109    em_spu_channel_mute_get, /* spu_channel_mute_get */
1110    em_chapter_count, /* chapter_count */
1111    em_chapter_set, /* chapter_set */
1112    em_chapter_get, /* chapter_get */
1113    em_chapter_name_get, /* chapter_name_get */
1114    em_speed_set, /* speed_set */
1115    em_speed_get, /* speed_get */
1116    em_eject, /* eject */
1117    em_meta_get, /* meta_get */
1118    NULL /* handle */
1119 };
1120
1121 static Eina_Bool
1122 module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
1123 {
1124    if (!module) {
1125         return EINA_FALSE;
1126    }
1127
1128    if (_emotion_generic_log_domain < 0)
1129      {
1130         eina_threads_init();
1131         eina_log_threads_enable();
1132         _emotion_generic_log_domain = eina_log_domain_register
1133           ("emotion-generic", EINA_COLOR_LIGHTCYAN);
1134         if (_emotion_generic_log_domain < 0)
1135           {
1136              EINA_LOG_CRIT("Could not register log domain 'emotion-generic'");
1137              return EINA_FALSE;
1138           }
1139      }
1140
1141
1142    if (!em_module.init(obj, video, opt))        {
1143         return EINA_FALSE;
1144    }
1145
1146    *module = &em_module;
1147
1148    return EINA_TRUE;
1149 }
1150
1151 static void module_close(Emotion_Video_Module *module __UNUSED__, void *video)
1152 {
1153         em_module.shutdown(video);
1154 }
1155
1156
1157 static Eina_Bool
1158 generic_module_init(void)
1159 {
1160    if (!pfx)
1161      {
1162         pfx = eina_prefix_new(NULL, emotion_object_add,
1163                               "EMOTION", "emotion", NULL,
1164                               PACKAGE_BIN_DIR,
1165                               PACKAGE_LIB_DIR,
1166                               PACKAGE_DATA_DIR,
1167                               "");
1168         if (!pfx) return EINA_FALSE;
1169      }
1170    return _emotion_module_register("generic", module_open, module_close);
1171 }
1172
1173 static void
1174 generic_module_shutdown(void)
1175 {
1176    if (pfx)
1177      {
1178         eina_prefix_free(pfx);
1179         pfx = NULL;
1180      }
1181    _emotion_module_unregister("generic");
1182 }
1183
1184 #ifndef EMOTION_STATIC_BUILD_GENERIC
1185
1186 EINA_MODULE_INIT(generic_module_init);
1187 EINA_MODULE_SHUTDOWN(generic_module_shutdown);
1188
1189 #endif
1190