14 #include "emotion_private.h"
15 #include "emotion_generic.h"
17 static Eina_Prefix *pfx = NULL;
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__)
27 struct _default_players {
32 static struct _default_players players[] = {
33 #ifdef EMOTION_BUILD_GENERIC_VLC
34 { "vlc", "em_generic_vlc" },
40 _get_player(const char *name)
42 const char *selected_name = NULL;
43 const char *libdir = eina_prefix_lib_get(pfx);
44 static char buf[PATH_MAX];
49 for (i = 0; players[i].name; i++)
51 if (!strcmp(players[i].name, name))
53 selected_name = players[i].cmdline;
59 if ((!selected_name) && (name))
66 if (selected_name[0] == '/') cmd = selected_name;
69 snprintf(buf, sizeof(buf), "%s/emotion/utils/%s",
70 libdir, selected_name);
74 DBG("Try generic player '%s'", cmd);
75 if (access(cmd, R_OK | X_OK) == 0)
77 INF("Using generic player '%s'", cmd);
82 for (i = 0; players[i].name; i++)
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)
89 INF("Using fallback player '%s'", buf);
94 ERR("no generic player found, given name='%s'", name ? name : "");
99 _player_send_cmd(Emotion_Generic_Video *ev, int cmd)
101 if (cmd >= EM_CMD_LAST)
103 ERR("invalid command to player.");
106 ecore_exe_send(ev->player.exe, &cmd, sizeof(cmd));
110 _player_send_int(Emotion_Generic_Video *ev, int number)
112 ecore_exe_send(ev->player.exe, &number, sizeof(number));
116 _player_send_float(Emotion_Generic_Video *ev, float number)
118 ecore_exe_send(ev->player.exe, &number, sizeof(number));
122 _player_send_str(Emotion_Generic_Video *ev, const char *str, Eina_Bool stringshared)
127 len = eina_stringshare_strlen(str) + 1;
129 len = strlen(str) + 1;
130 ecore_exe_send(ev->player.exe, &len, sizeof(len));
131 ecore_exe_send(ev->player.exe, str, len);
135 _create_shm_data(Emotion_Generic_Video *ev, const char *shmname)
140 Emotion_Generic_Video_Shared *vs;
142 shmfd = shm_open(shmname, O_CREAT | O_RDWR | O_TRUNC, 0777);
145 ERR("player: could not open shm: %s", shmname);
146 ERR("player: %s", strerror(errno));
149 size = 3 * (ev->w * ev->h * DEFAULTPITCH) + sizeof(*vs);
151 npages = (int)(size / getpagesize()) + 1;
152 size = npages * getpagesize();
154 if (ftruncate(shmfd, size))
156 ERR("error when allocating shared memory (size = %zd): "
157 "%s", size, strerror(errno));
161 vs = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, shmfd, 0);
162 if (vs == MAP_FAILED)
164 ERR("error when mapping shared memory.\n");
171 vs->pitch = DEFAULTPITCH;
172 vs->frame.emotion = 0;
173 vs->frame.player = 1;
176 sem_init(&vs->lock, 1, 1);
177 ev->frame.frames[0] = (unsigned char *)vs + sizeof(*vs);
178 ev->frame.frames[1] = (unsigned char *)vs + sizeof(*vs) + vs->height * vs->width * vs->pitch;
179 ev->frame.frames[2] = (unsigned char *)vs + sizeof(*vs) + 2 * vs->height * vs->width * vs->pitch;
182 munmap(ev->shared, ev->shared->size);
189 _player_new_frame(Emotion_Generic_Video *ev)
192 _emotion_frame_new(ev->obj);
196 _player_file_set_done(Emotion_Generic_Video *ev)
198 if (!_create_shm_data(ev, ev->shmname))
200 ERR("could not create shared memory.");
203 _player_send_cmd(ev, EM_CMD_FILE_SET_DONE);
207 _file_open(Emotion_Generic_Video *ev)
209 INF("Opening file: %s", ev->filename);
210 ev->w = DEFAULTWIDTH;
211 ev->h = DEFAULTHEIGHT;
212 ev->ratio = (double)DEFAULTWIDTH / DEFAULTHEIGHT;
219 _player_send_cmd(ev, EM_CMD_FILE_SET);
220 _player_send_str(ev, ev->filename, EINA_TRUE);
224 _player_ready(Emotion_Generic_Video *ev)
226 INF("received: player ready.");
228 ev->initializing = EINA_FALSE;
229 ev->ready = EINA_TRUE;
237 #define RCV_CMD_PARAM(src, param) \
238 memcpy(&(param), (src), sizeof((param))); \
239 (src) = (char *)(src) + sizeof((param));
241 #define RCV_CMD_STR(src, buf, len) \
242 RCV_CMD_PARAM((src), (len)); \
243 memcpy((buf), (src), (len)); \
244 (src) = (char *)(src) + len;
247 _player_int_read(Emotion_Generic_Video *ev __UNUSED__, void **data)
250 memcpy(&number, *data, sizeof(number));
251 *data = (char *)(*data) + sizeof(number);
257 _player_frame_resize(Emotion_Generic_Video *ev, void *line)
260 RCV_CMD_PARAM(line, w);
261 RCV_CMD_PARAM(line, h);
263 INF("received frame resize: %dx%d", w, h);
266 ev->ratio = (float)w / h;
271 _emotion_frame_resize(ev->obj, ev->w, ev->h, ev->ratio);
275 _player_length_changed(Emotion_Generic_Video *ev, void *line)
278 RCV_CMD_PARAM(line, length);
280 INF("received length changed: %0.3f", length);
283 _emotion_video_pos_update(ev->obj, ev->pos, ev->len);
287 _player_position_changed(Emotion_Generic_Video *ev, void *line)
290 RCV_CMD_PARAM(line, position);
292 INF("received position changed: %0.3f", position);
295 _emotion_video_pos_update(ev->obj, ev->pos, ev->len);
300 float progress = ev->pos / ev->len;
302 snprintf(buf, sizeof(buf), "%0.1f%%", progress * 100);
304 _emotion_progress_set(ev->obj, buf, progress);
308 _player_seekable_changed(Emotion_Generic_Video *ev, void *line)
311 RCV_CMD_PARAM(line, seekable);
313 INF("received seekable changed: %d", seekable);
315 seekable = !!seekable;
317 ev->seekable = seekable;
321 _player_volume(Emotion_Generic_Video *ev, void *line)
324 RCV_CMD_PARAM(line, vol);
326 INF("received volume: %0.3f", vol);
330 if (vol != oldvol && !ev->opening)
331 _emotion_audio_level_change(ev->obj);
335 _player_audio_mute(Emotion_Generic_Video *ev, void *line)
338 RCV_CMD_PARAM(line, mute);
340 INF("received audio mute: %d", mute);
342 ev->audio_mute = !!mute;
346 _audio_channels_free(Emotion_Generic_Video *ev)
349 for (i = 0; i < ev->audio_channels_count; i++)
350 eina_stringshare_del(ev->audio_channels[i].name);
351 free(ev->audio_channels);
352 ev->audio_channels_count = 0;
356 _player_audio_tracks_info(Emotion_Generic_Video *ev, void *line)
358 int track_current, tracks_count;
361 if (ev->audio_channels_count)
362 _audio_channels_free(ev);
364 RCV_CMD_PARAM(line, track_current);
365 RCV_CMD_PARAM(line, tracks_count);
366 INF("video with %d audio tracks (current = %d):", tracks_count, track_current);
367 ev->audio_channels = calloc(
368 tracks_count, sizeof(Emotion_Generic_Audio_Channel));
369 ev->audio_channels_count = tracks_count;
370 ev->audio_channel_current = track_current;
371 for (i = 0; i < tracks_count; i++)
375 RCV_CMD_PARAM(line, tid);
376 RCV_CMD_STR(line, buf, len);
377 ev->audio_channels[i].id = tid;
378 ev->audio_channels[i].name = eina_stringshare_add_length(buf, len);
379 INF("\t%d: %s", tid, buf);
384 _player_file_closed(Emotion_Generic_Video *ev)
386 INF("Closed previous file.");
387 sem_destroy(&ev->shared->lock);
389 ev->closing = EINA_FALSE;
396 _player_open_done(Emotion_Generic_Video *ev, void *line)
400 ev->opening = EINA_FALSE;
401 RCV_CMD_PARAM(line, success);
403 shm_unlink(ev->shmname);
406 ERR("Could not open file.");
410 _emotion_open_done(ev->obj);
414 _player_send_cmd(ev, EM_CMD_PLAY);
415 _player_send_float(ev, ev->pos);
422 _player_read_cmd(Emotion_Generic_Video *ev, void *line, int size __UNUSED__)
425 RCV_CMD_PARAM(line, type);
431 case EM_RESULT_FRAME_NEW:
432 _player_new_frame(ev);
434 case EM_RESULT_FILE_SET:
435 _player_file_set_done(ev);
437 case EM_RESULT_FILE_SET_DONE:
438 _player_open_done(ev, line);
440 case EM_RESULT_FILE_CLOSE:
441 _player_file_closed(ev);
443 case EM_RESULT_PLAYBACK_STOPPED:
444 _emotion_playback_finished(ev->obj);
446 case EM_RESULT_FRAME_SIZE:
447 _player_frame_resize(ev, line);
449 case EM_RESULT_LENGTH_CHANGED:
450 _player_length_changed(ev, line);
452 case EM_RESULT_POSITION_CHANGED:
453 _player_position_changed(ev, line);
455 case EM_RESULT_SEEKABLE_CHANGED:
456 _player_seekable_changed(ev, line);
458 case EM_RESULT_AUDIO_TRACK_INFO:
459 _player_audio_tracks_info(ev, line);
462 WRN("received wrong command: %d", type);
469 _player_data_cb(void *data, int type __UNUSED__, void *event)
471 Ecore_Exe_Event_Data *ev = event;
472 Emotion_Generic_Video *evideo = data;
475 if (ev->exe != evideo->player.exe)
477 ERR("slave != ev->exe");
478 return ECORE_CALLBACK_DONE;
483 ERR("invalid command: missing bytes.");
484 return ECORE_CALLBACK_DONE;
487 for (i = 0; ev->lines[i].line; i++)
488 _player_read_cmd(evideo, ev->lines[i].line, ev->lines[i].size);
490 return ECORE_CALLBACK_DONE;
494 _player_add_cb(void *data, int type __UNUSED__, void *event)
496 Ecore_Exe_Event_Add *event_add = event;
497 Ecore_Exe *player = event_add->exe;
498 Emotion_Generic_Video *ev = data;
500 if (ev->player.exe != player)
502 ERR("ev->player != player.");
503 return ECORE_CALLBACK_DONE;
506 _player_send_cmd(ev, EM_CMD_INIT);
507 _player_send_str(ev, ev->shmname, EINA_TRUE);
509 return ECORE_CALLBACK_DONE;
513 _player_del_cb(void *data, int type __UNUSED__, void *event __UNUSED__)
515 Emotion_Generic_Video *ev = data;
518 ev->player.exe = NULL;
519 ev->ready = EINA_FALSE;
520 _emotion_decode_stop(ev->obj);
522 return ECORE_CALLBACK_DONE;
526 _fork_and_exec(Evas_Object *obj __UNUSED__, Emotion_Generic_Video *ev)
531 gettimeofday(&tv, NULL);
532 snprintf(shmname, sizeof(shmname), "/em-generic-shm_%d_%d",
533 (int)tv.tv_sec, (int)tv.tv_usec);
535 ev->shmname = eina_stringshare_add(shmname);
537 ev->player_add = ecore_event_handler_add(
538 ECORE_EXE_EVENT_ADD, _player_add_cb, ev);
539 ev->player_del = ecore_event_handler_add(
540 ECORE_EXE_EVENT_DEL, _player_del_cb, ev);
541 ev->player_data = ecore_event_handler_add(
542 ECORE_EXE_EVENT_DATA, _player_data_cb, ev);
544 ev->player.exe = ecore_exe_pipe_run(
546 ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
547 ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_NOT_LEADER,
552 ERR("could not start player.");
556 ev->initializing = EINA_TRUE;
562 em_init(Evas_Object *obj, void **emotion_video, Emotion_Module_Options *opt)
564 Emotion_Generic_Video *ev;
567 if (!emotion_video) return 0;
568 player = _get_player(opt ? opt->player : NULL);
569 if (!player) return 0;
571 ev = (Emotion_Generic_Video *)calloc(1, sizeof(*ev));
576 ev->audio_mute = EINA_FALSE;
579 ev->cmdline = eina_stringshare_add(player);
582 return _fork_and_exec(obj, ev);
586 em_shutdown(void *data)
588 Emotion_Generic_Video *ev = data;
594 ecore_exe_terminate(ev->player.exe);
595 ecore_exe_free(ev->player.exe);
596 ev->player.exe = NULL;
600 munmap(ev->shared, ev->shared->size);
602 _audio_channels_free(ev);
604 eina_stringshare_del(ev->cmdline);
605 eina_stringshare_del(ev->shmname);
607 ecore_event_handler_del(ev->player_add);
608 ecore_event_handler_del(ev->player_data);
609 ecore_event_handler_del(ev->player_del);
615 em_file_open(const char *file, Evas_Object *obj __UNUSED__, void *data)
617 Emotion_Generic_Video *ev = data;
618 INF("file set: %s", file);
622 ev->opening = EINA_TRUE;
624 eina_stringshare_replace(&ev->filename, file);
633 em_file_close(void *data)
635 Emotion_Generic_Video *ev = data;
638 INF("file close: %s", ev->filename);
643 _player_send_cmd(ev, EM_CMD_FILE_CLOSE);
644 ev->closing = EINA_TRUE;
647 static Emotion_Format
648 em_format_get(void *ef __UNUSED__)
650 return EMOTION_FORMAT_BGRA;
654 em_video_data_size_get(void *data, int *w, int *h)
656 Emotion_Generic_Video *ev = data;
664 em_play(void *data, double pos)
666 Emotion_Generic_Video *ev = data;
671 ev->play = EINA_TRUE;
672 INF("play: %0.3f", pos);
674 if (ev->initializing || ev->opening)
679 _player_send_cmd(ev, EM_CMD_PLAY);
680 _player_send_float(ev, ev->pos);
684 ev->player.exe = ecore_exe_pipe_run(
686 ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_WRITE |
687 ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_NOT_LEADER,
691 ERR("could not start player.");
697 Emotion_Generic_Video *ev = data;
702 ev->play = EINA_FALSE;
707 _player_send_cmd(ev, EM_CMD_STOP);
708 _emotion_decode_stop(ev->obj);
712 em_size_get(void *data, int *w, int *h)
714 Emotion_Generic_Video *ev = data;
720 em_pos_set(void *data, double pos)
722 Emotion_Generic_Video *ev = data;
723 float position = pos;
724 _player_send_cmd(ev, EM_CMD_POSITION_SET);
725 _player_send_float(ev, position);
726 _emotion_seek_done(ev->obj);
730 em_len_get(void *data)
732 Emotion_Generic_Video *ev = data;
737 em_fps_num_get(void *data)
739 Emotion_Generic_Video *ev = data;
740 return (int)(ev->fps * 1000.0);
744 em_fps_den_get(void *ef __UNUSED__)
750 em_fps_get(void *data)
752 Emotion_Generic_Video *ev = data;
757 em_pos_get(void *data)
759 Emotion_Generic_Video *ev = data;
764 em_vis_set(void *ef __UNUSED__, Emotion_Vis vis __UNUSED__)
769 em_vis_get(void *data)
771 Emotion_Generic_Video *ev = data;
776 em_vis_supported(void *ef __UNUSED__, Emotion_Vis vis __UNUSED__)
782 em_ratio_get(void *data)
784 Emotion_Generic_Video *ev = data;
788 static int em_video_handled(void *ef __UNUSED__)
790 fprintf(stderr, "video handled!\n");
794 static int em_audio_handled(void *ef __UNUSED__)
796 fprintf(stderr, "audio handled!\n");
800 static int em_seekable(void *data)
802 Emotion_Generic_Video *ev = data;
806 static void em_frame_done(void *ef __UNUSED__)
811 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__)
817 em_bgra_data_get(void *data, unsigned char **bgra_data)
819 Emotion_Generic_Video *ev = data;
821 if (!ev || ev->opening || ev->closing)
825 sem_wait(&ev->shared->lock);
827 // send current frame to emotion
828 if (ev->shared->frame.emotion != ev->shared->frame.last)
830 ev->shared->frame.next = ev->shared->frame.emotion;
831 ev->shared->frame.emotion = ev->shared->frame.last;
833 *bgra_data = ev->frame.frames[ev->shared->frame.emotion];
836 sem_post(&ev->shared->lock);
843 em_event_feed(void *ef __UNUSED__, int event __UNUSED__)
848 em_event_mouse_button_feed(void *ef __UNUSED__, int button __UNUSED__, int x __UNUSED__, int y __UNUSED__)
853 em_event_mouse_move_feed(void *ef __UNUSED__, int x __UNUSED__, int y __UNUSED__)
858 em_video_channel_count(void *ef __UNUSED__)
865 em_video_channel_set(void *ef __UNUSED__, int channel __UNUSED__)
870 em_video_channel_get(void *ef __UNUSED__)
876 em_video_channel_name_get(void *ef __UNUSED__, int channel __UNUSED__)
882 em_video_channel_mute_set(void *ef __UNUSED__, int mute __UNUSED__)
887 em_video_channel_mute_get(void *data)
889 Emotion_Generic_Video *ev = data;
890 return ev->video_mute;
894 em_audio_channel_count(void *data)
896 Emotion_Generic_Video *ev = data;
897 return ev->audio_channels_count;
901 em_audio_channel_set(void *data, int channel)
903 Emotion_Generic_Video *ev = data;
906 for (i = 0; i < ev->audio_channels_count; i++)
908 if (ev->audio_channels[i].id == channel)
910 _player_send_cmd(ev, EM_CMD_AUDIO_TRACK_SET);
911 _player_send_int(ev, channel);
918 em_audio_channel_get(void *data)
920 Emotion_Generic_Video *ev = data;
921 return ev->audio_channel_current;
925 em_audio_channel_name_get(void *data, int channel)
927 Emotion_Generic_Video *ev = data;
930 for (i = 0; i < ev->audio_channels_count; i++)
932 if (ev->audio_channels[i].id == channel)
933 return ev->audio_channels[i].name;
940 em_audio_channel_mute_set(void *data, int mute)
942 Emotion_Generic_Video *ev = data;
943 _player_send_cmd(ev, EM_CMD_AUDIO_MUTE_SET);
944 _player_send_int(ev, mute);
945 ev->audio_mute = !!mute;
949 em_audio_channel_mute_get(void *data)
951 Emotion_Generic_Video *ev = data;
952 return ev->audio_mute;
956 em_audio_channel_volume_set(void *data, double vol)
958 Emotion_Generic_Video *ev = data;
961 if (vol > 1.0) vol = 1.0;
962 if (vol < 0.0) vol = 0.0;
965 _player_send_cmd(ev, EM_CMD_VOLUME_SET);
966 _player_send_float(ev, fvol);
972 em_audio_channel_volume_get(void *data)
974 Emotion_Generic_Video *ev = data;
979 em_spu_channel_count(void *ef __UNUSED__)
985 em_spu_channel_set(void *ef __UNUSED__, int channel __UNUSED__)
990 em_spu_channel_get(void *ef __UNUSED__)
997 em_spu_channel_name_get(void *ef __UNUSED__, int channel __UNUSED__)
1003 em_spu_channel_mute_set(void *ef __UNUSED__, int mute __UNUSED__)
1009 em_spu_channel_mute_get(void *ef __UNUSED__)
1015 em_chapter_count(void *ef __UNUSED__)
1022 em_chapter_set(void *ef __UNUSED__, int chapter __UNUSED__)
1027 em_chapter_get(void *ef __UNUSED__)
1034 em_chapter_name_get(void *ef __UNUSED__, int chapter __UNUSED__)
1040 em_speed_set(void *data, double speed)
1042 Emotion_Generic_Video *ev = data;
1045 _player_send_cmd(ev, EM_CMD_SPEED_SET);
1046 _player_send_float(ev, rate);
1052 em_speed_get(void *data)
1054 Emotion_Generic_Video *ev = data;
1055 return (double)ev->speed;
1059 em_eject(void *ef __UNUSED__)
1065 em_meta_get(void *ef __UNUSED__, int meta __UNUSED__)
1067 char * meta_data = NULL;
1071 static Emotion_Video_Module em_module =
1074 em_shutdown, /* shutdown */
1075 em_file_open, /* file_open */
1076 em_file_close, /* file_close */
1079 em_size_get, /* size_get */
1080 em_pos_set, /* pos_set */
1081 em_len_get, /* len_get */
1082 em_fps_num_get, /* fps_num_get */
1083 em_fps_den_get, /* fps_den_get */
1084 em_fps_get, /* fps_get */
1085 em_pos_get, /* pos_get */
1086 em_vis_set, /* vis_set */
1087 em_vis_get, /* vis_get */
1088 em_vis_supported, /* vis_supported */
1089 em_ratio_get, /* ratio_get */
1090 em_video_handled, /* video_handled */
1091 em_audio_handled, /* audio_handled */
1092 em_seekable, /* seekable */
1093 em_frame_done, /* frame_done */
1094 em_format_get, /* format_get */
1095 em_video_data_size_get, /* video_data_size_get */
1096 em_yuv_rows_get, /* yuv_rows_get */
1097 em_bgra_data_get, /* bgra_data_get */
1098 em_event_feed, /* event_feed */
1099 em_event_mouse_button_feed, /* event_mouse_button_feed */
1100 em_event_mouse_move_feed, /* event_mouse_move_feed */
1101 em_video_channel_count, /* video_channel_count */
1102 em_video_channel_set, /* video_channel_set */
1103 em_video_channel_get, /* video_channel_get */
1104 em_video_channel_name_get, /* video_channel_name_get */
1105 em_video_channel_mute_set, /* video_channel_mute_set */
1106 em_video_channel_mute_get, /* video_channel_mute_get */
1107 em_audio_channel_count, /* audio_channel_count */
1108 em_audio_channel_set, /* audio_channel_set */
1109 em_audio_channel_get, /* audio_channel_get */
1110 em_audio_channel_name_get, /* audio_channel_name_get */
1111 em_audio_channel_mute_set, /* audio_channel_mute_set */
1112 em_audio_channel_mute_get, /* audio_channel_mute_get */
1113 em_audio_channel_volume_set, /* audio_channel_volume_set */
1114 em_audio_channel_volume_get, /* audio_channel_volume_get */
1115 em_spu_channel_count, /* spu_channel_count */
1116 em_spu_channel_set, /* spu_channel_set */
1117 em_spu_channel_get, /* spu_channel_get */
1118 em_spu_channel_name_get, /* spu_channel_name_get */
1119 em_spu_channel_mute_set, /* spu_channel_mute_set */
1120 em_spu_channel_mute_get, /* spu_channel_mute_get */
1121 em_chapter_count, /* chapter_count */
1122 em_chapter_set, /* chapter_set */
1123 em_chapter_get, /* chapter_get */
1124 em_chapter_name_get, /* chapter_name_get */
1125 em_speed_set, /* speed_set */
1126 em_speed_get, /* speed_get */
1127 em_eject, /* eject */
1128 em_meta_get, /* meta_get */
1133 module_open(Evas_Object *obj, const Emotion_Video_Module **module, void **video, Emotion_Module_Options *opt)
1139 if (_emotion_generic_log_domain < 0)
1141 eina_threads_init();
1142 eina_log_threads_enable();
1143 _emotion_generic_log_domain = eina_log_domain_register
1144 ("emotion-generic", EINA_COLOR_LIGHTCYAN);
1145 if (_emotion_generic_log_domain < 0)
1147 EINA_LOG_CRIT("Could not register log domain 'emotion-generic'");
1153 if (!em_module.init(obj, video, opt)) {
1157 *module = &em_module;
1162 static void module_close(Emotion_Video_Module *module __UNUSED__, void *video)
1164 em_module.shutdown(video);
1169 generic_module_init(void)
1173 pfx = eina_prefix_new(NULL, emotion_object_add,
1174 "EMOTION", "emotion", NULL,
1179 if (!pfx) return EINA_FALSE;
1181 return _emotion_module_register("generic", module_open, module_close);
1185 generic_module_shutdown(void)
1189 eina_prefix_free(pfx);
1192 _emotion_module_unregister("generic");
1195 #ifndef EMOTION_STATIC_BUILD_GENERIC
1197 EINA_MODULE_INIT(generic_module_init);
1198 EINA_MODULE_SHUTDOWN(generic_module_shutdown);