add roi API
[platform/core/multimedia/libmm-evas-renderer.git] / src / mm_evas_renderer.c
1 /*
2 * Copyright (c) 2011 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 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19
20 #include <glib.h>
21
22 #include <sys/types.h>
23 #include <unistd.h>
24 #include <sys/stat.h>
25 #include <string.h>
26 #include <sys/time.h>
27 #include <stdlib.h>
28 #include <dlog.h>
29 #include <mm_error.h>
30 #include <sys/syscall.h>
31 #include "mm_evas_renderer.h"
32
33 #ifdef LOG_TAG
34 #undef LOG_TAG
35 #endif
36 #define LOG_TAG "MM_EVAS_RENDER"
37 //#define _INTERNAL_DEBUG_ /* debug only */
38
39 #define MM_CHECK_NULL( x_var ) \
40 if ( ! x_var ) \
41 { \
42         LOGE("[%s] is NULL\n", #x_var ); \
43         return MM_ERROR_INVALID_ARGUMENT; \
44 }
45
46 #define SET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object, x_usr_data ) \
47         do \
48         { \
49                 if (x_evas_image_object) { \
50                         LOGD("object callback add"); \
51                         evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_DEL, _evas_del_cb, x_usr_data); \
52                         evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_RESIZE, _evas_resize_cb, x_usr_data); \
53                 } \
54         } while(0)
55
56 #define UNSET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object ) \
57         do \
58         { \
59                 if (x_evas_image_object) { \
60                         LOGD("object callback del"); \
61                         evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_DEL, _evas_del_cb); \
62                         evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_RESIZE, _evas_resize_cb); \
63                 } \
64         } while(0)
65
66 #define SET_EVAS_EVENT_CALLBACK( x_evas, x_usr_data ) \
67         do \
68         { \
69                 if (x_evas) { \
70                         LOGD("callback add... evas_callback_render_pre.. evas : %p evas_info : %p", x_evas, x_usr_data); \
71                         evas_event_callback_add (x_evas, EVAS_CALLBACK_RENDER_PRE, _evas_render_pre_cb, x_usr_data); \
72                 } \
73         } while(0)
74
75 #define UNSET_EVAS_EVENT_CALLBACK( x_evas ) \
76         do \
77         { \
78                 if (x_evas) { \
79                         LOGD("callback del... evas_callback_render_pre %p", x_evas); \
80                         evas_event_callback_del (x_evas, EVAS_CALLBACK_RENDER_PRE, _evas_render_pre_cb); \
81                 } \
82         } while(0)
83
84 enum {
85         DISP_GEO_METHOD_LETTER_BOX = 0,
86         DISP_GEO_METHOD_ORIGIN_SIZE,
87         DISP_GEO_METHOD_FULL_SCREEN,
88         DISP_GEO_METHOD_CROPPED_FULL_SCREEN,
89         DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX,
90         DISP_GEO_METHOD_CUSTOM_ROI,
91         DISP_GEO_METHOD_NUM,
92 };
93
94 enum {
95         DEGREE_0 = 0,
96         DEGREE_90,
97         DEGREE_180,
98         DEGREE_270,
99         DEGREE_NUM,
100 };
101
102 enum {
103         FLIP_NONE = 0,
104         FLIP_HORIZONTAL,
105         FLIP_VERTICAL,
106         FLIP_BOTH,
107         FLIP_NUM,
108 };
109
110 #ifdef _INTERNAL_DEBUG_
111 void __print_idx(mm_evas_info *evas_info);
112 #endif
113 /* internal */
114 void _free_previous_packets(mm_evas_info *evas_info);
115 int _flush_packets(mm_evas_info *evas_info);
116 int _mm_evas_renderer_create(mm_evas_info **evas_info);
117 int _mm_evas_renderer_destroy(mm_evas_info **evas_info);
118 int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo);
119 int _mm_evas_renderer_reset(mm_evas_info *evas_info);
120 void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result);
121 int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info);
122 int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_screen);
123 int _mm_evas_renderer_make_flush_buffer(mm_evas_info *evas_info);
124 void _mm_evas_renderer_release_flush_buffer(mm_evas_info *evas_info);
125 static void _mm_evas_renderer_set_callback(mm_evas_info *evas_info);
126 static void _mm_evas_renderer_unset_callback(mm_evas_info *evas_info);
127
128 static void _evas_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
129 {
130         int x, y, w, h, ret;
131         x = y = w = h = 0;
132
133         mm_evas_info *evas_info = data;
134         LOGD("[ENTER]");
135
136         if (!evas_info || !evas_info->eo) {
137                 return;
138         }
139
140         evas_object_geometry_get(evas_info->eo, &x, &y, &w, &h);
141         if (!w || !h) {
142                 LOGW("evas object size (w:%d,h:%d) was not set", w, h);
143         } else {
144                 evas_info->eo_size.x = x;
145                 evas_info->eo_size.y = y;
146                 evas_info->eo_size.w = w;
147                 evas_info->eo_size.h = h;
148                 LOGW("resize (x:%d, y:%d, w:%d, h:%d)", x, y, w, h);
149                 ret = _mm_evas_renderer_apply_geometry(evas_info);
150                 if (ret != MM_ERROR_NONE)
151                         LOGW("fail to apply geometry info");
152         }
153         LOGD("[LEAVE]");
154 }
155
156 static void _evas_render_pre_cb(void *data, Evas *e, void *event_info)
157 {
158         mm_evas_info *evas_info = data;
159
160         if (!evas_info || !evas_info->eo) {
161                 LOGW("there is no esink info.... esink : %p, or eo is NULL returning", evas_info);
162                 return;
163         }
164
165         /* flush will be executed in this callback normally,
166         because native_surface_set must be called in main thread */
167         if (evas_info->retrieve_packet) {
168                 g_mutex_lock(&evas_info->idx_lock);
169                 if (_flush_packets(evas_info) != MM_ERROR_NONE)
170                         LOGE("flushing packets are failed");
171                 g_mutex_unlock(&evas_info->idx_lock);
172         }
173 }
174
175 static void _evas_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
176 {
177         mm_evas_info *evas_info = data;
178         LOGD("[ENTER]");
179         if (!evas_info || !evas_info->eo) {
180                 return;
181         }
182         if (evas_info->eo) {
183                 _mm_evas_renderer_unset_callback(evas_info);
184                 evas_object_image_data_set(evas_info->eo, NULL);
185                 evas_info->eo = NULL;
186         }
187         LOGD("[LEAVE]");
188 }
189
190 void _evas_pipe_cb(void *data, void *buffer, update_info info)
191 {
192         mm_evas_info *evas_info = data;
193
194         LOGD("[ENTER]");
195
196         if (!evas_info) {
197                 LOGW("evas_info is NULL", evas_info);
198                 return;
199         }
200
201         g_mutex_lock(&evas_info->mp_lock);
202
203         if (!evas_info->eo) {
204                 LOGW("evas_info %p", evas_info);
205                 g_mutex_unlock(&evas_info->mp_lock);
206                 return;
207         }
208
209         LOGD("evas_info : %p, evas_info->eo : %p", evas_info, evas_info->eo);
210         if (info == UPDATE_VISIBILITY) {
211                 if (evas_info->visible == VISIBLE_FALSE) {
212                         evas_object_hide(evas_info->eo);
213                         LOGI("object hide..");
214                 } else {
215                         evas_object_show(evas_info->eo);
216                         LOGI("object show.. %d", evas_info->visible);
217                 }
218                 LOGD("[LEAVE]");
219                 g_mutex_unlock(&evas_info->mp_lock);
220                 return;
221         }
222
223         if (info != UPDATE_TBM_SURF) {
224                 LOGW("invalid info type : %d", info);
225                 g_mutex_unlock(&evas_info->mp_lock);
226                 return;
227         }
228
229         if (evas_info->cur_idx==-1 || !evas_info->pkt_info[evas_info->cur_idx].tbm_surf) {
230                 LOGW("cur_idx %d, tbm_surf may be NULL", evas_info->cur_idx);
231                 g_mutex_unlock(&evas_info->mp_lock);
232                 return;
233         }
234         /* perhaps, it is needed to skip setting when state is pause */
235
236         g_mutex_lock(&evas_info->idx_lock);
237         /* index */
238         gint cur_idx = evas_info->cur_idx;
239         gint prev_idx = evas_info->pkt_info[cur_idx].prev;
240
241         LOGD("received (idx %d, packet %p)", cur_idx, evas_info->pkt_info[cur_idx].packet);
242
243         tbm_format tbm_fmt = tbm_surface_get_format(evas_info->pkt_info[cur_idx].tbm_surf);
244         switch (tbm_fmt) {
245         case TBM_FORMAT_NV12:
246                 LOGD("tbm_surface format : TBM_FORMAT_NV12");
247                 break;
248         case TBM_FORMAT_YUV420:
249                 LOGD("tbm_surface format : TBM_FORMAT_YUV420");
250                 break;
251         default:
252                 LOGW("tbm_surface format : unknown %d", tbm_fmt);
253                 break;
254         }
255
256         Evas_Native_Surface surf;
257         surf.type = EVAS_NATIVE_SURFACE_TBM;
258         surf.version = EVAS_NATIVE_SURFACE_VERSION;
259         surf.data.tbm.buffer = evas_info->pkt_info[cur_idx].tbm_surf;
260         surf.data.tbm.rot = evas_info->rotate_angle;
261         surf.data.tbm.flip = evas_info->flip;
262
263         rect_info result = { 0 };
264
265         evas_object_geometry_get(evas_info->eo, &evas_info->eo_size.x, &evas_info->eo_size.y, &evas_info->eo_size.w, &evas_info->eo_size.h);
266         if (!evas_info->eo_size.w || !evas_info->eo_size.h) {
267                 LOGE("there is no information for evas object size");
268                 goto ERROR;
269         }
270         _mm_evas_renderer_update_geometry(evas_info, &result);
271         if (!result.w || !result.h) {
272                 LOGE("no information about geometry (%d, %d)", result.w, result.h);
273                 goto ERROR;
274         }
275
276         if (evas_info->use_ratio) {
277                 surf.data.tbm.ratio = (float) evas_info->w / evas_info->h;
278                 LOGD("set ratio for letter mode");
279         }
280         evas_object_size_hint_align_set(evas_info->eo, EVAS_HINT_FILL, EVAS_HINT_FILL);
281         evas_object_size_hint_weight_set(evas_info->eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
282         if (evas_info->w > 0 && evas_info->h > 0)
283                 evas_object_image_size_set(evas_info->eo, evas_info->w, evas_info->h);
284
285         evas_object_image_native_surface_set(evas_info->eo, &surf);
286         LOGD("native surface set finish");
287
288         if (result.x || result.y)
289                 LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
290
291         if (evas_info->display_geometry_method != DISP_GEO_METHOD_CUSTOM_ROI)
292                 evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
293
294         evas_object_image_pixels_dirty_set(evas_info->eo, EINA_TRUE);
295         LOGD("GEO_METHOD : src(%dx%d), dst(%dx%d), dst_x(%d), dst_y(%d), rotate(%d), flip(%d)", evas_info->w, evas_info->h, evas_info->eo_size.w, evas_info->eo_size.h, evas_info->eo_size.x, evas_info->eo_size.y, evas_info->rotate_angle, evas_info->flip);
296
297         /* when _evas_pipe_cb is called sequentially, previous packet and current packet will be the same */
298         if ((prev_idx != -1) && evas_info->pkt_info[prev_idx].packet && (prev_idx != cur_idx))
299                 _free_previous_packets(evas_info);
300
301         LOGD("[LEAVE]");
302         g_mutex_unlock(&evas_info->idx_lock);
303         g_mutex_unlock(&evas_info->mp_lock);
304
305         return;
306
307  ERROR:
308         if ((prev_idx != -1) && evas_info->pkt_info[prev_idx].packet) {
309                 LOGI("cant render");
310                 _free_previous_packets(evas_info);
311         }
312         g_mutex_unlock(&evas_info->idx_lock);
313         g_mutex_unlock(&evas_info->mp_lock);
314 }
315
316 #ifdef _INTERNAL_DEBUG_
317 void __print_idx(mm_evas_info *evas_info)
318 {
319         gint prev_idx = evas_info->pkt_info[evas_info->cur_idx].prev;
320         LOGE("***** start cur_idx : %d -> prev_idx : %d", evas_info->cur_idx, prev_idx);
321         while(prev_idx != -1)
322         {
323                 LOGE("***** cur_idx : %d -> prev_idx : %d", prev_idx, evas_info->pkt_info[prev_idx].prev);
324                 prev_idx = evas_info->pkt_info[prev_idx].prev;
325         }
326         LOGE("***** end");
327         return;
328 }
329 #endif
330
331 void _free_previous_packets(mm_evas_info *evas_info)
332 {
333         gint index = evas_info->cur_idx;
334         gint prev_idx = evas_info->pkt_info[index].prev;
335
336         while(prev_idx != -1)
337         {
338                 LOGD("destroy previous packet [%p] idx %d", evas_info->pkt_info[prev_idx].packet, prev_idx);
339                 if (media_packet_destroy(evas_info->pkt_info[prev_idx].packet) != MEDIA_PACKET_ERROR_NONE)
340                         LOGE("media_packet_destroy failed %p", evas_info->pkt_info[prev_idx].packet);
341                 evas_info->pkt_info[prev_idx].packet = NULL;
342                 evas_info->pkt_info[prev_idx].tbm_surf = NULL;
343                 evas_info->pkt_info[index].prev = -1;
344                 evas_info->sent_buffer_cnt--;
345
346                 /* move index to previous index */
347                 index= prev_idx;
348                 prev_idx = evas_info->pkt_info[prev_idx].prev;
349                 LOGD("sent packet %d", evas_info->sent_buffer_cnt);
350         }
351         return;
352 }
353
354 static int _get_video_size(media_packet_h packet, mm_evas_info *evas_info)
355 {
356         media_format_h fmt;
357         if (media_packet_get_format(packet, &fmt) == MEDIA_PACKET_ERROR_NONE) {
358                 int w, h;
359                 if (media_format_get_video_info(fmt, NULL, &w, &h, NULL, NULL) == MEDIA_PACKET_ERROR_NONE) {
360                         LOGD("video width = %d, height =%d", w, h);
361                         evas_info->w = w;
362                         evas_info->h = h;
363                         return true;
364                 } else
365                         LOGW("media_format_get_video_info is failed");
366                 if (media_format_unref(fmt) != MEDIA_PACKET_ERROR_NONE) /* because of media_packet_get_format */
367                         LOGW("media_format_unref is failed");
368         } else {
369                 LOGW("media_packet_get_format is failed");
370         }
371         return false;
372 }
373
374 int _find_empty_index(mm_evas_info *evas_info)
375 {
376         int i;
377         for (i = 0; i < MAX_PACKET_NUM; i++) {
378                 if (!evas_info->pkt_info[i].packet) {
379                         LOGD("selected idx %d", i);
380                         return i;
381                 }
382         }
383         LOGE("there is no empty idx");
384
385         return -1;
386 }
387
388 int _flush_packets(mm_evas_info *evas_info)
389 {
390         int ret = MM_ERROR_NONE;
391         int ret_mp = MEDIA_PACKET_ERROR_NONE;
392         int i = 0;
393
394         if (!evas_info) {
395                 LOGW("there is no esink info");
396                 return MM_ERROR_INVALID_ARGUMENT;
397         }
398         /* update the screen only if visible is ture */
399         if (evas_info->keep_screen && (evas_info->visible != VISIBLE_FALSE)) {
400                 Evas_Native_Surface surf;
401                 rect_info result = { 0 };
402                 evas_object_geometry_get(evas_info->eo, &evas_info->eo_size.x, &evas_info->eo_size.y, &evas_info->eo_size.w, &evas_info->eo_size.h);
403                 if (!evas_info->eo_size.w || !evas_info->eo_size.h) {
404                         LOGE("there is no information for evas object size");
405                         return MM_ERROR_INVALID_ARGUMENT;
406                 }
407                 _mm_evas_renderer_update_geometry(evas_info, &result);
408                 if (!result.w || !result.h) {
409                         LOGE("no information about geometry (%d, %d)", result.w, result.h);
410                         return MM_ERROR_INVALID_ARGUMENT;
411                 }
412
413                 if (evas_info->use_ratio) {
414                         surf.data.tbm.ratio = (float) evas_info->w / evas_info->h;
415                         LOGD("set ratio for letter mode");
416                 }
417                 evas_object_size_hint_align_set(evas_info->eo, EVAS_HINT_FILL, EVAS_HINT_FILL);
418                 evas_object_size_hint_weight_set(evas_info->eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
419                 if (evas_info->w > 0 && evas_info->h > 0)
420                         evas_object_image_size_set(evas_info->eo, evas_info->w, evas_info->h);
421
422                 if (result.x || result.y)
423                         LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
424
425                 if (evas_info->display_geometry_method != DISP_GEO_METHOD_CUSTOM_ROI)
426                         evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
427
428                 /* set flush buffer */
429                 surf.type = EVAS_NATIVE_SURFACE_TBM;
430                 surf.version = EVAS_NATIVE_SURFACE_VERSION;
431                 surf.data.tbm.buffer = evas_info->flush_buffer->tbm_surf;
432                 surf.data.tbm.rot = evas_info->rotate_angle;
433                 surf.data.tbm.flip = evas_info->flip;
434                 evas_object_image_native_surface_set(evas_info->eo, &surf);
435
436                 LOGD("flush_buffer surf(%p), rotate(%d), flip(%d)", evas_info->flush_buffer->tbm_surf, evas_info->rotate_angle, evas_info->flip);
437         } else {
438                 /* unset evas native surface for displaying black screen */
439                 evas_object_image_native_surface_set (evas_info->eo, NULL);
440                 evas_object_image_data_set (evas_info->eo, NULL);
441         }
442         LOGD("sent packet %d", evas_info->sent_buffer_cnt);
443
444         /* destroy all packets */
445         g_mutex_lock(&evas_info->mp_lock);
446         for (i = 0; i < MAX_PACKET_NUM; i++) {
447                 if (evas_info->pkt_info[i].packet) {
448                         LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
449                         ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
450                         if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
451                                 LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
452                                 ret = MM_ERROR_UNKNOWN;
453                         }
454                         else
455                                 evas_info->sent_buffer_cnt--;
456                         evas_info->pkt_info[i].packet = NULL;
457                         evas_info->pkt_info[i].tbm_surf = NULL;
458                         evas_info->pkt_info[i].prev = -1;
459                 }
460         }
461
462         if (evas_info->sent_buffer_cnt != 0)
463                 LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
464         evas_info->sent_buffer_cnt = 0;
465         evas_info->cur_idx = -1;
466         g_mutex_unlock(&evas_info->mp_lock);
467
468         evas_object_image_pixels_dirty_set (evas_info->eo, EINA_TRUE);
469         evas_info->retrieve_packet = FALSE;
470
471         return ret;
472 }
473
474 #if 0
475 int _reset_pipe(mm_evas_info *evas_info)
476 {
477         int i = 0;
478         int ret = MM_ERROR_NONE;
479         int ret_mp = MEDIA_PACKET_ERROR_NONE;
480
481         /* delete old pipe */
482         if (evas_info->epipe) {
483                 LOGD("pipe %p will be deleted", evas_info->epipe);
484                 ecore_pipe_del(evas_info->epipe);
485                 evas_info->epipe = NULL;
486         }
487
488         for (i = 0; i < MAX_PACKET_NUM; i++) {
489                 if (evas_info->pkt_info[i].packet) {
490                         /* destroy all packets */
491                         LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
492                         ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
493                         if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
494                                 LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
495                                 ret = MM_ERROR_UNKNOWN;
496                         }
497                         else
498                                 evas_info->sent_buffer_cnt--;
499                         evas_info->pkt_info[i].packet = NULL;
500                         evas_info->pkt_info[i].tbm_surf = NULL;
501                         evas_info->pkt_info[i].prev = -1;
502                 }
503         }
504
505         if (evas_info->sent_buffer_cnt != 0)
506                 LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
507         evas_info->sent_buffer_cnt = 0;
508         evas_info->cur_idx = -1;
509
510         /* make new pipe */
511         if (!evas_info->epipe) {
512                 evas_info->epipe = ecore_pipe_add((Ecore_Pipe_Cb) _evas_pipe_cb, evas_info);
513                 if (!evas_info->epipe) {
514                         LOGE("pipe is not created");
515                         ret = MM_ERROR_UNKNOWN;
516                 }
517                 LOGD("created pipe %p", evas_info->epipe);
518         }
519
520         return ret;
521 }
522 #endif
523
524 static void _mm_evas_renderer_set_callback(mm_evas_info *evas_info)
525 {
526         if (evas_info->eo) {
527                 SET_EVAS_OBJECT_EVENT_CALLBACK(evas_info->eo, evas_info);
528                 SET_EVAS_EVENT_CALLBACK(evas_object_evas_get(evas_info->eo), evas_info);
529         }
530 }
531
532 static void _mm_evas_renderer_unset_callback(mm_evas_info *evas_info)
533 {
534         if (evas_info->eo) {
535                 UNSET_EVAS_OBJECT_EVENT_CALLBACK(evas_info->eo);
536                 UNSET_EVAS_EVENT_CALLBACK(evas_object_evas_get(evas_info->eo));
537         }
538 }
539
540 int _mm_evas_renderer_create(mm_evas_info **evas_info)
541 {
542         mm_evas_info *ptr = NULL;
543         ptr = g_malloc0(sizeof(mm_evas_info));
544
545         if (!ptr) {
546                 LOGE("Cannot allocate memory for evas_info\n");
547                 goto ERROR;
548         } else {
549                 *evas_info = ptr;
550                 LOGD("Success create evas_info(%p)", *evas_info);
551         }
552         g_mutex_init(&ptr->mp_lock);
553         g_mutex_init(&ptr->idx_lock);
554
555         return MM_ERROR_NONE;
556
557  ERROR:
558         *evas_info = NULL;
559         return MM_ERROR_OUT_OF_STORAGE;
560 }
561
562 int _mm_evas_renderer_destroy(mm_evas_info **evas_info)
563 {
564         mm_evas_info *ptr = (mm_evas_info *)*evas_info;
565         MM_CHECK_NULL(ptr);
566         int ret = MM_ERROR_NONE;
567
568         LOGD("finalize evas_info %p", ptr);
569
570         ret = _mm_evas_renderer_reset(ptr);
571         g_mutex_clear(&ptr->mp_lock);
572         g_mutex_clear(&ptr->idx_lock);
573
574         g_free(ptr);
575         ptr = NULL;
576
577         return ret;
578 }
579
580 int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo)
581 {
582         MM_CHECK_NULL(evas_info);
583         MM_CHECK_NULL(eo);
584         g_mutex_lock(&evas_info->idx_lock);
585
586         LOGD("set evas_info");
587         int i;
588         for (i = 0; i < MAX_PACKET_NUM; i++) {
589                 evas_info->pkt_info[i].packet = NULL;
590                 evas_info->pkt_info[i].tbm_surf = NULL;
591                 evas_info->pkt_info[i].prev = -1;
592         }
593         evas_info->cur_idx = -1;
594         evas_info->dst_roi.x = evas_info->dst_roi.y = evas_info->dst_roi.w = evas_info->dst_roi.h = 0;
595         evas_info->eo = eo;
596         evas_info->epipe = ecore_pipe_add((Ecore_Pipe_Cb) _evas_pipe_cb, evas_info);
597         if (!evas_info->epipe) {
598                 LOGE("pipe is not created");
599                 g_mutex_unlock(&evas_info->idx_lock);
600                 return MM_ERROR_UNKNOWN;
601         }
602         LOGD("created pipe %p", evas_info->epipe);
603         _mm_evas_renderer_set_callback(evas_info);
604
605         evas_object_geometry_get(evas_info->eo, &evas_info->eo_size.x, &evas_info->eo_size.y, &evas_info->eo_size.w, &evas_info->eo_size.h);
606         LOGI("evas object %p (%d, %d, %d, %d)", evas_info->eo, evas_info->eo_size.x, evas_info->eo_size.y, evas_info->eo_size.w, evas_info->eo_size.h);
607
608         g_mutex_unlock(&evas_info->idx_lock);
609
610         return MM_ERROR_NONE;
611 }
612
613 int _mm_evas_renderer_reset(mm_evas_info *evas_info)
614 {
615         MM_CHECK_NULL(evas_info);
616         g_mutex_lock(&evas_info->idx_lock);
617
618         int i;
619         int ret = MM_ERROR_NONE;
620         int ret_mp = MEDIA_PACKET_ERROR_NONE;
621
622         if (evas_info->eo) {
623                 _mm_evas_renderer_unset_callback(evas_info);
624                 evas_object_image_data_set(evas_info->eo, NULL);
625                 evas_info->eo = NULL;
626         }
627         if (evas_info->epipe) {
628                 LOGD("pipe %p will be deleted", evas_info->epipe);
629                 ecore_pipe_del(evas_info->epipe);
630                 evas_info->epipe = NULL;
631         }
632
633         evas_info->eo_size.x = evas_info->eo_size.y = evas_info->eo_size.w = evas_info->eo_size.h = 0;
634         evas_info->dst_roi.x = evas_info->dst_roi.y = evas_info->dst_roi.w = evas_info->dst_roi.h = 0;
635         evas_info->w = evas_info->h = 0;
636
637         if (evas_info->flush_buffer)
638                 _mm_evas_renderer_release_flush_buffer(evas_info);
639
640         g_mutex_lock(&evas_info->mp_lock);
641         for (i = 0; i < MAX_PACKET_NUM; i++) {
642                 if (evas_info->pkt_info[i].packet) {
643                         /* destroy all packets */
644                         LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
645                         ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
646                         if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
647                                 LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
648                                 ret = MM_ERROR_UNKNOWN;
649                         }
650                         else
651                                 evas_info->sent_buffer_cnt--;
652                         evas_info->pkt_info[i].packet = NULL;
653                         evas_info->pkt_info[i].tbm_surf = NULL;
654                         evas_info->pkt_info[i].prev = -1;
655                 }
656         }
657         g_mutex_unlock(&evas_info->mp_lock);
658         if (evas_info->sent_buffer_cnt != 0)
659                 LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
660         evas_info->sent_buffer_cnt = 0;
661         evas_info->cur_idx = -1;
662
663         g_mutex_unlock(&evas_info->idx_lock);
664
665         return ret;
666 }
667
668 void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result)
669 {
670         if (!evas_info || !evas_info->eo) {
671                 LOGW("there is no evas_info or evas object");
672                 return;
673         }
674         if (!result) {
675                 LOGW("there is no rect info");
676                 return;
677         }
678
679         result->x = 0;
680         result->y = 0;
681
682         switch (evas_info->display_geometry_method) {
683         case DISP_GEO_METHOD_LETTER_BOX:
684                 /* set black padding for letter box mode */
685                 LOGD("letter box mode");
686                 evas_info->use_ratio = TRUE;
687                 result->w = evas_info->eo_size.w;
688                 result->h = evas_info->eo_size.h;
689                 break;
690         case DISP_GEO_METHOD_ORIGIN_SIZE:
691                 LOGD("origin size mode");
692                 evas_info->use_ratio = FALSE;
693                 /* set coordinate for each case */
694                 result->x = (evas_info->eo_size.w - evas_info->w) / 2;
695                 result->y = (evas_info->eo_size.h - evas_info->h) / 2;
696                 result->w = evas_info->w;
697                 result->h = evas_info->h;
698                 break;
699         case DISP_GEO_METHOD_FULL_SCREEN:
700                 LOGD("full screen mode");
701                 evas_info->use_ratio = FALSE;
702                 result->w = evas_info->eo_size.w;
703                 result->h = evas_info->eo_size.h;
704                 break;
705         case DISP_GEO_METHOD_CROPPED_FULL_SCREEN:
706                 LOGD("cropped full screen mode");
707                 evas_info->use_ratio = FALSE;
708                 /* compare evas object's ratio with video's */
709                 if ((evas_info->eo_size.w / evas_info->eo_size.h) > (evas_info->w / evas_info->h)) {
710                         result->w = evas_info->eo_size.w;
711                         result->h = evas_info->eo_size.w * evas_info->h / evas_info->w;
712                         result->y = -(result->h - evas_info->eo_size.h) / 2;
713                 } else {
714                         result->w = evas_info->eo_size.h * evas_info->w / evas_info->h;
715                         result->h = evas_info->eo_size.h;
716                         result->x = -(result->w - evas_info->eo_size.w) / 2;
717                 }
718                 break;
719         case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX:
720                 LOGD("origin size or letter box mode");
721                 /* if video size is smaller than evas object's, it will be set to origin size mode */
722                 if ((evas_info->eo_size.w > evas_info->w) && (evas_info->eo_size.h > evas_info->h)) {
723                         LOGD("origin size mode");
724                         evas_info->use_ratio = FALSE;
725                         /* set coordinate for each case */
726                         result->x = (evas_info->eo_size.w - evas_info->w) / 2;
727                         result->y = (evas_info->eo_size.h - evas_info->h) / 2;
728                         result->w = evas_info->w;
729                         result->h = evas_info->h;
730                 } else {
731                         LOGD("letter box mode");
732                         evas_info->use_ratio = TRUE;
733                         result->w = evas_info->eo_size.w;
734                         result->h = evas_info->eo_size.h;
735                 }
736                 break;
737         case DISP_GEO_METHOD_CUSTOM_ROI:
738                 LOGD("custom roi mode");
739                 evas_info->use_ratio= FALSE;
740                 result->x = evas_info->dst_roi.x;
741                 result->y = evas_info->dst_roi.y;
742                 result->w = evas_info->dst_roi.w;
743                 result->h = evas_info->dst_roi.h;
744
745                 /* don't call evas_object_image_fill_set */
746                 evas_object_move(evas_info->eo, result->x, result->y);
747                 evas_object_resize(evas_info->eo, result->w, result->h);
748                 break;
749         default:
750                 LOGW("unsupported mode.");
751                 break;
752         }
753         LOGD("geometry result [%d, %d, %d, %d]", result->x, result->y, result->w, result->h);
754 }
755
756 int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info)
757 {
758         if (!evas_info || !evas_info->eo) {
759                 LOGW("there is no evas_info or evas object");
760                 return MM_ERROR_NONE;
761         }
762
763         Evas_Native_Surface *surf = evas_object_image_native_surface_get(evas_info->eo);
764         rect_info result = { 0 };
765
766         if (surf) {
767                 LOGD("native surface exists");
768                 surf->data.tbm.rot = evas_info->rotate_angle;
769                 surf->data.tbm.flip = evas_info->flip;
770                 evas_object_image_native_surface_set(evas_info->eo, surf);
771
772                 _mm_evas_renderer_update_geometry(evas_info, &result);
773
774                 if (evas_info->use_ratio) {
775                         surf->data.tbm.ratio = (float) evas_info->w / evas_info->h;
776                         LOGD("set ratio for letter mode");
777                 }
778
779                 if (result.x || result.y)
780                         LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
781
782                 if (evas_info->display_geometry_method != DISP_GEO_METHOD_CUSTOM_ROI)
783                         evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
784                 return MM_ERROR_NONE;
785         } else
786                 LOGW("there is no surf");
787         /* FIXME: before pipe_cb is invoked, apply_geometry can be called. */
788         return MM_ERROR_NONE;
789 }
790
791 int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_screen)
792 {
793         MM_CHECK_NULL(evas_info);
794
795         int ret = MM_ERROR_NONE;
796         pid_t pid = getpid();
797         pid_t tid = syscall(SYS_gettid);
798
799         /* write and this API can be called at the same time.
800         so lock is needed for counting sent_buffer_cnt correctly */
801         g_mutex_lock(&evas_info->idx_lock);
802
803         /* make flush buffer */
804         if (keep_screen)
805                 ret = _mm_evas_renderer_make_flush_buffer(evas_info);
806         evas_info->keep_screen = keep_screen;
807
808         LOGD("pid [%d], tid [%d]", pid, tid);
809         if (pid == tid) {
810                 /* in this case, we deem it is main thread */
811                 if (_flush_packets(evas_info) != MM_ERROR_NONE) {
812                         LOGE("flushing packets are failed");
813                         ret = MM_ERROR_UNKNOWN;
814                 }
815         } else {
816                 /* it will be executed to write flush buffer and destroy media packets in pre_cb */
817                 evas_info->retrieve_packet = TRUE;
818         }
819         g_mutex_unlock(&evas_info->idx_lock);
820
821         return ret;
822 }
823
824 /* make buffer for copying */
825 int _mm_evas_renderer_make_flush_buffer (mm_evas_info *evas_info)
826 {
827         if (evas_info->cur_idx == -1) {
828                 LOGW("there is no remained buffer");
829                 return MM_ERROR_INVALID_ARGUMENT;
830         }
831         media_packet_h packet = evas_info->pkt_info[evas_info->cur_idx].packet;
832         MM_CHECK_NULL(packet);
833
834         flush_info *flush_buffer = NULL;
835         tbm_bo src_bo = NULL;
836         tbm_surface_h src_tbm_surf = NULL;
837         int src_size = 0;
838         int size = 0;
839         tbm_bo bo = NULL;
840         tbm_format tbm_fmt;
841         tbm_bo_handle vaddr_src = {0};
842         tbm_bo_handle vaddr_dst = {0};
843         int ret = MM_ERROR_NONE;
844
845         if (evas_info->flush_buffer)
846                 _mm_evas_renderer_release_flush_buffer(evas_info);
847
848         /* malloc buffer */
849         flush_buffer = (flush_info *)malloc(sizeof(flush_info));
850         if (flush_buffer == NULL) {
851                 LOGE("malloc is failed");
852                 return FALSE;
853         }
854         memset(flush_buffer, 0x0, sizeof(flush_info));
855
856         ret = media_packet_get_tbm_surface(packet, &src_tbm_surf);
857         if (ret != MEDIA_PACKET_ERROR_NONE || !src_tbm_surf) {
858                 LOGW("get_tbm_surface is failed");
859                 goto ERROR;
860         }
861
862         /* get src buffer info */
863         tbm_fmt = tbm_surface_get_format(src_tbm_surf);
864         src_bo = tbm_surface_internal_get_bo(src_tbm_surf, 0);
865         src_size = tbm_bo_size(src_bo);
866         if (!src_bo || !src_size) {
867                 LOGE("bo(%p), size(%d)", src_bo, src_size);
868                 goto ERROR;
869         }
870
871         /* create tbm surface */
872         flush_buffer->tbm_surf = tbm_surface_create(evas_info->w, evas_info->h, tbm_fmt);
873         if (!flush_buffer->tbm_surf)
874         {
875                 LOGE("tbm_surf is NULL!!");
876                 goto ERROR;
877         }
878
879         /* get bo and size */
880         bo = tbm_surface_internal_get_bo(flush_buffer->tbm_surf, 0);
881         size = tbm_bo_size(bo);
882         if (!bo || !size)
883         {
884                 LOGE("bo(%p), size(%d)", bo, size);
885                 goto ERROR;
886         }
887         flush_buffer->bo = bo;
888
889         vaddr_src = tbm_bo_map(src_bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE);
890         vaddr_dst = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE);
891         if (!vaddr_src.ptr || !vaddr_dst.ptr) {
892                 LOGW("get vaddr failed src %p, dst %p", vaddr_src.ptr, vaddr_dst.ptr);
893                 if (vaddr_src.ptr) {
894                         tbm_bo_unmap(src_bo);
895                 }
896                 if (vaddr_dst.ptr) {
897                         tbm_bo_unmap(bo);
898                 }
899                 goto ERROR;
900         } else {
901                 memset (vaddr_dst.ptr, 0x0, size);
902                 LOGW ("tbm_bo_map(vaddr) is finished, bo(%p), vaddr(%p)", bo, vaddr_dst.ptr);
903         }
904
905         /* copy buffer */
906         memcpy(vaddr_dst.ptr, vaddr_src.ptr, src_size);
907
908         tbm_bo_unmap(src_bo);
909         tbm_bo_unmap(bo);
910         LOGW("copy is done. tbm surface : %p src_size : %d", flush_buffer->tbm_surf, src_size);
911
912         evas_info->flush_buffer = flush_buffer;
913
914         return MM_ERROR_NONE;
915
916 ERROR:
917         if (flush_buffer) {
918                 if(flush_buffer->tbm_surf)
919                 {
920                         tbm_surface_destroy(flush_buffer->tbm_surf);
921                         flush_buffer->tbm_surf = NULL;
922                 }
923
924                 free(flush_buffer);
925                 flush_buffer = NULL;
926         }
927         return MM_ERROR_UNKNOWN;
928 }
929
930 /* release flush buffer */
931 void _mm_evas_renderer_release_flush_buffer (mm_evas_info *evas_info)
932 {
933         LOGW("release FLUSH BUFFER start");
934         if (evas_info->flush_buffer->bo) {
935                 evas_info->flush_buffer->bo = NULL;
936         }
937         if (evas_info->flush_buffer->tbm_surf) {
938                 tbm_surface_destroy(evas_info->flush_buffer->tbm_surf);
939                 evas_info->flush_buffer->tbm_surf = NULL;
940         }
941
942         LOGW("release FLUSH BUFFER done");
943
944         free(evas_info->flush_buffer);
945         evas_info->flush_buffer = NULL;
946
947         return;
948 }
949
950 void mm_evas_renderer_write(media_packet_h packet, void *data)
951 {
952         if (!packet) {
953                 LOGE("packet %p is NULL", packet);
954                 return;
955         }
956         mm_evas_info *handle = (mm_evas_info *)data;
957         int ret = MEDIA_PACKET_ERROR_NONE;
958         bool has;
959         tbm_surface_h tbm_surf;
960         gint index;
961
962         LOGD("packet [%p]", packet);
963
964         if (!data || !handle) {
965                 LOGE("handle %p or evas_info %p is NULL", data, handle);
966                 goto INVALID_PARAM;
967         }
968         g_mutex_lock(&handle->idx_lock);
969
970         ret = media_packet_has_tbm_surface_buffer(packet, &has);
971         if (ret != MEDIA_PACKET_ERROR_NONE) {
972                 LOGW("has_tbm_surface is failed");
973                 goto ERROR;
974         }
975         /* FIXME: when setCaps occurs, _get_video_size should be called */
976         /* currently we are always checking it */
977         if (has && _get_video_size(packet, handle)) {
978                 /* Attention! if this error occurs, we need to consider managing buffer */
979                 if (handle->sent_buffer_cnt > 4) {
980                         LOGE("too many buffers are not released %d", handle->sent_buffer_cnt);
981                         goto ERROR;
982 #if 0
983                         /* FIXME: fix this logic */
984                         /* destroy all media packets and reset pipe at present */
985                         /* Attention! it might free buffer that is being rendered */
986                         g_mutex_lock(&handle->mp_lock);
987                         _reset_pipe(handle);
988                         g_mutex_unlock(&handle->mp_lock);
989 #endif
990                 }
991                 ret = media_packet_get_tbm_surface(packet, &tbm_surf);
992                 if (ret != MEDIA_PACKET_ERROR_NONE || !tbm_surf) {
993                         LOGW("get_tbm_surface is failed");
994                         goto ERROR;
995                 }
996
997                 /* find new index for current packet */
998                 index = _find_empty_index(handle);
999                 if (index == -1) {
1000                         goto ERROR;
1001                 }
1002
1003                 /* save previous index */
1004                 handle->pkt_info[index].prev = handle->cur_idx;
1005                 handle->pkt_info[index].packet = packet;
1006                 handle->pkt_info[index].tbm_surf = tbm_surf;
1007                 handle->cur_idx = index;
1008                 handle->sent_buffer_cnt++;
1009                 LOGD("sent packet %d", handle->sent_buffer_cnt);
1010
1011                 ret = ecore_pipe_write(handle->epipe, handle, UPDATE_TBM_SURF);
1012                 if (!ret) {
1013                         handle->pkt_info[index].packet = NULL;
1014                         handle->pkt_info[index].tbm_surf = NULL;
1015                         handle->pkt_info[index].prev = -1;
1016                         handle->cur_idx = handle->pkt_info[index].prev;
1017                         handle->sent_buffer_cnt--;
1018                         LOGW("Failed to ecore_pipe_write() for updating tbm surf\n");
1019                         goto ERROR;
1020                 }
1021         } else {
1022                 LOGW("no tbm_surf");
1023                 goto ERROR;
1024         }
1025         g_mutex_unlock(&handle->idx_lock);
1026
1027         return;
1028 ERROR:
1029         g_mutex_unlock(&handle->idx_lock);
1030 INVALID_PARAM:
1031         /* destroy media_packet immediately */
1032         if (packet) {
1033                 g_mutex_lock(&handle->mp_lock);
1034                 LOGD("cant write. destroy packet [%p]", packet);
1035                 if (media_packet_destroy(packet) != MEDIA_PACKET_ERROR_NONE)
1036                         LOGE("media_packet_destroy failed %p", packet);
1037                 packet = NULL;
1038                 g_mutex_unlock(&handle->mp_lock);
1039         }
1040         return;
1041 }
1042
1043 int mm_evas_renderer_update_param(MMHandleType handle)
1044 {
1045         int ret = MM_ERROR_NONE;
1046         mm_evas_info *evas_info = (mm_evas_info *)handle;
1047
1048         if (!evas_info) {
1049                 LOGW("skip it. it is not evas surface type.");
1050                 return ret;
1051         }
1052
1053         /* when handle is realized, we need to update all properties */
1054         if (evas_info) {
1055                 LOGD("set video param : evas-object %x, method %d", evas_info->eo, evas_info->display_geometry_method);
1056                 LOGD("set video param : visible %d", evas_info->visible);
1057                 LOGD("set video param : rotate %d", evas_info->rotate_angle);
1058
1059                 ret = _mm_evas_renderer_apply_geometry(evas_info);
1060                 if (ret != MM_ERROR_NONE)
1061                         return ret;
1062
1063                 if (evas_info->epipe) {
1064                         ret = ecore_pipe_write(evas_info->epipe, &evas_info->visible, UPDATE_VISIBILITY);
1065                         if (!ret) {
1066                                 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1067                                 return MM_ERROR_UNKNOWN;
1068                         } else
1069                                 ret = MM_ERROR_NONE;
1070
1071 #if 0           /* FIXME: pause state only */
1072                         g_mutex_lock(&evas_info->idx_lock);
1073                         ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1074                         if (!ret) {
1075                                 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1076                                 ret = MM_ERROR_UNKNOWN;
1077                         } else {
1078                                 ret = MM_ERROR_NONE;
1079                         }
1080                         g_mutex_unlock(&evas_info->idx_lock);
1081 #endif
1082                 }
1083         }
1084
1085         return ret;
1086 }
1087
1088 int mm_evas_renderer_create(MMHandleType *handle, Evas_Object *eo)
1089 {
1090         MM_CHECK_NULL(handle);
1091
1092         int ret = MM_ERROR_NONE;
1093         mm_evas_info *evas_info = NULL;
1094
1095         ret = _mm_evas_renderer_create(&evas_info);
1096         if (ret != MM_ERROR_NONE) {
1097                 LOGE("fail to create evas_info");
1098                 return ret;
1099         }
1100         ret = _mm_evas_renderer_set_info(evas_info, eo);
1101         if (ret != MM_ERROR_NONE) {
1102                 LOGE("fail to init evas_info");
1103                 if (_mm_evas_renderer_destroy(&evas_info) != MM_ERROR_NONE)
1104                         LOGE("fail to destroy evas_info");
1105                 return ret;
1106         }
1107
1108         *handle = (MMHandleType)evas_info;
1109
1110         return MM_ERROR_NONE;
1111 }
1112
1113 int mm_evas_renderer_destroy(MMHandleType *handle)
1114 {
1115         MM_CHECK_NULL(handle);
1116
1117         int ret = MM_ERROR_NONE;
1118         mm_evas_info *evas_info = (mm_evas_info *)*handle;
1119
1120         if (!evas_info) {
1121                 LOGD("skip it. it is not evas surface type.");
1122                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1123         }
1124
1125         ret = _mm_evas_renderer_destroy(&evas_info);
1126         if (ret != MM_ERROR_NONE) {
1127                 LOGE("fail to destroy evas_info");
1128                 return ret;
1129         }
1130         *handle = NULL;
1131
1132         return MM_ERROR_NONE;
1133 }
1134
1135 int mm_evas_renderer_set_visible(MMHandleType handle, bool visible)
1136 {
1137         int ret = MM_ERROR_NONE;
1138         mm_evas_info *evas_info = (mm_evas_info *)handle;
1139
1140         if (!evas_info) {
1141                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1142                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1143         }
1144
1145         if (visible)
1146                 evas_info->visible = VISIBLE_TRUE;
1147         else
1148                 evas_info->visible = VISIBLE_FALSE;
1149
1150         if (evas_info->epipe) {
1151                 ret = ecore_pipe_write(evas_info->epipe, &visible, UPDATE_VISIBILITY);
1152                 if (!ret) {
1153                         LOGW("fail to ecore_pipe_write() for updating visibility\n");
1154                         ret = MM_ERROR_UNKNOWN;
1155                 } else {
1156                         ret = MM_ERROR_NONE;
1157                 }
1158         } else {
1159                 LOGW("there is no epipe. we cant update it");
1160         }
1161
1162         return ret;
1163 }
1164
1165 int mm_evas_renderer_get_visible(MMHandleType handle, bool *visible)
1166 {
1167         mm_evas_info *evas_info = (mm_evas_info *)handle;
1168
1169         if (!evas_info) {
1170                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1171                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1172         }
1173
1174         if (evas_info->visible == VISIBLE_FALSE)
1175                 *visible = FALSE;
1176         else
1177                 *visible = TRUE;
1178
1179         return MM_ERROR_NONE;
1180 }
1181
1182 int mm_evas_renderer_set_rotation(MMHandleType handle, int rotate)
1183 {
1184         int ret = MM_ERROR_NONE;
1185         mm_evas_info *evas_info = (mm_evas_info *)handle;
1186
1187         if (!evas_info) {
1188                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1189                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1190         }
1191
1192         switch(rotate) {
1193         case DEGREE_0:
1194                 evas_info->rotate_angle = EVAS_IMAGE_ORIENT_0;
1195                 break;
1196         case DEGREE_90:
1197                 evas_info->rotate_angle = EVAS_IMAGE_ORIENT_90;
1198                 break;
1199         case DEGREE_180:
1200                 evas_info->rotate_angle = EVAS_IMAGE_ORIENT_180;
1201                 break;
1202         case DEGREE_270:
1203                 evas_info->rotate_angle = EVAS_IMAGE_ORIENT_270;
1204                 break;
1205         default:
1206                 return MM_ERROR_INVALID_ARGUMENT;
1207         }
1208 #if 0   /* FIXME: pause state only */
1209         if (evas_info->epipe) {
1210                 g_mutex_lock(&evas_info->idx_lock);
1211                 ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1212                 if (!ret) {
1213                         LOGW("fail to ecore_pipe_write() for updating visibility\n");
1214                         ret = MM_ERROR_UNKNOWN;
1215                 } else {
1216                         ret = MM_ERROR_NONE;
1217                 }
1218                 g_mutex_unlock(&evas_info->idx_lock);
1219         }
1220 #endif
1221         return ret;
1222 }
1223
1224 int mm_evas_renderer_get_rotation(MMHandleType handle, int *rotate)
1225 {
1226         mm_evas_info *evas_info = (mm_evas_info *)handle;
1227
1228         if (!evas_info) {
1229                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1230                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1231         }
1232
1233         switch(evas_info->rotate_angle) {
1234         case EVAS_IMAGE_ORIENT_0:
1235                 *rotate = DEGREE_0;
1236                 break;
1237         case EVAS_IMAGE_ORIENT_90:
1238                 *rotate = DEGREE_90;
1239                 break;
1240         case EVAS_IMAGE_ORIENT_180:
1241                 *rotate = DEGREE_180;
1242                 break;
1243         case EVAS_IMAGE_ORIENT_270:
1244                 *rotate = DEGREE_270;
1245                 break;
1246         default:
1247                 return MM_ERROR_INVALID_ARGUMENT;
1248         }
1249
1250         return MM_ERROR_NONE;
1251 }
1252
1253 int mm_evas_renderer_set_geometry(MMHandleType handle, int mode)
1254 {
1255         int ret = MM_ERROR_NONE;
1256         mm_evas_info *evas_info = (mm_evas_info *)handle;
1257
1258         if (!evas_info) {
1259                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1260                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1261         }
1262
1263         evas_info->display_geometry_method = mode;
1264         ret = _mm_evas_renderer_apply_geometry(evas_info);
1265
1266         /* ecore_pipe_write is needed, because of setting ratio for letterbox mode */
1267 #if 0   /* FIXME: pause state only */
1268         if (evas_info->epipe) {
1269                 g_mutex_lock(&evas_info->idx_lock);
1270                 ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1271                 if (!ret) {
1272                         LOGW("fail to ecore_pipe_write() for updating visibility\n");
1273                         ret = MM_ERROR_UNKNOWN;
1274                 } else {
1275                         ret = MM_ERROR_NONE;
1276                 }
1277                 g_mutex_unlock(&evas_info->idx_lock);
1278         }
1279 #endif
1280
1281         return ret;
1282 }
1283
1284 int mm_evas_renderer_get_geometry(MMHandleType handle, int *mode)
1285 {
1286         mm_evas_info *evas_info = (mm_evas_info *)handle;
1287
1288         if (!evas_info) {
1289                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1290                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1291         }
1292         *mode = evas_info->display_geometry_method;
1293
1294         return MM_ERROR_NONE;
1295 }
1296
1297 int mm_evas_renderer_set_roi_area(MMHandleType handle, int x, int y, int w, int h)
1298 {
1299         int ret = MM_ERROR_NONE;
1300         mm_evas_info *evas_info = (mm_evas_info *)handle;
1301
1302         if (!evas_info) {
1303                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1304                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1305         }
1306         if (!w || !h) {
1307                 LOGW("invalid resolution");
1308                 return MM_ERROR_INVALID_ARGUMENT;
1309         }
1310
1311         /* display mode is set to DISP_GEO_METHOD_CUSTOM_ROI internally */
1312         evas_info->display_geometry_method = DISP_GEO_METHOD_CUSTOM_ROI;
1313         evas_info->dst_roi.x = x;
1314         evas_info->dst_roi.y = y;
1315         evas_info->dst_roi.w = w;
1316         evas_info->dst_roi.h = h;
1317         ret = _mm_evas_renderer_apply_geometry(evas_info);
1318
1319         return ret;
1320 }
1321
1322 int mm_evas_renderer_get_roi_area(MMHandleType handle, int *x, int *y, int *w, int *h)
1323 {
1324         mm_evas_info *evas_info = (mm_evas_info *)handle;
1325
1326         if (!evas_info) {
1327                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1328                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1329         }
1330         if (evas_info->display_geometry_method != DISP_GEO_METHOD_CUSTOM_ROI) {
1331                 LOGW("invalid mode");
1332                 return MM_ERROR_INVALID_ARGUMENT;
1333         }
1334
1335         *x = evas_info->dst_roi.x;
1336         *y = evas_info->dst_roi.y;
1337         *w = evas_info->dst_roi.w;
1338         *h = evas_info->dst_roi.h;
1339
1340         return MM_ERROR_NONE;
1341 }
1342
1343 int mm_evas_renderer_set_flip(MMHandleType handle, int flip)
1344 {
1345         int ret = MM_ERROR_NONE;
1346         mm_evas_info *evas_info = (mm_evas_info *)handle;
1347
1348         if (!evas_info) {
1349                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1350                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1351         }
1352
1353         switch(flip) {
1354         case FLIP_NONE :
1355                 evas_info->flip = EVAS_IMAGE_ORIENT_NONE;
1356                 break;
1357         case FLIP_HORIZONTAL:
1358                 evas_info->flip = EVAS_IMAGE_FLIP_HORIZONTAL;
1359                 break;
1360         case FLIP_VERTICAL:
1361                 evas_info->flip = EVAS_IMAGE_FLIP_VERTICAL;
1362                 break;
1363         case FLIP_BOTH:
1364                 evas_info->flip = EVAS_IMAGE_ORIENT_180;
1365                 break;
1366         default:
1367                 return MM_ERROR_INVALID_ARGUMENT;
1368         }
1369 #if 0   /* FIXME: pause state only */
1370         if (evas_info->epipe) {
1371                 g_mutex_lock(&evas_info->idx_lock);
1372                 ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1373                 if (!ret) {
1374                         LOGW("fail to ecore_pipe_write() for updating visibility\n");
1375                         ret = MM_ERROR_UNKNOWN;
1376                 } else {
1377                         ret = MM_ERROR_NONE;
1378                 }
1379                 g_mutex_unlock(&evas_info->idx_lock);
1380         }
1381 #endif
1382         return ret;
1383 }
1384
1385 int mm_evas_renderer_get_flip(MMHandleType handle, int *flip)
1386 {
1387         mm_evas_info *evas_info = (mm_evas_info *)handle;
1388
1389         if (!evas_info) {
1390                 LOGW("skip it. it is not evas surface type or handle is not prepared");
1391                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1392         }
1393
1394         switch(evas_info->flip) {
1395         case EVAS_IMAGE_ORIENT_NONE:
1396                 *flip = FLIP_NONE;
1397                 break;
1398         case EVAS_IMAGE_FLIP_HORIZONTAL:
1399                 *flip = FLIP_HORIZONTAL;
1400                 break;
1401         case EVAS_IMAGE_FLIP_VERTICAL:
1402                 *flip = FLIP_VERTICAL;
1403                 break;
1404         case EVAS_IMAGE_ORIENT_180:
1405                 *flip = FLIP_BOTH;
1406                 break;
1407         default:
1408                 return MM_ERROR_INVALID_ARGUMENT;
1409         }
1410
1411         return MM_ERROR_NONE;
1412 }
1413
1414 int mm_evas_renderer_retrieve_all_packets (MMHandleType handle, bool keep_screen)
1415 {
1416         int ret = MM_ERROR_NONE;
1417         mm_evas_info *evas_info = (mm_evas_info*) handle;
1418
1419         if (!evas_info) {
1420                 LOGW("skip it. it is not evas surface type or player is not prepared");
1421                 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1422         }
1423         ret = _mm_evas_renderer_retrieve_all_packets(evas_info, keep_screen);
1424
1425         return ret;
1426 }