fix svace issue
[platform/core/multimedia/libmm-evas-renderer.git] / src / mm_evas_renderer.c
index 7a8b8d7..a62fa61 100644 (file)
 #undef LOG_TAG
 #endif
 #define LOG_TAG "MM_EVAS_RENDER"
+//#define _INTERNAL_DEBUG_ /* debug only */
 
-#define MM_CHECK_NULL( x_var ) \
-if ( ! x_var ) \
-{ \
-       LOGE("[%s] is NULL\n", #x_var ); \
-       return MM_ERROR_INVALID_ARGUMENT; \
-}
+#if 0
+#define MMER_FENTER();                                 LOGD("<ENTER>");
+#define MMER_FLEAVE();                                 LOGD("<LEAVE>");
+#else
+#define MMER_FENTER();
+#define MMER_FLEAVE();
+#endif
+
+#define MM_CHECK_NULL(x_var) \
+       if (!x_var) { \
+               LOGE("[%s] is NULL\n", #x_var); \
+               return MM_ERROR_INVALID_ARGUMENT; \
+       }
 
-#define SET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object, x_usr_data ) \
-       do \
-       { \
+#define SET_EVAS_OBJECT_EVENT_CALLBACK(x_evas_image_object, x_usr_data) \
+       do { \
                if (x_evas_image_object) { \
                        LOGD("object callback add"); \
-                       evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_DEL, _evas_del_cb, x_usr_data); \
-                       evas_object_event_callback_add (x_evas_image_object, EVAS_CALLBACK_RESIZE, _evas_resize_cb, x_usr_data); \
+                       evas_object_event_callback_add(x_evas_image_object, EVAS_CALLBACK_DEL, _evas_del_cb, x_usr_data); \
+                       evas_object_event_callback_add(x_evas_image_object, EVAS_CALLBACK_RESIZE, _evas_resize_cb, x_usr_data); \
                } \
-       } while(0)
+       } while (0)
 
-#define UNSET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object ) \
-       do \
-       { \
+#define UNSET_EVAS_OBJECT_EVENT_CALLBACK(x_evas_image_object) \
+       do { \
                if (x_evas_image_object) { \
                        LOGD("object callback del"); \
-                       evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_DEL, _evas_del_cb); \
-                       evas_object_event_callback_del (x_evas_image_object, EVAS_CALLBACK_RESIZE, _evas_resize_cb); \
+                       evas_object_event_callback_del(x_evas_image_object, EVAS_CALLBACK_DEL, _evas_del_cb); \
+                       evas_object_event_callback_del(x_evas_image_object, EVAS_CALLBACK_RESIZE, _evas_resize_cb); \
                } \
-       } while(0)
+       } while (0)
 
-#define SET_EVAS_EVENT_CALLBACK( x_evas, x_usr_data ) \
-       do \
-       { \
+#define SET_EVAS_EVENT_CALLBACK(x_evas, x_usr_data) \
+       do { \
                if (x_evas) { \
                        LOGD("callback add... evas_callback_render_pre.. evas : %p evas_info : %p", x_evas, x_usr_data); \
-                       evas_event_callback_add (x_evas, EVAS_CALLBACK_RENDER_PRE, _evas_render_pre_cb, x_usr_data); \
+                       evas_event_callback_add(x_evas, EVAS_CALLBACK_RENDER_PRE, _evas_render_pre_cb, x_usr_data); \
                } \
-       } while(0)
+       } while (0)
 
-#define UNSET_EVAS_EVENT_CALLBACK( x_evas ) \
-       do \
-       { \
+#define UNSET_EVAS_EVENT_CALLBACK(x_evas) \
+       do { \
                if (x_evas) { \
                        LOGD("callback del... evas_callback_render_pre %p", x_evas); \
-                       evas_event_callback_del (x_evas, EVAS_CALLBACK_RENDER_PRE, _evas_render_pre_cb); \
+                       evas_event_callback_del(x_evas, EVAS_CALLBACK_RENDER_PRE, _evas_render_pre_cb); \
                } \
-       } while(0)
+       } while (0)
 
 enum {
        DISP_GEO_METHOD_LETTER_BOX = 0,
@@ -86,6 +90,7 @@ enum {
        DISP_GEO_METHOD_FULL_SCREEN,
        DISP_GEO_METHOD_CROPPED_FULL_SCREEN,
        DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX,
+       DISP_GEO_METHOD_CUSTOM_ROI,
        DISP_GEO_METHOD_NUM,
 };
 
@@ -105,35 +110,37 @@ enum {
        FLIP_NUM,
 };
 
-/* internal */
-#ifdef _DEBUG_INDEX
-void __print_idx(mm_evas_info *evas_info);
+#ifdef _INTERNAL_DEBUG_
+static int g_cnt = 0;
+static void __print_idx(mm_evas_info *evas_info);
+static int __dump_pkt(media_packet_h pkt);
 #endif
-void _free_previous_packets(mm_evas_info *evas_info);
-int _flush_packets(mm_evas_info *evas_info);
-int _mm_evas_renderer_create(mm_evas_info **evas_info);
-int _mm_evas_renderer_destroy(mm_evas_info **evas_info);
-int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo);
-int _mm_evas_renderer_reset(mm_evas_info *evas_info);
-void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result);
-int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info);
-int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_screen);
-int _mm_evas_renderer_make_flush_buffer(mm_evas_info *evas_info);
-void _mm_evas_renderer_release_flush_buffer(mm_evas_info *evas_info);
+/* internal */
+static void _free_previous_packets(mm_evas_info *evas_info);
+static int _flush_packets(mm_evas_info *evas_info);
+static int _mm_evas_renderer_create(mm_evas_info **evas_info);
+static int _mm_evas_renderer_destroy(mm_evas_info **evas_info);
+static int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo);
+static int _mm_evas_renderer_reset(mm_evas_info *evas_info);
+static void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result);
+static int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info);
+static int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_screen);
+static int _mm_evas_renderer_make_flush_buffer(mm_evas_info *evas_info);
+static void _mm_evas_renderer_release_flush_buffer(mm_evas_info *evas_info);
 static void _mm_evas_renderer_set_callback(mm_evas_info *evas_info);
 static void _mm_evas_renderer_unset_callback(mm_evas_info *evas_info);
 
 static void _evas_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
 {
+       MMER_FENTER();
+
        int x, y, w, h, ret;
        x = y = w = h = 0;
 
        mm_evas_info *evas_info = data;
-       LOGD("[ENTER]");
 
-       if (!evas_info || !evas_info->eo) {
+       if (!evas_info || !evas_info->eo)
                return;
-       }
 
        evas_object_geometry_get(evas_info->eo, &x, &y, &w, &h);
        if (!w || !h) {
@@ -148,11 +155,13 @@ static void _evas_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_i
                if (ret != MM_ERROR_NONE)
                        LOGW("fail to apply geometry info");
        }
-       LOGD("[LEAVE]");
+       MMER_FLEAVE();
 }
 
 static void _evas_render_pre_cb(void *data, Evas *e, void *event_info)
 {
+       MMER_FENTER();
+
        mm_evas_info *evas_info = data;
 
        if (!evas_info || !evas_info->eo) {
@@ -168,28 +177,31 @@ static void _evas_render_pre_cb(void *data, Evas *e, void *event_info)
                        LOGE("flushing packets are failed");
                g_mutex_unlock(&evas_info->idx_lock);
        }
+       MMER_FLEAVE();
 }
 
 static void _evas_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
 {
+       MMER_FENTER();
+
        mm_evas_info *evas_info = data;
-       LOGD("[ENTER]");
-       if (!evas_info || !evas_info->eo) {
+
+       if (!evas_info || !evas_info->eo)
                return;
-       }
+
        if (evas_info->eo) {
                _mm_evas_renderer_unset_callback(evas_info);
                evas_object_image_data_set(evas_info->eo, NULL);
                evas_info->eo = NULL;
        }
-       LOGD("[LEAVE]");
+       MMER_FLEAVE();
 }
 
-void _evas_pipe_cb(void *data, void *buffer, update_info info)
+static void _evas_pipe_cb(void *data, void *buffer, update_info info)
 {
-       mm_evas_info *evas_info = data;
+       MMER_FENTER();
 
-       LOGD("[ENTER]");
+       mm_evas_info *evas_info = data;
 
        if (!evas_info) {
                LOGW("evas_info is NULL", evas_info);
@@ -224,11 +236,13 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
                return;
        }
 
-       if (evas_info->cur_idx==-1 || !evas_info->pkt_info[evas_info->cur_idx].tbm_surf) {
+       if ((evas_info->cur_idx == -1) || !evas_info->pkt_info[evas_info->cur_idx].tbm_surf) {
                LOGW("cur_idx %d, tbm_surf may be NULL", evas_info->cur_idx);
                g_mutex_unlock(&evas_info->mp_lock);
                return;
        }
+       /* perhaps, it is needed to skip setting when state is pause */
+
        g_mutex_lock(&evas_info->idx_lock);
        /* index */
        gint cur_idx = evas_info->cur_idx;
@@ -248,17 +262,18 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
                LOGW("tbm_surface format : unknown %d", tbm_fmt);
                break;
        }
-       /* it is needed to skip setting when state is pause */
-       Evas_Native_Surface surf;
+
+       Evas_Native_Surface surf = { 0 };
        surf.type = EVAS_NATIVE_SURFACE_TBM;
        surf.version = EVAS_NATIVE_SURFACE_VERSION;
        surf.data.tbm.buffer = evas_info->pkt_info[cur_idx].tbm_surf;
-//  surf.data.tbm.rot = evas_info->rotate_angle;
-//  surf.data.tbm.flip = evas_info->flip;
+       surf.data.tbm.rot = evas_info->rotate_angle;
+       surf.data.tbm.flip = evas_info->flip;
 
        rect_info result = { 0 };
 
-       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);
+       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);
        if (!evas_info->eo_size.w || !evas_info->eo_size.h) {
                LOGE("there is no information for evas object size");
                goto ERROR;
@@ -269,9 +284,15 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
                goto ERROR;
        }
 
+       if (evas_info->update_needed) {
+               /* update geometry on pause state */
+               evas_object_image_native_surface_set(evas_info->eo, NULL);
+               evas_info->update_needed = FALSE;
+       }
+
        if (evas_info->use_ratio) {
-//      surf.data.tbm.ratio = (float) evas_info->w / evas_info->h;
-               LOGD("set ratio for letter mode");
+               surf.data.tbm.ratio = (float) evas_info->w / evas_info->h;
+               LOGD("set ratio");
        }
        evas_object_size_hint_align_set(evas_info->eo, EVAS_HINT_FILL, EVAS_HINT_FILL);
        evas_object_size_hint_weight_set(evas_info->eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -283,6 +304,7 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
 
        if (result.x || result.y)
                LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
+
        evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
 
        evas_object_image_pixels_dirty_set(evas_info->eo, EINA_TRUE);
@@ -292,10 +314,11 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
        if ((prev_idx != -1) && evas_info->pkt_info[prev_idx].packet && (prev_idx != cur_idx))
                _free_previous_packets(evas_info);
 
-       LOGD("[LEAVE]");
        g_mutex_unlock(&evas_info->idx_lock);
        g_mutex_unlock(&evas_info->mp_lock);
 
+       MMER_FLEAVE();
+
        return;
 
  ERROR:
@@ -307,46 +330,77 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
        g_mutex_unlock(&evas_info->mp_lock);
 }
 
-#ifdef _DEBUG_INDEX
-void __print_idx(mm_evas_info *evas_info)
+#ifdef _INTERNAL_DEBUG_
+static void __print_idx(mm_evas_info *evas_info)
 {
        gint prev_idx = evas_info->pkt_info[evas_info->cur_idx].prev;
        LOGE("***** start cur_idx : %d -> prev_idx : %d", evas_info->cur_idx, prev_idx);
-       while(prev_idx != -1)
-       {
+       while (prev_idx != -1) {
                LOGE("***** cur_idx : %d -> prev_idx : %d", prev_idx, evas_info->pkt_info[prev_idx].prev);
                prev_idx = evas_info->pkt_info[prev_idx].prev;
        }
        LOGE("***** end");
        return;
 }
+
+static int __dump_pkt(media_packet_h pkt)
+{
+       void *data;
+       uint64_t buf_size;
+       char filename[100] = {0};
+       FILE *fp = NULL;
+
+       sprintf(filename, "/tmp/DUMP_IMG_%2.2d.dump", g_cnt);
+       fp = fopen(filename, "wb");
+       if (fp == NULL)
+               return 1;
+
+       LOGW("DUMP IMG_%2.2d", g_cnt);
+       media_packet_get_buffer_data_ptr(pkt, &data);
+       media_packet_get_buffer_size(pkt, &buf_size);
+       LOGW("input data : %p, size %d\n", data, (int)buf_size);
+       fwrite(data, (int)buf_size, 1, fp);
+       fclose(fp);
+
+       return 0;
+}
 #endif
 
-void _free_previous_packets(mm_evas_info *evas_info)
+static void _free_previous_packets(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
+
        gint index = evas_info->cur_idx;
        gint prev_idx = evas_info->pkt_info[index].prev;
 
-       while(prev_idx != -1)
-       {
+       while (prev_idx != -1) {
                LOGD("destroy previous packet [%p] idx %d", evas_info->pkt_info[prev_idx].packet, prev_idx);
-               if (media_packet_destroy(evas_info->pkt_info[prev_idx].packet) != MEDIA_PACKET_ERROR_NONE)
-                       LOGE("media_packet_destroy failed %p", evas_info->pkt_info[prev_idx].packet);
+               if (evas_info->packet_rendered_cb) {
+                       evas_info->packet_rendered_cb(evas_info->pkt_info[prev_idx].packet, evas_info->packet_rendered_cb_user);
+               } else {
+                       if (media_packet_destroy(evas_info->pkt_info[prev_idx].packet) != MEDIA_PACKET_ERROR_NONE)
+                               LOGE("media_packet_destroy failed %p", evas_info->pkt_info[prev_idx].packet);
+               }
+               evas_info->sent_buffer_cnt--;
                evas_info->pkt_info[prev_idx].packet = NULL;
                evas_info->pkt_info[prev_idx].tbm_surf = NULL;
                evas_info->pkt_info[index].prev = -1;
-               evas_info->sent_buffer_cnt--;
 
                /* move index to previous index */
-               index= prev_idx;
+               index = prev_idx;
                prev_idx = evas_info->pkt_info[prev_idx].prev;
                LOGD("sent packet %d", evas_info->sent_buffer_cnt);
        }
+
+       MMER_FLEAVE();
+
        return;
 }
 
 static int _get_video_size(media_packet_h packet, mm_evas_info *evas_info)
 {
+       MMER_FENTER();
+
        media_format_h fmt;
        if (media_packet_get_format(packet, &fmt) == MEDIA_PACKET_ERROR_NONE) {
                int w, h;
@@ -362,11 +416,16 @@ static int _get_video_size(media_packet_h packet, mm_evas_info *evas_info)
        } else {
                LOGW("media_packet_get_format is failed");
        }
+
+       MMER_FLEAVE();
+
        return false;
 }
 
-int _find_empty_index(mm_evas_info *evas_info)
+static int _find_empty_index(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
+
        int i;
        for (i = 0; i < MAX_PACKET_NUM; i++) {
                if (!evas_info->pkt_info[i].packet) {
@@ -376,11 +435,15 @@ int _find_empty_index(mm_evas_info *evas_info)
        }
        LOGE("there is no empty idx");
 
+       MMER_FLEAVE();
+
        return -1;
 }
 
-int _flush_packets(mm_evas_info *evas_info)
+static int _flush_packets(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
+
        int ret = MM_ERROR_NONE;
        int ret_mp = MEDIA_PACKET_ERROR_NONE;
        int i = 0;
@@ -389,9 +452,11 @@ int _flush_packets(mm_evas_info *evas_info)
                LOGW("there is no esink info");
                return MM_ERROR_INVALID_ARGUMENT;
        }
-       /* update the screen only if visible is ture */
-       if (evas_info->keep_screen && (evas_info->visible != VISIBLE_FALSE)) {
-               Evas_Native_Surface surf;
+
+       /* update the screen only if visible is true */
+       /* if flush buffer is null, we cant keep screen */
+       if (evas_info->keep_screen && (evas_info->visible != VISIBLE_FALSE) && evas_info->flush_buffer) {
+               Evas_Native_Surface surf = { 0 };
                rect_info result = { 0 };
                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);
                if (!evas_info->eo_size.w || !evas_info->eo_size.h) {
@@ -405,8 +470,8 @@ int _flush_packets(mm_evas_info *evas_info)
                }
 
                if (evas_info->use_ratio) {
-       //      surf.data.tbm.ratio = (float) evas_info->w / evas_info->h;
-                       LOGD("set ratio for letter mode");
+                       surf.data.tbm.ratio = (float) evas_info->w / evas_info->h;
+                       LOGD("set ratio");
                }
                evas_object_size_hint_align_set(evas_info->eo, EVAS_HINT_FILL, EVAS_HINT_FILL);
                evas_object_size_hint_weight_set(evas_info->eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@@ -415,21 +480,22 @@ int _flush_packets(mm_evas_info *evas_info)
 
                if (result.x || result.y)
                        LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
+
                evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
 
                /* set flush buffer */
                surf.type = EVAS_NATIVE_SURFACE_TBM;
                surf.version = EVAS_NATIVE_SURFACE_VERSION;
                surf.data.tbm.buffer = evas_info->flush_buffer->tbm_surf;
-//             surf.data.tbm.rot = evas_info->rotate_angle;
-//             surf.data.tbm.flip = evas_info->flip;
+               surf.data.tbm.rot = evas_info->rotate_angle;
+               surf.data.tbm.flip = evas_info->flip;
                evas_object_image_native_surface_set(evas_info->eo, &surf);
 
                LOGD("flush_buffer surf(%p), rotate(%d), flip(%d)", evas_info->flush_buffer->tbm_surf, evas_info->rotate_angle, evas_info->flip);
        } else {
                /* unset evas native surface for displaying black screen */
-               evas_object_image_native_surface_set (evas_info->eo, NULL);
-               evas_object_image_data_set (evas_info->eo, NULL);
+               evas_object_image_native_surface_set(evas_info->eo, NULL);
+               evas_object_image_data_set(evas_info->eo, NULL);
        }
        LOGD("sent packet %d", evas_info->sent_buffer_cnt);
 
@@ -438,13 +504,16 @@ int _flush_packets(mm_evas_info *evas_info)
        for (i = 0; i < MAX_PACKET_NUM; i++) {
                if (evas_info->pkt_info[i].packet) {
                        LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
-                       ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
-                       if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
-                               LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
-                               ret = MM_ERROR_UNKNOWN;
+                       if (evas_info->packet_rendered_cb) {
+                               evas_info->packet_rendered_cb(evas_info->pkt_info[i].packet, evas_info->packet_rendered_cb_user);
+                       } else {
+                               ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
+                               if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
+                                       LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
+                                       ret = MM_ERROR_UNKNOWN;
+                               }
                        }
-                       else
-                               evas_info->sent_buffer_cnt--;
+                       evas_info->sent_buffer_cnt--;
                        evas_info->pkt_info[i].packet = NULL;
                        evas_info->pkt_info[i].tbm_surf = NULL;
                        evas_info->pkt_info[i].prev = -1;
@@ -457,9 +526,11 @@ int _flush_packets(mm_evas_info *evas_info)
        evas_info->cur_idx = -1;
        g_mutex_unlock(&evas_info->mp_lock);
 
-       evas_object_image_pixels_dirty_set (evas_info->eo, EINA_TRUE);
+       evas_object_image_pixels_dirty_set(evas_info->eo, EINA_TRUE);
        evas_info->retrieve_packet = FALSE;
 
+       MMER_FLEAVE();
+
        return ret;
 }
 
@@ -481,13 +552,16 @@ int _reset_pipe(mm_evas_info *evas_info)
                if (evas_info->pkt_info[i].packet) {
                        /* destroy all packets */
                        LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
-                       ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
-                       if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
-                               LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
-                               ret = MM_ERROR_UNKNOWN;
+                       if (evas_info->packet_rendered_cb) {
+                               evas_info->packet_rendered_cb(evas_info->pkt_info[i].packet, evas_info->packet_rendered_cb_user);
+                       } else {
+                               ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
+                               if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
+                                       LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
+                                       ret = MM_ERROR_UNKNOWN;
+                               }
                        }
-                       else
-                               evas_info->sent_buffer_cnt--;
+                       evas_info->sent_buffer_cnt--;
                        evas_info->pkt_info[i].packet = NULL;
                        evas_info->pkt_info[i].tbm_surf = NULL;
                        evas_info->pkt_info[i].prev = -1;
@@ -515,22 +589,28 @@ int _reset_pipe(mm_evas_info *evas_info)
 
 static void _mm_evas_renderer_set_callback(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
        if (evas_info->eo) {
                SET_EVAS_OBJECT_EVENT_CALLBACK(evas_info->eo, evas_info);
                SET_EVAS_EVENT_CALLBACK(evas_object_evas_get(evas_info->eo), evas_info);
        }
+       MMER_FLEAVE();
 }
 
 static void _mm_evas_renderer_unset_callback(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
        if (evas_info->eo) {
                UNSET_EVAS_OBJECT_EVENT_CALLBACK(evas_info->eo);
                UNSET_EVAS_EVENT_CALLBACK(evas_object_evas_get(evas_info->eo));
        }
+       MMER_FLEAVE();
 }
 
-int _mm_evas_renderer_create(mm_evas_info **evas_info)
+static int _mm_evas_renderer_create(mm_evas_info **evas_info)
 {
+       MMER_FENTER();
+
        mm_evas_info *ptr = NULL;
        ptr = g_malloc0(sizeof(mm_evas_info));
 
@@ -544,6 +624,8 @@ int _mm_evas_renderer_create(mm_evas_info **evas_info)
        g_mutex_init(&ptr->mp_lock);
        g_mutex_init(&ptr->idx_lock);
 
+       MMER_FLEAVE();
+
        return MM_ERROR_NONE;
 
  ERROR:
@@ -551,8 +633,10 @@ int _mm_evas_renderer_create(mm_evas_info **evas_info)
        return MM_ERROR_OUT_OF_STORAGE;
 }
 
-int _mm_evas_renderer_destroy(mm_evas_info **evas_info)
+static int _mm_evas_renderer_destroy(mm_evas_info **evas_info)
 {
+       MMER_FENTER();
+
        mm_evas_info *ptr = (mm_evas_info *)*evas_info;
        MM_CHECK_NULL(ptr);
        int ret = MM_ERROR_NONE;
@@ -566,11 +650,14 @@ int _mm_evas_renderer_destroy(mm_evas_info **evas_info)
        g_free(ptr);
        ptr = NULL;
 
+       MMER_FLEAVE();
+
        return ret;
 }
 
-int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo)
+static int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo)
 {
+       MMER_FENTER();
        MM_CHECK_NULL(evas_info);
        MM_CHECK_NULL(eo);
        g_mutex_lock(&evas_info->idx_lock);
@@ -582,8 +669,8 @@ int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo)
                evas_info->pkt_info[i].tbm_surf = NULL;
                evas_info->pkt_info[i].prev = -1;
        }
-
        evas_info->cur_idx = -1;
+       evas_info->dst_roi.x = evas_info->dst_roi.y = evas_info->dst_roi.w = evas_info->dst_roi.h = 0;
        evas_info->eo = eo;
        evas_info->epipe = ecore_pipe_add((Ecore_Pipe_Cb) _evas_pipe_cb, evas_info);
        if (!evas_info->epipe) {
@@ -599,11 +686,14 @@ int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo)
 
        g_mutex_unlock(&evas_info->idx_lock);
 
+       MMER_FLEAVE();
+
        return MM_ERROR_NONE;
 }
 
-int _mm_evas_renderer_reset(mm_evas_info *evas_info)
+static int _mm_evas_renderer_reset(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
        MM_CHECK_NULL(evas_info);
        g_mutex_lock(&evas_info->idx_lock);
 
@@ -623,6 +713,7 @@ int _mm_evas_renderer_reset(mm_evas_info *evas_info)
        }
 
        evas_info->eo_size.x = evas_info->eo_size.y = evas_info->eo_size.w = evas_info->eo_size.h = 0;
+       evas_info->dst_roi.x = evas_info->dst_roi.y = evas_info->dst_roi.w = evas_info->dst_roi.h = 0;
        evas_info->w = evas_info->h = 0;
 
        if (evas_info->flush_buffer)
@@ -633,13 +724,16 @@ int _mm_evas_renderer_reset(mm_evas_info *evas_info)
                if (evas_info->pkt_info[i].packet) {
                        /* destroy all packets */
                        LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
-                       ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
-                       if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
-                               LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
-                               ret = MM_ERROR_UNKNOWN;
+                       if (evas_info->packet_rendered_cb) {
+                               evas_info->packet_rendered_cb(evas_info->pkt_info[i].packet, evas_info->packet_rendered_cb_user);
+                       } else {
+                               ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
+                               if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
+                                       LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
+                                       ret = MM_ERROR_UNKNOWN;
+                               }
                        }
-                       else
-                               evas_info->sent_buffer_cnt--;
+                       evas_info->sent_buffer_cnt--;
                        evas_info->pkt_info[i].packet = NULL;
                        evas_info->pkt_info[i].tbm_surf = NULL;
                        evas_info->pkt_info[i].prev = -1;
@@ -653,11 +747,15 @@ int _mm_evas_renderer_reset(mm_evas_info *evas_info)
 
        g_mutex_unlock(&evas_info->idx_lock);
 
+       MMER_FLEAVE();
+
        return ret;
 }
 
-void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result)
+static void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result)
 {
+       MMER_FENTER();
+
        if (!evas_info || !evas_info->eo) {
                LOGW("there is no evas_info or evas object");
                return;
@@ -725,15 +823,27 @@ void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *resul
                        result->h = evas_info->eo_size.h;
                }
                break;
+       case DISP_GEO_METHOD_CUSTOM_ROI:
+               LOGD("custom roi mode");
+               evas_info->use_ratio = TRUE;
+               result->x = evas_info->dst_roi.x;
+               result->y = evas_info->dst_roi.y;
+               result->w = evas_info->dst_roi.w;
+               result->h = evas_info->dst_roi.h;
+               break;
        default:
                LOGW("unsupported mode.");
                break;
        }
        LOGD("geometry result [%d, %d, %d, %d]", result->x, result->y, result->w, result->h);
+
+       MMER_FLEAVE();
 }
 
-int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info)
+static int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
+
        if (!evas_info || !evas_info->eo) {
                LOGW("there is no evas_info or evas object");
                return MM_ERROR_NONE;
@@ -744,30 +854,34 @@ int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info)
 
        if (surf) {
                LOGD("native surface exists");
-//      surf->data.tbm.rot = evas_info->rotate_angle;
-//      surf->data.tbm.flip = evas_info->flip;
+               surf->data.tbm.rot = evas_info->rotate_angle;
+               surf->data.tbm.flip = evas_info->flip;
                evas_object_image_native_surface_set(evas_info->eo, surf);
 
                _mm_evas_renderer_update_geometry(evas_info, &result);
 
                if (evas_info->use_ratio) {
-//          surf->data.tbm.ratio = (float) evas_info->w / evas_info->h;
-                       LOGD("set ratio for letter mode");
+                       surf->data.tbm.ratio = (float) evas_info->w / evas_info->h;
+                       LOGD("set ratio");
                }
-
                if (result.x || result.y)
                        LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
 
                evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
+
                return MM_ERROR_NONE;
        } else
                LOGW("there is no surf");
        /* FIXME: before pipe_cb is invoked, apply_geometry can be called. */
+
+       MMER_FLEAVE();
+
        return MM_ERROR_NONE;
 }
 
-int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_screen)
+static int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_screen)
 {
+       MMER_FENTER();
        MM_CHECK_NULL(evas_info);
 
        int ret = MM_ERROR_NONE;
@@ -796,12 +910,16 @@ int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_sc
        }
        g_mutex_unlock(&evas_info->idx_lock);
 
+       MMER_FLEAVE();
+
        return ret;
 }
 
 /* make buffer for copying */
-int _mm_evas_renderer_make_flush_buffer (mm_evas_info *evas_info)
+static int _mm_evas_renderer_make_flush_buffer(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
+
        if (evas_info->cur_idx == -1) {
                LOGW("there is no remained buffer");
                return MM_ERROR_INVALID_ARGUMENT;
@@ -813,9 +931,8 @@ int _mm_evas_renderer_make_flush_buffer (mm_evas_info *evas_info)
        tbm_bo src_bo = NULL;
        tbm_surface_h src_tbm_surf = NULL;
        int src_size = 0;
-       int size = 0;
        tbm_bo bo = NULL;
-       tbm_format tbm_fmt;
+       tbm_surface_info_s info = {0};
        tbm_bo_handle vaddr_src = {0};
        tbm_bo_handle vaddr_dst = {0};
        int ret = MM_ERROR_NONE;
@@ -838,46 +955,48 @@ int _mm_evas_renderer_make_flush_buffer (mm_evas_info *evas_info)
        }
 
        /* get src buffer info */
-       tbm_fmt = tbm_surface_get_format(src_tbm_surf);
        src_bo = tbm_surface_internal_get_bo(src_tbm_surf, 0);
-       src_size = tbm_bo_size(src_bo);
+       src_size = tbm_surface_internal_get_size(src_tbm_surf);
        if (!src_bo || !src_size) {
-               LOGE("bo(%p), size(%d)", src_bo, src_size);
+               LOGE("src bo(%p), size(%d)", src_bo, src_size);
                goto ERROR;
        }
+       LOGD("src bo(%p), size(%d)", src_bo, src_size);
 
        /* create tbm surface */
-       flush_buffer->tbm_surf = tbm_surface_create(evas_info->w, evas_info->h, tbm_fmt);
-       if (!flush_buffer->tbm_surf)
-       {
+       info.format = tbm_surface_get_format(src_tbm_surf);
+       flush_buffer->tbm_surf = tbm_surface_create(evas_info->w, evas_info->h, info.format);
+       if (!flush_buffer->tbm_surf) {
                LOGE("tbm_surf is NULL!!");
                goto ERROR;
        }
 
        /* get bo and size */
        bo = tbm_surface_internal_get_bo(flush_buffer->tbm_surf, 0);
-       size = tbm_bo_size(bo);
-       if (!bo || !size)
-       {
-               LOGE("bo(%p), size(%d)", bo, size);
+       info.size = tbm_surface_internal_get_size(flush_buffer->tbm_surf);
+       if (!bo || !info.size) {
+               LOGE("dst bo(%p), size(%d)", bo, info.size);
                goto ERROR;
        }
+       LOGD("dst bo(%p), size(%d)", bo, info.size);
+
+       /* FIXME: each plane should be copied */
+       info.num_planes = tbm_surface_internal_get_num_planes(info.format);
+
        flush_buffer->bo = bo;
 
        vaddr_src = tbm_bo_map(src_bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE);
        vaddr_dst = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE);
        if (!vaddr_src.ptr || !vaddr_dst.ptr) {
                LOGW("get vaddr failed src %p, dst %p", vaddr_src.ptr, vaddr_dst.ptr);
-               if (vaddr_src.ptr) {
+               if (vaddr_src.ptr)
                        tbm_bo_unmap(src_bo);
-               }
-               if (vaddr_dst.ptr) {
+               if (vaddr_dst.ptr)
                        tbm_bo_unmap(bo);
-               }
                goto ERROR;
        } else {
-               memset (vaddr_dst.ptr, 0x0, size);
-               LOGW ("tbm_bo_map(vaddr) is finished, bo(%p), vaddr(%p)", bo, vaddr_dst.ptr);
+               memset(vaddr_dst.ptr, 0x0, info.size);
+               LOGW("tbm_bo_map(vaddr) is finished, bo(%p), vaddr(%p)", bo, vaddr_dst.ptr);
        }
 
        /* copy buffer */
@@ -885,16 +1004,17 @@ int _mm_evas_renderer_make_flush_buffer (mm_evas_info *evas_info)
 
        tbm_bo_unmap(src_bo);
        tbm_bo_unmap(bo);
-       LOGW("copy is done. tbm surface : %p src_size : %d", flush_buffer->tbm_surf, src_size);
+       LOGW("copy is done. tbm surface : %p", flush_buffer->tbm_surf);
 
        evas_info->flush_buffer = flush_buffer;
 
+       MMER_FLEAVE();
+
        return MM_ERROR_NONE;
 
 ERROR:
        if (flush_buffer) {
-               if(flush_buffer->tbm_surf)
-               {
+               if (flush_buffer->tbm_surf) {
                        tbm_surface_destroy(flush_buffer->tbm_surf);
                        flush_buffer->tbm_surf = NULL;
                }
@@ -906,12 +1026,14 @@ ERROR:
 }
 
 /* release flush buffer */
-void _mm_evas_renderer_release_flush_buffer (mm_evas_info *evas_info)
+static void _mm_evas_renderer_release_flush_buffer(mm_evas_info *evas_info)
 {
+       MMER_FENTER();
+
        LOGW("release FLUSH BUFFER start");
-       if (evas_info->flush_buffer->bo) {
+       if (evas_info->flush_buffer->bo)
                evas_info->flush_buffer->bo = NULL;
-       }
+
        if (evas_info->flush_buffer->tbm_surf) {
                tbm_surface_destroy(evas_info->flush_buffer->tbm_surf);
                evas_info->flush_buffer->tbm_surf = NULL;
@@ -922,11 +1044,15 @@ void _mm_evas_renderer_release_flush_buffer (mm_evas_info *evas_info)
        free(evas_info->flush_buffer);
        evas_info->flush_buffer = NULL;
 
+       MMER_FLEAVE();
+
        return;
 }
 
 void mm_evas_renderer_write(media_packet_h packet, void *data)
 {
+       MMER_FENTER();
+
        if (!packet) {
                LOGE("packet %p is NULL", packet);
                return;
@@ -954,7 +1080,7 @@ void mm_evas_renderer_write(media_packet_h packet, void *data)
        /* currently we are always checking it */
        if (has && _get_video_size(packet, handle)) {
                /* Attention! if this error occurs, we need to consider managing buffer */
-               if (handle->sent_buffer_cnt > 4) {
+               if (handle->sent_buffer_cnt > 3) {
                        LOGE("too many buffers are not released %d", handle->sent_buffer_cnt);
                        goto ERROR;
 #if 0
@@ -974,10 +1100,19 @@ void mm_evas_renderer_write(media_packet_h packet, void *data)
 
                /* find new index for current packet */
                index = _find_empty_index(handle);
-               if (index == -1) {
+               if (index == -1)
                        goto ERROR;
-               }
 
+#ifdef _INTERNAL_DEBUG_
+               int ret2 = 0;
+               if ((g_cnt%10 == 0) && (g_cnt < 500))
+                       ret2 = __dump_pkt(packet);
+
+               if (ret2)
+                       LOGW("__dump_pkt() is failed");
+               else
+                       g_cnt++;
+#endif
                /* save previous index */
                handle->pkt_info[index].prev = handle->cur_idx;
                handle->pkt_info[index].packet = packet;
@@ -1002,6 +1137,8 @@ void mm_evas_renderer_write(media_packet_h packet, void *data)
        }
        g_mutex_unlock(&handle->idx_lock);
 
+       MMER_FLEAVE();
+
        return;
 ERROR:
        g_mutex_unlock(&handle->idx_lock);
@@ -1010,9 +1147,13 @@ INVALID_PARAM:
        if (packet) {
                g_mutex_lock(&handle->mp_lock);
                LOGD("cant write. destroy packet [%p]", packet);
-               if (media_packet_destroy(packet) != MEDIA_PACKET_ERROR_NONE)
-                       LOGE("media_packet_destroy failed %p", packet);
-               packet = NULL;
+               if (handle && handle->packet_rendered_cb) {
+                       handle->packet_rendered_cb(packet, handle->packet_rendered_cb_user);
+               } else {
+                       if (media_packet_destroy(packet) != MEDIA_PACKET_ERROR_NONE)
+                               LOGE("media_packet_destroy failed %p", packet);
+                       packet = NULL;
+               }
                g_mutex_unlock(&handle->mp_lock);
        }
        return;
@@ -1020,6 +1161,8 @@ INVALID_PARAM:
 
 int mm_evas_renderer_update_param(MMHandleType handle)
 {
+       MMER_FENTER();
+
        int ret = MM_ERROR_NONE;
        mm_evas_info *evas_info = (mm_evas_info *)handle;
 
@@ -1042,18 +1185,30 @@ int mm_evas_renderer_update_param(MMHandleType handle)
                        ret = ecore_pipe_write(evas_info->epipe, &evas_info->visible, UPDATE_VISIBILITY);
                        if (!ret) {
                                LOGW("fail to ecore_pipe_write() for updating visibility\n");
+                               return MM_ERROR_UNKNOWN;
+                       }
+                       evas_info->update_needed = TRUE;
+                       /* FIXME: pause state only */
+                       g_mutex_lock(&evas_info->idx_lock);
+                       ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
+                       if (!ret) {
+                               LOGW("fail to ecore_pipe_write() for updating visibility\n");
                                ret = MM_ERROR_UNKNOWN;
                        } else {
                                ret = MM_ERROR_NONE;
                        }
+                       g_mutex_unlock(&evas_info->idx_lock);
                }
        }
 
+       MMER_FLEAVE();
+
        return ret;
 }
 
 int mm_evas_renderer_create(MMHandleType *handle, Evas_Object *eo)
 {
+       MMER_FENTER();
        MM_CHECK_NULL(handle);
 
        int ret = MM_ERROR_NONE;
@@ -1079,6 +1234,7 @@ int mm_evas_renderer_create(MMHandleType *handle, Evas_Object *eo)
 
 int mm_evas_renderer_destroy(MMHandleType *handle)
 {
+       MMER_FENTER();
        MM_CHECK_NULL(handle);
 
        int ret = MM_ERROR_NONE;
@@ -1096,11 +1252,15 @@ int mm_evas_renderer_destroy(MMHandleType *handle)
        }
        *handle = NULL;
 
+       MMER_FLEAVE();
+
        return MM_ERROR_NONE;
 }
 
 int mm_evas_renderer_set_visible(MMHandleType handle, bool visible)
 {
+       MMER_FENTER();
+
        int ret = MM_ERROR_NONE;
        mm_evas_info *evas_info = (mm_evas_info *)handle;
 
@@ -1126,11 +1286,15 @@ int mm_evas_renderer_set_visible(MMHandleType handle, bool visible)
                LOGW("there is no epipe. we cant update it");
        }
 
+       MMER_FLEAVE();
+
        return ret;
 }
 
 int mm_evas_renderer_get_visible(MMHandleType handle, bool *visible)
 {
+       MMER_FENTER();
+
        mm_evas_info *evas_info = (mm_evas_info *)handle;
 
        if (!evas_info) {
@@ -1143,40 +1307,99 @@ int mm_evas_renderer_get_visible(MMHandleType handle, bool *visible)
        else
                *visible = TRUE;
 
+       MMER_FLEAVE();
+
        return MM_ERROR_NONE;
 }
 
 int mm_evas_renderer_set_rotation(MMHandleType handle, int rotate)
 {
+       MMER_FENTER();
+
        int ret = MM_ERROR_NONE;
        mm_evas_info *evas_info = (mm_evas_info *)handle;
+       guint value;
 
        if (!evas_info) {
                LOGW("skip it. it is not evas surface type or handle is not prepared");
                return MM_ERROR_RESOURCE_NOT_INITIALIZED;
        }
 
-       evas_info->rotate_angle = rotate;
-       ret = _mm_evas_renderer_apply_geometry(evas_info);
+       switch (rotate) {
+       case DEGREE_0:
+               value = EVAS_IMAGE_ORIENT_0;
+               break;
+       case DEGREE_90:
+               value = EVAS_IMAGE_ORIENT_90;
+               break;
+       case DEGREE_180:
+               value = EVAS_IMAGE_ORIENT_180;
+               break;
+       case DEGREE_270:
+               value = EVAS_IMAGE_ORIENT_270;
+               break;
+       default:
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+       if (evas_info->rotate_angle != value) {
+               evas_info->update_needed = TRUE;
+               evas_info->rotate_angle = value;
+       }
+
+       /* FIXME: pause state only */
+       if (evas_info->epipe) {
+               g_mutex_lock(&evas_info->idx_lock);
+               ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
+               if (!ret) {
+                       LOGW("fail to ecore_pipe_write() for updating visibility\n");
+                       ret = MM_ERROR_UNKNOWN;
+               } else {
+                       ret = MM_ERROR_NONE;
+               }
+               g_mutex_unlock(&evas_info->idx_lock);
+       }
+       MMER_FLEAVE();
 
        return ret;
 }
 
 int mm_evas_renderer_get_rotation(MMHandleType handle, int *rotate)
 {
+       MMER_FENTER();
+
        mm_evas_info *evas_info = (mm_evas_info *)handle;
 
        if (!evas_info) {
                LOGW("skip it. it is not evas surface type or handle is not prepared");
                return MM_ERROR_RESOURCE_NOT_INITIALIZED;
        }
-       *rotate = evas_info->rotate_angle;
+
+       switch (evas_info->rotate_angle) {
+       case EVAS_IMAGE_ORIENT_0:
+               *rotate = DEGREE_0;
+               break;
+       case EVAS_IMAGE_ORIENT_90:
+               *rotate = DEGREE_90;
+               break;
+       case EVAS_IMAGE_ORIENT_180:
+               *rotate = DEGREE_180;
+               break;
+       case EVAS_IMAGE_ORIENT_270:
+               *rotate = DEGREE_270;
+               break;
+       default:
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       MMER_FLEAVE();
 
        return MM_ERROR_NONE;
 }
 
 int mm_evas_renderer_set_geometry(MMHandleType handle, int mode)
 {
+       MMER_FENTER();
+
        int ret = MM_ERROR_NONE;
        mm_evas_info *evas_info = (mm_evas_info *)handle;
 
@@ -1184,15 +1407,33 @@ int mm_evas_renderer_set_geometry(MMHandleType handle, int mode)
                LOGW("skip it. it is not evas surface type or handle is not prepared");
                return MM_ERROR_RESOURCE_NOT_INITIALIZED;
        }
+       if (evas_info->display_geometry_method != mode) {
+               evas_info->update_needed = TRUE;
+               evas_info->display_geometry_method = mode;
+       }
 
-       evas_info->display_geometry_method = mode;
-       ret = _mm_evas_renderer_apply_geometry(evas_info);
+       /* ecore_pipe_write is needed, because of setting ratio for letterbox mode */
+       /* FIXME: pause state only */
+       if (evas_info->epipe) {
+               g_mutex_lock(&evas_info->idx_lock);
+               ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
+               if (!ret) {
+                       LOGW("fail to ecore_pipe_write() for updating visibility\n");
+                       ret = MM_ERROR_UNKNOWN;
+               } else {
+                       ret = MM_ERROR_NONE;
+               }
+               g_mutex_unlock(&evas_info->idx_lock);
+       }
+       MMER_FLEAVE();
 
        return ret;
 }
 
 int mm_evas_renderer_get_geometry(MMHandleType handle, int *mode)
 {
+       MMER_FENTER();
+
        mm_evas_info *evas_info = (mm_evas_info *)handle;
 
        if (!evas_info) {
@@ -1201,11 +1442,168 @@ int mm_evas_renderer_get_geometry(MMHandleType handle, int *mode)
        }
        *mode = evas_info->display_geometry_method;
 
+       MMER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+int mm_evas_renderer_set_roi_area(MMHandleType handle, int x, int y, int w, int h)
+{
+       MMER_FENTER();
+
+       int ret = MM_ERROR_NONE;
+       mm_evas_info *evas_info = (mm_evas_info *)handle;
+
+       if (!evas_info) {
+               LOGW("skip it. it is not evas surface type or handle is not prepared");
+               return MM_ERROR_RESOURCE_NOT_INITIALIZED;
+       }
+       if (!w || !h) {
+               LOGW("invalid resolution");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       /* display mode is set to DISP_GEO_METHOD_CUSTOM_ROI internally */
+       if (evas_info->display_geometry_method != DISP_GEO_METHOD_CUSTOM_ROI)
+               evas_info->update_needed = TRUE;
+       evas_info->display_geometry_method = DISP_GEO_METHOD_CUSTOM_ROI;
+       evas_info->dst_roi.x = x;
+       evas_info->dst_roi.y = y;
+       evas_info->dst_roi.w = w;
+       evas_info->dst_roi.h = h;
+
+       /* pipe_write could be needed because ratio can be changed on pause state */
+       if (evas_info->epipe) {
+               g_mutex_lock(&evas_info->idx_lock);
+               ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
+               if (!ret) {
+                       LOGW("fail to ecore_pipe_write() for updating visibility\n");
+                       ret = MM_ERROR_UNKNOWN;
+               } else {
+                       ret = MM_ERROR_NONE;
+               }
+               g_mutex_unlock(&evas_info->idx_lock);
+       }
+
+       MMER_FLEAVE();
+
+       return ret;
+}
+
+int mm_evas_renderer_get_roi_area(MMHandleType handle, int *x, int *y, int *w, int *h)
+{
+       MMER_FENTER();
+
+       mm_evas_info *evas_info = (mm_evas_info *)handle;
+
+       if (!evas_info) {
+               LOGW("skip it. it is not evas surface type or handle is not prepared");
+               return MM_ERROR_RESOURCE_NOT_INITIALIZED;
+       }
+       if (evas_info->display_geometry_method != DISP_GEO_METHOD_CUSTOM_ROI) {
+               LOGW("invalid mode");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       *x = evas_info->dst_roi.x;
+       *y = evas_info->dst_roi.y;
+       *w = evas_info->dst_roi.w;
+       *h = evas_info->dst_roi.h;
+
+       MMER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}
+
+int mm_evas_renderer_set_flip(MMHandleType handle, int flip)
+{
+       MMER_FENTER();
+
+       int ret = MM_ERROR_NONE;
+       mm_evas_info *evas_info = (mm_evas_info *)handle;
+       guint value;
+
+       if (!evas_info) {
+               LOGW("skip it. it is not evas surface type or handle is not prepared");
+               return MM_ERROR_RESOURCE_NOT_INITIALIZED;
+       }
+
+       switch (flip) {
+       case FLIP_NONE:
+               value = EVAS_IMAGE_ORIENT_NONE;
+               break;
+       case FLIP_HORIZONTAL:
+               value = EVAS_IMAGE_FLIP_HORIZONTAL;
+               break;
+       case FLIP_VERTICAL:
+               value = EVAS_IMAGE_FLIP_VERTICAL;
+               break;
+       case FLIP_BOTH:
+               value = EVAS_IMAGE_ORIENT_180;
+               break;
+       default:
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+       if (evas_info->flip != value) {
+               evas_info->update_needed = TRUE;
+               evas_info->flip = value;
+       }
+
+       /* FIXME: pause state only */
+       if (evas_info->epipe) {
+               g_mutex_lock(&evas_info->idx_lock);
+               ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
+               if (!ret) {
+                       LOGW("fail to ecore_pipe_write() for updating visibility\n");
+                       ret = MM_ERROR_UNKNOWN;
+               } else {
+                       ret = MM_ERROR_NONE;
+               }
+               g_mutex_unlock(&evas_info->idx_lock);
+       }
+
+       MMER_FLEAVE();
+
+       return ret;
+}
+
+int mm_evas_renderer_get_flip(MMHandleType handle, int *flip)
+{
+       MMER_FENTER();
+
+       mm_evas_info *evas_info = (mm_evas_info *)handle;
+
+       if (!evas_info) {
+               LOGW("skip it. it is not evas surface type or handle is not prepared");
+               return MM_ERROR_RESOURCE_NOT_INITIALIZED;
+       }
+
+       switch (evas_info->flip) {
+       case EVAS_IMAGE_ORIENT_NONE:
+               *flip = FLIP_NONE;
+               break;
+       case EVAS_IMAGE_FLIP_HORIZONTAL:
+               *flip = FLIP_HORIZONTAL;
+               break;
+       case EVAS_IMAGE_FLIP_VERTICAL:
+               *flip = FLIP_VERTICAL;
+               break;
+       case EVAS_IMAGE_ORIENT_180:
+               *flip = FLIP_BOTH;
+               break;
+       default:
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
+
+       MMER_FLEAVE();
+
        return MM_ERROR_NONE;
 }
 
-int mm_evas_renderer_retrieve_all_packets (MMHandleType handle, bool keep_screen)
+int mm_evas_renderer_retrieve_all_packets(MMHandleType handle, bool keep_screen)
 {
+       MMER_FENTER();
+
        int ret = MM_ERROR_NONE;
        mm_evas_info *evas_info = (mm_evas_info*) handle;
 
@@ -1215,5 +1613,27 @@ int mm_evas_renderer_retrieve_all_packets (MMHandleType handle, bool keep_screen
        }
        ret = _mm_evas_renderer_retrieve_all_packets(evas_info, keep_screen);
 
+       MMER_FLEAVE();
+
        return ret;
 }
+
+int mm_evas_renderer_set_packet_rendered_callback(MMHandleType handle, mm_evas_renderer_media_packet_rendered_cb callback, void *user_data)
+{
+       MMER_FENTER();
+
+       mm_evas_info *evas_info = (mm_evas_info*) handle;
+
+       if (!evas_info) {
+               LOGW("skip it. it is not evas surface type or player is not prepared");
+               return MM_ERROR_RESOURCE_NOT_INITIALIZED;
+       }
+       evas_info->packet_rendered_cb = callback;
+       evas_info->packet_rendered_cb_user = user_data;
+
+       LOGW("set rendered callback %p, user_data %p", evas_info->packet_rendered_cb, evas_info->packet_rendered_cb_user);
+
+       MMER_FLEAVE();
+
+       return MM_ERROR_NONE;
+}