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;
65 unsigned char play : 1;
66 unsigned char seek : 1;
67 unsigned char seeking : 1;
87 const char *time_seek;
90 Emotion_Module_Options module_options;
93 static void _mouse_move(void *data, Evas *ev, Evas_Object *obj, void *event_info);
94 static void _mouse_down(void *data, Evas *ev, Evas_Object *obj, void *event_info);
95 static void _pos_set_job(void *data);
96 static void _pixels_get(void *data, Evas_Object *obj);
98 static void _smart_init(void);
99 static void _smart_add(Evas_Object * obj);
100 static void _smart_del(Evas_Object * obj);
101 static void _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y);
102 static void _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h);
103 static void _smart_show(Evas_Object * obj);
104 static void _smart_hide(Evas_Object * obj);
105 static void _smart_color_set(Evas_Object * obj, int r, int g, int b, int a);
106 static void _smart_clip_set(Evas_Object * obj, Evas_Object * clip);
107 static void _smart_clip_unset(Evas_Object * obj);
109 /**********************************/
110 /* Globals for the E Video Object */
111 /**********************************/
112 static Evas_Smart *smart = NULL;
113 static Eina_Hash *_backends = NULL;
114 static Eina_Array *_modules = NULL;
115 static int _log_domain = -1;
117 static const char *_backend_priority[] = {
123 static const char SIG_FRAME_DECODE[] = "frame_decode";
124 static const char SIG_POSITION_UPDATE[] = "position_update";
125 static const char SIG_LENGTH_CHANGE[] = "length_change";
126 static const char SIG_FRAME_RESIZE[] = "frame_resize";
127 static const char SIG_DECODE_STOP[] = "decode_stop";
128 static const char SIG_PLAYBACK_STARTED[] = "playback_started";
129 static const char SIG_PLAYBACK_FINISHED[] = "playback_finished";
130 static const char SIG_AUDIO_LEVEL_CHANGE[] = "audio_level_change";
131 static const char SIG_CHANNELS_CHANGE[] = "channels_change";
132 static const char SIG_TITLE_CHANGE[] = "title_change";
133 static const char SIG_PROGRESS_CHANGE[] = "progress_change";
134 static const char SIG_REF_CHANGE[] = "ref_change";
135 static const char SIG_BUTTON_NUM_CHANGE[] = "button_num_change";
136 static const char SIG_BUTTON_CHANGE[] = "button_change";
137 static const char SIG_OPEN_DONE[] = "open_done";
138 static const Evas_Smart_Cb_Description _smart_callbacks[] = {
139 {SIG_FRAME_DECODE, ""},
140 {SIG_POSITION_UPDATE, ""},
141 {SIG_LENGTH_CHANGE, ""},
142 {SIG_FRAME_RESIZE, ""},
143 {SIG_DECODE_STOP, ""},
144 {SIG_PLAYBACK_STARTED, ""},
145 {SIG_PLAYBACK_FINISHED, ""},
146 {SIG_AUDIO_LEVEL_CHANGE, ""},
147 {SIG_CHANNELS_CHANGE, ""},
148 {SIG_TITLE_CHANGE, ""},
149 {SIG_PROGRESS_CHANGE, ""},
150 {SIG_REF_CHANGE, ""},
151 {SIG_BUTTON_NUM_CHANGE, ""},
152 {SIG_BUTTON_CHANGE, ""},
158 _emotion_image_data_zero(Evas_Object *img)
162 data = evas_object_image_data_get(img, 1);
168 evas_object_image_size_get(img, &w, &h);
169 cs = evas_object_image_colorspace_get(img);
170 if (cs == EVAS_COLORSPACE_ARGB8888)
172 if ((cs == EVAS_COLORSPACE_YCBCR422P601_PL) ||
173 (cs == EVAS_COLORSPACE_YCBCR422P709_PL))
174 sz = h * 2 * sizeof(unsigned char *);
175 if (sz != 0) memset(data, 0, sz);
177 evas_object_image_data_set(img, data);
181 _emotion_module_close(Emotion_Video_Module *mod, void *video)
184 if (mod->plugin->close && video)
185 mod->plugin->close(mod, video);
186 /* FIXME: we can't go dlclosing here as a thread still may be running from
187 * the module - this in theory will leak- but it shouldnt be too bad and
188 * mean that once a module is dlopened() it cant be closed - its refcount
189 * will just keep going up
194 _smart_data_free(Smart_Data *sd)
196 if (sd->video) sd->module->file_close(sd->video);
197 _emotion_module_close(sd->module, sd->video);
198 evas_object_del(sd->obj);
199 eina_stringshare_del(sd->file);
200 free(sd->module_name);
201 if (sd->job) ecore_job_del(sd->job);
202 free(sd->progress.info);
210 _emotion_module_register(const char *name, Emotion_Module_Open mod_open, Emotion_Module_Close mod_close)
212 Eina_Emotion_Plugins *plugin;
214 plugin = malloc(sizeof (Eina_Emotion_Plugins));
215 if (!plugin) return EINA_FALSE;
217 plugin->open = mod_open;
218 plugin->close = mod_close;
220 return eina_hash_add(_backends, name, plugin);
224 _emotion_module_unregister(const char *name)
226 return eina_hash_del(_backends, name, NULL);
230 _emotion_module_open(const char *name, Evas_Object *obj, Emotion_Video_Module **mod, void **video)
232 Eina_Emotion_Plugins *plugin;
236 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
239 ERR("No backend loaded");
243 if (!name && getenv("EMOTION_ENGINE"))
244 name = getenv("EMOTION_ENGINE");
246 /* FIXME: Always look for a working backend. */
249 name = _backend_priority[i++];
251 plugin = eina_hash_find(_backends, name);
254 if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*)))
257 ERR("No backend loaded");
261 if (plugin->open(obj, (const Emotion_Video_Module **) mod, video, &(sd->module_options)))
265 (*mod)->plugin = plugin;
270 if (i != 0 && i < (sizeof (_backend_priority) / sizeof (char*)))
273 ERR("Unable to load module: %s", name);
278 /*******************************/
279 /* Externally accessible calls */
280 /*******************************/
285 emotion_object_add(Evas *evas)
288 return evas_object_smart_add(evas, smart);
292 emotion_object_module_option_set(Evas_Object *obj, const char *opt, const char *val)
296 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
297 if ((!opt) || (!val)) return;
298 if (!strcmp(opt, "video"))
300 if (!strcmp(val, "off")) sd->module_options.no_video = EINA_TRUE;
302 else if (!strcmp(opt, "audio"))
304 if (!strcmp(val, "off")) sd->module_options.no_audio = EINA_TRUE;
309 emotion_object_init(Evas_Object *obj, const char *module_filename)
314 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
316 if ((sd->module_name) && module_filename && (!strcmp(sd->module_name, module_filename)))
318 free(sd->module_name);
319 sd->module_name = NULL;
326 free(sd->progress.info);
327 sd->progress.info = NULL;
328 sd->progress.stat = 0.0;
332 sd->spu.button_num = 0;
339 _emotion_module_close(sd->module, sd->video);
343 module_filename = _emotion_module_open(module_filename, obj, &sd->module, &sd->video);
344 if (!module_filename)
347 sd->module_name = strdup(module_filename);
351 emotion_object_file_set(obj, file);
352 eina_stringshare_del(file);
359 emotion_object_file_set(Evas_Object *obj, const char *file)
363 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EINA_FALSE);
365 DBG("file=%s", file);
366 if (!sd->module) return EINA_FALSE;
368 if ((file) && (sd->file) && (file == sd->file || !strcmp(file, sd->file))) return EINA_FALSE;
369 if ((file) && (file[0] != 0))
373 eina_stringshare_replace(&sd->file, file);
374 sd->module->file_close(sd->video);
375 evas_object_image_data_set(sd->obj, NULL);
376 evas_object_image_size_set(sd->obj, 1, 1);
377 if (!sd->module->file_open(sd->file, obj, sd->video))
379 sd->module->size_get(sd->video, &w, &h);
380 evas_object_image_size_set(sd->obj, w, h);
381 _emotion_image_data_zero(sd->obj);
382 sd->ratio = sd->module->ratio_get(sd->video);
384 if (sd->play) sd->module->play(sd->video, 0.0);
388 if (sd->video && sd->module)
390 sd->module->file_close(sd->video);
391 evas_object_image_data_set(sd->obj, NULL);
392 evas_object_image_size_set(sd->obj, 1, 1);
393 _emotion_image_data_zero(sd->obj);
395 eina_stringshare_replace(&sd->file, NULL);
399 /* Only cancel the load_xattr or we will loose ref to time_seek stringshare */
400 if (sd->load_xattr) eio_file_cancel(sd->load_xattr);
401 sd->load_xattr = NULL;
408 emotion_object_file_get(const Evas_Object *obj)
412 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
417 emotion_object_play_set(Evas_Object *obj, Eina_Bool play)
421 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
422 DBG("play=%hhu, was=%hhu", play, sd->play);
423 if (play == sd->play) return;
424 if (!sd->module) return;
425 if (!sd->video) return;
427 if (sd->play) sd->module->play(sd->video, sd->pos);
428 else sd->module->stop(sd->video);
432 emotion_object_play_get(const Evas_Object *obj)
436 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
437 if (!sd->video) return EINA_FALSE;
443 emotion_object_position_set(Evas_Object *obj, double sec)
447 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
449 if (!sd->module) return;
450 if (!sd->video) return;
453 sd->pos = sd->seek_pos;
454 if (sd->job) ecore_job_del(sd->job);
455 sd->job = ecore_job_add(_pos_set_job, obj);
459 emotion_object_position_get(const Evas_Object *obj)
463 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
464 if (!sd->module) return 0.0;
465 if (!sd->video) return 0.0;
466 if (!sd->module->pos_get) return 0.0;
467 sd->pos = sd->module->pos_get(sd->video);
472 emotion_object_seekable_get(const Evas_Object *obj)
476 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
477 if (!sd->module) return EINA_FALSE;
478 if (!sd->video) return EINA_FALSE;
479 return sd->module->seekable(sd->video);
483 emotion_object_video_handled_get(const Evas_Object *obj)
487 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
488 if (!sd->module) return EINA_FALSE;
489 if (!sd->video) return EINA_FALSE;
490 return sd->module->video_handled(sd->video);
494 emotion_object_audio_handled_get(const Evas_Object *obj)
498 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
499 if (!sd->module) return EINA_FALSE;
500 if (!sd->video) return EINA_FALSE;
501 return sd->module->audio_handled(sd->video);
505 emotion_object_play_length_get(const Evas_Object *obj)
509 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
510 if (!sd->module) return 0.0;
511 if (!sd->video) return 0.0;
512 sd->len = sd->module->len_get(sd->video);
517 emotion_object_size_get(const Evas_Object *obj, int *iw, int *ih)
523 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
524 evas_object_image_size_get(sd->obj, iw, ih);
528 * Sets whether to use of high-quality image scaling algorithm
529 * of the given video object.
531 * When enabled, a higher quality video scaling algorithm is used when
532 * scaling videos to sizes other than the source video. This gives
533 * better results but is more computationally expensive.
535 * @param obj The given video object.
536 * @param smooth Whether to use smooth scale or not.
539 emotion_object_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
543 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
544 evas_object_image_smooth_scale_set(sd->obj, smooth);
548 * Gets whether the high-quality image scaling algorithm
549 * of the given video object is used.
551 * @return Whether the smooth scale is used or not.
554 emotion_object_smooth_scale_get(const Evas_Object *obj)
558 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
559 return evas_object_image_smooth_scale_get(sd->obj);
563 emotion_object_ratio_get(const Evas_Object *obj)
567 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0);
568 if (!sd->module) return 0.0;
569 if (!sd->video) return 0.0;
574 * Send a control event to the DVD.
577 emotion_object_event_simple_send(Evas_Object *obj, Emotion_Event ev)
581 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
582 if (!sd->module) return;
583 if (!sd->video) return;
584 sd->module->event_feed(sd->video, ev);
588 emotion_object_audio_volume_set(Evas_Object *obj, double vol)
592 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
594 if (!sd->module) return;
595 if (!sd->video) return;
596 sd->module->audio_channel_volume_set(sd->video, vol);
600 emotion_object_audio_volume_get(const Evas_Object *obj)
604 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0);
605 if (!sd->module) return 0.0;
606 if (!sd->video) return 0.0;
607 return sd->module->audio_channel_volume_get(sd->video);
611 emotion_object_audio_mute_set(Evas_Object *obj, Eina_Bool mute)
615 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
616 DBG("mute=%hhu", mute);
617 if (!sd->module) return;
618 if (!sd->video) return;
619 sd->module->audio_channel_mute_set(sd->video, mute);
623 emotion_object_audio_mute_get(const Evas_Object *obj)
627 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
628 if (!sd->module) return EINA_FALSE;
629 if (!sd->video) return EINA_FALSE;
630 return sd->module->audio_channel_mute_get(sd->video);
634 emotion_object_audio_channel_count(const Evas_Object *obj)
638 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
639 if (!sd->module) return 0;
640 if (!sd->video) return 0;
641 return sd->module->audio_channel_count(sd->video);
645 emotion_object_audio_channel_name_get(const Evas_Object *obj, int channel)
649 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
650 if (!sd->module) return NULL;
651 if (!sd->video) return NULL;
652 return sd->module->audio_channel_name_get(sd->video, channel);
656 emotion_object_audio_channel_set(Evas_Object *obj, int channel)
660 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
661 DBG("channel=%d", channel);
662 if (!sd->module) return;
663 if (!sd->video) return;
664 sd->module->audio_channel_set(sd->video, channel);
668 emotion_object_audio_channel_get(const Evas_Object *obj)
672 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
673 if (!sd->module) return 0;
674 if (!sd->video) return 0;
675 return sd->module->audio_channel_get(sd->video);
679 emotion_object_video_mute_set(Evas_Object *obj, Eina_Bool mute)
683 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
684 DBG("mute=%hhu", mute);
685 if (!sd->module) return;
686 if (!sd->video) return;
687 sd->module->video_channel_mute_set(sd->video, mute);
691 emotion_object_video_mute_get(const Evas_Object *obj)
695 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
696 if (!sd->module) return EINA_FALSE;
697 if (!sd->video) return EINA_FALSE;
698 return sd->module->video_channel_mute_get(sd->video);
702 emotion_object_video_channel_count(const Evas_Object *obj)
706 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
707 if (!sd->module) return EINA_FALSE;
708 if (!sd->video) return EINA_FALSE;
709 return sd->module->video_channel_count(sd->video);
713 emotion_object_video_channel_name_get(const Evas_Object *obj, int channel)
717 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
718 if (!sd->module) return NULL;
719 if (!sd->video) return NULL;
720 return sd->module->video_channel_name_get(sd->video, channel);
724 emotion_object_video_channel_set(Evas_Object *obj, int channel)
728 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
729 DBG("channel=%d", channel);
730 if (!sd->module) return;
731 if (!sd->video) return;
732 sd->module->video_channel_set(sd->video, channel);
736 emotion_object_video_channel_get(const Evas_Object *obj)
740 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
741 if (!sd->module) return 0;
742 if (!sd->video) return 0;
743 return sd->module->video_channel_get(sd->video);
747 emotion_object_spu_mute_set(Evas_Object *obj, Eina_Bool mute)
751 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
752 DBG("mute=%hhu", mute);
753 if (!sd->module) return;
754 if (!sd->video) return;
755 sd->module->spu_channel_mute_set(sd->video, mute);
759 emotion_object_spu_mute_get(const Evas_Object *obj)
763 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
764 if (!sd->module) return EINA_FALSE;
765 if (!sd->video) return EINA_FALSE;
766 return sd->module->spu_channel_mute_get(sd->video);
770 emotion_object_spu_channel_count(const Evas_Object *obj)
774 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
775 if (!sd->module) return 0;
776 if (!sd->video) return 0;
777 return sd->module->spu_channel_count(sd->video);
781 emotion_object_spu_channel_name_get(const Evas_Object *obj, int channel)
785 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
786 if (!sd->module) return NULL;
787 if (!sd->video) return NULL;
788 return sd->module->spu_channel_name_get(sd->video, channel);
792 emotion_object_spu_channel_set(Evas_Object *obj, int channel)
796 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
797 DBG("channel=%d", channel);
798 if (!sd->module) return;
799 if (!sd->video) return;
800 sd->module->spu_channel_set(sd->video, channel);
804 emotion_object_spu_channel_get(const Evas_Object *obj)
808 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
809 if (!sd->module) return 0;
810 if (!sd->video) return 0;
811 return sd->module->spu_channel_get(sd->video);
815 emotion_object_chapter_count(const Evas_Object *obj)
819 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
820 if (!sd->module) return 0;
821 if (!sd->video) return 0;
822 return sd->module->chapter_count(sd->video);
826 emotion_object_chapter_set(Evas_Object *obj, int chapter)
830 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
831 DBG("chapter=%d", chapter);
832 if (!sd->module) return;
833 if (!sd->video) return;
834 sd->module->chapter_set(sd->video, chapter);
838 emotion_object_chapter_get(const Evas_Object *obj)
842 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
843 if (!sd->module) return 0;
844 if (!sd->video) return 0;
845 return sd->module->chapter_get(sd->video);
849 emotion_object_chapter_name_get(const Evas_Object *obj, int chapter)
853 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
854 if (!sd->module) return NULL;
855 if (!sd->video) return NULL;
856 return sd->module->chapter_name_get(sd->video, chapter);
860 emotion_object_play_speed_set(Evas_Object *obj, double speed)
864 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
865 DBG("speed=%f", speed);
866 if (!sd->module) return;
867 if (!sd->video) return;
868 sd->module->speed_set(sd->video, speed);
872 emotion_object_play_speed_get(const Evas_Object *obj)
876 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
877 if (!sd->module) return 0.0;
878 if (!sd->video) return 0.0;
879 return sd->module->speed_get(sd->video);
883 emotion_object_eject(Evas_Object *obj)
887 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
888 if (!sd->module) return;
889 if (!sd->video) return;
890 sd->module->eject(sd->video);
894 emotion_object_title_get(const Evas_Object *obj)
898 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
903 emotion_object_progress_info_get(const Evas_Object *obj)
907 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
908 return sd->progress.info;
912 emotion_object_progress_status_get(const Evas_Object *obj)
916 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
917 return sd->progress.stat;
921 emotion_object_ref_file_get(const Evas_Object *obj)
925 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
930 emotion_object_ref_num_get(const Evas_Object *obj)
934 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
939 emotion_object_spu_button_count_get(const Evas_Object *obj)
943 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
944 return sd->spu.button_num;
948 emotion_object_spu_button_get(const Evas_Object *obj)
952 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
953 return sd->spu.button;
957 emotion_object_meta_info_get(const Evas_Object *obj, Emotion_Meta_Info meta)
961 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
962 if (!sd->module) return NULL;
963 if (!sd->video) return NULL;
966 case EMOTION_META_INFO_TRACK_TITLE:
967 return sd->module->meta_get(sd->video, META_TRACK_TITLE);
969 case EMOTION_META_INFO_TRACK_ARTIST:
970 return sd->module->meta_get(sd->video, META_TRACK_ARTIST);
972 case EMOTION_META_INFO_TRACK_ALBUM:
973 return sd->module->meta_get(sd->video, META_TRACK_ALBUM);
975 case EMOTION_META_INFO_TRACK_YEAR:
976 return sd->module->meta_get(sd->video, META_TRACK_YEAR);
978 case EMOTION_META_INFO_TRACK_GENRE:
979 return sd->module->meta_get(sd->video, META_TRACK_GENRE);
981 case EMOTION_META_INFO_TRACK_COMMENT:
982 return sd->module->meta_get(sd->video, META_TRACK_COMMENT);
984 case EMOTION_META_INFO_TRACK_DISC_ID:
985 return sd->module->meta_get(sd->video, META_TRACK_DISCID);
994 emotion_object_vis_set(Evas_Object *obj, Emotion_Vis visualization)
998 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
999 DBG("visualization=%d", visualization);
1000 if (!sd->module) return;
1001 if (!sd->video) return;
1002 if (!sd->module->vis_set) return;
1003 sd->module->vis_set(sd->video, visualization);
1007 emotion_object_vis_get(const Evas_Object *obj)
1011 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_VIS_NONE);
1012 if (!sd->module) return EMOTION_VIS_NONE;
1013 if (!sd->video) return EMOTION_VIS_NONE;
1014 if (!sd->module->vis_get) return EMOTION_VIS_NONE;
1015 return sd->module->vis_get(sd->video);
1019 emotion_object_vis_supported(const Evas_Object *obj, Emotion_Vis visualization)
1023 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1024 if (!sd->module) return EINA_FALSE;
1025 if (!sd->video) return EINA_FALSE;
1026 if (!sd->module->vis_supported) return EINA_FALSE;
1027 return sd->module->vis_supported(sd->video, visualization);
1032 _eio_load_xattr_cleanup(Smart_Data *sd, Eio_File *handler)
1034 if (handler == sd->load_xattr) sd->load_xattr = NULL;
1036 EINA_REFCOUNT_UNREF(sd)
1037 _smart_data_free(sd);
1041 _eio_load_xattr_done(void *data, Eio_File *handler, const char *xattr_data, unsigned int xattr_size)
1043 Smart_Data *sd = data;
1045 if (xattr_size < 128 && xattr_data[xattr_size] == '\0')
1047 long long int m = 0;
1050 eina_convert_atod(xattr_data, xattr_size, &m, &e);
1051 emotion_object_position_set(evas_object_smart_parent_get(sd->obj), ldexp((double)m, e));
1054 _eio_load_xattr_cleanup(sd, handler);
1058 _eio_load_xattr_error(void *data, Eio_File *handler, int err __UNUSED__)
1060 Smart_Data *sd = data;
1062 _eio_load_xattr_cleanup(sd, handler);
1067 emotion_object_last_position_load(Evas_Object *obj)
1072 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1073 if (!sd->file) return ;
1075 if (!strncmp(sd->file, "file://", 7))
1077 else if (!strstr(sd->file, "://"))
1083 if (sd->load_xattr) return ;
1085 EINA_REFCOUNT_REF(sd);
1087 sd->load_xattr = eio_file_xattr_get(tmp, "user.e.time_seek", _eio_load_xattr_done, _eio_load_xattr_error, sd);
1091 char double_to_string[128];
1093 long long int m = 0;
1096 sz = getxattr(tmp, "user.e.time_seek", double_to_string, 128);
1097 if (sz <= 0 || sz > 128 || double_to_string[sz] != '\0')
1100 eina_convert_atod(double_to_string, 128, &m, &e);
1101 emotion_object_position_set(obj, ldexp((double)m, e));
1109 _eio_save_xattr_cleanup(Smart_Data *sd)
1111 sd->save_xattr = NULL;
1112 eina_stringshare_del(sd->time_seek);
1113 sd->time_seek = NULL;
1115 EINA_REFCOUNT_UNREF(sd)
1116 _smart_data_free(sd);
1120 _eio_save_xattr_done(void *data, Eio_File *handler __UNUSED__)
1122 Smart_Data *sd = data;
1124 _eio_save_xattr_cleanup(sd);
1128 _eio_save_xattr_error(void *data, Eio_File *handler __UNUSED__, int err __UNUSED__)
1130 Smart_Data *sd = data;
1132 _eio_save_xattr_cleanup(sd);
1137 emotion_object_last_position_save(Evas_Object *obj)
1141 char double_to_string[128];
1143 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1144 if (!sd->file) return ;
1146 if (!strncmp(sd->file, "file://", 7))
1148 else if (!strstr(sd->file, "://"))
1153 eina_convert_dtoa(emotion_object_position_get(obj), double_to_string);
1156 if (sd->save_xattr) return ;
1158 EINA_REFCOUNT_REF(sd);
1160 sd->time_seek = eina_stringshare_add(double_to_string);
1161 sd->save_xattr = eio_file_xattr_set(tmp, "user.e.time_seek",
1162 sd->time_seek, eina_stringshare_strlen(sd->time_seek) + 1, 0,
1163 _eio_save_xattr_done, _eio_save_xattr_error, sd);
1166 setxattr(tmp, "user.e.time_seek", double_to_string, strlen(double_to_string), 0);
1172 emotion_object_extension_can_play_fast_get(const Evas_Object *obj, const char *file)
1174 const Smart_Data *sd;
1176 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1177 if (!sd->module) return EINA_FALSE;
1178 if (!sd->video) return EINA_FALSE;
1179 if (!sd->module->can_play_get) return EINA_FALSE;
1180 return sd->module->can_play_get(sd->video, file);
1184 emotion_object_extension_can_play_get(const Evas_Object *obj, const char *file)
1189 tmp = eina_stringshare_add(file);
1190 result = emotion_object_extension_can_play_fast_get(obj, tmp);
1191 eina_stringshare_del(tmp);
1197 emotion_object_extension_may_play_fast_get(const char *file)
1199 if (!file) return EINA_FALSE;
1200 return _emotion_object_extension_can_play_generic_get(NULL, file);
1204 emotion_object_extension_may_play_get(const char *file)
1209 if (!file) return EINA_FALSE;
1210 tmp = eina_stringshare_add(file);
1211 result = emotion_object_extension_may_play_fast_get(tmp);
1212 eina_stringshare_del(tmp);
1217 /*****************************/
1218 /* Utility calls for modules */
1219 /*****************************/
1223 unsigned int length;
1224 const char *extension;
1227 #define MATCHING(Ext) \
1228 { sizeof (Ext), Ext }
1230 static const struct ext_match_s matchs[] =
1231 { /* map extensions to know if it's a emotion playable content for good first-guess tries */
1282 _emotion_object_extension_can_play_generic_get(const void *data __UNUSED__, const char *file)
1284 unsigned int length;
1287 length = eina_stringshare_strlen(file) + 1;
1288 if (length < 5) return EINA_FALSE;
1290 for (i = 0; i < sizeof (matchs) / sizeof (struct ext_match_s); ++i)
1292 if (matchs[i].length > length) continue;
1294 if (!strcasecmp(matchs[i].extension,
1295 file + length - matchs[i].length))
1303 _emotion_video_get(const Evas_Object *obj)
1307 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1312 _emotion_frame_new(Evas_Object *obj)
1316 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1317 // printf("pix get set 1 %p\n", sd->obj);
1318 evas_object_image_pixels_dirty_set(sd->obj, 1);
1319 evas_object_smart_callback_call(obj, SIG_FRAME_DECODE, NULL);
1323 _emotion_video_pos_update(Evas_Object *obj, double pos, double len)
1326 int npos = 0, nlen = 0;
1328 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1329 if (pos != sd->pos) npos = 1;
1330 if (len != sd->len) nlen = 1;
1333 if (npos) evas_object_smart_callback_call(obj, SIG_POSITION_UPDATE, NULL);
1334 if (nlen) evas_object_smart_callback_call(obj, SIG_LENGTH_CHANGE, NULL);
1338 _emotion_frame_resize(Evas_Object *obj, int w, int h, double ratio)
1345 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1346 evas_object_image_size_get(sd->obj, &iw, &ih);
1347 if ((w != iw) || (h != ih))
1349 evas_object_image_size_set(sd->obj, w, h);
1350 _emotion_image_data_zero(sd->obj);
1353 if (h > 0) tmp = (double)w / (double)h;
1355 if (ratio != tmp) tmp = ratio;
1356 if (tmp != sd->ratio)
1363 evas_object_size_hint_request_set(obj, w, h);
1364 evas_object_smart_callback_call(obj, SIG_FRAME_RESIZE, NULL);
1369 _emotion_decode_stop(Evas_Object *obj)
1373 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1377 evas_object_smart_callback_call(obj, SIG_DECODE_STOP, NULL);
1382 _emotion_open_done(Evas_Object *obj)
1384 evas_object_smart_callback_call(obj, SIG_OPEN_DONE, NULL);
1388 _emotion_playback_started(Evas_Object *obj)
1390 evas_object_smart_callback_call(obj, SIG_PLAYBACK_STARTED, NULL);
1394 _emotion_playback_finished(Evas_Object *obj)
1396 evas_object_smart_callback_call(obj, SIG_PLAYBACK_FINISHED, NULL);
1400 _emotion_audio_level_change(Evas_Object *obj)
1402 evas_object_smart_callback_call(obj, SIG_AUDIO_LEVEL_CHANGE, NULL);
1406 _emotion_channels_change(Evas_Object *obj)
1410 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1411 evas_object_smart_callback_call(obj, SIG_CHANNELS_CHANGE, NULL);
1415 _emotion_title_set(Evas_Object *obj, char *title)
1419 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1421 sd->title = strdup(title);
1422 evas_object_smart_callback_call(obj, SIG_TITLE_CHANGE, NULL);
1426 _emotion_progress_set(Evas_Object *obj, char *info, double st)
1430 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1431 free(sd->progress.info);
1432 sd->progress.info = strdup(info);
1433 sd->progress.stat = st;
1434 evas_object_smart_callback_call(obj, SIG_PROGRESS_CHANGE, NULL);
1438 _emotion_file_ref_set(Evas_Object *obj, const char *file, int num)
1442 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1444 sd->ref.file = strdup(file);
1446 evas_object_smart_callback_call(obj, SIG_REF_CHANGE, NULL);
1450 _emotion_spu_button_num_set(Evas_Object *obj, int num)
1454 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1455 sd->spu.button_num = num;
1456 evas_object_smart_callback_call(obj, SIG_BUTTON_NUM_CHANGE, NULL);
1460 _emotion_spu_button_set(Evas_Object *obj, int button)
1464 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1465 sd->spu.button = button;
1466 evas_object_smart_callback_call(obj, SIG_BUTTON_CHANGE, NULL);
1470 _emotion_seek_done(Evas_Object *obj)
1474 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1478 if (sd->seek) emotion_object_position_set(obj, sd->seek_pos);
1484 /****************************/
1485 /* Internal object routines */
1486 /****************************/
1489 _mouse_move(void *data, Evas *ev __UNUSED__, Evas_Object *obj, void *event_info)
1491 Evas_Event_Mouse_Move *e;
1494 Evas_Coord ox, oy, ow, oh;
1498 if (!sd->module) return;
1499 if (!sd->video) return;
1500 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
1501 evas_object_image_size_get(obj, &iw, &ih);
1502 if ((iw < 1) || (ih < 1)) return;
1503 x = (((int)e->cur.canvas.x - ox) * iw) / ow;
1504 y = (((int)e->cur.canvas.y - oy) * ih) / oh;
1505 sd->module->event_mouse_move_feed(sd->video, x, y);
1509 _mouse_down(void *data, Evas *ev __UNUSED__, Evas_Object *obj, void *event_info)
1511 Evas_Event_Mouse_Down *e;
1514 Evas_Coord ox, oy, ow, oh;
1518 if (!sd->module) return;
1519 if (!sd->video) return;
1520 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
1521 evas_object_image_size_get(obj, &iw, &ih);
1522 if ((iw < 1) || (ih < 1)) return;
1523 x = (((int)e->canvas.x - ox) * iw) / ow;
1524 y = (((int)e->canvas.y - oy) * ih) / oh;
1525 sd->module->event_mouse_button_feed(sd->video, 1, x, y);
1529 _pos_set_job(void *data)
1535 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1537 if (sd->seeking) return;
1541 sd->module->pos_set(sd->video, sd->seek_pos);
1546 /* called by evas when it needs pixels for the image object */
1548 _pixels_get(void *data, Evas_Object *obj)
1552 Emotion_Format format;
1553 unsigned char *bgra_data;
1556 evas_object_image_size_get(obj, &iw, &ih);
1557 sd->module->video_data_size_get(sd->video, &w, &h);
1560 if ((w != iw) || (h != ih))
1562 evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
1563 evas_object_image_alpha_set(obj, 0);
1564 evas_object_image_size_set(obj, w, h);
1565 _emotion_image_data_zero(sd->obj);
1569 if ((iw < 1) || (ih < 1))
1571 // printf("pix get set 0 (1)\n");
1572 evas_object_image_pixels_dirty_set(obj, 0);
1576 format = sd->module->format_get(sd->video);
1577 if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420))
1579 unsigned char **rows;
1581 evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
1582 rows = evas_object_image_data_get(obj, 1);
1585 if (sd->module->yuv_rows_get(sd->video, iw, ih,
1588 &rows[ih + (ih / 2)]))
1589 evas_object_image_data_update_add(obj, 0, 0, iw, ih);
1591 evas_object_image_data_set(obj, rows);
1592 // printf("pix get set 0 (2)\n");
1593 evas_object_image_pixels_dirty_set(obj, 0);
1595 else if (format == EMOTION_FORMAT_BGRA)
1597 if (sd->module->bgra_data_get(sd->video, &bgra_data))
1599 evas_object_image_data_set(obj, bgra_data);
1600 // printf("pix get set 0 (3)\n");
1601 evas_object_image_pixels_dirty_set(obj, 0);
1605 // no need for this because on any new frame decode info from the decoder
1606 // module, the previous "current frame" is released (done) for us anyway
1607 // sd->module->frame_done(sd->video);
1610 evas_object_image_size_get(obj, &iw, &ih);
1611 sd->module->video_data_size_get(sd->video, &w, &h);
1612 if ((w != iw) || (h != ih))
1614 evas_object_image_size_set(obj, w, h);
1615 _emotion_image_data_zero(sd->obj);
1619 format = sd->module->format_get(sd->video);
1620 if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420))
1622 unsigned char **rows;
1623 Evas_Pixel_Import_Source ps;
1625 ps.format = EVAS_PIXEL_FORMAT_YUV420P_601;
1629 ps.rows = malloc(ps.h * 2 * sizeof(void *));
1632 sd->module->frame_done(sd->video);
1636 rows = (unsigned char **)ps.rows;
1638 if (sd->module->yuv_rows_get(sd->video, iw, ih,
1641 &rows[ps.h + (ps.h / 2)]))
1642 evas_object_image_pixels_import(obj, &ps);
1643 evas_object_image_pixels_dirty_set(obj, 0);
1646 else if (format == EMOTION_FORMAT_BGRA)
1648 if (sd->module->bgra_data_get(sd->video, &bgra_data));
1650 evas_object_image_data_set(obj, bgra_data);
1651 evas_object_image_pixels_dirty_set(obj, 0);
1654 sd->module->frame_done(sd->video);
1658 /*******************************************/
1659 /* Internal smart object required routines */
1660 /*******************************************/
1661 #ifdef EMOTION_STATIC_BUILD_XINE
1662 Eina_Bool xine_module_init(void);
1664 #ifdef EMOTION_STATIC_BUILD_VLC
1665 Eina_Bool vlc_module_init(void);
1667 #ifdef EMOTION_STATIC_BUILD_GSTREAMER
1668 Eina_Bool gstreamer_module_init(void);
1680 _log_domain = eina_log_domain_register("emotion", EINA_COLOR_LIGHTCYAN);
1681 if (_log_domain < 0)
1683 EINA_LOG_CRIT("Could not register log domain 'emotion'");
1688 _backends = eina_hash_string_small_new(free);
1690 _modules = eina_module_list_get(NULL, PACKAGE_LIB_DIR "/emotion/", 0, NULL, NULL);
1692 path = eina_module_environment_path_get("HOME", "/.emotion/");
1693 _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1694 if (path) free(path);
1696 path = eina_module_environment_path_get("EMOTION_MODULES_DIR", "/emotion/");
1697 _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1698 if (path) free(path);
1700 path = eina_module_symbol_path_get(emotion_object_add, "/emotion/");
1701 _modules = eina_module_list_get(_modules, path, 0, NULL, NULL);
1702 if (path) free(path);
1706 ERR("No module found!");
1710 eina_module_list_load(_modules);
1712 /* Init static module */
1713 #ifdef EMOTION_STATIC_BUILD_XINE
1716 #ifdef EMOTION_STATIC_BUILD_VLC
1719 #ifdef EMOTION_STATIC_BUILD_GSTREAMER
1720 gstreamer_module_init();
1723 static Evas_Smart_Class sc =
1724 EVAS_SMART_CLASS_INIT_NAME_VERSION(E_OBJ_NAME);
1727 sc.add = _smart_add;
1728 sc.del = _smart_del;
1729 sc.move = _smart_move;
1730 sc.resize = _smart_resize;
1731 sc.show = _smart_show;
1732 sc.hide = _smart_hide;
1733 sc.color_set = _smart_color_set;
1734 sc.clip_set = _smart_clip_set;
1735 sc.clip_unset = _smart_clip_unset;
1736 sc.callbacks = _smart_callbacks;
1738 smart = evas_smart_class_new(&sc);
1743 _smart_add(Evas_Object * obj)
1746 unsigned int *pixel;
1748 sd = calloc(1, sizeof(Smart_Data));
1750 EINA_REFCOUNT_INIT(sd);
1751 sd->obj = evas_object_image_add(evas_object_evas_get(obj));
1752 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, sd);
1753 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, sd);
1754 evas_object_image_pixels_get_callback_set(sd->obj, _pixels_get, sd);
1755 evas_object_smart_member_add(sd->obj, obj);
1757 sd->spu.button = -1;
1758 evas_object_image_alpha_set(sd->obj, 0);
1759 pixel = evas_object_image_data_get(sd->obj, 1);
1762 *pixel = 0xff000000;
1763 evas_object_image_data_set(obj, pixel);
1765 evas_object_smart_data_set(obj, sd);
1771 _smart_del(Evas_Object * obj)
1775 sd = evas_object_smart_data_get(obj);
1777 EINA_REFCOUNT_UNREF(sd)
1778 _smart_data_free(sd);
1782 _smart_move(Evas_Object * obj, Evas_Coord x, Evas_Coord y)
1786 sd = evas_object_smart_data_get(obj);
1788 evas_object_move(sd->obj, x, y);
1792 _smart_resize(Evas_Object * obj, Evas_Coord w, Evas_Coord h)
1796 sd = evas_object_smart_data_get(obj);
1798 evas_object_image_fill_set(sd->obj, 0, 0, w, h);
1799 evas_object_resize(sd->obj, w, h);
1803 _smart_show(Evas_Object * obj)
1807 sd = evas_object_smart_data_get(obj);
1809 evas_object_show(sd->obj);
1814 _smart_hide(Evas_Object * obj)
1818 sd = evas_object_smart_data_get(obj);
1820 evas_object_hide(sd->obj);
1824 _smart_color_set(Evas_Object * obj, int r, int g, int b, int a)
1828 sd = evas_object_smart_data_get(obj);
1830 evas_object_color_set(sd->obj, r, g, b, a);
1834 _smart_clip_set(Evas_Object * obj, Evas_Object * clip)
1838 sd = evas_object_smart_data_get(obj);
1840 evas_object_clip_set(sd->obj, clip);
1844 _smart_clip_unset(Evas_Object * obj)
1848 sd = evas_object_smart_data_get(obj);
1850 evas_object_clip_unset(sd->obj);
1854 _emotion_image_get(const Evas_Object *obj)
1858 sd = evas_object_smart_data_get(obj);
1859 if (!sd) return NULL;