summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNAMJEONGYOON <just.nam@samsung.com>2016-04-05 20:59:06 +0900
committerNAMJEONGYOON <just.nam@samsung.com>2016-04-07 15:00:16 +0900
commit2d072b84b67e1dfe2f012f9140b149d0ca7b282e (patch)
tree1abdc0bc933cdf1109ce4c01e4f4c2f9c60b8e3c
parent62c24fb160ab937f329b269b00ac0a901d20c97d (diff)
downloadlibmm-evas-renderer-2d072b84b67e1dfe2f012f9140b149d0ca7b282e.tar.gz
libmm-evas-renderer-2d072b84b67e1dfe2f012f9140b149d0ca7b282e.tar.bz2
libmm-evas-renderer-2d072b84b67e1dfe2f012f9140b149d0ca7b282e.zip
Change-Id: I480a0448e1f636a9a924b05b1dc6c68d32d0509f
-rw-r--r--src/include/mm_evas_renderer.h14
-rw-r--r--src/mm_evas_renderer.c196
2 files changed, 148 insertions, 62 deletions
diff --git a/src/include/mm_evas_renderer.h b/src/include/mm_evas_renderer.h
index 433da22..247f26d 100644
--- a/src/include/mm_evas_renderer.h
+++ b/src/include/mm_evas_renderer.h
@@ -70,6 +70,12 @@ typedef enum {
} visible_info;
typedef struct {
+ media_packet_h packet;
+ tbm_surface_h tbm_surf;
+ gint prev; /* keep previous index for destroying remained packets */
+} packet_info;
+
+typedef struct {
gint x;
gint y;
gint w;
@@ -96,17 +102,15 @@ typedef struct {
tbm_surface_h tbm_surf;
/* media packet */
- media_packet_h prev_mp;
- media_packet_h cur_mp;
- media_packet_h pkt[MAX_PACKET_NUM];
- gint prev_idx;
+ packet_info pkt_info[MAX_PACKET_NUM];
gint cur_idx;
/* count undestroyed media packet */
guint sent_buffer_cnt;
/* lock */
- GMutex mp_lock;
+ GMutex mp_lock; /* media_packet free lock */
+ GMutex idx_lock; /* to keep value of cur_idx */
} mm_evas_info;
/* create and initialize evas_info */
diff --git a/src/mm_evas_renderer.c b/src/mm_evas_renderer.c
index 9f1e666..833b366 100644
--- a/src/mm_evas_renderer.c
+++ b/src/mm_evas_renderer.c
@@ -106,6 +106,10 @@ enum {
};
/* internal */
+#ifdef _DEBUG_INDEX
+void __print_idx(mm_evas_info *evas_info);
+#endif
+void _free_previous_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);
@@ -150,7 +154,7 @@ static void _evas_render_pre_cb(void *data, Evas *e, void *event_info)
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
+ /* LOGI("- test -"); pre_cb will be used for flush_buffer */
}
static void _evas_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
@@ -171,7 +175,7 @@ static void _evas_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info
void _evas_pipe_cb(void *data, void *buffer, update_info info)
{
mm_evas_info *evas_info = data;
- int ret;
+
LOGD("[ENTER]");
if (!evas_info) {
@@ -183,7 +187,8 @@ void _evas_pipe_cb(void *data, void *buffer, update_info 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);
@@ -202,16 +207,23 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
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);
+ 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[evas_info->cur_idx].tbm_surf);
switch (tbm_fmt) {
case TBM_FORMAT_NV12:
LOGD("tbm_surface format : TBM_FORMAT_NV12");
@@ -224,12 +236,10 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
break;
}
/* it is needed to skip setting when state is pause */
- LOGD("received (tbm_surf %p)", evas_info->tbm_surf);
-
Evas_Native_Surface surf;
surf.type = EVAS_NATIVE_SURFACE_TBM;
surf.version = EVAS_NATIVE_SURFACE_VERSION;
- surf.data.tbm.buffer = evas_info->tbm_surf;
+ 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;
@@ -266,33 +276,62 @@ void _evas_pipe_cb(void *data, void *buffer, update_info info)
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);
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 _DEBUG_INDEX
+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;
+}
+#endif
+
+void _free_previous_packets(mm_evas_info *evas_info)
+{
+ 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 (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->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;
+ prev_idx = evas_info->pkt_info[prev_idx].prev;
+ LOGD("sent packet %d", evas_info->sent_buffer_cnt);
+ }
+ return;
+}
+
static int _get_video_size(media_packet_h packet, mm_evas_info *evas_info)
{
media_format_h fmt;
@@ -305,7 +344,7 @@ static int _get_video_size(media_packet_h packet, mm_evas_info *evas_info)
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");
@@ -317,7 +356,7 @@ int _find_empty_index(mm_evas_info *evas_info)
{
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;
}
@@ -342,14 +381,14 @@ void _reset_pipe(mm_evas_info *evas_info)
/* 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 (evas_info->pkt_info[i].packet) {
+ LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
+ ret = media_packet_destroy(evas_info->pkt_info[i].packet);
if (ret != MEDIA_PACKET_ERROR_NONE)
- LOGW("media_packet_destroy failed %p", evas_info->pkt[i]);
+ LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
else
evas_info->sent_buffer_cnt--;
- evas_info->pkt[i] = NULL;
+ evas_info->pkt_info[i].packet = NULL;
}
}
@@ -394,6 +433,7 @@ int _mm_evas_renderer_create(mm_evas_info **evas_info)
LOGD("Success create evas_info(%p)", *evas_info);
}
g_mutex_init(&ptr->mp_lock);
+ g_mutex_init(&ptr->idx_lock);
return MM_ERROR_NONE;
@@ -412,6 +452,7 @@ int _mm_evas_renderer_destroy(mm_evas_info **evas_info)
ret = _mm_evas_renderer_reset(ptr);
g_mutex_clear(&ptr->mp_lock);
+ g_mutex_clear(&ptr->idx_lock);
g_free(ptr);
ptr = NULL;
@@ -423,14 +464,22 @@ int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo)
{
MM_CHECK_NULL(evas_info);
MM_CHECK_NULL(eo);
+ g_mutex_lock(&evas_info->idx_lock);
LOGD("set evas_info");
+ 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->prev_idx = evas_info->cur_idx = -1;
+ evas_info->cur_idx = -1;
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);
@@ -439,15 +488,19 @@ int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo)
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);
+
return MM_ERROR_NONE;
}
int _mm_evas_renderer_reset(mm_evas_info *evas_info)
{
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);
@@ -462,29 +515,33 @@ 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->w = evas_info->h = 0;
- evas_info->tbm_surf = NULL;
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]);
+ 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;
+ }
else
evas_info->sent_buffer_cnt--;
- evas_info->pkt[i] = NULL;
+ 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);
+
+ return ret;
}
void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result)
@@ -606,13 +663,16 @@ void mm_evas_renderer_write(media_packet_h packet, void *data)
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) {
@@ -623,7 +683,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 > 14) {
+ if (handle->sent_buffer_cnt > 10) {
LOGE("too many buffers are not released %d", handle->sent_buffer_cnt);
goto ERROR;
#if 0
@@ -635,16 +695,32 @@ void mm_evas_renderer_write(media_packet_h packet, void *data)
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;
- handle->pkt[handle->cur_idx] = packet;
+ }
+
+ /* find new index for current packet */
+ index = _find_empty_index(handle);
+ if (index == -1) {
+ goto ERROR;
+ }
+
+ /* 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;
@@ -653,10 +729,12 @@ void mm_evas_renderer_write(media_packet_h packet, void *data)
LOGW("no tbm_surf");
goto ERROR;
}
+ g_mutex_unlock(&handle->idx_lock);
return;
-
- ERROR:
+ERROR:
+ g_mutex_unlock(&handle->idx_lock);
+INVALID_PARAM:
/* destroy media_packet immediately */
if (packet) {
g_mutex_lock(&handle->mp_lock);
@@ -705,6 +783,8 @@ int mm_evas_renderer_update_param(MMHandleType handle)
int mm_evas_renderer_create(MMHandleType *handle, Evas_Object *eo)
{
+ MM_CHECK_NULL(handle);
+
int ret = MM_ERROR_NONE;
mm_evas_info *evas_info = NULL;
@@ -728,6 +808,8 @@ int mm_evas_renderer_create(MMHandleType *handle, Evas_Object *eo)
int mm_evas_renderer_destroy(MMHandleType *handle)
{
+ MM_CHECK_NULL(handle);
+
int ret = MM_ERROR_NONE;
mm_evas_info *evas_info = (mm_evas_info *)*handle;