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