1 #ifdef HAVE_CONFIG_H
2 # include "config.h"
3 #endif
4
5 #define EFL_CANVAS_OBJECT_PROTECTED
6 #define EFL_CANVAS_GROUP_PROTECTED
7
8 #include <Evas.h>
9 #include <Ecore.h>
10
11 #ifdef HAVE_EIO
12 # include <math.h>
13 # include <Eio.h>
14 #endif
15
16 #define EFL_INTERNAL_UNSTABLE
17 #include <Evas_Internal.h>
18
19 #include "Emotion.h"
20 #include "emotion_private.h"
21
22 #include "canvas/evas_canvas_eo.h"
23
24 #ifdef _WIN32
25 # define FMT_UCHAR "%c"
26 #else
27 # define FMT_UCHAR "%hhu"
28 #endif
29
30 #define E_SMART_OBJ_GET(smart, o, type) \
31 { \
32 if (!o) return; \
33 if (!efl_isa(o, MY_CLASS)) { \
34 ERR("Tried calling on a non-emotion object."); \
35 return; \
36 } \
37 smart = efl_data_scope_get(o, MY_CLASS); \
38 if (!smart) return; \
39 }
40
41 #define E_SMART_OBJ_GET_RETURN(smart, o, type, ret) \
42 { \
43 if (!o) return ret; \
44 if (!efl_isa(o, MY_CLASS)) { \
45 ERR("Tried calling on a non-emotion object."); \
46 return ret; \
47 } \
48 smart = efl_data_scope_get(o, MY_CLASS); \
49 if (!smart) return ret; \
50 }
51
52 #define E_OBJ_NAME "efl_canvas_video"
53
54 #ifdef MY_CLASS
55 # undef MY_CLASS
56 #endif
57
58 #define MY_CLASS EFL_CANVAS_VIDEO_CLASS
59
60 typedef struct _Efl_Canvas_Video_Data Efl_Canvas_Video_Data;
61 typedef struct _Emotion_Xattr_Data Emotion_Xattr_Data;
62
63 struct _Efl_Canvas_Video_Data
64 {
65 Emotion_Engine_Instance *engine_instance;
66
67 const char *engine;
68 const char *file;
69 Evas_Object *obj;
70 Evas_Object *bg;
71
72 Ecore_Job *job;
73
74 Emotion_Xattr_Data *xattr;
75
76 const char *title;
77
78 struct {
79 const char *info;
80 double stat;
81 } progress;
82 struct {
83 const char *file;
84 int num;
85 } ref;
86 struct {
87 int button_num;
88 int button;
89 } spu;
90 struct {
91 int l; /* left */
92 int r; /* right */
93 int t; /* top */
94 int b; /* bottom */
95 Evas_Object *clipper;
96 } crop;
97
98 struct {
99 int w, h;
100 } video;
101 struct {
102 double w, h;
103 } fill;
104
105 double ratio;
106 double pos;
107 double remember_jump;
108 double seek_pos;
109 double len;
110
111 Emotion_Module_Options module_options;
112
113 Emotion_Suspend state;
114 Emotion_Aspect aspect;
115
116 Ecore_Animator *anim;
117
118 Eina_Bool open : 1;
119 Eina_Bool play : 1;
120 Eina_Bool pause : 1;
121 Eina_Bool remember_play : 1;
122 Eina_Bool seek : 1;
123 Eina_Bool seeking : 1;
124 Eina_Bool loaded : 1;
125 };
126
127 struct _Emotion_Xattr_Data
128 {
129 EINA_REFCOUNT;
130 Eo *obj_wref;
131 #ifdef HAVE_EIO
132 Eio_File *load;
133 Eio_File *save;
134 #endif
135 };
136
137 static void _mouse_move(void *data, Evas *ev, Evas_Object *obj, void *event_info);
138 static void _mouse_down(void *data, Evas *ev, Evas_Object *obj, void *event_info);
139 static void _pos_set_job(void *data);
140 static void _pixels_get(void *data, Evas_Object *obj);
141
142 static void
_engine_init(Eo * obj,Efl_Canvas_Video_Data * sd)143 _engine_init(Eo *obj, Efl_Canvas_Video_Data *sd)
144 {
145 if (sd->engine_instance) return;
146 sd->engine_instance = emotion_engine_instance_new(sd->engine, obj,
147 &(sd->module_options));
148 }
149
150 static void
_emotion_image_data_zero(Evas_Object * img)151 _emotion_image_data_zero(Evas_Object *img)
152 {
153 void *data = NULL;
154
155 data = evas_object_image_data_get(img, 1);
156 if (data)
157 {
158 int w, h, sz = 0;
159 Evas_Colorspace cs;
160
161 evas_object_image_size_get(img, &w, &h);
162 cs = evas_object_image_colorspace_get(img);
163 if (cs == EVAS_COLORSPACE_ARGB8888)
164 sz = w * h * 4;
165 if ((cs == EVAS_COLORSPACE_YCBCR422P601_PL) ||
166 (cs == EVAS_COLORSPACE_YCBCR422P709_PL))
167 sz = h * 2 * sizeof(unsigned char *);
168 if (sz != 0) memset(data, 0, sz);
169 }
170 evas_object_image_data_set(img, data);
171 }
172
173 static void
_xattr_data_cancel(Emotion_Xattr_Data * xattr)174 _xattr_data_cancel(Emotion_Xattr_Data *xattr)
175 {
176 (void) xattr;
177 #ifdef HAVE_EIO
178 /* Only cancel the load_xattr or we will loose ref to time_seek stringshare */
179 if (xattr->load) eio_file_cancel(xattr->load);
180 xattr->load = NULL;
181 if (xattr->save) eio_file_cancel(xattr->save);
182 xattr->save = NULL;
183 #endif
184 }
185
186 static void
_xattr_data_unref(Emotion_Xattr_Data * xattr)187 _xattr_data_unref(Emotion_Xattr_Data *xattr)
188 {
189 EINA_REFCOUNT_UNREF(xattr) {} else return;
190
191 _xattr_data_cancel(xattr);
192 efl_wref_del_safe(&xattr->obj_wref);
193 free(xattr);
194 }
195
196 static void
_clipper_position_size_update(Evas_Object * obj,int x,int y,int w,int h,int vid_w,int vid_h)197 _clipper_position_size_update(Evas_Object *obj, int x, int y, int w, int h, int vid_w, int vid_h)
198 {
199 Efl_Canvas_Video_Data *sd;
200 double scale_w, scale_h;
201
202 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
203
204 if (vid_w == 0 || vid_h == 0)
205 {
206 evas_object_image_fill_set(sd->obj, 0, 0, 0, 0);
207 evas_object_move(sd->obj, x, y);
208 evas_object_resize(sd->obj, 0, 0);
209 if (!sd->crop.clipper) return;
210 evas_object_move(sd->crop.clipper, x, y);
211 evas_object_resize(sd->crop.clipper, 0, 0);
212 }
213 else
214 {
215 scale_w = (double)w / (double)(vid_w - sd->crop.l - sd->crop.r);
216 scale_h = (double)h / (double)(vid_h - sd->crop.t - sd->crop.b);
217
218 if (sd->fill.w < 0 && sd->fill.h < 0)
219 evas_object_image_fill_set(sd->obj, 0, 0, vid_w * scale_w, vid_h * scale_h);
220 else
221 evas_object_image_fill_set(sd->obj, 0, 0, sd->fill.w * w, sd->fill.h * h);
222 evas_object_resize(sd->obj, vid_w * scale_w, vid_h * scale_h);
223 evas_object_move(sd->obj, x - sd->crop.l * scale_w, y - sd->crop.t * scale_h);
224 if (!sd->crop.clipper) return;
225 evas_object_move(sd->crop.clipper, x, y);
226 evas_object_resize(sd->crop.clipper, w, h);
227 }
228 }
229
230 /*******************************/
231 /* Externally accessible calls */
232 /*******************************/
233
234
235
236 EAPI Evas_Object *
emotion_object_add(Evas * evas)237 emotion_object_add(Evas *evas)
238 {
239 evas = evas_find(evas);
240 EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(evas, EVAS_CANVAS_CLASS), NULL);
241 return efl_add(MY_CLASS, evas, efl_canvas_object_legacy_ctor(efl_added));
242 }
243
244 EOLIAN static Eo *
_efl_canvas_video_efl_object_constructor(Eo * obj,Efl_Canvas_Video_Data * pd EINA_UNUSED)245 _efl_canvas_video_efl_object_constructor(Eo *obj, Efl_Canvas_Video_Data *pd EINA_UNUSED)
246 {
247 efl_canvas_group_clipped_set(obj, EINA_TRUE);
248 obj = efl_constructor(efl_super(obj, MY_CLASS));
249 efl_canvas_object_type_set(obj, E_OBJ_NAME);
250
251 return obj;
252 }
253
254 EAPI Evas_Object *
emotion_object_image_get(const Evas_Object * obj)255 emotion_object_image_get(const Evas_Object *obj)
256 {
257 Efl_Canvas_Video_Data *sd = efl_data_scope_safe_get(obj, MY_CLASS);
258 if (!sd) return NULL;
259 return sd->obj;
260 }
261
262 EOLIAN static void
_efl_canvas_video_option_set(Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * pd,const char * opt,const char * val)263 _efl_canvas_video_option_set(Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *pd, const char *opt, const char *val)
264 {
265 Efl_Canvas_Video_Data *sd = pd;
266
267 if ((!opt) || (!val)) return;
268
269 if (strcmp(opt, "video") == 0)
270 {
271 if (strcmp(val, "off") == 0)
272 sd->module_options.no_video = EINA_TRUE;
273 else if (strcmp(val, "on") == 0)
274 sd->module_options.no_video = EINA_FALSE;
275 else
276 sd->module_options.no_video = !!atoi(val);
277
278 ERR("Deprecated. Use emotion_object_video_mute_set()");
279 }
280 else if (strcmp(opt, "audio") == 0)
281 {
282 if (strcmp(val, "off") == 0)
283 sd->module_options.no_audio = EINA_TRUE;
284 else if (strcmp(val, "on") == 0)
285 sd->module_options.no_audio = EINA_FALSE;
286 else
287 sd->module_options.no_audio = !!atoi(val);
288
289 ERR("Deprecated. Use emotion_object_audio_mute_set()");
290 }
291 else
292 ERR("Unsupported %s=%s", opt, val);
293 }
294
295 EOLIAN static Eina_Bool
_efl_canvas_video_engine_set(Eo * obj,Efl_Canvas_Video_Data * pd,const char * engine)296 _efl_canvas_video_engine_set(Eo *obj, Efl_Canvas_Video_Data *pd, const char *engine)
297 {
298 Efl_Canvas_Video_Data *sd = pd;
299 const char *file;
300
301 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
302
303 if (!engine) engine = "gstreamer1";
304 if (!strcmp(engine, sd->engine)) return EINA_TRUE;
305
306 eina_stringshare_replace(&(sd->engine), engine);
307
308 file = sd->file;
309 sd->file = NULL;
310
311 eina_stringshare_del(sd->title);
312 sd->title = NULL;
313 eina_stringshare_del(sd->progress.info);
314 sd->progress.info = NULL;
315 sd->progress.stat = 0.0;
316 eina_stringshare_del(sd->ref.file);
317 sd->ref.file = NULL;
318 sd->ref.num = 0;
319 sd->spu.button_num = 0;
320 sd->spu.button = -1;
321 sd->ratio = 1.0;
322 sd->pos = 0;
323 sd->remember_jump = 0;
324 sd->seek_pos = 0;
325 sd->len = 0;
326 sd->remember_play = 0;
327
328 if (sd->anim) ecore_animator_del(sd->anim);
329 sd->anim = NULL;
330
331 if (sd->engine_instance) emotion_engine_instance_del(sd->engine_instance);
332 sd->engine_instance = NULL;
333 _engine_init(obj, sd);
334 if (!sd->engine_instance)
335 {
336 sd->file = file;
337 return EINA_FALSE;
338 }
339
340 if (file)
341 {
342 emotion_object_file_set(obj, file);
343 eina_stringshare_del(file);
344 }
345
346 return EINA_TRUE;
347 }
348
349 EAPI Eina_Bool
emotion_object_file_set(Evas_Object * obj,const char * file)350 emotion_object_file_set(Evas_Object *obj, const char *file)
351 {
352 return efl_file_simple_load(obj, file, NULL);
353 }
354
355 EOLIAN static Eina_Error
_efl_canvas_video_efl_file_file_set(Eo * obj,Efl_Canvas_Video_Data * sd,const char * file)356 _efl_canvas_video_efl_file_file_set(Eo *obj, Efl_Canvas_Video_Data *sd, const char *file)
357 {
358 DBG("file=%s", file);
359
360 eina_stringshare_replace(&sd->file, file);
361 sd->loaded = 0;
362 return efl_file_set(efl_super(obj, MY_CLASS), file);
363 }
364
365 EOLIAN static Eina_Bool
_efl_canvas_video_efl_file_loaded_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)366 _efl_canvas_video_efl_file_loaded_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
367 {
368 return sd->open && sd->loaded;
369 }
370
371 EOLIAN static void
_efl_canvas_video_efl_file_unload(Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)372 _efl_canvas_video_efl_file_unload(Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
373 {
374 if (sd->engine_instance) emotion_engine_instance_file_close(sd->engine_instance);
375 sd->engine_instance = NULL;
376 evas_object_image_data_set(sd->obj, NULL);
377 evas_object_image_size_set(sd->obj, 1, 1);
378 _emotion_image_data_zero(sd->obj);
379
380 if (sd->anim) ecore_animator_del(sd->anim);
381 sd->anim = NULL;
382
383 _xattr_data_cancel(sd->xattr);
384 sd->loaded = 0;
385 }
386
387 EOLIAN static Eina_Error
_efl_canvas_video_efl_file_load(Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)388 _efl_canvas_video_efl_file_load(Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
389 {
390 const char *file = sd->file;
391 if (!sd->engine_instance) _engine_init(obj, sd);
392 if (!sd->engine_instance)
393 {
394 WRN("No engine chosen. Please set an engine.");
395 return EFL_GFX_IMAGE_LOAD_ERROR_GENERIC;
396 }
397
398 sd->video.w = 0;
399 sd->video.h = 0;
400 if ((file) && (file[0] != 0))
401 {
402 char *file2 = NULL;
403
404 emotion_engine_instance_file_close(sd->engine_instance);
405 evas_object_image_data_set(sd->obj, NULL);
406 evas_object_image_size_set(sd->obj, 1, 1);
407 _emotion_image_data_zero(sd->obj);
408 sd->open = 0;
409
410 if (file)
411 {
412 file2 = eina_vpath_resolve(file);
413 }
414
415 if (!emotion_engine_instance_file_open(sd->engine_instance, file2))
416 {
417 WRN("Couldn't open file=%s", sd->file);
418 return EFL_GFX_IMAGE_LOAD_ERROR_GENERIC;
419 }
420 free(file2);
421 DBG("successfully opened file=%s", sd->file);
422 sd->pos = 0.0;
423 if (sd->play) emotion_engine_instance_play(sd->engine_instance, 0.0);
424 }
425 else
426 {
427 emotion_engine_instance_file_close(sd->engine_instance);
428 evas_object_image_data_set(sd->obj, NULL);
429 evas_object_image_size_set(sd->obj, 1, 1);
430 _emotion_image_data_zero(sd->obj);
431 }
432
433 if (sd->anim) ecore_animator_del(sd->anim);
434 sd->anim = NULL;
435
436 _xattr_data_cancel(sd->xattr);
437 sd->loaded = 1;
438
439 return 0;
440 }
441
442 EAPI const char *
emotion_object_file_get(const Evas_Object * obj)443 emotion_object_file_get(const Evas_Object *obj)
444 {
445 return efl_file_get(obj);
446 }
447
448 static void
_emotion_aspect_borders_apply(Evas_Object * obj,Efl_Canvas_Video_Data * sd,int w,int h,int iw,int ih)449 _emotion_aspect_borders_apply(Evas_Object *obj, Efl_Canvas_Video_Data *sd, int w, int h, int iw, int ih)
450 {
451 int x, y;
452
453 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
454
455 /* applying calculated borders */
456 if ((sd->crop.l == 0) && (sd->crop.r == 0) &&
457 (sd->crop.t == 0) && (sd->crop.b == 0))
458 {
459 Evas_Object *old_clipper;
460 if (sd->crop.clipper)
461 {
462 old_clipper = evas_object_clip_get(sd->crop.clipper);
463 evas_object_clip_unset(sd->obj);
464 evas_object_clip_set(sd->obj, old_clipper);
465 evas_object_del(sd->crop.clipper);
466 sd->crop.clipper = NULL;
467 }
468 }
469 else
470 {
471 if (!sd->crop.clipper)
472 {
473 Evas_Object *old_clipper;
474 sd->crop.clipper = evas_object_rectangle_add
475 (evas_object_evas_get(obj));
476 evas_object_smart_member_add(sd->crop.clipper, obj);
477 old_clipper = evas_object_clip_get(sd->obj);
478 evas_object_clip_set(sd->obj, sd->crop.clipper);
479 evas_object_clip_set(sd->crop.clipper, old_clipper);
480 evas_object_show(sd->crop.clipper);
481 }
482 }
483 _clipper_position_size_update(obj, x, y, w, h, iw, ih);
484 }
485
486 static void
_efl_canvas_video_aspect_border_apply(Evas_Object * obj,Efl_Canvas_Video_Data * sd,int w,int h)487 _efl_canvas_video_aspect_border_apply(Evas_Object *obj, Efl_Canvas_Video_Data *sd, int w, int h)
488 {
489 int iw, ih;
490 double ir;
491 double r;
492
493 int aspect_opt = 0;
494
495 /* Prefer (if available) the video aspect ratio to calculate the sizes */
496 if (sd->ratio > 0.0)
497 {
498 ir = sd->ratio;
499 ih = sd->video.h;
500 iw = (double)ih * ir;
501 }
502 else
503 {
504 iw = sd->video.w;
505 ih = sd->video.h;
506 ir = (double)iw / ih;
507 }
508
509 r = (double)w / h;
510
511 /* First check if we should fit the width or height of the video inside the
512 * width/height of the object. This check takes into account the original
513 * aspect ratio and the object aspect ratio, if we are keeping both sizes or
514 * cropping the exceding area.
515 */
516 if (sd->aspect == EMOTION_ASPECT_KEEP_NONE)
517 {
518 sd->crop.l = 0;
519 sd->crop.r = 0;
520 sd->crop.t = 0;
521 sd->crop.b = 0;
522 aspect_opt = 0; // just ignore keep_aspect
523 }
524 else if (sd->aspect == EMOTION_ASPECT_KEEP_WIDTH)
525 {
526 aspect_opt = 1;
527 }
528 else if (sd->aspect == EMOTION_ASPECT_KEEP_HEIGHT)
529 {
530 aspect_opt = 2;
531 }
532 else if (sd->aspect == EMOTION_ASPECT_KEEP_BOTH)
533 {
534 if (ir > r) aspect_opt = 1;
535 else aspect_opt = 2;
536 }
537 else if (sd->aspect == EMOTION_ASPECT_CROP)
538 {
539 if (ir > r) aspect_opt = 2;
540 else aspect_opt = 1;
541 }
542 else if (sd->aspect == EMOTION_ASPECT_CUSTOM)
543 {
544 // nothing to do, just respect the border settings
545 aspect_opt = 0;
546 }
547
548 /* updating borders based on keep_aspect settings */
549 if (aspect_opt == 1) // keep width
550 {
551 int th, dh;
552 double scale;
553
554 sd->crop.l = 0;
555 sd->crop.r = 0;
556 scale = (double)iw / w;
557 th = h * scale;
558 dh = ih - th;
559 sd->crop.t = sd->crop.b = dh / 2;
560 }
561 else if (aspect_opt == 2) // keep height
562 {
563 int tw, dw;
564 double scale;
565
566 sd->crop.t = 0;
567 sd->crop.b = 0;
568 scale = (double)ih / h;
569 tw = w * scale;
570 dw = iw - tw;
571 sd->crop.l = sd->crop.r = dw / 2;
572 }
573
574 _emotion_aspect_borders_apply(obj, sd, w, h, iw, ih);
575 }
576
577 EAPI void
emotion_object_border_set(Evas_Object * obj,int l,int r,int t,int b)578 emotion_object_border_set(Evas_Object *obj, int l, int r, int t, int b)
579 {
580 Efl_Canvas_Video_Data *sd;
581 int w, h;
582
583 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
584
585 sd->aspect = EMOTION_ASPECT_CUSTOM;
586 sd->crop.l = -l;
587 sd->crop.r = -r;
588 sd->crop.t = -t;
589 sd->crop.b = -b;
590 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
591 _efl_canvas_video_aspect_border_apply(obj, sd, w, h);
592 }
593
594 EAPI void
emotion_object_border_get(const Evas_Object * obj,int * l,int * r,int * t,int * b)595 emotion_object_border_get(const Evas_Object *obj, int *l, int *r, int *t, int *b)
596 {
597 Efl_Canvas_Video_Data *sd;
598
599 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
600 *l = -sd->crop.l;
601 *r = -sd->crop.r;
602 *t = -sd->crop.t;
603 *b = -sd->crop.b;
604 }
605
606 EAPI void
emotion_object_bg_color_set(Evas_Object * obj,int r,int g,int b,int a)607 emotion_object_bg_color_set(Evas_Object *obj, int r, int g, int b, int a)
608 {
609 Efl_Canvas_Video_Data *sd;
610
611 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
612 evas_object_color_set(sd->bg, r, g, b, a);
613 }
614
615 EAPI void
emotion_object_bg_color_get(const Evas_Object * obj,int * r,int * g,int * b,int * a)616 emotion_object_bg_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a)
617 {
618 Efl_Canvas_Video_Data *sd;
619
620 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
621 evas_object_color_get(sd->bg, r, g, b, a);
622 }
623
624 EAPI void
emotion_object_keep_aspect_set(Evas_Object * obj,Emotion_Aspect a)625 emotion_object_keep_aspect_set(Evas_Object *obj, Emotion_Aspect a)
626 {
627 Efl_Canvas_Video_Data *sd;
628 int w, h;
629
630 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
631 if (a == sd->aspect) return;
632
633 sd->aspect = a;
634 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
635 _efl_canvas_video_aspect_border_apply(obj, sd, w, h);
636 }
637
638 EAPI Emotion_Aspect
emotion_object_keep_aspect_get(const Evas_Object * obj)639 emotion_object_keep_aspect_get(const Evas_Object *obj)
640 {
641 Efl_Canvas_Video_Data *sd;
642
643 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_ASPECT_KEEP_NONE);
644 return sd->aspect;
645 }
646
647 EAPI void
emotion_object_play_set(Evas_Object * obj,Eina_Bool play)648 emotion_object_play_set(Evas_Object *obj, Eina_Bool play)
649 {
650 /* avoid calling playback_position_set(0) for legacy */
651 if (play)
652 efl_player_playing_set(obj, EINA_TRUE);
653 efl_player_paused_set(obj, !play);
654 }
655
656 EOLIAN static Eina_Bool
_efl_canvas_video_efl_player_playing_set(Eo * obj,Efl_Canvas_Video_Data * sd,Eina_Bool play)657 _efl_canvas_video_efl_player_playing_set(Eo *obj, Efl_Canvas_Video_Data *sd, Eina_Bool play)
658 {
659 play = !!play;
660 DBG("play=" FMT_UCHAR ", was=" FMT_UCHAR, play, sd->play);
661 if (!sd->engine_instance) return EINA_FALSE;
662 /* always unset pause if playing is false */
663 if (!play) sd->pause = EINA_FALSE;
664 if (!sd->open)
665 {
666 sd->remember_play = play;
667 return EINA_TRUE;
668 }
669 if (play == sd->play) return EINA_TRUE;
670 sd->play = play;
671 sd->remember_play = play;
672 if (sd->state != EMOTION_WAKEUP) emotion_object_suspend_set(obj, EMOTION_WAKEUP);
673 if (sd->play) emotion_engine_instance_play(sd->engine_instance, 0.0);
674 else
675 {
676 emotion_engine_instance_stop(sd->engine_instance);
677 efl_player_playback_position_set(obj, 0.0);
678 }
679 return EINA_TRUE;
680 }
681
682 EOLIAN static Eina_Bool
_efl_canvas_video_efl_player_paused_set(Eo * obj,Efl_Canvas_Video_Data * sd,Eina_Bool paused)683 _efl_canvas_video_efl_player_paused_set(Eo *obj, Efl_Canvas_Video_Data *sd, Eina_Bool paused)
684 {
685 paused = !!paused;
686 DBG("paused=" FMT_UCHAR ", was=" FMT_UCHAR, paused, sd->pause);
687 if (!sd->engine_instance) return EINA_FALSE;
688 if (!sd->open)
689 {
690 /* queue pause */
691 if (sd->remember_play)
692 sd->pause = paused;
693 return sd->remember_play;
694 }
695 if (!sd->play) return EINA_FALSE;
696 if (paused == sd->pause) return EINA_TRUE;
697 sd->pause = paused;
698 if (sd->pause)
699 emotion_engine_instance_stop(sd->engine_instance);
700 else
701 {
702 if (sd->state != EMOTION_WAKEUP) emotion_object_suspend_set(obj, EMOTION_WAKEUP);
703 emotion_engine_instance_play(sd->engine_instance, sd->pos);
704 }
705 return EINA_TRUE;
706 }
707
708 EAPI Eina_Bool
emotion_object_play_get(const Evas_Object * obj)709 emotion_object_play_get(const Evas_Object *obj)
710 {
711 return efl_player_playing_get(obj) && !efl_player_paused_get(obj);
712 }
713
714 EOLIAN static Eina_Bool
_efl_canvas_video_efl_player_playing_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)715 _efl_canvas_video_efl_player_playing_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
716 {
717 if (!sd->engine_instance) return EINA_FALSE;
718 return sd->play;
719 }
720
721 EOLIAN static Eina_Bool
_efl_canvas_video_efl_player_paused_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)722 _efl_canvas_video_efl_player_paused_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
723 {
724 if (!sd->engine_instance) return EINA_FALSE;
725 if (!sd->play) return EINA_FALSE;
726 return sd->pause;
727 }
728
729 EAPI void
emotion_object_position_set(Evas_Object * obj,double sec)730 emotion_object_position_set(Evas_Object *obj, double sec)
731 {
732 efl_player_playback_position_set(obj, sec);
733 }
734
735 EOLIAN static void
_efl_canvas_video_efl_player_playback_position_set(Eo * obj,Efl_Canvas_Video_Data * sd,double sec)736 _efl_canvas_video_efl_player_playback_position_set(Eo *obj, Efl_Canvas_Video_Data *sd, double sec)
737 {
738 DBG("sec=%f", sec);
739 if (!sd->engine_instance) return;
740 if (sec < 0.0) sec = 0.0;
741 if (!sd->open)
742 {
743 sd->remember_jump = sec;
744 return;
745 }
746 sd->remember_jump = 0;
747 sd->seek_pos = sec;
748 sd->seek = 1;
749 sd->pos = sd->seek_pos;
750 if (sd->job) ecore_job_del(sd->job);
751 sd->job = ecore_job_add(_pos_set_job, obj);
752 }
753
754 EAPI double
emotion_object_position_get(const Evas_Object * obj)755 emotion_object_position_get(const Evas_Object *obj)
756 {
757 return efl_player_playback_position_get(obj);
758 }
759
760 EOLIAN static double
_efl_canvas_video_efl_player_playback_position_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)761 _efl_canvas_video_efl_player_playback_position_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
762 {
763 if (!sd->engine_instance) return 0.0;
764 sd->pos = emotion_engine_instance_pos_get(sd->engine_instance);
765 return sd->pos;
766 }
767
768 EAPI double
emotion_object_buffer_size_get(const Evas_Object * obj)769 emotion_object_buffer_size_get(const Evas_Object *obj)
770 {
771 Efl_Canvas_Video_Data *sd;
772
773 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 1.0);
774 if (!sd->engine_instance) return 0.0;
775 return emotion_engine_instance_buffer_size_get(sd->engine_instance);
776 }
777
778 EAPI Eina_Bool
emotion_object_seekable_get(const Evas_Object * obj)779 emotion_object_seekable_get(const Evas_Object *obj)
780 {
781 return efl_playable_seekable_get(obj);
782 }
783
784 EAPI Eina_Bool
emotion_object_video_handled_get(const Evas_Object * obj)785 emotion_object_video_handled_get(const Evas_Object *obj)
786 {
787 Efl_Canvas_Video_Data *sd;
788
789 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
790 if (!sd->engine_instance) return EINA_FALSE;
791 return emotion_engine_instance_video_handled(sd->engine_instance);
792 }
793
794 EAPI Eina_Bool
emotion_object_audio_handled_get(const Evas_Object * obj)795 emotion_object_audio_handled_get(const Evas_Object *obj)
796 {
797 Efl_Canvas_Video_Data *sd;
798
799 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
800 if (!sd->engine_instance) return EINA_FALSE;
801 return emotion_engine_instance_audio_handled(sd->engine_instance);
802 }
803
804 EAPI double
emotion_object_play_length_get(const Evas_Object * obj)805 emotion_object_play_length_get(const Evas_Object *obj)
806 {
807 return efl_playable_length_get(obj);
808 }
809
810 EAPI void
emotion_object_size_get(const Evas_Object * obj,int * iw,int * ih)811 emotion_object_size_get(const Evas_Object *obj, int *iw, int *ih)
812 {
813 Eina_Size2D sz;
814
815 sz = efl_gfx_image_load_controller_load_size_get(obj);
816 if (iw) *iw = sz.w;
817 if (ih) *ih = sz.h;
818 }
819
820 EOLIAN static Eina_Size2D
_efl_canvas_video_efl_gfx_image_load_controller_load_size_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)821 _efl_canvas_video_efl_gfx_image_load_controller_load_size_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
822 {
823 // FIXME: Shouldn't this be efl_gfx_view_size instead?
824 return EINA_SIZE2D(sd->video.w, sd->video.h);
825 }
826
827 EAPI void
emotion_object_smooth_scale_set(Evas_Object * obj,Eina_Bool smooth)828 emotion_object_smooth_scale_set(Evas_Object *obj, Eina_Bool smooth)
829 {
830 efl_gfx_image_smooth_scale_set(obj, smooth);
831 }
832
833 EOLIAN static void
_efl_canvas_video_efl_gfx_image_smooth_scale_set(Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd,Eina_Bool smooth)834 _efl_canvas_video_efl_gfx_image_smooth_scale_set(Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd, Eina_Bool smooth)
835 {
836 evas_object_image_smooth_scale_set(sd->obj, smooth);
837 }
838
839 EAPI Eina_Bool
emotion_object_smooth_scale_get(const Evas_Object * obj)840 emotion_object_smooth_scale_get(const Evas_Object *obj)
841 {
842 return efl_gfx_image_smooth_scale_get(obj);
843 }
844
845 EOLIAN static Eina_Bool
_efl_canvas_video_efl_gfx_image_smooth_scale_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)846 _efl_canvas_video_efl_gfx_image_smooth_scale_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
847 {
848 return evas_object_image_smooth_scale_get(sd->obj);
849 }
850
851 EAPI double
emotion_object_ratio_get(const Evas_Object * obj)852 emotion_object_ratio_get(const Evas_Object *obj)
853 {
854 return efl_gfx_image_ratio_get(obj);
855 }
856
857 EOLIAN static double
_efl_canvas_video_efl_gfx_image_ratio_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)858 _efl_canvas_video_efl_gfx_image_ratio_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
859 {
860 if (!sd->engine_instance) return 0.0;
861 return sd->ratio;
862 }
863
864 /*
865 * Send a control event to the DVD.
866 */
867 EAPI void
emotion_object_event_simple_send(Evas_Object * obj,Emotion_Event ev)868 emotion_object_event_simple_send(Evas_Object *obj, Emotion_Event ev)
869 {
870 Efl_Canvas_Video_Data *sd;
871
872 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
873 if (!sd->engine_instance) return;
874 emotion_engine_instance_event_feed(sd->engine_instance, ev);
875 }
876
877 EAPI void
emotion_object_audio_volume_set(Evas_Object * obj,double vol)878 emotion_object_audio_volume_set(Evas_Object *obj, double vol)
879 {
880 efl_audio_control_volume_set(obj, vol);
881 }
882
883 EOLIAN static void
_efl_canvas_video_efl_audio_control_volume_set(Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd,double vol)884 _efl_canvas_video_efl_audio_control_volume_set(Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd, double vol)
885 {
886 DBG("vol=%f", vol);
887 if (!sd->engine_instance) return;
888 emotion_engine_instance_audio_channel_volume_set(sd->engine_instance, vol);
889 }
890
891 EAPI double
emotion_object_audio_volume_get(const Evas_Object * obj)892 emotion_object_audio_volume_get(const Evas_Object *obj)
893 {
894 return efl_audio_control_volume_get(obj);
895 }
896
897 EOLIAN static double
_efl_canvas_video_efl_audio_control_volume_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)898 _efl_canvas_video_efl_audio_control_volume_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
899 {
900 if (!sd->engine_instance) return 0.0;
901 return emotion_engine_instance_audio_channel_volume_get(sd->engine_instance);
902 }
903
904 EAPI void
emotion_object_audio_mute_set(Evas_Object * obj,Eina_Bool mute)905 emotion_object_audio_mute_set(Evas_Object *obj, Eina_Bool mute)
906 {
907 efl_audio_control_mute_set(obj, mute);
908 }
909
910 EOLIAN static void
_efl_canvas_video_efl_audio_control_mute_set(Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd,Eina_Bool mute)911 _efl_canvas_video_efl_audio_control_mute_set(Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd, Eina_Bool mute)
912 {
913 DBG("mute=" FMT_UCHAR, mute);
914 if (!sd->engine_instance) return;
915 emotion_engine_instance_audio_channel_mute_set(sd->engine_instance, mute);
916 }
917
918 EAPI Eina_Bool
emotion_object_audio_mute_get(const Evas_Object * obj)919 emotion_object_audio_mute_get(const Evas_Object *obj)
920 {
921 return efl_audio_control_mute_get(obj);
922 }
923
924 EOLIAN static Eina_Bool
_efl_canvas_video_efl_audio_control_mute_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)925 _efl_canvas_video_efl_audio_control_mute_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
926 {
927 if (!sd->engine_instance) return EINA_FALSE;
928 return emotion_engine_instance_audio_channel_mute_get(sd->engine_instance);
929 }
930
931 EAPI int
emotion_object_audio_channel_count(const Evas_Object * obj)932 emotion_object_audio_channel_count(const Evas_Object *obj)
933 {
934 Efl_Canvas_Video_Data *sd;
935
936 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
937 if (!sd->engine_instance) return 0;
938 return emotion_engine_instance_audio_channel_count(sd->engine_instance);
939 }
940
941 EAPI const char *
emotion_object_audio_channel_name_get(const Evas_Object * obj,int channel)942 emotion_object_audio_channel_name_get(const Evas_Object *obj, int channel)
943 {
944 Efl_Canvas_Video_Data *sd;
945
946 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
947 if (!sd->engine_instance) return NULL;
948 return emotion_engine_instance_audio_channel_name_get(sd->engine_instance, channel);
949 }
950
951 EAPI void
emotion_object_audio_channel_set(Evas_Object * obj,int channel)952 emotion_object_audio_channel_set(Evas_Object *obj, int channel)
953 {
954 Efl_Canvas_Video_Data *sd;
955
956 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
957 DBG("channel=%d", channel);
958 if (!sd->engine_instance) return;
959 emotion_engine_instance_audio_channel_set(sd->engine_instance, channel);
960 }
961
962 EAPI int
emotion_object_audio_channel_get(const Evas_Object * obj)963 emotion_object_audio_channel_get(const Evas_Object *obj)
964 {
965 Efl_Canvas_Video_Data *sd;
966
967 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
968 if (!sd->engine_instance) return 0;
969 return emotion_engine_instance_audio_channel_get(sd->engine_instance);
970 }
971
972 EAPI void
emotion_object_video_mute_set(Evas_Object * obj,Eina_Bool mute)973 emotion_object_video_mute_set(Evas_Object *obj, Eina_Bool mute)
974 {
975 Efl_Canvas_Video_Data *sd;
976
977 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
978 DBG("mute=" FMT_UCHAR, mute);
979 if (!sd->engine_instance) return;
980 emotion_engine_instance_video_channel_mute_set(sd->engine_instance, mute);
981 }
982
983 EAPI Eina_Bool
emotion_object_video_mute_get(const Evas_Object * obj)984 emotion_object_video_mute_get(const Evas_Object *obj)
985 {
986 Efl_Canvas_Video_Data *sd;
987
988 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
989 if (!sd->engine_instance) return EINA_FALSE;
990 return emotion_engine_instance_video_channel_mute_get(sd->engine_instance);
991 }
992
993 EAPI void
emotion_object_video_subtitle_file_set(Evas_Object * obj,const char * filepath)994 emotion_object_video_subtitle_file_set(Evas_Object *obj, const char *filepath)
995 {
996 Efl_Canvas_Video_Data *sd;
997
998 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
999 DBG("subtitle=%s", filepath);
1000 if (!sd->engine_instance) _engine_init(obj, sd);
1001 if (!sd->engine_instance) return;
1002 emotion_engine_instance_video_subtitle_file_set(sd->engine_instance, filepath);
1003 }
1004
1005 EAPI const char *
emotion_object_video_subtitle_file_get(const Evas_Object * obj)1006 emotion_object_video_subtitle_file_get(const Evas_Object *obj)
1007 {
1008 Efl_Canvas_Video_Data *sd;
1009
1010 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1011 if (!sd->engine_instance) return NULL;
1012 return emotion_engine_instance_video_subtitle_file_get(sd->engine_instance);
1013 }
1014
1015 EAPI int
emotion_object_video_channel_count(const Evas_Object * obj)1016 emotion_object_video_channel_count(const Evas_Object *obj)
1017 {
1018 Efl_Canvas_Video_Data *sd;
1019
1020 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1021 if (!sd->engine_instance) return 0;
1022 return emotion_engine_instance_video_channel_count(sd->engine_instance);
1023 }
1024
1025 EAPI const char *
emotion_object_video_channel_name_get(const Evas_Object * obj,int channel)1026 emotion_object_video_channel_name_get(const Evas_Object *obj, int channel)
1027 {
1028 Efl_Canvas_Video_Data *sd;
1029
1030 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1031 if (!sd->engine_instance) return NULL;
1032 return emotion_engine_instance_video_channel_name_get(sd->engine_instance, channel);
1033 }
1034
1035 EAPI void
emotion_object_video_channel_set(Evas_Object * obj,int channel)1036 emotion_object_video_channel_set(Evas_Object *obj, int channel)
1037 {
1038 Efl_Canvas_Video_Data *sd;
1039
1040 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1041 DBG("channel=%d", channel);
1042 if (!sd->engine_instance) return;
1043 emotion_engine_instance_video_channel_set(sd->engine_instance, channel);
1044 }
1045
1046 EAPI int
emotion_object_video_channel_get(const Evas_Object * obj)1047 emotion_object_video_channel_get(const Evas_Object *obj)
1048 {
1049 Efl_Canvas_Video_Data *sd;
1050
1051 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1052 if (!sd->engine_instance) return 0;
1053 return emotion_engine_instance_video_channel_get(sd->engine_instance);
1054 }
1055
1056 EAPI void
emotion_object_spu_mute_set(Evas_Object * obj,Eina_Bool mute)1057 emotion_object_spu_mute_set(Evas_Object *obj, Eina_Bool mute)
1058 {
1059 Efl_Canvas_Video_Data *sd;
1060
1061 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1062 DBG("mute=" FMT_UCHAR, mute);
1063 if (!sd->engine_instance) return;
1064 emotion_engine_instance_spu_channel_mute_set(sd->engine_instance, mute);
1065 }
1066
1067 EAPI Eina_Bool
emotion_object_spu_mute_get(const Evas_Object * obj)1068 emotion_object_spu_mute_get(const Evas_Object *obj)
1069 {
1070 Efl_Canvas_Video_Data *sd;
1071
1072 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1073 if (!sd->engine_instance) return EINA_FALSE;
1074 return emotion_engine_instance_spu_channel_mute_get(sd->engine_instance);
1075 }
1076
1077 EAPI int
emotion_object_spu_channel_count(const Evas_Object * obj)1078 emotion_object_spu_channel_count(const Evas_Object *obj)
1079 {
1080 Efl_Canvas_Video_Data *sd;
1081
1082 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1083 if (!sd->engine_instance) return 0;
1084 return emotion_engine_instance_spu_channel_count(sd->engine_instance);
1085 }
1086
1087 EAPI const char *
emotion_object_spu_channel_name_get(const Evas_Object * obj,int channel)1088 emotion_object_spu_channel_name_get(const Evas_Object *obj, int channel)
1089 {
1090 Efl_Canvas_Video_Data *sd;
1091
1092 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1093 if (!sd->engine_instance) return NULL;
1094 return emotion_engine_instance_spu_channel_name_get(sd->engine_instance, channel);
1095 }
1096
1097 EAPI void
emotion_object_spu_channel_set(Evas_Object * obj,int channel)1098 emotion_object_spu_channel_set(Evas_Object *obj, int channel)
1099 {
1100 Efl_Canvas_Video_Data *sd;
1101
1102 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1103 DBG("channel=%d", channel);
1104 if (!sd->engine_instance) return;
1105 emotion_engine_instance_spu_channel_set(sd->engine_instance, channel);
1106 }
1107
1108 EAPI int
emotion_object_spu_channel_get(const Evas_Object * obj)1109 emotion_object_spu_channel_get(const Evas_Object *obj)
1110 {
1111 Efl_Canvas_Video_Data *sd;
1112
1113 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1114 if (!sd->engine_instance) return 0;
1115 return emotion_engine_instance_spu_channel_get(sd->engine_instance);
1116 }
1117
1118 EAPI int
emotion_object_chapter_count(const Evas_Object * obj)1119 emotion_object_chapter_count(const Evas_Object *obj)
1120 {
1121 Efl_Canvas_Video_Data *sd;
1122
1123 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1124 if (!sd->engine_instance) return 0;
1125 return emotion_engine_instance_chapter_count(sd->engine_instance);
1126 }
1127
1128 EAPI void
emotion_object_chapter_set(Evas_Object * obj,int chapter)1129 emotion_object_chapter_set(Evas_Object *obj, int chapter)
1130 {
1131 Efl_Canvas_Video_Data *sd;
1132
1133 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1134 DBG("chapter=%d", chapter);
1135 if (!sd->engine_instance) return;
1136 emotion_engine_instance_chapter_set(sd->engine_instance, chapter);
1137 }
1138
1139 EAPI int
emotion_object_chapter_get(const Evas_Object * obj)1140 emotion_object_chapter_get(const Evas_Object *obj)
1141 {
1142 Efl_Canvas_Video_Data *sd;
1143
1144 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1145 if (!sd->engine_instance) return 0;
1146 return emotion_engine_instance_chapter_get(sd->engine_instance);
1147 }
1148
1149 EAPI const char *
emotion_object_chapter_name_get(const Evas_Object * obj,int chapter)1150 emotion_object_chapter_name_get(const Evas_Object *obj, int chapter)
1151 {
1152 Efl_Canvas_Video_Data *sd;
1153
1154 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1155 if (!sd->engine_instance) return NULL;
1156 return emotion_engine_instance_chapter_name_get(sd->engine_instance, chapter);
1157 }
1158
1159 EAPI void
emotion_object_play_speed_set(Evas_Object * obj,double speed)1160 emotion_object_play_speed_set(Evas_Object *obj, double speed)
1161 {
1162 Efl_Canvas_Video_Data *sd;
1163
1164 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1165 DBG("speed=%f", speed);
1166 if (!sd->engine_instance) return;
1167 emotion_engine_instance_speed_set(sd->engine_instance, speed);
1168 }
1169
1170 EAPI double
emotion_object_play_speed_get(const Evas_Object * obj)1171 emotion_object_play_speed_get(const Evas_Object *obj)
1172 {
1173 Efl_Canvas_Video_Data *sd;
1174
1175 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0.0);
1176 if (!sd->engine_instance) return 0.0;
1177 return emotion_engine_instance_speed_get(sd->engine_instance);
1178 }
1179
1180 EAPI void
emotion_object_eject(Evas_Object * obj)1181 emotion_object_eject(Evas_Object *obj)
1182 {
1183 Efl_Canvas_Video_Data *sd;
1184
1185 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1186 if (!sd->engine_instance) return;
1187 emotion_engine_instance_eject(sd->engine_instance);
1188 }
1189
1190 EAPI const char *
emotion_object_title_get(const Evas_Object * obj)1191 emotion_object_title_get(const Evas_Object *obj)
1192 {
1193 Efl_Canvas_Video_Data *sd;
1194
1195 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1196 return sd->title;
1197 }
1198
1199 EAPI const char *
emotion_object_progress_info_get(const Evas_Object * obj)1200 emotion_object_progress_info_get(const Evas_Object *obj)
1201 {
1202 Efl_Canvas_Video_Data *sd;
1203
1204 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1205 return sd->progress.info;
1206 }
1207
1208 EAPI double
emotion_object_progress_status_get(const Evas_Object * obj)1209 emotion_object_progress_status_get(const Evas_Object *obj)
1210 {
1211 return efl_player_playback_progress_get(obj);
1212 }
1213
1214 EOLIAN static double
_efl_canvas_video_efl_player_playback_progress_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)1215 _efl_canvas_video_efl_player_playback_progress_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
1216 {
1217 return sd->progress.stat;
1218 }
1219
1220 EOLIAN static void
_efl_canvas_video_efl_player_playback_progress_set(Eo * obj,Efl_Canvas_Video_Data * sd EINA_UNUSED,double progress)1221 _efl_canvas_video_efl_player_playback_progress_set(Eo *obj, Efl_Canvas_Video_Data *sd EINA_UNUSED, double progress)
1222 {
1223 const char *info = emotion_object_progress_info_get((const Evas_Object*)obj);
1224 _emotion_progress_set(obj, (char*)info, progress);
1225 }
1226
1227 EOLIAN static double
_efl_canvas_video_efl_playable_length_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)1228 _efl_canvas_video_efl_playable_length_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
1229 {
1230 if (!sd->engine_instance) return 0.0;
1231 sd->len = emotion_engine_instance_len_get(sd->engine_instance);
1232 return sd->len;
1233 }
1234
1235 EOLIAN static Eina_Bool
_efl_canvas_video_efl_playable_seekable_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)1236 _efl_canvas_video_efl_playable_seekable_get(const Eo *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
1237 {
1238 if (!sd->engine_instance) return EINA_FALSE;
1239 return emotion_engine_instance_seekable(sd->engine_instance);
1240 }
1241
1242 EAPI const char *
emotion_object_ref_file_get(const Evas_Object * obj)1243 emotion_object_ref_file_get(const Evas_Object *obj)
1244 {
1245 Efl_Canvas_Video_Data *sd;
1246
1247 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1248 return sd->ref.file;
1249 }
1250
1251 EAPI int
emotion_object_ref_num_get(const Evas_Object * obj)1252 emotion_object_ref_num_get(const Evas_Object *obj)
1253 {
1254 Efl_Canvas_Video_Data *sd;
1255
1256 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1257 return sd->ref.num;
1258 }
1259
1260 EAPI int
emotion_object_spu_button_count_get(const Evas_Object * obj)1261 emotion_object_spu_button_count_get(const Evas_Object *obj)
1262 {
1263 Efl_Canvas_Video_Data *sd;
1264
1265 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1266 return sd->spu.button_num;
1267 }
1268
1269 EAPI int
emotion_object_spu_button_get(const Evas_Object * obj)1270 emotion_object_spu_button_get(const Evas_Object *obj)
1271 {
1272 Efl_Canvas_Video_Data *sd;
1273
1274 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0);
1275 return sd->spu.button;
1276 }
1277
1278 EAPI const char *
emotion_object_meta_info_get(const Evas_Object * obj,Emotion_Meta_Info meta)1279 emotion_object_meta_info_get(const Evas_Object *obj, Emotion_Meta_Info meta)
1280 {
1281 Efl_Canvas_Video_Data *sd;
1282 int id;
1283
1284 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1285 if (!sd->engine_instance) return NULL;
1286 switch (meta)
1287 {
1288 case EMOTION_META_INFO_TRACK_TITLE:
1289 id = META_TRACK_TITLE;
1290 break;
1291 case EMOTION_META_INFO_TRACK_ARTIST:
1292 id = META_TRACK_ARTIST;
1293 break;
1294 case EMOTION_META_INFO_TRACK_ALBUM:
1295 id = META_TRACK_ALBUM;
1296 break;
1297 case EMOTION_META_INFO_TRACK_YEAR:
1298 id = META_TRACK_YEAR;
1299 break;
1300 case EMOTION_META_INFO_TRACK_GENRE:
1301 id = META_TRACK_GENRE;
1302 break;
1303 case EMOTION_META_INFO_TRACK_COMMENT:
1304 id = META_TRACK_COMMENT;
1305 break;
1306 case EMOTION_META_INFO_TRACK_DISC_ID:
1307 id = META_TRACK_DISCID;
1308 break;
1309 default:
1310 ERR("Unknown meta info id: %d", meta);
1311 return NULL;
1312 }
1313
1314 return emotion_engine_instance_meta_get(sd->engine_instance, id);
1315 }
1316
1317
1318 EAPI Evas_Object *
emotion_file_meta_artwork_get(const Evas_Object * obj,const char * path,Emotion_Artwork_Info type)1319 emotion_file_meta_artwork_get(const Evas_Object *obj, const char *path, Emotion_Artwork_Info type)
1320 {
1321 Efl_Canvas_Video_Data *sd;
1322 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1323 if (!sd->engine_instance) return NULL;
1324
1325 Evas *ev = evas_object_evas_get(obj);
1326 Evas_Object *artwork = evas_object_image_add(ev);
1327
1328 Evas_Object *result = emotion_engine_instance_meta_artwork_get(sd->engine_instance, artwork, path, type);
1329 if (!result) return NULL;
1330
1331 Evas_Load_Error _error = evas_object_image_load_error_get(result);
1332 if (_error != EVAS_LOAD_ERROR_NONE) return NULL;
1333
1334 return result;
1335 }
1336
1337 EAPI void
emotion_object_vis_set(Evas_Object * obj,Emotion_Vis visualization)1338 emotion_object_vis_set(Evas_Object *obj, Emotion_Vis visualization)
1339 {
1340 Efl_Canvas_Video_Data *sd;
1341
1342 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1343 DBG("visualization=%d", visualization);
1344 if (!sd->engine_instance) return;
1345 emotion_engine_instance_vis_set(sd->engine_instance, visualization);
1346 }
1347
1348 EAPI Emotion_Vis
emotion_object_vis_get(const Evas_Object * obj)1349 emotion_object_vis_get(const Evas_Object *obj)
1350 {
1351 Efl_Canvas_Video_Data *sd;
1352
1353 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_VIS_NONE);
1354 if (!sd->engine_instance) return EMOTION_VIS_NONE;
1355 return emotion_engine_instance_vis_get(sd->engine_instance);
1356 }
1357
1358 EAPI Eina_Bool
emotion_object_vis_supported(const Evas_Object * obj,Emotion_Vis visualization)1359 emotion_object_vis_supported(const Evas_Object *obj, Emotion_Vis visualization)
1360 {
1361 Efl_Canvas_Video_Data *sd;
1362
1363 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EINA_FALSE);
1364 if (!sd->engine_instance) return EINA_FALSE;
1365 return emotion_engine_instance_vis_supported(sd->engine_instance, visualization);
1366 }
1367
1368 EAPI void
emotion_object_priority_set(Evas_Object * obj,Eina_Bool priority)1369 emotion_object_priority_set(Evas_Object *obj, Eina_Bool priority)
1370 {
1371 Efl_Canvas_Video_Data *sd;
1372
1373 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1374 if (!sd->engine_instance) return;
1375 emotion_engine_instance_priority_set(sd->engine_instance, priority);
1376 }
1377
1378 EAPI Eina_Bool
emotion_object_priority_get(const Evas_Object * obj)1379 emotion_object_priority_get(const Evas_Object *obj)
1380 {
1381 Efl_Canvas_Video_Data *sd;
1382
1383 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EINA_FALSE);
1384 if (!sd->engine_instance) return EINA_FALSE;
1385 return emotion_engine_instance_priority_get(sd->engine_instance);
1386 }
1387
1388 #ifdef HAVE_EIO
1389 static void
_eio_load_xattr_cleanup(Emotion_Xattr_Data * xattr,Eio_File * handler)1390 _eio_load_xattr_cleanup(Emotion_Xattr_Data *xattr, Eio_File *handler)
1391 {
1392 if (handler == xattr->load) xattr->load = NULL;
1393 _xattr_data_unref(xattr);
1394 }
1395
1396 static void
_eio_load_xattr_done(void * data,Eio_File * handler,double xattr_double)1397 _eio_load_xattr_done(void *data, Eio_File *handler, double xattr_double)
1398 {
1399 Emotion_Xattr_Data *xattr = data;
1400
1401 emotion_object_position_set(evas_object_smart_parent_get(xattr->obj_wref), xattr_double);
1402 efl_event_callback_call(evas_object_smart_parent_get(xattr->obj_wref), EFL_CANVAS_VIDEO_EVENT_POSITION_LOAD_DONE, NULL);
1403 evas_object_smart_callback_call(evas_object_smart_parent_get(xattr->obj_wref), "position_load,succeed", NULL);
1404 _eio_load_xattr_cleanup(xattr, handler);
1405 }
1406
1407 static void
_eio_load_xattr_error(void * data,Eio_File * handler,int err EINA_UNUSED)1408 _eio_load_xattr_error(void *data, Eio_File *handler, int err EINA_UNUSED)
1409 {
1410 Emotion_Xattr_Data *xattr = data;
1411
1412 efl_event_callback_call(evas_object_smart_parent_get(xattr->obj_wref), EFL_CANVAS_VIDEO_EVENT_POSITION_LOAD_FAIL, NULL);
1413 evas_object_smart_callback_call(evas_object_smart_parent_get(xattr->obj_wref), "position_load,failed", NULL);
1414 _eio_load_xattr_cleanup(xattr, handler);
1415 }
1416 #endif
1417
1418 EAPI void
emotion_object_last_position_load(Evas_Object * obj)1419 emotion_object_last_position_load(Evas_Object *obj)
1420 {
1421 Efl_Canvas_Video_Data *sd;
1422 const char *tmp;
1423 #ifndef HAVE_EIO
1424 double xattr;
1425 #endif
1426
1427 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1428 if (!sd->file) return;
1429
1430 if (!strncmp(sd->file, "file://", 7)) tmp = sd->file + 7;
1431 else if (!strstr(sd->file, "://")) tmp = sd->file;
1432 else return;
1433
1434 #ifdef HAVE_EIO
1435 Emotion_Xattr_Data *xattr = sd->xattr;
1436
1437 if (xattr->load) return;
1438 EINA_REFCOUNT_REF(xattr);
1439
1440 xattr->load = eio_file_xattr_double_get(tmp,
1441 "user.e.time_seek",
1442 _eio_load_xattr_done,
1443 _eio_load_xattr_error,
1444 xattr);
1445 #else
1446 if (eina_xattr_double_get(tmp, "user.e.time_seek", &xattr))
1447 {
1448 emotion_object_position_set(obj, xattr);
1449 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_POSITION_LOAD_DONE, NULL);
1450 evas_object_smart_callback_call(obj, "position_load,succeed", NULL);
1451 }
1452 else
1453 {
1454 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_POSITION_LOAD_FAIL, NULL);
1455 evas_object_smart_callback_call(obj, "position_load,failed", NULL);
1456 }
1457 #endif
1458 }
1459
1460 #ifdef HAVE_EIO
1461 static void
_eio_save_xattr_cleanup(Emotion_Xattr_Data * xattr,Eio_File * handler)1462 _eio_save_xattr_cleanup(Emotion_Xattr_Data *xattr, Eio_File *handler)
1463 {
1464 if (handler == xattr->save) xattr->save = NULL;
1465 _xattr_data_unref(xattr);
1466 }
1467
1468 static void
_eio_save_xattr_done(void * data,Eio_File * handler)1469 _eio_save_xattr_done(void *data, Eio_File *handler)
1470 {
1471 Emotion_Xattr_Data *xattr = data;
1472
1473 efl_event_callback_call(xattr->obj_wref, EFL_CANVAS_VIDEO_EVENT_POSITION_SAVE_DONE, NULL);
1474 evas_object_smart_callback_call(xattr->obj_wref, "position_save,succeed", NULL);
1475 _eio_save_xattr_cleanup(xattr, handler);
1476 }
1477
1478 static void
_eio_save_xattr_error(void * data,Eio_File * handler,int err EINA_UNUSED)1479 _eio_save_xattr_error(void *data, Eio_File *handler, int err EINA_UNUSED)
1480 {
1481 Emotion_Xattr_Data *xattr = data;
1482
1483 efl_event_callback_call(xattr->obj_wref, EFL_CANVAS_VIDEO_EVENT_POSITION_SAVE_FAIL, NULL);
1484 evas_object_smart_callback_call(xattr->obj_wref, "position_save,failed", NULL);
1485 _eio_save_xattr_cleanup(xattr, handler);
1486 }
1487 #endif
1488
1489 EAPI void
emotion_object_last_position_save(Evas_Object * obj)1490 emotion_object_last_position_save(Evas_Object *obj)
1491 {
1492 Efl_Canvas_Video_Data *sd;
1493 const char *tmp;
1494
1495 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1496 if (!sd->file) return;
1497
1498 if (!strncmp(sd->file, "file://", 7)) tmp = sd->file + 7;
1499 else if (!strstr(sd->file, "://")) tmp = sd->file;
1500 else return;
1501 #ifdef HAVE_EIO
1502 Emotion_Xattr_Data *xattr = sd->xattr;
1503
1504 if (xattr->save) return;
1505 EINA_REFCOUNT_REF(xattr);
1506
1507 xattr->save = eio_file_xattr_double_set(tmp,
1508 "user.e.time_seek",
1509 emotion_object_position_get(obj),
1510 0,
1511 _eio_save_xattr_done,
1512 _eio_save_xattr_error,
1513 xattr);
1514 #else
1515 if (eina_xattr_double_set(tmp, "user.e.time_seek", emotion_object_position_get(obj), 0))
1516 {
1517 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_POSITION_SAVE_DONE, NULL);
1518 evas_object_smart_callback_call(obj, "position_save,succeed", NULL);
1519 }
1520 else
1521 {
1522 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_POSITION_SAVE_FAIL, NULL);
1523 evas_object_smart_callback_call(obj, "position_save,failed", NULL);
1524 }
1525 #endif
1526 }
1527
1528 EAPI void
emotion_object_suspend_set(Evas_Object * obj,Emotion_Suspend state)1529 emotion_object_suspend_set(Evas_Object *obj, Emotion_Suspend state)
1530 {
1531 Efl_Canvas_Video_Data *sd;
1532
1533 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1534 switch (state)
1535 {
1536 case EMOTION_WAKEUP:
1537 /* Restore the rendering pipeline, offset and everything back to play again (this will be called automatically by play_set) */
1538 case EMOTION_SLEEP:
1539 /* This destroy some part of the rendering pipeline */
1540 case EMOTION_DEEP_SLEEP:
1541 /* This destroy all the rendering pipeline and just keep the last rendered image (fullscreen) */
1542 case EMOTION_HIBERNATE:
1543 /* This destroy all the rendering pipeline and keep 1/4 of the last rendered image */
1544 default:
1545 break;
1546 }
1547 sd->state = state;
1548 }
1549
1550 EAPI Emotion_Suspend
emotion_object_suspend_get(Evas_Object * obj)1551 emotion_object_suspend_get(Evas_Object *obj)
1552 {
1553 Efl_Canvas_Video_Data *sd;
1554
1555 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_WAKEUP);
1556 return sd->state;
1557 }
1558
1559 /*****************************/
1560 /* Utility calls for modules */
1561 /*****************************/
1562
1563 EAPI void *
_emotion_video_get(const Evas_Object * obj)1564 _emotion_video_get(const Evas_Object *obj)
1565 {
1566 Efl_Canvas_Video_Data *sd;
1567
1568 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL);
1569 return emotion_engine_instance_data_get(sd->engine_instance);
1570 }
1571
1572 static Eina_Bool
_emotion_frame_anim(void * data)1573 _emotion_frame_anim(void *data)
1574 {
1575 Evas_Object *obj = data;
1576 Efl_Canvas_Video_Data *sd;
1577
1578 E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EINA_FALSE);
1579
1580 sd->anim = NULL;
1581 evas_object_image_pixels_dirty_set(sd->obj, 1);
1582 _emotion_video_pos_update(obj,
1583 emotion_engine_instance_pos_get(sd->engine_instance),
1584 emotion_engine_instance_len_get(sd->engine_instance));
1585 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_FRAME_DECODE, NULL);
1586 evas_object_smart_callback_call(obj, "frame_decode", NULL);
1587 return EINA_FALSE;
1588 }
1589
1590 EAPI void
_emotion_frame_new(Evas_Object * obj)1591 _emotion_frame_new(Evas_Object *obj)
1592 {
1593 Efl_Canvas_Video_Data *sd;
1594
1595 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1596 if (!sd->anim)
1597 sd->anim = ecore_evas_animator_add(obj, _emotion_frame_anim, obj);
1598 }
1599
1600 EAPI void
_emotion_video_pos_update(Evas_Object * obj,double pos,double len)1601 _emotion_video_pos_update(Evas_Object *obj, double pos, double len)
1602 {
1603 Efl_Canvas_Video_Data *sd;
1604 int npos = 0, nlen = 0;
1605
1606 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1607 if (!EINA_DBL_EQ(pos, sd->pos)) npos = 1;
1608 if (!EINA_DBL_EQ(len, sd->len)) nlen = 1;
1609 sd->pos = pos;
1610 sd->len = len;
1611 if (npos)
1612 {
1613 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_POSITION_CHANGE, NULL);
1614 evas_object_smart_callback_call(obj, "position_update", NULL);
1615 }
1616 if (nlen)
1617 {
1618 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_LENGTH_CHANGE, NULL);
1619 evas_object_smart_callback_call(obj, "length_change", NULL);
1620 }
1621 }
1622
1623 EAPI void
_emotion_frame_resize(Evas_Object * obj,int w,int h,double ratio)1624 _emotion_frame_resize(Evas_Object *obj, int w, int h, double ratio)
1625 {
1626 Efl_Canvas_Video_Data *sd;
1627 double tmp;
1628 int changed = 0;
1629
1630 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1631 if ((w != sd->video.w) || (h != sd->video.h))
1632 {
1633 sd->video.w = w;
1634 sd->video.h = h;
1635 _emotion_image_data_zero(sd->obj);
1636 changed = 1;
1637 }
1638 if (h > 0) tmp = (double)w / (double)h;
1639 else tmp = 1.0;
1640 if (!EINA_DBL_EQ(ratio, tmp)) tmp = ratio;
1641 if (!EINA_DBL_EQ(tmp, sd->ratio))
1642 {
1643 sd->ratio = tmp;
1644 changed = 1;
1645 }
1646 if (changed)
1647 {
1648 evas_object_size_hint_request_set(obj, w, h);
1649 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_FRAME_RESIZE, NULL);
1650 evas_object_smart_callback_call(obj, "frame_resize", NULL);
1651 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
1652 _efl_canvas_video_aspect_border_apply(obj, sd, w, h);
1653 }
1654 }
1655
1656 EAPI void
_emotion_image_reset(Evas_Object * obj)1657 _emotion_image_reset(Evas_Object *obj)
1658 {
1659 Efl_Canvas_Video_Data *sd;
1660
1661 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1662 _emotion_image_data_zero(sd->obj);
1663 }
1664
1665 EAPI void
_emotion_decode_stop(Evas_Object * obj)1666 _emotion_decode_stop(Evas_Object *obj)
1667 {
1668 Efl_Canvas_Video_Data *sd;
1669
1670 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1671 if (sd->play)
1672 {
1673 sd->play = 0;
1674 evas_object_smart_callback_call(obj, "decode_stop", NULL);
1675 }
1676 }
1677
1678 EAPI void
_emotion_open_done(Evas_Object * obj)1679 _emotion_open_done(Evas_Object *obj)
1680 {
1681 Efl_Canvas_Video_Data *sd;
1682
1683 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1684 sd->open = 1;
1685
1686 if (!EINA_DBL_EQ(sd->remember_jump, 0.0))
1687 emotion_object_position_set(obj, sd->remember_jump);
1688 if (sd->remember_play != sd->play)
1689 {
1690 if (sd->pause)
1691 sd->play = sd->remember_play;
1692 else
1693 emotion_object_play_set(obj, sd->remember_play);
1694 }
1695 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_OPEN_DONE, NULL);
1696 evas_object_smart_callback_call(obj, "open_done", NULL);
1697 }
1698
1699 EAPI void
_emotion_playback_started(Evas_Object * obj)1700 _emotion_playback_started(Evas_Object *obj)
1701 {
1702 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_PLAYBACK_START, NULL);
1703 evas_object_smart_callback_call(obj, "playback_started", NULL);
1704 }
1705
1706 EAPI void
_emotion_playback_finished(Evas_Object * obj)1707 _emotion_playback_finished(Evas_Object *obj)
1708 {
1709 Efl_Canvas_Video_Data *sd;
1710
1711 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1712 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_PLAYBACK_STOP, NULL);
1713 evas_object_smart_callback_call(obj, "playback_finished", NULL);
1714 }
1715
1716 EAPI void
_emotion_audio_level_change(Evas_Object * obj)1717 _emotion_audio_level_change(Evas_Object *obj)
1718 {
1719 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_VOLUME_CHANGE, NULL);
1720 evas_object_smart_callback_call(obj, "audio_level_change", NULL);
1721 }
1722
1723 EAPI void
_emotion_channels_change(Evas_Object * obj)1724 _emotion_channels_change(Evas_Object *obj)
1725 {
1726 Efl_Canvas_Video_Data *sd;
1727
1728 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1729 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_CHANNELS_CHANGE, NULL);
1730 evas_object_smart_callback_call(obj, "channels_change", NULL);
1731 }
1732
1733 EAPI void
_emotion_title_set(Evas_Object * obj,char * title)1734 _emotion_title_set(Evas_Object *obj, char *title)
1735 {
1736 Efl_Canvas_Video_Data *sd;
1737
1738 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1739 eina_stringshare_replace(&sd->title, title);
1740 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_TITLE_CHANGE, NULL);
1741 evas_object_smart_callback_call(obj, "title_change", NULL);
1742 }
1743
1744 EAPI void
_emotion_progress_set(Evas_Object * obj,char * info,double st)1745 _emotion_progress_set(Evas_Object *obj, char *info, double st)
1746 {
1747 Efl_Canvas_Video_Data *sd;
1748
1749 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1750 eina_stringshare_replace(&sd->progress.info, info);
1751 sd->progress.stat = st;
1752 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_PROGRESS_CHANGE, NULL);
1753 evas_object_smart_callback_call(obj, "progress_change", NULL);
1754 }
1755
1756 EAPI void
_emotion_file_ref_set(Evas_Object * obj,const char * file,int num)1757 _emotion_file_ref_set(Evas_Object *obj, const char *file, int num)
1758 {
1759 Efl_Canvas_Video_Data *sd;
1760
1761 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1762 eina_stringshare_replace(&sd->ref.file, file);
1763 sd->ref.num = num;
1764 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_REF_CHANGE, NULL);
1765 evas_object_smart_callback_call(obj, "ref_change", NULL);
1766 }
1767
1768 EAPI void
_emotion_spu_button_num_set(Evas_Object * obj,int num)1769 _emotion_spu_button_num_set(Evas_Object *obj, int num)
1770 {
1771 Efl_Canvas_Video_Data *sd;
1772
1773 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1774 sd->spu.button_num = num;
1775 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_BUTTON_NUM_CHANGE, NULL);
1776 evas_object_smart_callback_call(obj, "button_num_change", NULL);
1777 }
1778
1779 EAPI void
_emotion_spu_button_set(Evas_Object * obj,int button)1780 _emotion_spu_button_set(Evas_Object *obj, int button)
1781 {
1782 Efl_Canvas_Video_Data *sd;
1783
1784 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1785 sd->spu.button = button;
1786 efl_event_callback_call(obj, EFL_CANVAS_VIDEO_EVENT_BUTTON_CHANGE, NULL);
1787 evas_object_smart_callback_call(obj, "button_change", NULL);
1788 }
1789
1790 EAPI void
_emotion_seek_done(Evas_Object * obj)1791 _emotion_seek_done(Evas_Object *obj)
1792 {
1793 Efl_Canvas_Video_Data *sd;
1794
1795 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1796 if (sd->seeking)
1797 {
1798 sd->seeking = 0;
1799 if (sd->seek) emotion_object_position_set(obj, sd->seek_pos);
1800 }
1801 }
1802
1803 EAPI void
_emotion_frame_refill(Evas_Object * obj,double w,double h)1804 _emotion_frame_refill(Evas_Object *obj, double w, double h)
1805 {
1806 Efl_Canvas_Video_Data *sd;
1807
1808 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1809 if ((!EINA_DBL_EQ(sd->fill.w, w)) ||
1810 (!EINA_DBL_EQ(sd->fill.h, h)))
1811 {
1812 Evas_Coord ow, oh;
1813
1814 evas_object_geometry_get(obj, NULL, NULL, &ow, &oh);
1815 if ((w <= 0) || (h <= 0))
1816 {
1817 double scale_w, scale_h;
1818
1819 sd->fill.w = -1;
1820 sd->fill.h = -1;
1821
1822 scale_w = (double)ow / (double)(sd->video.w - sd->crop.l - sd->crop.r);
1823 scale_h = (double)oh / (double)(sd->video.h - sd->crop.t - sd->crop.b);
1824 evas_object_image_fill_set(sd->obj, 0, 0, scale_w * sd->video.w, scale_h * sd->video.h);
1825 }
1826 else
1827 {
1828 sd->fill.w = w;
1829 sd->fill.h = h;
1830 evas_object_image_fill_set(sd->obj, 0, 0, w * ow, h * oh);
1831 }
1832 }
1833 }
1834
1835 /****************************/
1836 /* Internal object routines */
1837 /****************************/
1838
1839 static void
_mouse_move(void * data,Evas * ev EINA_UNUSED,Evas_Object * obj,void * event_info)1840 _mouse_move(void *data, Evas *ev EINA_UNUSED, Evas_Object *obj, void *event_info)
1841 {
1842 Evas_Event_Mouse_Move *e;
1843 Efl_Canvas_Video_Data *sd;
1844 int x, y, iw, ih;
1845 Evas_Coord ox, oy, ow, oh;
1846
1847 e = event_info;
1848 sd = data;
1849 if (!sd->engine_instance) return;
1850 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
1851 evas_object_image_size_get(obj, &iw, &ih);
1852 if ((iw < 1) || (ih < 1)) return;
1853 x = (((int)e->cur.canvas.x - ox) * iw) / ow;
1854 y = (((int)e->cur.canvas.y - oy) * ih) / oh;
1855 emotion_engine_instance_event_mouse_move_feed(sd->engine_instance, x, y);
1856 }
1857
1858 static void
_mouse_down(void * data,Evas * ev EINA_UNUSED,Evas_Object * obj,void * event_info)1859 _mouse_down(void *data, Evas *ev EINA_UNUSED, Evas_Object *obj, void *event_info)
1860 {
1861 Evas_Event_Mouse_Down *e;
1862 Efl_Canvas_Video_Data *sd;
1863 int x, y, iw, ih;
1864 Evas_Coord ox, oy, ow, oh;
1865
1866 e = event_info;
1867 sd = data;
1868 if (!sd->engine_instance) return;
1869 evas_object_geometry_get(obj, &ox, &oy, &ow, &oh);
1870 evas_object_image_size_get(obj, &iw, &ih);
1871 if ((iw < 1) || (ih < 1)) return;
1872 x = (((int)e->canvas.x - ox) * iw) / ow;
1873 y = (((int)e->canvas.y - oy) * ih) / oh;
1874 emotion_engine_instance_event_mouse_button_feed(sd->engine_instance, 1, x, y);
1875 }
1876
1877 static void
_pos_set_job(void * data)1878 _pos_set_job(void *data)
1879 {
1880 Evas_Object *obj;
1881 Efl_Canvas_Video_Data *sd;
1882
1883 obj = data;
1884 E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME);
1885 sd->job = NULL;
1886 if (!sd->engine_instance) return;
1887 if (sd->seeking) return;
1888 if (sd->seek)
1889 {
1890 sd->seeking = 1;
1891 emotion_engine_instance_pos_set(sd->engine_instance, sd->seek_pos);
1892 sd->seek = 0;
1893 }
1894 }
1895
1896 /* called by evas when it needs pixels for the image object */
1897 static void
_pixels_get(void * data,Evas_Object * obj)1898 _pixels_get(void *data, Evas_Object *obj)
1899 {
1900 int iw, ih, w, h;
1901 Efl_Canvas_Video_Data *sd;
1902 Emotion_Format format;
1903 unsigned char *bgra_data;
1904
1905 sd = data;
1906 if (!sd->engine_instance) return;
1907 emotion_engine_instance_video_data_size_get(sd->engine_instance, &w, &h);
1908 w = (w >> 1) << 1;
1909 h = (h >> 1) << 1;
1910
1911 evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
1912 evas_object_image_alpha_set(obj, 0);
1913 evas_object_image_size_set(obj, w, h);
1914 iw = w;
1915 ih = h;
1916
1917 if ((iw <= 1) || (ih <= 1))
1918 {
1919 _emotion_image_data_zero(sd->obj);
1920 evas_object_image_pixels_dirty_set(obj, 0);
1921 }
1922 else
1923 {
1924 format = emotion_engine_instance_format_get(sd->engine_instance);
1925 if ((format == EMOTION_FORMAT_YV12) || (format == EMOTION_FORMAT_I420))
1926 {
1927 unsigned char **rows;
1928
1929 evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_YCBCR422P601_PL);
1930 rows = evas_object_image_data_get(obj, 1);
1931 if (rows)
1932 {
1933 if (emotion_engine_instance_yuv_rows_get(sd->engine_instance, iw, ih,
1934 rows,
1935 &rows[ih],
1936 &rows[ih + (ih / 2)]))
1937 evas_object_image_data_update_add(obj, 0, 0, iw, ih);
1938 }
1939 evas_object_image_data_set(obj, rows);
1940 evas_object_image_pixels_dirty_set(obj, 0);
1941 }
1942 else if (format == EMOTION_FORMAT_BGRA)
1943 {
1944 evas_object_image_colorspace_set(obj, EVAS_COLORSPACE_ARGB8888);
1945 if (emotion_engine_instance_bgra_data_get(sd->engine_instance, &bgra_data))
1946 {
1947 evas_object_image_data_set(obj, bgra_data);
1948 evas_object_image_pixels_dirty_set(obj, 0);
1949 }
1950 }
1951 }
1952 }
1953
1954 /*******************************************/
1955 /* Internal smart object required routines */
1956 /*******************************************/
1957
1958 EOLIAN static void
_efl_canvas_video_efl_canvas_group_group_add(Evas_Object * obj,Efl_Canvas_Video_Data * sd)1959 _efl_canvas_video_efl_canvas_group_group_add(Evas_Object *obj, Efl_Canvas_Video_Data *sd)
1960 {
1961 Emotion_Xattr_Data *xattr;
1962 unsigned int *pixel;
1963
1964 /* TODO: remove legacy: emotion used to have no init, call automatically */
1965 emotion_init();
1966
1967 efl_canvas_group_add(efl_super(obj, MY_CLASS));
1968
1969 sd->state = EMOTION_WAKEUP;
1970 sd->obj = evas_object_image_add(evas_object_evas_get(obj));
1971 sd->bg = evas_object_rectangle_add(evas_object_evas_get(obj));
1972 sd->engine = eina_stringshare_add("gstreamer1");
1973 evas_object_color_set(sd->bg, 0, 0, 0, 0);
1974 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_MOVE, _mouse_move, sd);
1975 evas_object_event_callback_add(sd->obj, EVAS_CALLBACK_MOUSE_DOWN, _mouse_down, sd);
1976 evas_object_image_pixels_get_callback_set(sd->obj, _pixels_get, sd);
1977 evas_object_smart_member_add(sd->obj, obj);
1978 evas_object_smart_member_add(sd->bg, obj);
1979 evas_object_lower(sd->bg);
1980 sd->ratio = 1.0;
1981 sd->spu.button = -1;
1982 sd->fill.w = -1;
1983 sd->fill.h = -1;
1984 evas_object_image_alpha_set(sd->obj, 0);
1985 pixel = evas_object_image_data_get(sd->obj, 1);
1986 if (pixel)
1987 {
1988 *pixel = 0xff000000;
1989 evas_object_image_data_set(obj, pixel);
1990 }
1991 evas_object_show(sd->obj);
1992 evas_object_show(sd->bg);
1993
1994 xattr = calloc(1, sizeof(*xattr));
1995 EINA_REFCOUNT_INIT(xattr);
1996 efl_wref_add(obj, &xattr->obj_wref);
1997 sd->xattr = xattr;
1998 }
1999
2000 EOLIAN static void
_efl_canvas_video_efl_canvas_group_group_del(Evas_Object * obj EINA_UNUSED,Efl_Canvas_Video_Data * sd)2001 _efl_canvas_video_efl_canvas_group_group_del(Evas_Object *obj EINA_UNUSED, Efl_Canvas_Video_Data *sd)
2002 {
2003 if (sd->engine_instance)
2004 {
2005 emotion_engine_instance_file_close(sd->engine_instance);
2006 emotion_engine_instance_del(sd->engine_instance);
2007 }
2008 sd->engine_instance = NULL;
2009 if (sd->job) ecore_job_del(sd->job);
2010 sd->job = NULL;
2011 if (sd->anim) ecore_animator_del(sd->anim);
2012 sd->anim = NULL;
2013 eina_stringshare_del(sd->file);
2014 eina_stringshare_del(sd->progress.info);
2015 eina_stringshare_del(sd->ref.file);
2016 sd->file = NULL;
2017 sd->progress.info = NULL;
2018 sd->ref.file = NULL;
2019 _xattr_data_unref(sd->xattr);
2020 efl_canvas_group_del(efl_super(obj, MY_CLASS));
2021 emotion_shutdown();
2022 }
2023
2024 EOLIAN static void
_efl_canvas_video_efl_gfx_entity_position_set(Evas_Object * obj,Efl_Canvas_Video_Data * sd,Eina_Position2D pos)2025 _efl_canvas_video_efl_gfx_entity_position_set(Evas_Object *obj, Efl_Canvas_Video_Data *sd, Eina_Position2D pos)
2026 {
2027 Eina_Size2D sz;
2028
2029 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
2030 return;
2031
2032 efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
2033
2034 sz = efl_gfx_entity_size_get(obj);
2035 _clipper_position_size_update(obj, pos.x, pos.y, sz.w, sz.h, sd->video.w, sd->video.h);
2036 }
2037
2038 EOLIAN static void
_efl_canvas_video_efl_gfx_entity_size_set(Evas_Object * obj,Efl_Canvas_Video_Data * sd,Eina_Size2D sz)2039 _efl_canvas_video_efl_gfx_entity_size_set(Evas_Object *obj, Efl_Canvas_Video_Data *sd, Eina_Size2D sz)
2040 {
2041 if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, sz.w, sz.h))
2042 return;
2043
2044 efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
2045
2046 _efl_canvas_video_aspect_border_apply(obj, sd, sz.w, sz.h);
2047 evas_object_resize(sd->bg, sz.w, sz.h);
2048 }
2049
2050 /* Internal EO APIs and hidden overrides */
2051
2052 #define EFL_CANVAS_VIDEO_EXTRA_OPS \
2053 EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_canvas_video)
2054
2055
2056 #include "efl_canvas_video.eo.c"
2057 #include "efl_canvas_video_eo.legacy.c"
2058