#include <stdlib.h>
#include <dlog.h>
#include <mm_error.h>
-
+#include <sys/syscall.h>
#include "mm_evas_renderer.h"
#ifdef LOG_TAG
#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 SET_EVAS_OBJECT_EVENT_CALLBACK( x_evas_image_object, x_usr_data ) \
- do \
- { \
+#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 { \
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,
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,
};
FLIP_NUM,
};
+#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
/* internal */
-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);
+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) {
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) {
LOGW("there is no esink info.... esink : %p, or eo is NULL returning", evas_info);
return;
}
- //LOGI("- test -"); //@@@@@ pre_cb will be deleted. actually it is useless
+
+ /* flush will be executed in this callback normally,
+ because native_surface_set must be called in main thread */
+ if (evas_info->retrieve_packet) {
+ g_mutex_lock(&evas_info->idx_lock);
+ if (_flush_packets(evas_info) != MM_ERROR_NONE)
+ 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)
{
+ MMER_FENTER();
+
mm_evas_info *evas_info = data;
- int ret;
- LOGD("[ENTER]");
if (!evas_info) {
LOGW("evas_info is NULL", evas_info);
if (!evas_info->eo) {
LOGW("evas_info %p", evas_info);
- goto ERROR;
+ g_mutex_unlock(&evas_info->mp_lock);
+ return;
}
LOGD("evas_info : %p, evas_info->eo : %p", evas_info, evas_info->eo);
if (info != UPDATE_TBM_SURF) {
LOGW("invalid info type : %d", info);
- goto ERROR;
+ g_mutex_unlock(&evas_info->mp_lock);
+ return;
}
- /* normally get tbm surf in pipe callback. if not, we can get changed tbm surf by other threads */
- ret = media_packet_get_tbm_surface(evas_info->pkt[evas_info->cur_idx], &evas_info->tbm_surf);
- if (ret != MEDIA_PACKET_ERROR_NONE || !evas_info->tbm_surf) {
- LOGW("get_tbm_surface is failed");
- goto ERROR;
+ 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;
}
- tbm_format tbm_fmt = tbm_surface_get_format(evas_info->tbm_surf);
+ /* 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;
+ gint prev_idx = evas_info->pkt_info[cur_idx].prev;
+
+ LOGD("received (idx %d, packet %p)", cur_idx, evas_info->pkt_info[cur_idx].packet);
+
+ tbm_format tbm_fmt = tbm_surface_get_format(evas_info->pkt_info[cur_idx].tbm_surf);
switch (tbm_fmt) {
case TBM_FORMAT_NV12:
LOGD("tbm_surface format : TBM_FORMAT_NV12");
LOGW("tbm_surface format : unknown %d", tbm_fmt);
break;
}
- /* it is needed to skip setting when state is pause */
- LOGD("received (tbm_surf %p)", evas_info->tbm_surf);
- 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->tbm_surf;
-// surf.data.tbm.rot = evas_info->rotate_angle;
-// surf.data.tbm.flip = evas_info->flip;
+ 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;
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;
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);
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);
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);
/* when _evas_pipe_cb is called sequentially, previous packet and current packet will be the same */
- if ((evas_info->prev_idx != -1) && evas_info->pkt[evas_info->prev_idx] && (evas_info->prev_idx != evas_info->cur_idx)) {
- LOGD("destroy previous packet [%p] idx %d", evas_info->pkt[evas_info->prev_idx], evas_info->prev_idx);
- if (media_packet_destroy(evas_info->pkt[evas_info->prev_idx]) != MEDIA_PACKET_ERROR_NONE)
- LOGE("media_packet_destroy failed %p", evas_info->pkt[evas_info->prev_idx]);
- evas_info->pkt[evas_info->prev_idx] = NULL;
- evas_info->sent_buffer_cnt--;
- LOGD("sent packet %d", evas_info->sent_buffer_cnt);
- }
- evas_info->prev_idx = evas_info->cur_idx;
+ 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:
- if ((evas_info->prev_idx != -1) && evas_info->pkt[evas_info->prev_idx]) {
- LOGD("cant render. destroy previous packet [%p] idx %d", evas_info->pkt[evas_info->prev_idx], evas_info->prev_idx);
- if (media_packet_destroy(evas_info->pkt[evas_info->prev_idx]) != MEDIA_PACKET_ERROR_NONE)
- LOGE("media_packet_destroy failed %p", evas_info->pkt[evas_info->prev_idx]);
- evas_info->pkt[evas_info->prev_idx] = NULL;
- evas_info->sent_buffer_cnt--;
+ if ((prev_idx != -1) && evas_info->pkt_info[prev_idx].packet) {
+ LOGI("cant render");
+ _free_previous_packets(evas_info);
}
- evas_info->prev_idx = evas_info->cur_idx;
+ g_mutex_unlock(&evas_info->idx_lock);
g_mutex_unlock(&evas_info->mp_lock);
}
+#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) {
+ 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
+
+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) {
+ LOGD("destroy previous packet [%p] idx %d", evas_info->pkt_info[prev_idx].packet, prev_idx);
+ 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;
+
+ /* move index to previous index */
+ 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;
return true;
} else
LOGW("media_format_get_video_info is failed");
- if (media_format_unref(fmt) != MEDIA_PACKET_ERROR_NONE) //because of media_packet_get_format
+ if (media_format_unref(fmt) != MEDIA_PACKET_ERROR_NONE) /* because of media_packet_get_format */
LOGW("media_format_unref is failed");
} 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[i]) {
+ if (!evas_info->pkt_info[i].packet) {
LOGD("selected idx %d", i);
return i;
}
}
LOGE("there is no empty idx");
+ MMER_FLEAVE();
+
return -1;
}
+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;
+
+ if (!evas_info) {
+ LOGW("there is no esink info");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+
+ /* 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) {
+ LOGE("there is no information for evas object size");
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+ _mm_evas_renderer_update_geometry(evas_info, &result);
+ if (!result.w || !result.h) {
+ LOGE("no information about geometry (%d, %d)", result.w, result.h);
+ return MM_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (evas_info->use_ratio) {
+ 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);
+ if (evas_info->w > 0 && evas_info->h > 0)
+ evas_object_image_size_set(evas_info->eo, evas_info->w, evas_info->h);
+
+ 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;
+ 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);
+ }
+ LOGD("sent packet %d", evas_info->sent_buffer_cnt);
+
+ /* destroy all packets */
+ g_mutex_lock(&evas_info->mp_lock);
+ 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);
+ 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;
+ }
+ }
+ 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;
+ }
+ }
+
+ if (evas_info->sent_buffer_cnt != 0)
+ LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
+ evas_info->sent_buffer_cnt = 0;
+ evas_info->cur_idx = -1;
+ g_mutex_unlock(&evas_info->mp_lock);
+
+ evas_object_image_pixels_dirty_set(evas_info->eo, EINA_TRUE);
+ evas_info->retrieve_packet = FALSE;
+
+ MMER_FLEAVE();
+
+ return ret;
+}
+
#if 0
-void _reset_pipe(mm_evas_info *evas_info)
+int _reset_pipe(mm_evas_info *evas_info)
{
int i = 0;
- int ret = MEDIA_PACKET_ERROR_NONE;
+ int ret = MM_ERROR_NONE;
+ int ret_mp = MEDIA_PACKET_ERROR_NONE;
/* delete old pipe */
if (evas_info->epipe) {
evas_info->epipe = NULL;
}
- /* destroy all packets */
for (i = 0; i < MAX_PACKET_NUM; i++) {
- if (evas_info->pkt[i]) {
- LOGD("destroy packet [%p]", evas_info->pkt[i]);
- ret = media_packet_destroy(evas_info->pkt[i]);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- LOGW("media_packet_destroy failed %p", evas_info->pkt[i]);
- else
- evas_info->sent_buffer_cnt--;
- evas_info->pkt[i] = NULL;
+ if (evas_info->pkt_info[i].packet) {
+ /* destroy all packets */
+ LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
+ 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;
+ }
+ }
+ 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;
}
}
+ if (evas_info->sent_buffer_cnt != 0)
+ LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
+ evas_info->sent_buffer_cnt = 0;
+ evas_info->cur_idx = -1;
+
/* make new pipe */
if (!evas_info->epipe) {
evas_info->epipe = ecore_pipe_add((Ecore_Pipe_Cb) _evas_pipe_cb, evas_info);
if (!evas_info->epipe) {
LOGE("pipe is not created");
+ ret = MM_ERROR_UNKNOWN;
}
LOGD("created pipe %p", evas_info->epipe);
}
- return;
+ return ret;
}
#endif
+
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));
LOGD("Success create evas_info(%p)", *evas_info);
}
g_mutex_init(&ptr->mp_lock);
+ g_mutex_init(&ptr->idx_lock);
+
+ MMER_FLEAVE();
return MM_ERROR_NONE;
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;
ret = _mm_evas_renderer_reset(ptr);
g_mutex_clear(&ptr->mp_lock);
+ g_mutex_clear(&ptr->idx_lock);
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);
LOGD("set evas_info");
-
- evas_info->prev_idx = evas_info->cur_idx = -1;
+ int i;
+ for (i = 0; i < MAX_PACKET_NUM; i++) {
+ evas_info->pkt_info[i].packet = NULL;
+ 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) {
LOGE("pipe is not created");
+ g_mutex_unlock(&evas_info->idx_lock);
return MM_ERROR_UNKNOWN;
}
LOGD("created pipe %p", evas_info->epipe);
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);
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);
+ 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);
int i;
- int ret = MEDIA_PACKET_ERROR_NONE;
+ int ret = MM_ERROR_NONE;
+ int ret_mp = MEDIA_PACKET_ERROR_NONE;
if (evas_info->eo) {
_mm_evas_renderer_unset_callback(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;
- evas_info->tbm_surf = NULL;
+
+ if (evas_info->flush_buffer)
+ _mm_evas_renderer_release_flush_buffer(evas_info);
g_mutex_lock(&evas_info->mp_lock);
for (i = 0; i < MAX_PACKET_NUM; i++) {
- if (evas_info->pkt[i]) {
+ if (evas_info->pkt_info[i].packet) {
/* destroy all packets */
- LOGD("destroy packet [%p]", evas_info->pkt[i]);
- ret = media_packet_destroy(evas_info->pkt[i]);
- if (ret != MEDIA_PACKET_ERROR_NONE)
- LOGW("media_packet_destroy failed %p", evas_info->pkt[i]);
- else
- evas_info->sent_buffer_cnt--;
- evas_info->pkt[i] = NULL;
+ LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
+ 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;
+ }
+ }
+ 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;
}
}
g_mutex_unlock(&evas_info->mp_lock);
-
if (evas_info->sent_buffer_cnt != 0)
LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
evas_info->sent_buffer_cnt = 0;
- evas_info->prev_idx = evas_info->cur_idx = -1;
+ evas_info->cur_idx = -1;
- return MM_ERROR_NONE;
+ 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;
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;
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;
}
+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;
+ pid_t pid = getpid();
+ pid_t tid = syscall(SYS_gettid);
+
+ /* write and this API can be called at the same time.
+ so lock is needed for counting sent_buffer_cnt correctly */
+ g_mutex_lock(&evas_info->idx_lock);
+
+ /* make flush buffer */
+ if (keep_screen)
+ ret = _mm_evas_renderer_make_flush_buffer(evas_info);
+ evas_info->keep_screen = keep_screen;
+
+ LOGD("pid [%d], tid [%d]", pid, tid);
+ if (pid == tid) {
+ /* in this case, we deem it is main thread */
+ if (_flush_packets(evas_info) != MM_ERROR_NONE) {
+ LOGE("flushing packets are failed");
+ ret = MM_ERROR_UNKNOWN;
+ }
+ } else {
+ /* it will be executed to write flush buffer and destroy media packets in pre_cb */
+ evas_info->retrieve_packet = TRUE;
+ }
+ g_mutex_unlock(&evas_info->idx_lock);
+
+ MMER_FLEAVE();
+
+ return ret;
+}
+
+/* make buffer for copying */
+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;
+ }
+ media_packet_h packet = evas_info->pkt_info[evas_info->cur_idx].packet;
+ MM_CHECK_NULL(packet);
+
+ flush_info *flush_buffer = NULL;
+ tbm_bo src_bo = NULL;
+ tbm_surface_h src_tbm_surf = NULL;
+ int src_size = 0;
+ tbm_bo bo = NULL;
+ tbm_surface_info_s info = {0};
+ tbm_bo_handle vaddr_src = {0};
+ tbm_bo_handle vaddr_dst = {0};
+ int ret = MM_ERROR_NONE;
+
+ if (evas_info->flush_buffer)
+ _mm_evas_renderer_release_flush_buffer(evas_info);
+
+ /* malloc buffer */
+ flush_buffer = (flush_info *)malloc(sizeof(flush_info));
+ if (flush_buffer == NULL) {
+ LOGE("malloc is failed");
+ return FALSE;
+ }
+ memset(flush_buffer, 0x0, sizeof(flush_info));
+
+ ret = media_packet_get_tbm_surface(packet, &src_tbm_surf);
+ if (ret != MEDIA_PACKET_ERROR_NONE || !src_tbm_surf) {
+ LOGW("get_tbm_surface is failed");
+ goto ERROR;
+ }
+
+ /* get src buffer info */
+ src_bo = tbm_surface_internal_get_bo(src_tbm_surf, 0);
+ src_size = tbm_surface_internal_get_size(src_tbm_surf);
+ if (!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 */
+ 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);
+ 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)
+ tbm_bo_unmap(src_bo);
+ if (vaddr_dst.ptr)
+ tbm_bo_unmap(bo);
+ goto ERROR;
+ } else {
+ memset(vaddr_dst.ptr, 0x0, info.size);
+ LOGW("tbm_bo_map(vaddr) is finished, bo(%p), vaddr(%p)", bo, vaddr_dst.ptr);
+ }
+
+ /* copy buffer */
+ memcpy(vaddr_dst.ptr, vaddr_src.ptr, src_size);
+
+ tbm_bo_unmap(src_bo);
+ tbm_bo_unmap(bo);
+ 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) {
+ tbm_surface_destroy(flush_buffer->tbm_surf);
+ flush_buffer->tbm_surf = NULL;
+ }
+
+ free(flush_buffer);
+ flush_buffer = NULL;
+ }
+ return MM_ERROR_UNKNOWN;
+}
+
+/* release flush buffer */
+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)
+ 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;
+ }
+
+ LOGW("release FLUSH BUFFER done");
+
+ 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;
mm_evas_info *handle = (mm_evas_info *)data;
int ret = MEDIA_PACKET_ERROR_NONE;
bool has;
+ tbm_surface_h tbm_surf;
+ gint index;
LOGD("packet [%p]", packet);
if (!data || !handle) {
LOGE("handle %p or evas_info %p is NULL", data, handle);
- goto ERROR;
+ goto INVALID_PARAM;
}
+ g_mutex_lock(&handle->idx_lock);
ret = media_packet_has_tbm_surface_buffer(packet, &has);
if (ret != MEDIA_PACKET_ERROR_NONE) {
/* 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 > 14) {
+ if (handle->sent_buffer_cnt > 3) {
LOGE("too many buffers are not released %d", handle->sent_buffer_cnt);
goto ERROR;
#if 0
g_mutex_unlock(&handle->mp_lock);
#endif
}
- handle->cur_idx = _find_empty_index(handle);
- if (handle->cur_idx == -1)
+ ret = media_packet_get_tbm_surface(packet, &tbm_surf);
+ if (ret != MEDIA_PACKET_ERROR_NONE || !tbm_surf) {
+ LOGW("get_tbm_surface is failed");
+ goto ERROR;
+ }
+
+ /* find new index for current packet */
+ index = _find_empty_index(handle);
+ if (index == -1)
goto ERROR;
- handle->pkt[handle->cur_idx] = packet;
+
+#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;
+ handle->pkt_info[index].tbm_surf = tbm_surf;
+ handle->cur_idx = index;
handle->sent_buffer_cnt++;
LOGD("sent packet %d", handle->sent_buffer_cnt);
+
ret = ecore_pipe_write(handle->epipe, handle, UPDATE_TBM_SURF);
if (!ret) {
- handle->pkt[handle->cur_idx] = NULL;
- handle->cur_idx = handle->prev_idx;
+ handle->pkt_info[index].packet = NULL;
+ handle->pkt_info[index].tbm_surf = NULL;
+ handle->pkt_info[index].prev = -1;
+ handle->cur_idx = handle->pkt_info[index].prev;
handle->sent_buffer_cnt--;
LOGW("Failed to ecore_pipe_write() for updating tbm surf\n");
goto ERROR;
LOGW("no tbm_surf");
goto ERROR;
}
+ g_mutex_unlock(&handle->idx_lock);
- return;
+ MMER_FLEAVE();
- ERROR:
+ return;
+ERROR:
+ g_mutex_unlock(&handle->idx_lock);
+INVALID_PARAM:
/* destroy media_packet immediately */
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;
int mm_evas_renderer_update_param(MMHandleType handle)
{
+ MMER_FENTER();
+
int ret = MM_ERROR_NONE;
mm_evas_info *evas_info = (mm_evas_info *)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;
mm_evas_info *evas_info = NULL;
int mm_evas_renderer_destroy(MMHandleType *handle)
{
+ MMER_FENTER();
+ MM_CHECK_NULL(handle);
+
int ret = MM_ERROR_NONE;
mm_evas_info *evas_info = (mm_evas_info *)*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;
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) {
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;
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) {
}
*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)
+{
+ 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 player is not prepared");
+ return MM_ERROR_RESOURCE_NOT_INITIALIZED;
+ }
+ 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;
}