Apply the Listener
[profile/tv/apps/native/videoplayer.git] / src / playermgr.cpp
1 /*
2  * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15 */
16
17 #include <Elementary.h>
18 #include <Eina.h>
19 #include <dbg.h>
20 #include "define.h"
21 #include "playermgr.h"
22
23 #define RATE_MAX 5.0
24 #define RATE_MIN -5.0
25
26 #define SPEED_MIN 0
27 #define SPEED_MAX 3
28
29 #define TIME_INTERVAL 1.0
30
31 static int _speed[] = {
32         0,
33         2000,
34         4000,
35         8000
36 };
37
38 struct playermgr {
39         player_h player;
40         Evas_Object *win;
41         Eina_List *media_list;
42
43         float speed;
44         int display_mode;
45         int audio_effect;
46         int current;
47         int total;
48         int rew_speed;
49         int ff_speed;
50         int duration;
51
52         Ecore_Timer *ffrew_timer;
53 };
54
55 static void _destroy_list(Eina_List *list)
56 {
57         char *buf;
58         void *o;
59
60         if (!list)
61                 return;
62
63         EINA_LIST_FREE(list, o) {
64                 buf = (char *)o;
65                 free(buf);
66         }
67 }
68
69 static Eina_List *_create_list(const char *playlist)
70 {
71         Eina_List *list = NULL;
72         FILE *fp;
73         char buf[1024];
74
75         if (!playlist)
76                 return NULL;
77
78         fp = fopen(playlist, "r");
79         if (!fp)
80                 return NULL;
81
82         while (fscanf(fp, "%s\n", buf) != EOF)
83                 list = eina_list_append(list, strdup(buf));
84
85         fclose(fp);
86
87         return list;
88 }
89
90 static int _get_current(Eina_List *list, const char *path)
91 {
92         Eina_List *l;
93         const char *filepath;
94         void *o;
95         int cur;
96
97         if (!list || !path)
98                 return 0;
99
100         cur = 0;
101
102         EINA_LIST_FOREACH(list, l, o) {
103                 filepath = (const char *)o;
104                 if (!strcmp(filepath, path))
105                         break;
106                 cur++;
107         }
108
109         return cur;
110 }
111
112 struct playermgr *playermgr_init(Evas_Object *win,
113                 const char *path, const char *playlist)
114 {
115         struct playermgr *mgr;
116
117         mgr = (playermgr *)calloc(1, sizeof(*mgr));
118         if (!mgr) {
119                 _ERR("Allocation fail");
120                 return NULL;
121         }
122
123         mgr->win = win;
124         mgr->display_mode = E_FULL_SCREEN;
125         mgr->audio_effect = 0;
126         mgr->rew_speed = 0;
127         mgr->ff_speed = 0;
128
129         mgr->media_list = _create_list(playlist);
130         if (!mgr->media_list) {
131                 _ERR("play list is null");
132                 free(mgr);
133                 return NULL;
134         }
135
136         mgr->current = _get_current(mgr->media_list, path);
137         mgr->total = eina_list_count(mgr->media_list);
138
139         if (player_create(&mgr->player) != PLAYER_ERROR_NONE) {
140                 _ERR("PLAYER CREATION ERROR");
141                 free(mgr);
142                 return NULL;
143         }
144
145
146         return mgr;
147 }
148
149 static int _play_video(struct playermgr *mgr, const char *path)
150 {
151         int r;
152
153         if (player_set_uri(mgr->player, path) != PLAYER_ERROR_NONE) {
154                 _ERR("PLAYER SET URI ERROR");
155                 return -1;
156         }
157
158         r = player_set_display(mgr->player, PLAYER_DISPLAY_TYPE_OVERLAY,
159                         GET_DISPLAY(mgr->win));
160         if (r != PLAYER_ERROR_NONE) {
161                 _ERR("SETTING DISPLAY ERROR: %d", r);
162                 return -1;
163         }
164
165         playermgr_set_display_mode(mgr, mgr->display_mode);
166
167         r = player_prepare(mgr->player);
168         if (r != PLAYER_ERROR_NONE) {
169                 if (r == PLAYER_ERROR_NOT_SUPPORTED_FILE)
170                         _ERR("PLAYER PREPARE ERROR NOT SUPPORTED FILE %d", r);
171                 else if (r == PLAYER_ERROR_INVALID_URI)
172                         _ERR("PLAYER PREPARE ERROR INVALID URI %d", r);
173                 else
174                         _ERR("PLAYER PREPARE ERROR");
175
176                 return -1;
177         }
178
179         r = player_start(mgr->player);
180         if (r != PLAYER_ERROR_NONE) {
181                 _ERR("PLAYER START ERROR");
182                 return -1;
183         }
184
185         playermgr_set_audio_effect(mgr, mgr->audio_effect);
186
187         return 0;
188 }
189
190 int playermgr_stop_video(struct playermgr *mgr)
191 {
192         if (!mgr || !mgr->player) {
193                 _ERR("invalid parameter");
194                 return -1;
195         }
196
197         player_pause(mgr->player);
198         player_stop(mgr->player);
199         player_unprepare(mgr->player);
200
201         return 0;
202 }
203
204 int playermgr_play_video(struct playermgr *mgr)
205 {
206         const char *path;
207         int r;
208
209         if (!mgr || !mgr->media_list) {
210                 _ERR("invalid parameter");
211                 return -1;
212         }
213
214         r = playermgr_stop_video(mgr);
215         if (r < 0)
216                 return r;
217
218         path = playermgr_get_video_path(mgr);
219         r = _play_video(mgr, path);
220
221         return r;
222 }
223
224 void playermgr_set_prev_video(struct playermgr *mgr)
225 {
226         if (!mgr) {
227                 _ERR("invalid parameter");
228                 return;
229         }
230
231         if (mgr->current == 0)
232                 mgr->current = mgr->total - 1;
233         else
234                 mgr->current--;
235 }
236
237 Eina_Bool playermgr_set_next_video(struct playermgr *mgr, Eina_Bool repeat)
238 {
239         if (!mgr) {
240                 _ERR("invalid parameter");
241                 return EINA_FALSE;
242         }
243
244         if (mgr->current == mgr->total - 1) {
245                 mgr->current = 0;
246
247                 if (!repeat)
248                         return EINA_FALSE;
249         } else {
250                 mgr->current++;
251         }
252
253         return EINA_TRUE;
254 }
255
256 const char *playermgr_get_video_path(struct playermgr *mgr)
257 {
258         const char *path;
259
260         if (!mgr || !mgr->media_list) {
261                 _ERR("invalid parameter");
262                 return NULL;
263         }
264
265         path = (const char *)eina_list_nth(mgr->media_list, mgr->current);
266
267         return path;
268 }
269
270 void playermgr_fini(struct playermgr *mgr)
271 {
272         if (!mgr)
273                 return;
274
275         if (mgr->ffrew_timer)
276                 ecore_timer_del(mgr->ffrew_timer);
277
278         if (mgr->media_list)
279                 _destroy_list(mgr->media_list);
280
281         if (mgr->player) {
282                 player_pause(mgr->player);
283                 player_stop(mgr->player);
284                 player_unprepare(mgr->player);
285                 player_destroy(mgr->player);
286         }
287
288         free(mgr);
289 }
290
291 int playermgr_pause(struct playermgr *mgr)
292 {
293         if (!mgr || !mgr->player) {
294                 _ERR("invalid parameter");
295                 return -1;
296         }
297
298         if (player_pause(mgr->player) != PLAYER_ERROR_NONE) {
299                 _ERR("Player pause error");
300                 return -1;
301         }
302
303         return 0;
304 }
305
306 int playermgr_resume(struct playermgr *mgr)
307 {
308         if (!mgr || !mgr->player) {
309                 _ERR("invalid parameter");
310                 return -1;
311         }
312
313         if (player_start(mgr->player) != PLAYER_ERROR_NONE) {
314                 _ERR("Player resume error");
315                 return -1;
316         }
317
318         return 0;
319 }
320
321 int playermgr_get_state(struct playermgr *mgr, player_state_e *state)
322 {
323         int r;
324
325         if (!mgr || !mgr->player) {
326                 _ERR("invalid parameter");
327                 return -1;
328         }
329
330         r = player_get_state(mgr->player, state);
331         if (r != PLAYER_ERROR_NONE) {
332                 _ERR("Player get state error");
333                 return -1;
334         }
335
336         return 0;
337 }
338
339 int playermgr_get_position(struct playermgr *mgr, int *position)
340 {
341         int r;
342
343         if (!mgr || !mgr->player) {
344                 _ERR("invalid parameter");
345                 return -1;
346         }
347
348         r = player_get_play_position(mgr->player, position);
349         if (r != PLAYER_ERROR_NONE) {
350                 _ERR("Player get position error");
351                 return -1;
352         }
353
354         return 0;
355 }
356
357 int playermgr_set_position(struct playermgr *mgr,
358                 int sec, player_seek_completed_cb cb, void *data)
359 {
360         int r;
361
362         if (!mgr || !mgr->player) {
363                 _ERR("invalid parameter");
364                 return -1;
365         }
366
367         r = player_set_play_position(mgr->player, sec, false, cb, data);
368         if (r != PLAYER_ERROR_NONE) {
369                 _ERR("Player set position error");
370                 return -1;
371         }
372
373         return 0;
374 }
375
376 int playermgr_set_playback_rate(struct playermgr *mgr, float speed)
377 {
378         int r;
379
380         if (!mgr || !mgr->player) {
381                 _ERR("invalid parameter");
382                 return -1;
383         }
384
385         if (speed > RATE_MAX)
386                 speed = RATE_MAX;
387         else if (speed < RATE_MIN)
388                 speed = RATE_MIN;
389
390         r = player_set_playback_rate(mgr->player, speed);
391         if (r != PLAYER_ERROR_NONE) {
392                 _ERR("Player set playback error");
393                 return -1;
394         }
395
396         mgr->speed = speed;
397
398         return 0;
399 }
400
401 int playermgr_get_playback_rate(struct playermgr *mgr, float *speed)
402 {
403         if (!mgr) {
404                 _ERR("invalid parameter");
405                 return -1;
406         }
407
408         *speed = mgr->speed;
409
410         return 0;
411 }
412
413 int playermgr_set_looping(struct playermgr *mgr, bool value)
414 {
415         int r;
416
417         if (!mgr || !mgr->player) {
418                 _ERR("invalid parameter");
419                 return -1;
420         }
421
422         r = player_set_looping(mgr->player, value);
423         if (r != PLAYER_ERROR_NONE) {
424                 _ERR("Player set looping error");
425                 return -1;
426         }
427
428         return 0;
429 }
430
431 int playermgr_set_audio_effect(struct playermgr *mgr, int value)
432 {
433         /* audio_effect not supported, just return 0 */
434         mgr->audio_effect = value;
435
436         return 0;
437 }
438
439 int playermgr_set_display_mode(struct playermgr *mgr, int value)
440 {
441         int r;
442         player_display_mode_e mode;
443
444         if (!mgr || !mgr->player) {
445                 _ERR("invalid parameter");
446                 return -1;
447         }
448
449         switch (value) {
450         case E_FULL_SCREEN:
451                 mode = PLAYER_DISPLAY_MODE_FULL_SCREEN;
452                 break;
453         case E_ORIGINAL:
454                 mode = PLAYER_DISPLAY_MODE_ORIGIN_SIZE;
455                 break;
456         default:
457                 _ERR("Invalid value");
458                 return -1;
459         }
460
461         r = player_set_display_mode(mgr->player, mode);
462         if (r != PLAYER_ERROR_NONE) {
463                 _ERR("Player display mode set error");
464                 return -1;
465         }
466
467         mgr->display_mode = value;
468
469         return 0;
470 }
471
472 int playermgr_set_completed_cb(struct playermgr *mgr,
473                 player_completed_cb cb, void *data)
474 {
475         int r;
476
477         if (!mgr || !mgr->player) {
478                 _ERR("invalid parameter");
479                 return -1;
480         }
481
482         r = player_set_completed_cb(mgr->player, cb, data);
483         if (r != PLAYER_ERROR_NONE) {
484                 _ERR("Player set completed cb error");
485                 return -1;
486         }
487
488         return 0;
489 }
490
491 void playermgr_get_play_count(struct playermgr *mgr, char *str, int len)
492 {
493         if (!mgr) {
494                 _ERR("invalid parameter");
495                 return;
496         }
497
498         snprintf(str, len, "%d/%d", mgr->current + 1, mgr->total);
499 }
500
501 static Eina_Bool _ffrew_timer_cb(void *dt)
502 {
503         struct playermgr *mgr;
504         int pos;
505         int r;
506
507         if (!dt)
508                 return ECORE_CALLBACK_CANCEL;
509
510         mgr = (struct playermgr *)dt;
511
512         if (!mgr->player)
513                 return ECORE_CALLBACK_CANCEL;
514
515         playermgr_get_position(mgr, &pos);
516
517         if (mgr->ff_speed) {
518                 pos = pos + _speed[mgr->ff_speed];
519                 if (pos > mgr->duration)
520                         pos = mgr->duration;
521         } else if (mgr->rew_speed) {
522                 pos = pos - _speed[mgr->rew_speed];
523                 if (pos < 0)
524                         pos = 0;
525         } else {
526                 r = playermgr_resume(mgr);
527                 if (r < 0)
528                         return ECORE_CALLBACK_RENEW;
529
530                 return ECORE_CALLBACK_CANCEL;
531         }
532
533         playermgr_set_position(mgr, pos, NULL, NULL);
534
535         if (mgr->rew_speed && pos <= 0) {
536                 mgr->rew_speed = SPEED_MIN;
537                 return ECORE_CALLBACK_CANCEL;
538         }
539
540         if (mgr->ff_speed && pos >= mgr->duration) {
541                 mgr->ff_speed = SPEED_MIN;
542                 return ECORE_CALLBACK_CANCEL;
543         }
544
545         if (ecore_timer_interval_get(mgr->ffrew_timer) != TIME_INTERVAL)
546                 ecore_timer_interval_set(mgr->ffrew_timer, TIME_INTERVAL);
547
548         return ECORE_CALLBACK_RENEW;
549 }
550
551 static void _start_ffrew_timer(struct playermgr *mgr)
552 {
553         playermgr_pause(mgr);
554
555         if (!mgr->ffrew_timer) {
556                 mgr->ffrew_timer = ecore_timer_add(0.0,
557                                 _ffrew_timer_cb, mgr);
558                 if (!mgr->ffrew_timer)
559                         return;
560         } else {
561                 ecore_timer_interval_set(mgr->ffrew_timer, 0.0);
562                 ecore_timer_reset(mgr->ffrew_timer);
563         }
564 }
565
566 int playermgr_set_ff(struct playermgr *mgr, int duration)
567 {
568         int r;
569
570         if (!mgr) {
571                 _ERR("invalid parameter");
572                 return -1;
573         }
574
575         r = 0;
576         mgr->duration = duration;
577         mgr->rew_speed = SPEED_MIN;
578
579         if (mgr->ff_speed == SPEED_MAX)
580                 return r;
581
582         if (mgr->ff_speed == SPEED_MIN) {
583                 _start_ffrew_timer(mgr);
584                 r = 1;
585         }
586
587         mgr->ff_speed++;
588
589         return r;
590 }
591
592 int playermgr_set_rew(struct playermgr *mgr, int duration)
593 {
594         int r;
595
596         if (!mgr) {
597                 _ERR("invalid parameter");
598                 return -1;
599         }
600
601         r = 0;
602         mgr->duration = duration;
603         mgr->ff_speed = SPEED_MIN;
604
605         if (mgr->rew_speed == SPEED_MAX)
606                 return r;
607
608         if (mgr->rew_speed == SPEED_MIN) {
609                 _start_ffrew_timer(mgr);
610                 r = 1;
611         }
612
613         mgr->rew_speed++;
614
615         return r;
616 }
617
618 bool playermgr_get_ffrew(struct playermgr *mgr)
619 {
620         if (mgr->ff_speed || mgr->rew_speed)
621                 return true;
622
623         return false;
624 }
625
626 void playermgr_stop_ffrew(struct playermgr *mgr)
627 {
628         if (!mgr)
629                 _ERR("invalid parameter");
630
631         mgr->ff_speed = SPEED_MIN;
632         mgr->rew_speed = SPEED_MIN;
633
634         if (mgr->ffrew_timer) {
635                 ecore_timer_del(mgr->ffrew_timer);
636                 mgr->ffrew_timer = NULL;
637         }
638 }