1 #include "emotion_private.h"
10 # include <sys/xattr.h>
14 #define E_SMART_OBJ_GET(smart, o, type) \
19 smart = evas_object_smart_data_get(o); \
21 _e_smart_str = (char *)evas_object_type_get(o); \
22 if (!_e_smart_str) return; \
23 if (strcmp(_e_smart_str, type)) return; \
26 #define E_SMART_OBJ_GET_RETURN(smart, o, type, ret) \
31 smart = evas_object_smart_data_get(o); \
32 if (!smart) return ret; \
33 _e_smart_str = (char *)evas_object_type_get(o); \
34 if (!_e_smart_str) return ret; \
35 if (strcmp(_e_smart_str, type)) return ret; \
38 #define DBG(...) EINA_LOG_DOM_DBG(_log_domain, __VA_ARGS__)
39 #define INF(...) EINA_LOG_DOM_INFO(_log_domain, __VA_ARGS__)
40 #define WRN(...) EINA_LOG_DOM_WARN(_log_domain, __VA_ARGS__)
41 #define ERR(...) EINA_LOG_DOM_ERR(_log_domain, __VA_ARGS__)
42 #define CRITICAL(...) EINA_LOG_DOM_CRIT(_log_domain, __VA_ARGS__)
44 #define E_OBJ_NAME "emotion_object"
46 typedef struct _Smart_Data Smart_Data;
51 Emotion_Video_Module *module;
67 const char *time_seek;
88 Emotion_Module_Options module_options;
90 Emotion_Suspend state;
94 Eina_Bool seeking : 1;
97 static void _mouse_move(void *data, Evas *ev, Evas_Object *obj, void *event_info);
98 static void _mouse_down(void *data, Evas *ev, Evas_Object *obj, void *event_info);
99 static void _pos_set_job(void *data);
100 static void _pixels_get(void *data, Evas_Object *obj);
102 static void _smart_init(void);
103 static void _smart_add(Evas_Object * obj);
104 static void _smart_del(Evas_Object * obj);
105 static void _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y);
106 static void _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h);
107 static void _smart_show(Evas_Object * obj);
108 static void _smart_hide(Evas_Object * obj);
109 static void _smart_color_set(Evas_Object * obj, int r, int g, int b, int a);
110 static void _smart_clip_set(Evas_Object * obj, Evas_Object * clip);
111 static void _smart_clip_unset(Evas_Object * obj);
113 /**********************************/
114 /* Globals for the E Video Object */
115 /**********************************/
116 static Evas_Smart *smart = NULL;
117 static Eina_Hash *_backends = NULL;
118 static Eina_Array *_modules = NULL;
119 static int _log_domain = -1;
121 static const char *_backend_priority[] = {
127 static const char SIG_FRAME_DECODE[] = "frame_decode";
128 static const char SIG_POSITION_UPDATE[] = "position_update";
129 static const char SIG_LENGTH_CHANGE[] = "length_change";
130 static const char SIG_FRAME_RESIZE[] = "frame_resize";
131 static const char SIG_DECODE_STOP[] = "decode_stop";
132 static const char SIG_PLAYBACK_STARTED[] = "playback_started";
133 static const char SIG_PLAYBACK_FINISHED[] = "playback_finished";
134 static const char SIG_AUDIO_LEVEL_CHANGE[] = "audio_level_change";
135 static const char SIG_CHANNELS_CHANGE[] = "channels_change";
136 static const char SIG_TITLE_CHANGE[] = "title_change";
137 static const char SIG_PROGRESS_CHANGE[] = "progress_change";
138 static const char SIG_REF_CHANGE[] = "ref_change";
139 static const char SIG_BUTTON_NUM_CHANGE[] = "button_num_change";
140 static const char SIG_BUTTON_CHANGE[] = "button_change";
141 static const char SIG_OPEN_DONE[] = "open_done";
142 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
143 {SIG_FRAME_DECODE, ""},
144 {SIG_POSITION_UPDATE, ""},
145 {SIG_LENGTH_CHANGE, ""},
146 {SIG_FRAME_RESIZE, ""},
147 {SIG_DECODE_STOP, ""},
148 {SIG_PLAYBACK_STARTED, ""},
149 {SIG_PLAYBACK_FINISHED, ""},
150 {SIG_AUDIO_LEVEL_CHANGE, ""},
151 {SIG_CHANNELS_CHANGE, ""},
152 {SIG_TITLE_CHANGE, ""},
153 {SIG_PROGRESS_CHANGE, ""},
154 {SIG_REF_CHANGE, ""},
155 {SIG_BUTTON_NUM_CHANGE, ""},
156 {SIG_BUTTON_CHANGE, ""},
162 _emotion_image_data_zero(Evas_Object *img)
166 data = evas_object_image_data_get(img, 1);
172 evas_object_image_size_get(img, &w, &h);
173 cs = evas_object_image_colorspace_get(img);
174 if (cs == EVAS_COLORSPACE_ARGB8888)
176 if ((cs == EVAS_COLORSPACE_YCBCR422P601_PL) ||
177 (cs == EVAS_COLORSPACE_YCBCR422P709_PL))
178 sz = h * 2 * sizeof(unsigned char *);
179 if (sz != 0) memset(data, 0, sz);
181 evas_object_image_data_set(img, data);
185 _emotion_module_close(Emotion_Video_Module *mod, void *video)
188 if (mod->plugin->close && video)
189 mod->plugin->close(mod, video);
190 /* FIXME: we can't go dlclosing here as a thread still may be running from
191 * the module - this in theory will leak- but it shouldn't be too bad and
192 * mean that once a module is dlopened() it can't be closed - its refcount
193 * will just keep going up
198 _smart_data_free(Smart_Data *sd)
200 if (sd->video) sd->module->file_close(sd->video);
201 _emotion_module_close(sd->module, sd->video);
202 evas_object_del(sd->obj);
203 eina_stringshare_del(sd->file);
204 free(sd->module_name);
205 if (sd->job) ecore_job_del(sd->job);
206 free(sd->progress.info);
214 _emotion_module_register(const char *name, Emotion_Module_Open mod_open, Emotion_Module_Close mod_close)
216 Eina_Emotion_Plugins *plugin;
218 plugin = malloc(sizeof (Eina_Emotion_Plugins));
219 if (!plugin) return EINA_FALSE;
221 plugin->open = mod_open;
222 plugin->close = mod_close;
224 return eina_hash_add(_backends, name, plugin);
228 _emotion_module_unregister(const char *name)
230 return eina_hash_del(_backends, name, NULL);
234 _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module **mod, void **video)
236 Eina_Emotion_Plugins *plugin;
240 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
243 ERR("No backend loaded");
247 if (!name && getenv("EMOTION_ENGINE"))
248 name = getenv("EMOTION_ENGINE");
250 /* FIXME: Always look for a working backend. */
253 name = _backend_priority[i++];
255 plugin = eina_hash_find(_backends, name);
258 if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*)))
261 ERR("No backend loaded");
265 if (plugin->open(obj, (const Emotion_Video_Module **) mod, video, &(sd->module_options)))
269 (*mod)->plugin = plugin;
274 if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*)))
277 ERR("Unable to load module: %s", name);
282 /*******************************/
283 /* Externally accessible calls */
284 /*******************************/
289 emotion_object_add(Evas *evas)
292 return evas_object_smart_add(evas, smart);
296 emotion_object_module_option_set(Evas_Object *obj, const char *opt, const char *val)
300 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
301 if ((!opt) || (!val)) return;
302 if (!strcmp(opt, "video"))
304 if (!strcmp(val, "off")) sd->module_options.no_video = EINA_TRUE;
306 else if (!strcmp(opt, "audio"))
308 if (!strcmp(val, "off")) sd->module_options.no_audio = EINA_TRUE;
313 emotion_object_init(Evas_Object *obj, const char *module_filename)
318 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
320 if ((sd->module_name) && module_filename && (!strcmp(sd->module_name, module_filename)))
322 free(sd->module_name);
323 sd->module_name = NULL;
330 free(sd->progress.info);
331 sd->progress.info = NULL;
332 sd->progress.stat = 0.0;
336 sd->spu.button_num = 0;
343 _emotion_module_close(sd->module, sd->video);
347 module_filename = _emotion_module_open(module_filename, obj, &sd->module, &sd->video);
348 if (!module_filename)
351 sd->module_name = strdup(module_filename);
355 emotion_object_file_set(obj, file);
356 eina_stringshare_del(file);
363 emotion_object_file_set(Evas_Object *obj, const char *file)
367 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EINA_FALSE);
369 DBG("file=%s", file);
370 if (!sd->module) return EINA_FALSE;
372 if ((file) && (sd->file) && (file == sd->file || !strcmp(file, sd->file))) return EINA_FALSE;
373 if ((file) && (file[0] != 0))
377 eina_stringshare_replace(&sd->file, file);
378 sd->module->file_close(sd->video);
379 evas_object_image_data_set(sd->obj, NULL);
380 evas_object_image_size_set(sd->obj, 1, 1);
381 if (!sd->module->file_open(sd->file, obj, sd->video))
383 sd->module->size_get(sd->video, &w, &h);
384 evas_object_image_size_set(sd->obj, w, h);
385 _emotion_image_data_zero(sd->obj);
386 sd->ratio = sd->module->ratio_get(sd->video);
388 if (sd->play) sd->module->play(sd->video, 0.0);
392 if (sd->video && sd->module)
394 sd->module->file_close(sd->video);
395 evas_object_image_data_set(sd->obj, NULL);
396 evas_object_image_size_set(sd->obj, 1, 1);
397 _emotion_image_data_zero(sd->obj);
399 eina_stringshare_replace(&sd->file, NULL);
403 /* Only cancel the load_xattr or we will loose ref to time_seek stringshare */
404 if (sd->load_xattr) eio_file_cancel(sd->load_xattr);
405 sd->load_xattr = NULL;
412 emotion_object_file_get(const Evas_Object *obj)
416 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
421 emotion_object_play_set(Evas_Object *obj, Eina_Bool play)
425 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
426 DBG("play=%hhu, was=%hhu", play, sd->play);
427 if (play == sd->play) return;
428 if (!sd->module) return;
429 if (!sd->video) return;
431 if (sd->state != EMOTION_WAKEUP) emotion_object_suspend_set(obj, EMOTION_WAKEUP);
432 if (sd->play) sd->module->play(sd->video, sd->pos);
433 else sd->module->stop(sd->video);
437 emotion_object_play_get(const Evas_Object *obj)
441 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
442 if (!sd->video) return EINA_FALSE;
448 emotion_object_position_set(Evas_Object *obj, double sec)
452 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
454 if (!sd->module) return;
455 if (!sd->video) return;
458 sd->pos = sd->seek_pos;
459 if (sd->job) ecore_job_del(sd->job);
460 sd->job = ecore_job_add(_pos_set_job, obj);
464 emotion_object_position_get(const Evas_Object *obj)
468 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
469 if (!sd->module) return 0.0;
470 if (!sd->video) return 0.0;
471 if (!sd->module->pos_get) return 0.0;
472 sd->pos = sd->module->pos_get(sd->video);
477 emotion_object_seekable_get(const Evas_Object *obj)
481 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
482 if (!sd->module) return EINA_FALSE;
483 if (!sd->video) return EINA_FALSE;
484 return sd->module->seekable(sd->video);
488 emotion_object_video_handled_get(const Evas_Object *obj)
492 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
493 if (!sd->module) return EINA_FALSE;
494 if (!sd->video) return EINA_FALSE;
495 return sd->module->video_handled(sd->video);
499 emotion_object_audio_handled_get(const Evas_Object *obj)
503 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
504 if (!sd->module) return EINA_FALSE;
505 if (!sd->video) return EINA_FALSE;
506 return sd->module->audio_handled(sd->video);
510 emotion_object_play_length_get(const Evas_Object *obj)
514 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
515 if (!sd->module) return 0.0;
516 if (!sd->video) return 0.0;
517 sd->len = sd->module->len_get(sd->video);
522 emotion_object_size_get(const Evas_Object *obj, int *iw, int *ih)
528 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
529 evas_object_image_size_get(sd->obj, iw, ih);
533 emotion_object_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
537 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
538 evas_object_image_smooth_scale_set(sd->obj, smooth);
542 emotion_object_smooth_scale_get(const Evas_Object *obj)
546 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
547 return evas_object_image_smooth_scale_get(sd->obj);
551 emotion_object_ratio_get(const Evas_Object *obj)
555 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0);
556 if (!sd->module) return 0.0;
557 if (!sd->video) return 0.0;
562 * Send a control event to the DVD.
565 emotion_object_event_simple_send(Evas_Object *obj, Emotion_Event ev)
569 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
570 if (!sd->module) return;
571 if (!sd->video) return;
572 sd->module->event_feed(sd->video, ev);
576 emotion_object_audio_volume_set(Evas_Object *obj, double vol)
580 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
582 if (!sd->module) return;
583 if (!sd->video) return;
584 sd->module->audio_channel_volume_set(sd->video, vol);
588 emotion_object_audio_volume_get(const Evas_Object *obj)
592 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0);
593 if (!sd->module) return 0.0;
594 if (!sd->video) return 0.0;
595 return sd->module->audio_channel_volume_get(sd->video);
599 emotion_object_audio_mute_set(Evas_Object *obj, Eina_Bool mute)
603 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
604 DBG("mute=%hhu", mute);
605 if (!sd->module) return;
606 if (!sd->video) return;
607 sd->module->audio_channel_mute_set(sd->video, mute);
611 emotion_object_audio_mute_get(const Evas_Object *obj)
615 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
616 if (!sd->module) return EINA_FALSE;
617 if (!sd->video) return EINA_FALSE;
618 return sd->module->audio_channel_mute_get(sd->video);
622 emotion_object_audio_channel_count(const Evas_Object *obj)
626 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
627 if (!sd->module) return 0;
628 if (!sd->video) return 0;
629 return sd->module->audio_channel_count(sd->video);
633 emotion_object_audio_channel_name_get(const Evas_Object *obj, int channel)
637 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
638 if (!sd->module) return NULL;
639 if (!sd->video) return NULL;
640 return sd->module->audio_channel_name_get(sd->video, channel);
644 emotion_object_audio_channel_set(Evas_Object *obj, int channel)
648 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
649 DBG("channel=%d", channel);
650 if (!sd->module) return;
651 if (!sd->video) return;
652 sd->module->audio_channel_set(sd->video, channel);
656 emotion_object_audio_channel_get(const Evas_Object *obj)
660 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
661 if (!sd->module) return 0;
662 if (!sd->video) return 0;
663 return sd->module->audio_channel_get(sd->video);
667 emotion_object_video_mute_set(Evas_Object *obj, Eina_Bool mute)
671 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
672 DBG("mute=%hhu", mute);
673 if (!sd->module) return;
674 if (!sd->video) return;
675 sd->module->video_channel_mute_set(sd->video, mute);
679 emotion_object_video_mute_get(const Evas_Object *obj)
683 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
684 if (!sd->module) return EINA_FALSE;
685 if (!sd->video) return EINA_FALSE;
686 return sd->module->video_channel_mute_get(sd->video);
690 emotion_object_video_channel_count(const Evas_Object *obj)
694 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
695 if (!sd->module) return EINA_FALSE;
696 if (!sd->video) return EINA_FALSE;
697 return sd->module->video_channel_count(sd->video);
701 emotion_object_video_channel_name_get(const Evas_Object *obj, int channel)
705 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
706 if (!sd->module) return NULL;
707 if (!sd->video) return NULL;
708 return sd->module->video_channel_name_get(sd->video, channel);
712 emotion_object_video_channel_set(Evas_Object *obj, int channel)
716 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
717 DBG("channel=%d", channel);
718 if (!sd->module) return;
719 if (!sd->video) return;
720 sd->module->video_channel_set(sd->video, channel);
724 emotion_object_video_channel_get(const Evas_Object *obj)
728 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
729 if (!sd->module) return 0;
730 if (!sd->video) return 0;
731 return sd->module->video_channel_get(sd->video);
735 emotion_object_spu_mute_set(Evas_Object *obj, Eina_Bool mute)
739 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
740 DBG("mute=%hhu", mute);
741 if (!sd->module) return;
742 if (!sd->video) return;
743 sd->module->spu_channel_mute_set(sd->video, mute);
747 emotion_object_spu_mute_get(const Evas_Object *obj)
751 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
752 if (!sd->module) return EINA_FALSE;
753 if (!sd->video) return EINA_FALSE;
754 return sd->module->spu_channel_mute_get(sd->video);
758 emotion_object_spu_channel_count(const Evas_Object *obj)
762 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
763 if (!sd->module) return 0;
764 if (!sd->video) return 0;
765 return sd->module->spu_channel_count(sd->video);
769 emotion_object_spu_channel_name_get(const Evas_Object *obj, int channel)
773 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
774 if (!sd->module) return NULL;
775 if (!sd->video) return NULL;
776 return sd->module->spu_channel_name_get(sd->video, channel);
780 emotion_object_spu_channel_set(Evas_Object *obj, int channel)
784 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
785 DBG("channel=%d", channel);
786 if (!sd->module) return;
787 if (!sd->video) return;
788 sd->module->spu_channel_set(sd->video, channel);
792 emotion_object_spu_channel_get(const Evas_Object *obj)
796 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
797 if (!sd->module) return 0;
798 if (!sd->video) return 0;
799 return sd->module->spu_channel_get(sd->video);
803 emotion_object_chapter_count(const Evas_Object *obj)
807 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
808 if (!sd->module) return 0;
809 if (!sd->video) return 0;
810 return sd->module->chapter_count(sd->video);
814 emotion_object_chapter_set(Evas_Object *obj, int chapter)
818 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
819 DBG("chapter=%d", chapter);
820 if (!sd->module) return;
821 if (!sd->video) return;
822 sd->module->chapter_set(sd->video, chapter);
826 emotion_object_chapter_get(const Evas_Object *obj)
830 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
831 if (!sd->module) return 0;
832 if (!sd->video) return 0;
833 return sd->module->chapter_get(sd->video);
837 emotion_object_chapter_name_get(const Evas_Object *obj, int chapter)
841 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
842 if (!sd->module) return NULL;
843 if (!sd->video) return NULL;
844 return sd->module->chapter_name_get(sd->video, chapter);
848 emotion_object_play_speed_set(Evas_Object *obj, double speed)
852 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
853 DBG("speed=%f", speed);
854 if (!sd->module) return;
855 if (!sd->video) return;
856 sd->module->speed_set(sd->video, speed);
860 emotion_object_play_speed_get(const Evas_Object *obj)
864 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
865 if (!sd->module) return 0.0;
866 if (!sd->video) return 0.0;
867 return sd->module->speed_get(sd->video);
871 emotion_object_eject(Evas_Object *obj)
875 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
876 if (!sd->module) return;
877 if (!sd->video) return;
878 sd->module->eject(sd->video);
882 emotion_object_title_get(const Evas_Object *obj)
886 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
891 emotion_object_progress_info_get(const Evas_Object *obj)
895 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
896 return sd->progress.info;
900 emotion_object_progress_status_get(const Evas_Object *obj)
904 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
905 return sd->progress.stat;
909 emotion_object_ref_file_get(const Evas_Object *obj)
913 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
918 emotion_object_ref_num_get(const Evas_Object *obj)
922 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
927 emotion_object_spu_button_count_get(const Evas_Object *obj)
931 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
932 return sd->spu.button_num;
936 emotion_object_spu_button_get(const Evas_Object *obj)
940 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
941 return sd->spu.button;
945 emotion_object_meta_info_get(const Evas_Object *obj, Emotion_Meta_Info meta)
949 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
950 if (!sd->module) return NULL;
951 if (!sd->video) return NULL;
954 case EMOTION_META_INFO_TRACK_TITLE:
955 return sd->module->meta_get(sd->video, META_TRACK_TITLE);
957 case EMOTION_META_INFO_TRACK_ARTIST:
958 return sd->module->meta_get(sd->video, META_TRACK_ARTIST);
960 case EMOTION_META_INFO_TRACK_ALBUM:
961 return sd->module->meta_get(sd->video, META_TRACK_ALBUM);
963 case EMOTION_META_INFO_TRACK_YEAR:
964 return sd->module->meta_get(sd->video, META_TRACK_YEAR);
966 case EMOTION_META_INFO_TRACK_GENRE:
967 return sd->module->meta_get(sd->video, META_TRACK_GENRE);
969 case EMOTION_META_INFO_TRACK_COMMENT:
970 return sd->module->meta_get(sd->video, META_TRACK_COMMENT);
972 case EMOTION_META_INFO_TRACK_DISC_ID:
973 return sd->module->meta_get(sd->video, META_TRACK_DISCID);
982 emotion_object_vis_set(Evas_Object *obj, Emotion_Vis visualization)
986 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
987 DBG("visualization=%d", visualization);
988 if (!sd->module) return;
989 if (!sd->video) return;
990 if (!sd->module->vis_set) return;
991 sd->module->vis_set(sd->video, visualization);
995 emotion_object_vis_get(const Evas_Object *obj)
999 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_VIS_NONE);
1000 if (!sd->module) return EMOTION_VIS_NONE;
1001 if (!sd->video) return EMOTION_VIS_NONE;
1002 if (!sd->module->vis_get) return EMOTION_VIS_NONE;
1003 return sd->module->vis_get(sd->video);
1007 emotion_object_vis_supported(const Evas_Object *obj, Emotion_Vis visualization)
1011 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1012 if (!sd->module) return EINA_FALSE;
1013 if (!sd->video) return EINA_FALSE;
1014 if (!sd->module->vis_supported) return EINA_FALSE;
1015 return sd->module->vis_supported(sd->video, visualization);
1020 _eio_load_xattr_cleanup(Smart_Data *sd, Eio_File *handler)
1022 if (handler == sd->load_xattr) sd->load_xattr = NULL;
1024 EINA_REFCOUNT_UNREF(sd)
1025 _smart_data_free(sd);
1029 _eio_load_xattr_done(void *data, Eio_File *handler, const char *xattr_data, unsigned int xattr_size)
1031 Smart_Data *sd = data;
1033 if (xattr_size < 128 && xattr_data[xattr_size - 1] == '\0')
1035 long long int m = 0;
1038 eina_convert_atod(xattr_data, xattr_size, &m, &e);
1039 emotion_object_position_set(evas_object_smart_parent_get(sd->obj), ldexp((double)m, e));
1042 _eio_load_xattr_cleanup(sd, handler);
1046 _eio_load_xattr_error(void *data, Eio_File *handler, int err __UNUSED__)
1048 Smart_Data *sd = data;
1050 _eio_load_xattr_cleanup(sd, handler);
1055 emotion_object_last_position_load(Evas_Object *obj)
1060 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1061 if (!sd->file) return ;
1063 if (!strncmp(sd->file, "file://", 7))
1065 else if (!strstr(sd->file, "://"))
1071 if (sd->load_xattr) return ;
1073 EINA_REFCOUNT_REF(sd);
1075 sd->load_xattr = eio_file_xattr_get(tmp, "user.e.time_seek", _eio_load_xattr_done, _eio_load_xattr_error, sd);
1079 char double_to_string[128];
1081 long long int m = 0;
1084 sz = getxattr(tmp, "user.e.time_seek", double_to_string, 128);
1085 if (sz <= 0 || sz > 128 || double_to_string[sz] != '\0')
1088 eina_convert_atod(double_to_string, 128, &m, &e);
1089 emotion_object_position_set(obj, ldexp((double)m, e));
1097 _eio_save_xattr_cleanup(Smart_Data *sd)
1099 sd->save_xattr = NULL;
1100 eina_stringshare_del(sd->time_seek);
1101 sd->time_seek = NULL;
1103 EINA_REFCOUNT_UNREF(sd)
1104 _smart_data_free(sd);
1108 _eio_save_xattr_done(void *data, Eio_File *handler __UNUSED__)
1110 Smart_Data *sd = data;
1112 _eio_save_xattr_cleanup(sd);
1116 _eio_save_xattr_error(void *data, Eio_File *handler __UNUSED__, int err __UNUSED__)
1118 Smart_Data *sd = data;
1120 _eio_save_xattr_cleanup(sd);
1125 emotion_object_last_position_save(Evas_Object *obj)
1129 char double_to_string[128];
1131 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1132 if (!sd->file) return ;
1134 if (!strncmp(sd->file, "file://", 7))
1136 else if (!strstr(sd->file, "://"))
1141 eina_convert_dtoa(emotion_object_position_get(obj), double_to_string);
1144 if (sd->save_xattr) return ;
1146 EINA_REFCOUNT_REF(sd);
1148 sd->time_seek = eina_stringshare_add(double_to_string);
1149 sd->save_xattr = eio_file_xattr_set(tmp, "user.e.time_seek",
1150 sd->time_seek, eina_stringshare_strlen(sd->time_seek) + 1, 0,
1151 _eio_save_xattr_done, _eio_save_xattr_error, sd);
1154 setxattr(tmp, "user.e.time_seek", double_to_string, strlen(double_to_string), 0);
1160 emotion_object_suspend_set(Evas_Object *obj, Emotion_Suspend state)
1164 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1167 case EMOTION_WAKEUP:
1168 /* Restore the rendering pipeline, offset and everything back to play again (this will be called automatically by play_set) */
1170 /* This destroy some part of the rendering pipeline */
1171 case EMOTION_DEEP_SLEEP:
1172 /* This destroy all the rendering pipeline and just keep the last rendered image (fullscreen) */
1173 case EMOTION_HIBERNATE:
1174 /* This destroy all the rendering pipeline and keep 1/4 of the last rendered image */
1182 EAPI Emotion_Suspend
1183 motion_object_suspend_get(Evas_Object *obj)
1187 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_WAKEUP);
1191 /*****************************/
1192 /* Utility calls for modules */
1193 /*****************************/
1196 _emotion_video_get(const Evas_Object *obj)
1200 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1205 _emotion_frame_new(Evas_Object *obj)
1209 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1210 // printf("pix get set 1 %p\n", sd->obj);
1211 evas_object_image_pixels_dirty_set(sd->obj, 1);
1212 evas_object_smart_callback_call(obj, SIG_FRAME_DECODE, NULL);
1216 _emotion_video_pos_update(Evas_Object *obj, double pos, double len)
1219 int npos = 0, nlen = 0;
1221 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1222 if (pos != sd->pos) npos = 1;
1223 if (len != sd->len) nlen = 1;
1226 if (npos) evas_object_smart_callback_call(obj, SIG_POSITION_UPDATE, NULL);
1227 if (nlen) evas_object_smart_callback_call(obj, SIG_LENGTH_CHANGE, NULL);
1231 _emotion_frame_resize(Evas_Object *obj, int w, int h, double ratio)
1238 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1239 evas_object_image_size_get(sd->obj, &iw, &ih);
1240 if ((w != iw) || (h != ih))
1242 evas_object_image_size_set(sd->obj, w, h);
1243 _emotion_image_data_zero(sd->obj);
1246 if (h > 0) tmp = (double)w / (double)h;
1248 if (ratio != tmp) tmp = ratio;
1249 if (tmp != sd->ratio)
1256 evas_object_size_hint_request_set(obj, w, h);
1257 evas_object_smart_callback_call(obj, SIG_FRAME_RESIZE, NULL);
1262 _emotion_decode_stop(Evas_Object *obj)
1266 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1270 evas_object_smart_callback_call(obj, SIG_DECODE_STOP, NULL);
1275 _emotion_open_done(Evas_Object *obj)
1277 evas_object_smart_callback_call(obj, SIG_OPEN_DONE, NULL);
1281 _emotion_playback_started(Evas_Object *obj)
1283 evas_object_smart_callback_call(obj, SIG_PLAYBACK_STARTED, NULL);
1287 _emotion_playback_finished(Evas_Object *obj)
1289 evas_object_smart_callback_call(obj, SIG_PLAYBACK_FINISHED, NULL);
1293 _emotion_audio_level_change(Evas_Object *obj)
1295 evas_object_smart_callback_call(obj, SIG_AUDIO_LEVEL_CHANGE, NULL);
1299 _emotion_channels_change(Evas_Object *obj)
1303 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1304 evas_object_smart_callback_call(obj, SIG_CHANNELS_CHANGE, NULL);
1308 _emotion_title_set(Evas_Object *obj, char *title)
1312 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1314 sd->title = strdup(title);
1315 evas_object_smart_callback_call(obj, SIG_TITLE_CHANGE, NULL);
1319 _emotion_progress_set(Evas_Object *obj, char *info, double st)
1323 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1324 free(sd->progress.info);
1325 sd->progress.info = strdup(info);
1326 sd->progress.stat = st;
1327 evas_object_smart_callback_call(obj, SIG_PROGRESS_CHANGE, NULL);
1331 _emotion_file_ref_set(Evas_Object *obj, const char *file, int num)
1335 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1337 sd->ref.file = strdup(file);
1339 evas_object_smart_callback_call(obj, SIG_REF_CHANGE, NULL);
1343 _emotion_spu_button_num_set(Evas_Object *obj, int num)
1347 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1348 sd->spu.button_num = num;
1349 evas_object_smart_callback_call(obj, SIG_BUTTON_NUM_CHANGE, NULL);
1353 _emotion_spu_button_set(Evas_Object *obj, int button)
1357 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1358 sd->spu.button = button;
1359 evas_object_smart_callback_call(obj, SIG_BUTTON_CHANGE, NULL);
1363 _emotion_seek_done(Evas_Object *obj)
1367 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1371 if (sd->seek) emotion_object_position_set(obj, sd->seek_pos);
1377 /****************************/
1378 /* Internal object routines */
1379 /****************************/
1382 _mouse_move(void *data, Evas *ev __UNUSED__, Evas_Object *obj, void *event_info)
1384 Evas_Event_Mouse_Move *e;
1387 Evas_Coord ox, oy, ow, oh;
1391 if (!sd->module) return;
1392 if (!sd->video) return;
1393 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
1394 evas_object_image_size_get(obj, &iw, &ih);
1395 if ((iw < 1) || (ih < 1)) return;
1396 x = (((int)e->cur.canvas.x - ox) * iw) / ow;
1397 y = (((int)e->cur.canvas.y - oy) * ih) / oh;
1398 sd->module->event_mouse_move_feed(sd->video, x, y);
1402 _mouse_down(void *data, Evas *ev __UNUSED__, Evas_Object *obj, void *event_info)
1404 Evas_Event_Mouse_Down *e;
1407 Evas_Coord ox, oy, ow, oh;
1411 if (!sd->module) return;
1412 if (!sd->video) return;
1413 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
1414 evas_object_image_size_get(obj, &iw, &ih);
1415 if ((iw < 1) || (ih < 1)) return;
1416 x = (((int)e->canvas.x - ox) * iw) / ow;
1417 y = (((int)e->canvas.y - oy) * ih) / oh;
1418 sd->module->event_mouse_button_feed(sd->video, 1, x, y);
1422 _pos_set_job(void *data)
1428 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1430 if (sd->seeking) return;
1434 sd->module->pos_set(sd->video, sd->seek_pos);
1439 /* called by evas when it needs pixels for the image object */
1441 _pixels_get(void *data, Evas_Object *obj)
1445 Emotion_Format format;
1446 unsigned char *bgra_data;
1449 evas_object_image_size_get(obj, &iw, &ih);
1450 sd->module->video_data_size_get(sd->video, &w, &h);
1453 if ((w != iw) || (h != ih))
1455 evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
1456 evas_object_image_alpha_set(obj, 0);
1457 evas_object_image_size_set(obj, w, h);
1458 _emotion_image_data_zero(sd->obj);
1462 if ((iw < 1) || (ih < 1))
1464 // printf("pix get set 0 (1)\n");
1465 evas_object_image_pixels_dirty_set(obj, 0);
1469 format = sd->module->format_get(sd->video);
1470 if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420))
1472 unsigned char **rows;
1474 evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
1475 rows = evas_object_image_data_get(obj, 1);
1478 if (sd->module->yuv_rows_get(sd->video, iw, ih,
1481 &rows[ih + (ih / 2)]))
1482 evas_object_image_data_update_add(obj, 0, 0, iw, ih);
1484 evas_object_image_data_set(obj, rows);
1485 // printf("pix get set 0 (2)\n");
1486 evas_object_image_pixels_dirty_set(obj, 0);
1488 else if (format == EMOTION_FORMAT_BGRA)
1490 if (sd->module->bgra_data_get(sd->video, &bgra_data))
1492 evas_object_image_data_set(obj, bgra_data);
1493 // printf("pix get set 0 (3)\n");
1494 evas_object_image_pixels_dirty_set(obj, 0);
1498 // no need for this because on any new frame decode info from the decoder
1499 // module, the previous "current frame" is released (done) for us anyway
1500 // sd->module->frame_done(sd->video);
1503 evas_object_image_size_get(obj, &iw, &ih);
1504 sd->module->video_data_size_get(sd->video, &w, &h);
1505 if ((w != iw) || (h != ih))
1507 evas_object_image_size_set(obj, w, h);
1508 _emotion_image_data_zero(sd->obj);
1512 format = sd->module->format_get(sd->video);
1513 if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420))
1515 unsigned char **rows;
1516 Evas_Pixel_Import_Source ps;
1518 ps.format = EVAS_PIXEL_FORMAT_YUV420P_601;
1522 ps.rows = malloc(ps.h * 2 * sizeof(void *));
1525 sd->module->frame_done(sd->video);
1529 rows = (unsigned char **)ps.rows;
1531 if (sd->module->yuv_rows_get(sd->video, iw, ih,
1534 &rows[ps.h + (ps.h / 2)]))
1535 evas_object_image_pixels_import(obj, &ps);
1536 evas_object_image_pixels_dirty_set(obj, 0);
1539 else if (format == EMOTION_FORMAT_BGRA)
1541 if (sd->module->bgra_data_get(sd->video, &bgra_data));
1543 evas_object_image_data_set(obj, bgra_data);
1544 evas_object_image_pixels_dirty_set(obj, 0);
1547 sd->module->frame_done(sd->video);
1551 /*******************************************/
1552 /* Internal smart object required routines */
1553 /*******************************************/
1554 #ifdef EMOTION_STATIC_BUILD_XINE
1555 Eina_Bool xine_module_init(void);
1557 #ifdef EMOTION_STATIC_BUILD_VLC
1558 Eina_Bool vlc_module_init(void);
1560 #ifdef EMOTION_STATIC_BUILD_GSTREAMER
1561 Eina_Bool gstreamer_module_init(void);
1573 _log_domain = eina_log_domain_register("emotion", EINA_COLOR_LIGHTCYAN);
1574 if (_log_domain < 0)
1576 EINA_LOG_CRIT("Could not register log domain 'emotion'");
1581 _backends = eina_hash_string_small_new(free);
1583 _modules = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/emotion/", 0, NULL, NULL);
1585 path = eina_module_environment_path_get("HOME", "/.emotion/");
1586 _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1587 if (path) free(path);
1589 path = eina_module_environment_path_get("EMOTION_MODULES_DIR", "/emotion/");
1590 _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1591 if (path) free(path);
1593 path = eina_module_symbol_path_get(emotion_object_add, "/emotion/");
1594 _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1595 if (path) free(path);
1599 ERR("No module found!");
1603 eina_module_list_load(_modules);
1605 /* Init static module */
1606 #ifdef EMOTION_STATIC_BUILD_XINE
1609 #ifdef EMOTION_STATIC_BUILD_VLC
1612 #ifdef EMOTION_STATIC_BUILD_GSTREAMER
1613 gstreamer_module_init();
1616 static Evas_Smart_Class sc =
1617 EVAS_SMART_CLASS_INIT_NAME_VERSION(E_OBJ_NAME);
1620 sc.add = _smart_add;
1621 sc.del = _smart_del;
1622 sc.move = _smart_move;
1623 sc.resize = _smart_resize;
1624 sc.show = _smart_show;
1625 sc.hide = _smart_hide;
1626 sc.color_set = _smart_color_set;
1627 sc.clip_set = _smart_clip_set;
1628 sc.clip_unset = _smart_clip_unset;
1629 sc.callbacks = _smart_callbacks;
1631 smart = evas_smart_class_new(&sc);
1636 _smart_add(Evas_Object * obj)
1639 unsigned int *pixel;
1641 sd = calloc(1, sizeof(Smart_Data));
1643 EINA_REFCOUNT_INIT(sd);
1644 sd->state = EMOTION_WAKEUP;
1645 sd->obj = evas_object_image_add(evas_object_evas_get(obj));
1646 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, sd);
1647 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, sd);
1648 evas_object_image_pixels_get_callback_set(sd->obj, _pixels_get, sd);
1649 evas_object_smart_member_add(sd->obj, obj);
1651 sd->spu.button = -1;
1652 evas_object_image_alpha_set(sd->obj, 0);
1653 pixel = evas_object_image_data_get(sd->obj, 1);
1656 *pixel = 0xff000000;
1657 evas_object_image_data_set(obj, pixel);
1659 evas_object_smart_data_set(obj, sd);
1665 _smart_del(Evas_Object * obj)
1669 sd = evas_object_smart_data_get(obj);
1671 EINA_REFCOUNT_UNREF(sd)
1672 _smart_data_free(sd);
1676 _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y)
1680 sd = evas_object_smart_data_get(obj);
1682 evas_object_move(sd->obj, x, y);
1686 _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h)
1690 sd = evas_object_smart_data_get(obj);
1692 evas_object_image_fill_set(sd->obj, 0, 0, w, h);
1693 evas_object_resize(sd->obj, w, h);
1697 _smart_show(Evas_Object * obj)
1701 sd = evas_object_smart_data_get(obj);
1703 evas_object_show(sd->obj);
1708 _smart_hide(Evas_Object * obj)
1712 sd = evas_object_smart_data_get(obj);
1714 evas_object_hide(sd->obj);
1718 _smart_color_set(Evas_Object * obj, int r, int g, int b, int a)
1722 sd = evas_object_smart_data_get(obj);
1724 evas_object_color_set(sd->obj, r, g, b, a);
1728 _smart_clip_set(Evas_Object * obj, Evas_Object * clip)
1732 sd = evas_object_smart_data_get(obj);
1734 evas_object_clip_set(sd->obj, clip);
1738 _smart_clip_unset(Evas_Object * obj)
1742 sd = evas_object_smart_data_get(obj);
1744 evas_object_clip_unset(sd->obj);
1748 _emotion_image_get(const Evas_Object *obj)
1752 sd = evas_object_smart_data_get(obj);
1753 if (!sd) return NULL;