fix exception handling
[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 <AppCommon.h>
20 #include <dbg.h>
21 #include "define.h"
22 #include "playermgr.h"
23
24 #define RATE_MAX 5.0
25 #define RATE_MIN -5.0
26
27 #define SPEED_MIN 0
28 #define SPEED_MAX 3
29
30 #define TIME_INTERVAL 1.0
31
32 static int _speed[] = {
33         0,
34         2000,
35         4000,
36         8000
37 };
38
39 struct SPlayerData {
40         player_h player;
41         Evas_Object *win;
42         Eina_List *media_list;
43
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         EINA_LIST_FREE(list, o) {
61                 buf = (char *)o;
62                 free(buf);
63         }
64 }
65
66 static Eina_List *_create_list(const char *playlist)
67 {
68         Eina_List *list = NULL;
69         FILE *fp;
70         char buf[1024];
71
72         if (!playlist)
73                 return NULL;
74
75         fp = fopen(playlist, "r");
76         if (!fp)
77                 return NULL;
78
79         while (fscanf(fp, "%s\n", buf) != EOF)
80                 list = eina_list_append(list, strdup(buf));
81
82         fclose(fp);
83
84         return list;
85 }
86
87 static int _get_current(Eina_List *list, const char *path)
88 {
89         Eina_List *l;
90         const char *filepath;
91         void *o;
92         int cur;
93
94         if (!list || !path)
95                 return 0;
96
97         cur = 0;
98
99         EINA_LIST_FOREACH(list, l, o) {
100                 filepath = (const char *)o;
101                 if (!strcmp(filepath, path))
102                         break;
103                 cur++;
104         }
105
106         return cur;
107 }
108
109 bool CPlayer::Create(Evas_Object *win, const char *path, const char *playlist)
110 {
111         ASSERT(!m);
112
113         m = new SPlayerData;
114         if (!m) {
115                 _ERR("allocation fail");
116                 return false;
117         }
118
119         m->win = win;
120         m->player = NULL;
121         m->ffrew_timer = NULL;
122         m->display_mode = E_FULL_SCREEN;
123         m->audio_effect = 0;
124         m->rew_speed = 0;
125         m->ff_speed = 0;
126
127         m->media_list = _create_list(playlist);
128         if (!m->media_list) {
129                 _ERR("play list is null");
130                 delete m;
131                 m = NULL;
132
133                 return false;
134         }
135
136         m->current = _get_current(m->media_list, path);
137         m->total = eina_list_count(m->media_list);
138
139         if (player_create(&m->player) != PLAYER_ERROR_NONE) {
140                 _ERR("PLAYER CREATION ERROR");
141                 delete m;
142                 m = NULL;
143
144                 return false;
145         }
146
147         return true;
148 }
149
150 void CPlayer::Destroy(void)
151 {
152         ASSERT(m);
153
154         ecore_timer_del(m->ffrew_timer);
155
156         if (m->media_list)
157                 _destroy_list(m->media_list);
158
159         if (m->player) {
160                 player_pause(m->player);
161                 player_stop(m->player);
162                 player_unprepare(m->player);
163                 player_destroy(m->player);
164         }
165
166         delete m;
167         m = NULL;
168 }
169
170 bool CPlayer::m_Play(const char *path)
171 {
172         ASSERT(m->player);
173
174         int r;
175
176         r = player_set_uri(m->player, path);
177         if (r != PLAYER_ERROR_NONE) {
178                 _ERR("PLAYER SET URI ERROR: %d", r);
179                 return false;
180         }
181
182         r = player_set_display(m->player, PLAYER_DISPLAY_TYPE_OVERLAY,
183                         GET_DISPLAY(m->win));
184         if (r != PLAYER_ERROR_NONE) {
185                 _ERR("SETTING DISPLAY ERROR: %d", r);
186                 return false;
187         }
188
189         SetDisplayMode(m->display_mode);
190         SetAudioEffect(m->audio_effect);
191
192         r = player_prepare(m->player);
193         if (r != PLAYER_ERROR_NONE) {
194                 _ERR("PLAYER PREPARE ERROR: %d", r);
195                 return false;
196         }
197
198         r = player_start(m->player);
199         if (r != PLAYER_ERROR_NONE) {
200                 _ERR("PLAYER START ERROR: %d", r);
201                 return false;
202         }
203
204         return true;
205 }
206
207 bool CPlayer::Stop(void)
208 {
209         ASSERT(m);
210         ASSERT(m->player);
211
212         player_pause(m->player);
213         player_stop(m->player);
214         player_unprepare(m->player);
215
216         return true;
217 }
218
219 bool CPlayer::Play(void)
220 {
221         ASSERT(m);
222
223         const char *path;
224         bool r;
225
226         r = Stop();
227         if (!r)
228                 return r;
229
230         path = GetPath();
231
232         r = m_Play(path);
233
234         return r;
235 }
236
237 bool CPlayer::Prev(void)
238 {
239         ASSERT(m);
240
241         if (m->current == 0)
242                 m->current = m->total - 1;
243         else
244                 m->current--;
245
246         return true;
247 }
248
249 bool CPlayer::Next(bool repeat)
250 {
251         ASSERT(m);
252
253         if (m->current == m->total - 1) {
254                 m->current = 0;
255
256                 if (!repeat)
257                         return false;
258         } else {
259                 m->current++;
260         }
261
262         return true;
263 }
264
265 const char *CPlayer::GetPath(void)
266 {
267         ASSERT(m);
268         ASSERT(m->media_list);
269
270         const char *path;
271
272         path = (const char *)eina_list_nth(m->media_list, m->current);
273         ASSERT(path);
274
275         return path;
276 }
277
278 bool CPlayer::Pause(void)
279 {
280         ASSERT(m);
281         ASSERT(m->player);
282
283         player_state_e state;
284
285         GetState(&state);
286         if (state == PLAYER_STATE_PAUSED)
287                 return true;
288
289         if (player_pause(m->player) != PLAYER_ERROR_NONE) {
290                 _ERR("Player pause error");
291                 return false;
292         }
293
294         return true;
295 }
296
297 bool CPlayer::Resume(void)
298 {
299         ASSERT(m);
300         ASSERT(m->player);
301
302         player_state_e state;
303
304         GetState(&state);
305         if (state == PLAYER_STATE_PLAYING)
306                 return true;
307
308         if (player_start(m->player) != PLAYER_ERROR_NONE) {
309                 _ERR("Player resume error");
310                 return false;
311         }
312
313         return true;
314 }
315
316 bool CPlayer::GetState(player_state_e *state)
317 {
318         ASSERT(m);
319         ASSERT(m->player);
320
321         int r;
322
323         r = player_get_state(m->player, state);
324         if (r != PLAYER_ERROR_NONE) {
325                 _ERR("Player get state error");
326                 return false;
327         }
328
329         return true;
330 }
331
332 bool CPlayer::GetPosition(int *ms)
333 {
334         ASSERT(m);
335         ASSERT(m->player);
336
337         int r;
338
339         r = player_get_play_position(m->player, ms);
340         if (r != PLAYER_ERROR_NONE) {
341                 _ERR("Player get position error");
342                 return false;
343         }
344
345         return true;
346 }
347
348 bool CPlayer::SetPosition(int ms, player_seek_completed_cb cb, void *data)
349 {
350         ASSERT(m);
351         ASSERT(m->player);
352
353         int r;
354
355         r = player_set_play_position(m->player, ms, false, cb, data);
356         if (r != PLAYER_ERROR_NONE) {
357                 _ERR("Player set position error");
358                 return false;
359         }
360
361         return true;
362 }
363
364 bool CPlayer::SetAudioEffect(int value)
365 {
366         ASSERT(m);
367
368         /* audio_effect not supported, just return 0 */
369         m->audio_effect = value;
370
371         return true;
372 }
373
374 bool CPlayer::SetDisplayMode(int value)
375 {
376         ASSERT(m);
377         ASSERT(m->player);
378
379         int r;
380         player_display_mode_e mode;
381
382         /* display mode not supported, set to full screen forced */
383         mode = PLAYER_DISPLAY_MODE_FULL_SCREEN;
384
385         r = player_set_display_mode(m->player, mode);
386         if (r != PLAYER_ERROR_NONE) {
387                 _ERR("Player display mode set error");
388                 return false;
389         }
390
391         m->display_mode = value;
392
393         return true;
394 }
395
396 bool CPlayer::SetCompletedCb(player_completed_cb cb, void *data)
397 {
398         ASSERT(m);
399         ASSERT(m->player);
400
401         int r;
402
403         r = player_set_completed_cb(m->player, cb, data);
404         if (r != PLAYER_ERROR_NONE) {
405                 _ERR("Player set completed cb error");
406                 return false;
407         }
408
409         return true;
410 }
411
412 int CPlayer::GetTotal(void)
413 {
414         ASSERT(m);
415
416         return m->total;
417 }
418
419 int CPlayer::GetCurrent(void)
420 {
421         ASSERT(m);
422
423         return m->current;
424 }
425
426 Eina_Bool CPlayer::sm_CbFFRew(void *dt)
427 {
428         ASSERT(dt);
429
430         CPlayer *p;
431         SPlayerData *m;
432         int pos;
433
434         p = (CPlayer *)dt;
435         m = p->m;
436
437         ASSERT(m);
438
439         if (!m->player)
440                 return ECORE_CALLBACK_CANCEL;
441
442         p->GetPosition(&pos);
443
444         if (m->ff_speed) {
445                 pos = pos + _speed[m->ff_speed];
446                 if (pos > m->duration)
447                         pos = m->duration;
448         } else if (m->rew_speed) {
449                 pos = pos - _speed[m->rew_speed];
450                 if (pos < 0)
451                         pos = 0;
452         }
453
454         p->SetPosition(pos, NULL, NULL);
455
456         if (m->rew_speed && pos <= 0) {
457                 m->rew_speed = SPEED_MIN;
458                 return ECORE_CALLBACK_CANCEL;
459         }
460
461         if (m->ff_speed && pos >= m->duration) {
462                 m->ff_speed = SPEED_MIN;
463                 return ECORE_CALLBACK_CANCEL;
464         }
465
466         if (ecore_timer_interval_get(m->ffrew_timer) != TIME_INTERVAL)
467                 ecore_timer_interval_set(m->ffrew_timer, TIME_INTERVAL);
468
469         return ECORE_CALLBACK_RENEW;
470 }
471
472 void CPlayer::m_StartFFRew(void)
473 {
474         Pause();
475
476         if (!m->ffrew_timer) {
477                 m->ffrew_timer = ecore_timer_add(0.0, sm_CbFFRew, this);
478         } else {
479                 ecore_timer_interval_set(m->ffrew_timer, 0.0);
480                 ecore_timer_reset(m->ffrew_timer);
481         }
482 }
483
484 bool CPlayer::SetFF(int duration)
485 {
486         ASSERT(m);
487
488         bool r;
489
490         m->duration = duration;
491         m->rew_speed = SPEED_MIN;
492
493         if (m->ff_speed == SPEED_MAX)
494                 return false;
495
496         r = false;
497         if (m->ff_speed == SPEED_MIN) {
498                 m_StartFFRew();
499                 r = true;
500         }
501
502         m->ff_speed++;
503
504         return r;
505 }
506
507 bool CPlayer::SetRew(int duration)
508 {
509         ASSERT(m);
510
511         bool r;
512
513         m->duration = duration;
514         m->ff_speed = SPEED_MIN;
515
516         if (m->rew_speed == SPEED_MAX)
517                 return false;
518
519         r = false;
520         if (m->rew_speed == SPEED_MIN) {
521                 m_StartFFRew();
522                 r = true;
523         }
524
525         m->rew_speed++;
526
527         return r;
528 }
529
530 bool CPlayer::GetFFRew(void)
531 {
532         ASSERT(m);
533
534         if (m->ff_speed || m->rew_speed)
535                 return true;
536
537         return false;
538 }
539
540 void CPlayer::StopFFRew(void)
541 {
542         ASSERT(m);
543
544         m->ff_speed = SPEED_MIN;
545         m->rew_speed = SPEED_MIN;
546
547         ecore_timer_del(m->ffrew_timer);
548         m->ffrew_timer = NULL;
549 }