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