2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <sys/types.h>
30 #include <sys/syscall.h>
31 #include "mm_evas_renderer.h"
36 #define LOG_TAG "MM_EVAS_RENDER"
37 //#define _INTERNAL_DEBUG_ /* debug only */
40 #define MMER_FENTER(); LOGD("<ENTER>");
41 #define MMER_FLEAVE(); LOGD("<LEAVE>");
43 #define MMER_FENTER();
44 #define MMER_FLEAVE();
47 #define MM_CHECK_NULL(x_var) \
49 LOGE("[%s] is NULL\n", #x_var); \
50 return MM_ERROR_INVALID_ARGUMENT; \
53 #define SET_EVAS_OBJECT_EVENT_CALLBACK(x_evas_image_object, x_usr_data) \
55 if (x_evas_image_object) { \
56 LOGD("object callback add"); \
57 evas_object_event_callback_add(x_evas_image_object, EVAS_CALLBACK_DEL, _evas_del_cb, x_usr_data); \
58 evas_object_event_callback_add(x_evas_image_object, EVAS_CALLBACK_RESIZE, _evas_resize_cb, x_usr_data); \
62 #define UNSET_EVAS_OBJECT_EVENT_CALLBACK(x_evas_image_object) \
64 if (x_evas_image_object) { \
65 LOGD("object callback del"); \
66 evas_object_event_callback_del(x_evas_image_object, EVAS_CALLBACK_DEL, _evas_del_cb); \
67 evas_object_event_callback_del(x_evas_image_object, EVAS_CALLBACK_RESIZE, _evas_resize_cb); \
71 #define SET_EVAS_EVENT_CALLBACK(x_evas, x_usr_data) \
74 LOGD("callback add... evas_callback_render_pre.. evas : %p evas_info : %p", x_evas, x_usr_data); \
75 evas_event_callback_add(x_evas, EVAS_CALLBACK_RENDER_PRE, _evas_render_pre_cb, x_usr_data); \
79 #define UNSET_EVAS_EVENT_CALLBACK(x_evas) \
82 LOGD("callback del... evas_callback_render_pre %p", x_evas); \
83 evas_event_callback_del(x_evas, EVAS_CALLBACK_RENDER_PRE, _evas_render_pre_cb); \
88 DISP_GEO_METHOD_LETTER_BOX = 0,
89 DISP_GEO_METHOD_ORIGIN_SIZE,
90 DISP_GEO_METHOD_FULL_SCREEN,
91 DISP_GEO_METHOD_CROPPED_FULL_SCREEN,
92 DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX,
93 DISP_GEO_METHOD_CUSTOM_ROI,
113 #ifdef _INTERNAL_DEBUG_
114 static int g_cnt = 0;
115 static void __print_idx(mm_evas_info *evas_info);
116 static int __dump_pkt(media_packet_h pkt);
119 static void _free_previous_packets(mm_evas_info *evas_info);
120 static int _flush_packets(mm_evas_info *evas_info);
121 static int _mm_evas_renderer_create(mm_evas_info **evas_info);
122 static int _mm_evas_renderer_destroy(mm_evas_info **evas_info);
123 static int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo);
124 static int _mm_evas_renderer_reset(mm_evas_info *evas_info);
125 static void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result);
126 static int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info);
127 static int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_screen);
128 static int _mm_evas_renderer_make_flush_buffer(mm_evas_info *evas_info);
129 static void _mm_evas_renderer_release_flush_buffer(mm_evas_info *evas_info);
130 static void _mm_evas_renderer_set_callback(mm_evas_info *evas_info);
131 static void _mm_evas_renderer_unset_callback(mm_evas_info *evas_info);
133 static void _evas_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
140 mm_evas_info *evas_info = data;
142 if (!evas_info || !evas_info->eo)
145 evas_object_geometry_get(evas_info->eo, &x, &y, &w, &h);
147 LOGW("evas object size (w:%d,h:%d) was not set", w, h);
149 evas_info->eo_size.x = x;
150 evas_info->eo_size.y = y;
151 evas_info->eo_size.w = w;
152 evas_info->eo_size.h = h;
153 LOGW("resize (x:%d, y:%d, w:%d, h:%d)", x, y, w, h);
154 ret = _mm_evas_renderer_apply_geometry(evas_info);
155 if (ret != MM_ERROR_NONE)
156 LOGW("fail to apply geometry info");
161 static void _evas_render_pre_cb(void *data, Evas *e, void *event_info)
165 mm_evas_info *evas_info = data;
167 if (!evas_info || !evas_info->eo) {
168 LOGW("there is no esink info.... esink : %p, or eo is NULL returning", evas_info);
172 /* flush will be executed in this callback normally,
173 because native_surface_set must be called in main thread */
174 if (evas_info->retrieve_packet) {
175 g_mutex_lock(&evas_info->idx_lock);
176 if (_flush_packets(evas_info) != MM_ERROR_NONE)
177 LOGE("flushing packets are failed");
178 g_mutex_unlock(&evas_info->idx_lock);
183 static void _evas_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
187 mm_evas_info *evas_info = data;
189 if (!evas_info || !evas_info->eo)
193 _mm_evas_renderer_unset_callback(evas_info);
194 evas_object_image_data_set(evas_info->eo, NULL);
195 evas_info->eo = NULL;
200 static void _evas_pipe_cb(void *data, void *buffer, update_info info)
204 mm_evas_info *evas_info = data;
207 LOGW("evas_info is NULL", evas_info);
211 g_mutex_lock(&evas_info->mp_lock);
213 if (!evas_info->eo) {
214 LOGW("evas_info %p", evas_info);
215 g_mutex_unlock(&evas_info->mp_lock);
219 LOGD("evas_info : %p, evas_info->eo : %p", evas_info, evas_info->eo);
220 if (info == UPDATE_VISIBILITY) {
221 if (evas_info->visible == VISIBLE_FALSE) {
222 evas_object_hide(evas_info->eo);
223 LOGI("object hide..");
225 evas_object_show(evas_info->eo);
226 LOGI("object show.. %d", evas_info->visible);
229 g_mutex_unlock(&evas_info->mp_lock);
233 if (info != UPDATE_TBM_SURF) {
234 LOGW("invalid info type : %d", info);
235 g_mutex_unlock(&evas_info->mp_lock);
239 if ((evas_info->cur_idx == -1) || !evas_info->pkt_info[evas_info->cur_idx].tbm_surf) {
240 LOGW("cur_idx %d, tbm_surf may be NULL", evas_info->cur_idx);
241 g_mutex_unlock(&evas_info->mp_lock);
244 /* perhaps, it is needed to skip setting when state is pause */
246 g_mutex_lock(&evas_info->idx_lock);
248 gint cur_idx = evas_info->cur_idx;
249 gint prev_idx = evas_info->pkt_info[cur_idx].prev;
251 LOGD("received (idx %d, packet %p)", cur_idx, evas_info->pkt_info[cur_idx].packet);
253 tbm_format tbm_fmt = tbm_surface_get_format(evas_info->pkt_info[cur_idx].tbm_surf);
255 case TBM_FORMAT_NV12:
256 LOGD("tbm_surface format : TBM_FORMAT_NV12");
258 case TBM_FORMAT_YUV420:
259 LOGD("tbm_surface format : TBM_FORMAT_YUV420");
262 LOGW("tbm_surface format : unknown %d", tbm_fmt);
266 Evas_Native_Surface surf = { 0 };
267 surf.type = EVAS_NATIVE_SURFACE_TBM;
268 surf.version = EVAS_NATIVE_SURFACE_VERSION;
269 surf.data.tbm.buffer = evas_info->pkt_info[cur_idx].tbm_surf;
270 surf.data.tbm.rot = evas_info->rotate_angle;
271 surf.data.tbm.flip = evas_info->flip;
273 rect_info result = { 0 };
275 evas_object_geometry_get(evas_info->eo, &evas_info->eo_size.x, &evas_info->eo_size.y,
276 &evas_info->eo_size.w, &evas_info->eo_size.h);
277 if (!evas_info->eo_size.w || !evas_info->eo_size.h) {
278 LOGE("there is no information for evas object size");
281 _mm_evas_renderer_update_geometry(evas_info, &result);
282 if (!result.w || !result.h) {
283 LOGE("no information about geometry (%d, %d)", result.w, result.h);
287 if (evas_info->update_needed) {
288 /* update geometry on pause state */
289 evas_object_image_native_surface_set(evas_info->eo, NULL);
290 evas_info->update_needed = FALSE;
293 if (evas_info->use_ratio) {
294 surf.data.tbm.ratio = (float) evas_info->w / evas_info->h;
297 evas_object_size_hint_align_set(evas_info->eo, EVAS_HINT_FILL, EVAS_HINT_FILL);
298 evas_object_size_hint_weight_set(evas_info->eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
299 if (evas_info->w > 0 && evas_info->h > 0)
300 evas_object_image_size_set(evas_info->eo, evas_info->w, evas_info->h);
302 evas_object_image_native_surface_set(evas_info->eo, &surf);
303 LOGD("native surface set finish");
305 if (result.x || result.y)
306 LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
308 evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
310 evas_object_image_pixels_dirty_set(evas_info->eo, EINA_TRUE);
311 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);
313 /* when _evas_pipe_cb is called sequentially, previous packet and current packet will be the same */
314 if ((prev_idx != -1) && evas_info->pkt_info[prev_idx].packet && (prev_idx != cur_idx))
315 _free_previous_packets(evas_info);
317 g_mutex_unlock(&evas_info->idx_lock);
318 g_mutex_unlock(&evas_info->mp_lock);
325 if ((prev_idx != -1) && evas_info->pkt_info[prev_idx].packet) {
327 _free_previous_packets(evas_info);
329 g_mutex_unlock(&evas_info->idx_lock);
330 g_mutex_unlock(&evas_info->mp_lock);
333 #ifdef _INTERNAL_DEBUG_
334 static void __print_idx(mm_evas_info *evas_info)
336 gint prev_idx = evas_info->pkt_info[evas_info->cur_idx].prev;
337 LOGE("***** start cur_idx : %d -> prev_idx : %d", evas_info->cur_idx, prev_idx);
338 while (prev_idx != -1) {
339 LOGE("***** cur_idx : %d -> prev_idx : %d", prev_idx, evas_info->pkt_info[prev_idx].prev);
340 prev_idx = evas_info->pkt_info[prev_idx].prev;
346 static int __dump_pkt(media_packet_h pkt)
350 char filename[100] = {0};
353 sprintf(filename, "/tmp/DUMP_IMG_%2.2d.dump", g_cnt);
354 fp = fopen(filename, "wb");
358 LOGW("DUMP IMG_%2.2d", g_cnt);
359 media_packet_get_buffer_data_ptr(pkt, &data);
360 media_packet_get_buffer_size(pkt, &buf_size);
361 LOGW("input data : %p, size %d\n", data, (int)buf_size);
362 fwrite(data, (int)buf_size, 1, fp);
369 static void _free_previous_packets(mm_evas_info *evas_info)
373 gint index = evas_info->cur_idx;
374 gint prev_idx = evas_info->pkt_info[index].prev;
376 while (prev_idx != -1) {
377 LOGD("destroy previous packet [%p] idx %d", evas_info->pkt_info[prev_idx].packet, prev_idx);
378 if (evas_info->packet_rendered_cb) {
379 evas_info->packet_rendered_cb(evas_info->pkt_info[prev_idx].packet, evas_info->packet_rendered_cb_user);
381 if (media_packet_destroy(evas_info->pkt_info[prev_idx].packet) != MEDIA_PACKET_ERROR_NONE)
382 LOGE("media_packet_destroy failed %p", evas_info->pkt_info[prev_idx].packet);
384 evas_info->sent_buffer_cnt--;
385 evas_info->pkt_info[prev_idx].packet = NULL;
386 evas_info->pkt_info[prev_idx].tbm_surf = NULL;
387 evas_info->pkt_info[index].prev = -1;
389 /* move index to previous index */
391 prev_idx = evas_info->pkt_info[prev_idx].prev;
392 LOGD("sent packet %d", evas_info->sent_buffer_cnt);
400 static int _get_video_size(media_packet_h packet, mm_evas_info *evas_info)
405 if (media_packet_get_format(packet, &fmt) == MEDIA_PACKET_ERROR_NONE) {
407 if (media_format_get_video_info(fmt, NULL, &w, &h, NULL, NULL) == MEDIA_PACKET_ERROR_NONE) {
408 LOGD("video width = %d, height =%d", w, h);
413 LOGW("media_format_get_video_info is failed");
414 if (media_format_unref(fmt) != MEDIA_PACKET_ERROR_NONE) /* because of media_packet_get_format */
415 LOGW("media_format_unref is failed");
417 LOGW("media_packet_get_format is failed");
425 static int _find_empty_index(mm_evas_info *evas_info)
430 for (i = 0; i < MAX_PACKET_NUM; i++) {
431 if (!evas_info->pkt_info[i].packet) {
432 LOGD("selected idx %d", i);
436 LOGE("there is no empty idx");
443 static int _flush_packets(mm_evas_info *evas_info)
447 int ret = MM_ERROR_NONE;
448 int ret_mp = MEDIA_PACKET_ERROR_NONE;
452 LOGW("there is no esink info");
453 return MM_ERROR_INVALID_ARGUMENT;
456 /* update the screen only if visible is true */
457 /* if flush buffer is null, we cant keep screen */
458 if (evas_info->keep_screen && (evas_info->visible != VISIBLE_FALSE) && evas_info->flush_buffer) {
459 Evas_Native_Surface surf = { 0 };
460 rect_info result = { 0 };
461 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);
462 if (!evas_info->eo_size.w || !evas_info->eo_size.h) {
463 LOGE("there is no information for evas object size");
464 return MM_ERROR_INVALID_ARGUMENT;
466 _mm_evas_renderer_update_geometry(evas_info, &result);
467 if (!result.w || !result.h) {
468 LOGE("no information about geometry (%d, %d)", result.w, result.h);
469 return MM_ERROR_INVALID_ARGUMENT;
472 if (evas_info->use_ratio) {
473 surf.data.tbm.ratio = (float) evas_info->w / evas_info->h;
476 evas_object_size_hint_align_set(evas_info->eo, EVAS_HINT_FILL, EVAS_HINT_FILL);
477 evas_object_size_hint_weight_set(evas_info->eo, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
478 if (evas_info->w > 0 && evas_info->h > 0)
479 evas_object_image_size_set(evas_info->eo, evas_info->w, evas_info->h);
481 if (result.x || result.y)
482 LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
484 evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
486 /* set flush buffer */
487 surf.type = EVAS_NATIVE_SURFACE_TBM;
488 surf.version = EVAS_NATIVE_SURFACE_VERSION;
489 surf.data.tbm.buffer = evas_info->flush_buffer->tbm_surf;
490 surf.data.tbm.rot = evas_info->rotate_angle;
491 surf.data.tbm.flip = evas_info->flip;
492 evas_object_image_native_surface_set(evas_info->eo, &surf);
494 LOGD("flush_buffer surf(%p), rotate(%d), flip(%d)", evas_info->flush_buffer->tbm_surf, evas_info->rotate_angle, evas_info->flip);
496 /* unset evas native surface for displaying black screen */
497 evas_object_image_native_surface_set(evas_info->eo, NULL);
498 evas_object_image_data_set(evas_info->eo, NULL);
500 LOGD("sent packet %d", evas_info->sent_buffer_cnt);
502 /* destroy all packets */
503 g_mutex_lock(&evas_info->mp_lock);
504 for (i = 0; i < MAX_PACKET_NUM; i++) {
505 if (evas_info->pkt_info[i].packet) {
506 LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
507 if (evas_info->packet_rendered_cb) {
508 evas_info->packet_rendered_cb(evas_info->pkt_info[i].packet, evas_info->packet_rendered_cb_user);
510 ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
511 if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
512 LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
513 ret = MM_ERROR_UNKNOWN;
516 evas_info->sent_buffer_cnt--;
517 evas_info->pkt_info[i].packet = NULL;
518 evas_info->pkt_info[i].tbm_surf = NULL;
519 evas_info->pkt_info[i].prev = -1;
523 if (evas_info->sent_buffer_cnt != 0)
524 LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
525 evas_info->sent_buffer_cnt = 0;
526 evas_info->cur_idx = -1;
527 g_mutex_unlock(&evas_info->mp_lock);
529 evas_object_image_pixels_dirty_set(evas_info->eo, EINA_TRUE);
530 evas_info->retrieve_packet = FALSE;
538 int _reset_pipe(mm_evas_info *evas_info)
541 int ret = MM_ERROR_NONE;
542 int ret_mp = MEDIA_PACKET_ERROR_NONE;
544 /* delete old pipe */
545 if (evas_info->epipe) {
546 LOGD("pipe %p will be deleted", evas_info->epipe);
547 ecore_pipe_del(evas_info->epipe);
548 evas_info->epipe = NULL;
551 for (i = 0; i < MAX_PACKET_NUM; i++) {
552 if (evas_info->pkt_info[i].packet) {
553 /* destroy all packets */
554 LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
555 if (evas_info->packet_rendered_cb) {
556 evas_info->packet_rendered_cb(evas_info->pkt_info[i].packet, evas_info->packet_rendered_cb_user);
558 ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
559 if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
560 LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
561 ret = MM_ERROR_UNKNOWN;
564 evas_info->sent_buffer_cnt--;
565 evas_info->pkt_info[i].packet = NULL;
566 evas_info->pkt_info[i].tbm_surf = NULL;
567 evas_info->pkt_info[i].prev = -1;
571 if (evas_info->sent_buffer_cnt != 0)
572 LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
573 evas_info->sent_buffer_cnt = 0;
574 evas_info->cur_idx = -1;
577 if (!evas_info->epipe) {
578 evas_info->epipe = ecore_pipe_add((Ecore_Pipe_Cb) _evas_pipe_cb, evas_info);
579 if (!evas_info->epipe) {
580 LOGE("pipe is not created");
581 ret = MM_ERROR_UNKNOWN;
583 LOGD("created pipe %p", evas_info->epipe);
590 static void _mm_evas_renderer_set_callback(mm_evas_info *evas_info)
594 SET_EVAS_OBJECT_EVENT_CALLBACK(evas_info->eo, evas_info);
595 SET_EVAS_EVENT_CALLBACK(evas_object_evas_get(evas_info->eo), evas_info);
600 static void _mm_evas_renderer_unset_callback(mm_evas_info *evas_info)
604 UNSET_EVAS_OBJECT_EVENT_CALLBACK(evas_info->eo);
605 UNSET_EVAS_EVENT_CALLBACK(evas_object_evas_get(evas_info->eo));
610 static int _mm_evas_renderer_create(mm_evas_info **evas_info)
614 mm_evas_info *ptr = NULL;
615 ptr = g_malloc0(sizeof(mm_evas_info));
618 LOGE("Cannot allocate memory for evas_info\n");
622 LOGD("Success create evas_info(%p)", *evas_info);
624 g_mutex_init(&ptr->mp_lock);
625 g_mutex_init(&ptr->idx_lock);
629 return MM_ERROR_NONE;
633 return MM_ERROR_OUT_OF_STORAGE;
636 static int _mm_evas_renderer_destroy(mm_evas_info **evas_info)
640 mm_evas_info *ptr = (mm_evas_info *)*evas_info;
642 int ret = MM_ERROR_NONE;
644 LOGD("finalize evas_info %p", ptr);
646 ret = _mm_evas_renderer_reset(ptr);
647 g_mutex_clear(&ptr->mp_lock);
648 g_mutex_clear(&ptr->idx_lock);
658 static int _mm_evas_renderer_set_info(mm_evas_info *evas_info, Evas_Object *eo)
661 MM_CHECK_NULL(evas_info);
663 g_mutex_lock(&evas_info->idx_lock);
665 LOGD("set evas_info");
667 for (i = 0; i < MAX_PACKET_NUM; i++) {
668 evas_info->pkt_info[i].packet = NULL;
669 evas_info->pkt_info[i].tbm_surf = NULL;
670 evas_info->pkt_info[i].prev = -1;
672 evas_info->cur_idx = -1;
673 evas_info->dst_roi.x = evas_info->dst_roi.y = evas_info->dst_roi.w = evas_info->dst_roi.h = 0;
675 evas_info->epipe = ecore_pipe_add((Ecore_Pipe_Cb) _evas_pipe_cb, evas_info);
676 if (!evas_info->epipe) {
677 LOGE("pipe is not created");
678 g_mutex_unlock(&evas_info->idx_lock);
679 return MM_ERROR_UNKNOWN;
681 LOGD("created pipe %p", evas_info->epipe);
682 _mm_evas_renderer_set_callback(evas_info);
684 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);
685 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);
687 g_mutex_unlock(&evas_info->idx_lock);
691 return MM_ERROR_NONE;
694 static int _mm_evas_renderer_reset(mm_evas_info *evas_info)
697 MM_CHECK_NULL(evas_info);
698 g_mutex_lock(&evas_info->idx_lock);
701 int ret = MM_ERROR_NONE;
702 int ret_mp = MEDIA_PACKET_ERROR_NONE;
705 _mm_evas_renderer_unset_callback(evas_info);
706 evas_object_image_data_set(evas_info->eo, NULL);
707 evas_info->eo = NULL;
709 if (evas_info->epipe) {
710 LOGD("pipe %p will be deleted", evas_info->epipe);
711 ecore_pipe_del(evas_info->epipe);
712 evas_info->epipe = NULL;
715 evas_info->eo_size.x = evas_info->eo_size.y = evas_info->eo_size.w = evas_info->eo_size.h = 0;
716 evas_info->dst_roi.x = evas_info->dst_roi.y = evas_info->dst_roi.w = evas_info->dst_roi.h = 0;
717 evas_info->w = evas_info->h = 0;
719 if (evas_info->flush_buffer)
720 _mm_evas_renderer_release_flush_buffer(evas_info);
722 g_mutex_lock(&evas_info->mp_lock);
723 for (i = 0; i < MAX_PACKET_NUM; i++) {
724 if (evas_info->pkt_info[i].packet) {
725 /* destroy all packets */
726 LOGD("destroy packet [%p]", evas_info->pkt_info[i].packet);
727 if (evas_info->packet_rendered_cb) {
728 evas_info->packet_rendered_cb(evas_info->pkt_info[i].packet, evas_info->packet_rendered_cb_user);
730 ret_mp = media_packet_destroy(evas_info->pkt_info[i].packet);
731 if (ret_mp != MEDIA_PACKET_ERROR_NONE) {
732 LOGW("media_packet_destroy failed %p", evas_info->pkt_info[i].packet);
733 ret = MM_ERROR_UNKNOWN;
736 evas_info->sent_buffer_cnt--;
737 evas_info->pkt_info[i].packet = NULL;
738 evas_info->pkt_info[i].tbm_surf = NULL;
739 evas_info->pkt_info[i].prev = -1;
742 g_mutex_unlock(&evas_info->mp_lock);
743 if (evas_info->sent_buffer_cnt != 0)
744 LOGE("it should be 0 --> [%d]", evas_info->sent_buffer_cnt);
745 evas_info->sent_buffer_cnt = 0;
746 evas_info->cur_idx = -1;
748 g_mutex_unlock(&evas_info->idx_lock);
755 static void _mm_evas_renderer_update_geometry(mm_evas_info *evas_info, rect_info *result)
759 if (!evas_info || !evas_info->eo) {
760 LOGW("there is no evas_info or evas object");
764 LOGW("there is no rect info");
771 switch (evas_info->display_geometry_method) {
772 case DISP_GEO_METHOD_LETTER_BOX:
773 /* set black padding for letter box mode */
774 LOGD("letter box mode");
775 evas_info->use_ratio = TRUE;
776 result->w = evas_info->eo_size.w;
777 result->h = evas_info->eo_size.h;
779 case DISP_GEO_METHOD_ORIGIN_SIZE:
780 LOGD("origin size mode");
781 evas_info->use_ratio = FALSE;
782 /* set coordinate for each case */
783 result->x = (evas_info->eo_size.w - evas_info->w) / 2;
784 result->y = (evas_info->eo_size.h - evas_info->h) / 2;
785 result->w = evas_info->w;
786 result->h = evas_info->h;
788 case DISP_GEO_METHOD_FULL_SCREEN:
789 LOGD("full screen mode");
790 evas_info->use_ratio = FALSE;
791 result->w = evas_info->eo_size.w;
792 result->h = evas_info->eo_size.h;
794 case DISP_GEO_METHOD_CROPPED_FULL_SCREEN:
795 LOGD("cropped full screen mode");
796 evas_info->use_ratio = FALSE;
797 /* compare evas object's ratio with video's */
798 if ((evas_info->eo_size.w / evas_info->eo_size.h) > (evas_info->w / evas_info->h)) {
799 result->w = evas_info->eo_size.w;
800 result->h = evas_info->eo_size.w * evas_info->h / evas_info->w;
801 result->y = -(result->h - evas_info->eo_size.h) / 2;
803 result->w = evas_info->eo_size.h * evas_info->w / evas_info->h;
804 result->h = evas_info->eo_size.h;
805 result->x = -(result->w - evas_info->eo_size.w) / 2;
808 case DISP_GEO_METHOD_ORIGIN_SIZE_OR_LETTER_BOX:
809 LOGD("origin size or letter box mode");
810 /* if video size is smaller than evas object's, it will be set to origin size mode */
811 if ((evas_info->eo_size.w > evas_info->w) && (evas_info->eo_size.h > evas_info->h)) {
812 LOGD("origin size mode");
813 evas_info->use_ratio = FALSE;
814 /* set coordinate for each case */
815 result->x = (evas_info->eo_size.w - evas_info->w) / 2;
816 result->y = (evas_info->eo_size.h - evas_info->h) / 2;
817 result->w = evas_info->w;
818 result->h = evas_info->h;
820 LOGD("letter box mode");
821 evas_info->use_ratio = TRUE;
822 result->w = evas_info->eo_size.w;
823 result->h = evas_info->eo_size.h;
826 case DISP_GEO_METHOD_CUSTOM_ROI:
827 LOGD("custom roi mode");
828 evas_info->use_ratio = TRUE;
829 result->x = evas_info->dst_roi.x;
830 result->y = evas_info->dst_roi.y;
831 result->w = evas_info->dst_roi.w;
832 result->h = evas_info->dst_roi.h;
835 LOGW("unsupported mode.");
838 LOGD("geometry result [%d, %d, %d, %d]", result->x, result->y, result->w, result->h);
843 static int _mm_evas_renderer_apply_geometry(mm_evas_info *evas_info)
847 if (!evas_info || !evas_info->eo) {
848 LOGW("there is no evas_info or evas object");
849 return MM_ERROR_NONE;
852 Evas_Native_Surface *surf = evas_object_image_native_surface_get(evas_info->eo);
853 rect_info result = { 0 };
856 LOGD("native surface exists");
857 surf->data.tbm.rot = evas_info->rotate_angle;
858 surf->data.tbm.flip = evas_info->flip;
859 evas_object_image_native_surface_set(evas_info->eo, surf);
861 _mm_evas_renderer_update_geometry(evas_info, &result);
863 if (evas_info->use_ratio) {
864 surf->data.tbm.ratio = (float) evas_info->w / evas_info->h;
867 if (result.x || result.y)
868 LOGD("coordinate x, y (%d, %d) for locating video to center", result.x, result.y);
870 evas_object_image_fill_set(evas_info->eo, result.x, result.y, result.w, result.h);
872 return MM_ERROR_NONE;
874 LOGW("there is no surf");
875 /* FIXME: before pipe_cb is invoked, apply_geometry can be called. */
879 return MM_ERROR_NONE;
882 static int _mm_evas_renderer_retrieve_all_packets(mm_evas_info *evas_info, bool keep_screen)
885 MM_CHECK_NULL(evas_info);
887 int ret = MM_ERROR_NONE;
888 pid_t pid = getpid();
889 pid_t tid = syscall(SYS_gettid);
891 /* write and this API can be called at the same time.
892 so lock is needed for counting sent_buffer_cnt correctly */
893 g_mutex_lock(&evas_info->idx_lock);
895 /* make flush buffer */
897 ret = _mm_evas_renderer_make_flush_buffer(evas_info);
898 evas_info->keep_screen = keep_screen;
900 LOGD("pid [%d], tid [%d]", pid, tid);
902 /* in this case, we deem it is main thread */
903 if (_flush_packets(evas_info) != MM_ERROR_NONE) {
904 LOGE("flushing packets are failed");
905 ret = MM_ERROR_UNKNOWN;
908 /* it will be executed to write flush buffer and destroy media packets in pre_cb */
909 evas_info->retrieve_packet = TRUE;
911 g_mutex_unlock(&evas_info->idx_lock);
918 /* make buffer for copying */
919 static int _mm_evas_renderer_make_flush_buffer(mm_evas_info *evas_info)
923 if (evas_info->cur_idx == -1) {
924 LOGW("there is no remained buffer");
925 return MM_ERROR_INVALID_ARGUMENT;
927 media_packet_h packet = evas_info->pkt_info[evas_info->cur_idx].packet;
928 MM_CHECK_NULL(packet);
930 flush_info *flush_buffer = NULL;
931 tbm_bo src_bo = NULL;
932 tbm_surface_h src_tbm_surf = NULL;
935 tbm_surface_info_s info = {0};
936 tbm_bo_handle vaddr_src = {0};
937 tbm_bo_handle vaddr_dst = {0};
938 int ret = MM_ERROR_NONE;
940 if (evas_info->flush_buffer)
941 _mm_evas_renderer_release_flush_buffer(evas_info);
944 flush_buffer = (flush_info *)malloc(sizeof(flush_info));
945 if (flush_buffer == NULL) {
946 LOGE("malloc is failed");
949 memset(flush_buffer, 0x0, sizeof(flush_info));
950 LOGD("flush_buffer %p is allocated", flush_buffer);
952 ret = media_packet_get_tbm_surface(packet, &src_tbm_surf);
953 if (ret != MEDIA_PACKET_ERROR_NONE || !src_tbm_surf) {
954 LOGW("get_tbm_surface is failed");
958 /* get src buffer info */
959 src_bo = tbm_surface_internal_get_bo(src_tbm_surf, 0);
960 src_size = tbm_surface_internal_get_size(src_tbm_surf);
961 if (!src_bo || !src_size) {
962 LOGE("src bo(%p), size(%d)", src_bo, src_size);
965 LOGD("src bo(%p), size(%d)", src_bo, src_size);
967 /* create tbm surface */
968 info.format = tbm_surface_get_format(src_tbm_surf);
969 flush_buffer->tbm_surf = tbm_surface_create(evas_info->w, evas_info->h, info.format);
970 if (!flush_buffer->tbm_surf) {
971 LOGE("tbm_surf is NULL!!");
975 /* get bo and size */
976 bo = tbm_surface_internal_get_bo(flush_buffer->tbm_surf, 0);
977 info.size = tbm_surface_internal_get_size(flush_buffer->tbm_surf);
978 if (!bo || !info.size) {
979 LOGE("dst bo(%p), size(%d)", bo, info.size);
982 LOGD("dst bo(%p), size(%d)", bo, info.size);
984 /* FIXME: each plane should be copied */
985 info.num_planes = tbm_surface_internal_get_num_planes(info.format);
987 flush_buffer->bo = bo;
989 vaddr_src = tbm_bo_map(src_bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE);
990 vaddr_dst = tbm_bo_map(bo, TBM_DEVICE_CPU, TBM_OPTION_READ|TBM_OPTION_WRITE);
991 if (!vaddr_src.ptr || !vaddr_dst.ptr) {
992 LOGW("get vaddr failed src %p, dst %p", vaddr_src.ptr, vaddr_dst.ptr);
994 tbm_bo_unmap(src_bo);
999 memset(vaddr_dst.ptr, 0x0, info.size);
1000 LOGW("tbm_bo_map(vaddr) is finished, bo(%p), vaddr(%p)", bo, vaddr_dst.ptr);
1004 memcpy(vaddr_dst.ptr, vaddr_src.ptr, src_size);
1006 tbm_bo_unmap(src_bo);
1008 LOGW("copy is done. tbm surface : %p", flush_buffer->tbm_surf);
1010 evas_info->flush_buffer = flush_buffer;
1014 return MM_ERROR_NONE;
1018 if (flush_buffer->tbm_surf) {
1019 tbm_surface_destroy(flush_buffer->tbm_surf);
1020 flush_buffer->tbm_surf = NULL;
1024 flush_buffer = NULL;
1026 return MM_ERROR_UNKNOWN;
1029 /* release flush buffer */
1030 static void _mm_evas_renderer_release_flush_buffer(mm_evas_info *evas_info)
1034 LOGW("release FLUSH BUFFER start");
1035 if (evas_info->flush_buffer->bo)
1036 evas_info->flush_buffer->bo = NULL;
1038 if (evas_info->flush_buffer->tbm_surf) {
1039 tbm_surface_destroy(evas_info->flush_buffer->tbm_surf);
1040 evas_info->flush_buffer->tbm_surf = NULL;
1043 LOGW("release FLUSH BUFFER done");
1045 free(evas_info->flush_buffer);
1046 evas_info->flush_buffer = NULL;
1053 void mm_evas_renderer_write(media_packet_h packet, void *data)
1058 LOGE("packet %p is NULL", packet);
1061 mm_evas_info *handle = (mm_evas_info *)data;
1062 int ret = MEDIA_PACKET_ERROR_NONE;
1064 tbm_surface_h tbm_surf;
1067 LOGD("packet [%p]", packet);
1069 if (!data || !handle) {
1070 LOGE("handle %p or evas_info %p is NULL", data, handle);
1073 g_mutex_lock(&handle->idx_lock);
1075 ret = media_packet_has_tbm_surface_buffer(packet, &has);
1076 if (ret != MEDIA_PACKET_ERROR_NONE) {
1077 LOGW("has_tbm_surface is failed");
1080 /* FIXME: when setCaps occurs, _get_video_size should be called */
1081 /* currently we are always checking it */
1082 if (has && _get_video_size(packet, handle)) {
1083 /* Attention! if this error occurs, we need to consider managing buffer */
1084 if (handle->sent_buffer_cnt > 3) {
1085 LOGE("too many buffers are not released %d", handle->sent_buffer_cnt);
1088 /* FIXME: fix this logic */
1089 /* destroy all media packets and reset pipe at present */
1090 /* Attention! it might free buffer that is being rendered */
1091 g_mutex_lock(&handle->mp_lock);
1092 _reset_pipe(handle);
1093 g_mutex_unlock(&handle->mp_lock);
1096 ret = media_packet_get_tbm_surface(packet, &tbm_surf);
1097 if (ret != MEDIA_PACKET_ERROR_NONE || !tbm_surf) {
1098 LOGW("get_tbm_surface is failed");
1102 /* find new index for current packet */
1103 index = _find_empty_index(handle);
1107 #ifdef _INTERNAL_DEBUG_
1109 if ((g_cnt%10 == 0) && (g_cnt < 500))
1110 ret2 = __dump_pkt(packet);
1113 LOGW("__dump_pkt() is failed");
1117 /* save previous index */
1118 handle->pkt_info[index].prev = handle->cur_idx;
1119 handle->pkt_info[index].packet = packet;
1120 handle->pkt_info[index].tbm_surf = tbm_surf;
1121 handle->cur_idx = index;
1122 handle->sent_buffer_cnt++;
1123 LOGD("sent packet %d", handle->sent_buffer_cnt);
1125 ret = ecore_pipe_write(handle->epipe, handle, UPDATE_TBM_SURF);
1127 handle->pkt_info[index].packet = NULL;
1128 handle->pkt_info[index].tbm_surf = NULL;
1129 handle->pkt_info[index].prev = -1;
1130 handle->cur_idx = handle->pkt_info[index].prev;
1131 handle->sent_buffer_cnt--;
1132 LOGW("Failed to ecore_pipe_write() for updating tbm surf\n");
1136 LOGW("no tbm_surf");
1139 g_mutex_unlock(&handle->idx_lock);
1145 g_mutex_unlock(&handle->idx_lock);
1147 /* destroy media_packet immediately */
1149 g_mutex_lock(&handle->mp_lock);
1150 LOGD("cant write. destroy packet [%p]", packet);
1151 if (handle->packet_rendered_cb) {
1152 handle->packet_rendered_cb(packet, handle->packet_rendered_cb_user);
1154 if (media_packet_destroy(packet) != MEDIA_PACKET_ERROR_NONE)
1155 LOGE("media_packet_destroy failed %p", packet);
1158 g_mutex_unlock(&handle->mp_lock);
1163 int mm_evas_renderer_update_param(MMHandleType handle)
1167 int ret = MM_ERROR_NONE;
1168 mm_evas_info *evas_info = (mm_evas_info *)handle;
1171 LOGW("skip it. it is not evas surface type.");
1175 /* when handle is realized, we need to update all properties */
1177 LOGD("set video param : evas-object %x, method %d", evas_info->eo, evas_info->display_geometry_method);
1178 LOGD("set video param : visible %d", evas_info->visible);
1179 LOGD("set video param : rotate %d", evas_info->rotate_angle);
1181 ret = _mm_evas_renderer_apply_geometry(evas_info);
1182 if (ret != MM_ERROR_NONE)
1185 if (evas_info->epipe) {
1186 ret = ecore_pipe_write(evas_info->epipe, &evas_info->visible, UPDATE_VISIBILITY);
1188 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1189 return MM_ERROR_UNKNOWN;
1191 evas_info->update_needed = TRUE;
1192 /* FIXME: pause state only */
1193 g_mutex_lock(&evas_info->idx_lock);
1194 ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1196 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1197 ret = MM_ERROR_UNKNOWN;
1199 ret = MM_ERROR_NONE;
1201 g_mutex_unlock(&evas_info->idx_lock);
1210 int mm_evas_renderer_create(MMHandleType *handle, Evas_Object *eo)
1213 MM_CHECK_NULL(handle);
1215 int ret = MM_ERROR_NONE;
1216 mm_evas_info *evas_info = NULL;
1218 ret = _mm_evas_renderer_create(&evas_info);
1219 if (ret != MM_ERROR_NONE) {
1220 LOGE("fail to create evas_info");
1223 ret = _mm_evas_renderer_set_info(evas_info, eo);
1224 if (ret != MM_ERROR_NONE) {
1225 LOGE("fail to init evas_info");
1226 if (_mm_evas_renderer_destroy(&evas_info) != MM_ERROR_NONE)
1227 LOGE("fail to destroy evas_info");
1231 *handle = (MMHandleType)evas_info;
1233 return MM_ERROR_NONE;
1236 int mm_evas_renderer_destroy(MMHandleType *handle)
1239 MM_CHECK_NULL(handle);
1241 int ret = MM_ERROR_NONE;
1242 mm_evas_info *evas_info = (mm_evas_info *)*handle;
1245 LOGD("skip it. it is not evas surface type.");
1246 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1249 ret = _mm_evas_renderer_destroy(&evas_info);
1250 if (ret != MM_ERROR_NONE) {
1251 LOGE("fail to destroy evas_info");
1258 return MM_ERROR_NONE;
1261 int mm_evas_renderer_set_visible(MMHandleType handle, bool visible)
1265 int ret = MM_ERROR_NONE;
1266 mm_evas_info *evas_info = (mm_evas_info *)handle;
1269 LOGW("skip it. it is not evas surface type or handle is not prepared");
1270 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1274 evas_info->visible = VISIBLE_TRUE;
1276 evas_info->visible = VISIBLE_FALSE;
1278 if (evas_info->epipe) {
1279 ret = ecore_pipe_write(evas_info->epipe, &visible, UPDATE_VISIBILITY);
1281 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1282 ret = MM_ERROR_UNKNOWN;
1284 ret = MM_ERROR_NONE;
1287 LOGW("there is no epipe. we cant update it");
1295 int mm_evas_renderer_get_visible(MMHandleType handle, bool *visible)
1299 mm_evas_info *evas_info = (mm_evas_info *)handle;
1302 LOGW("skip it. it is not evas surface type or handle is not prepared");
1303 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1306 if (evas_info->visible == VISIBLE_FALSE)
1313 return MM_ERROR_NONE;
1316 int mm_evas_renderer_set_rotation(MMHandleType handle, int rotate)
1320 int ret = MM_ERROR_NONE;
1321 mm_evas_info *evas_info = (mm_evas_info *)handle;
1325 LOGW("skip it. it is not evas surface type or handle is not prepared");
1326 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1331 value = EVAS_IMAGE_ORIENT_0;
1334 value = EVAS_IMAGE_ORIENT_90;
1337 value = EVAS_IMAGE_ORIENT_180;
1340 value = EVAS_IMAGE_ORIENT_270;
1343 return MM_ERROR_INVALID_ARGUMENT;
1345 if (evas_info->rotate_angle != value) {
1346 evas_info->update_needed = TRUE;
1347 evas_info->rotate_angle = value;
1350 /* FIXME: pause state only */
1351 if (evas_info->epipe) {
1352 g_mutex_lock(&evas_info->idx_lock);
1353 ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1355 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1356 ret = MM_ERROR_UNKNOWN;
1358 ret = MM_ERROR_NONE;
1360 g_mutex_unlock(&evas_info->idx_lock);
1367 int mm_evas_renderer_get_rotation(MMHandleType handle, int *rotate)
1371 mm_evas_info *evas_info = (mm_evas_info *)handle;
1374 LOGW("skip it. it is not evas surface type or handle is not prepared");
1375 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1378 switch (evas_info->rotate_angle) {
1379 case EVAS_IMAGE_ORIENT_0:
1382 case EVAS_IMAGE_ORIENT_90:
1383 *rotate = DEGREE_90;
1385 case EVAS_IMAGE_ORIENT_180:
1386 *rotate = DEGREE_180;
1388 case EVAS_IMAGE_ORIENT_270:
1389 *rotate = DEGREE_270;
1392 return MM_ERROR_INVALID_ARGUMENT;
1397 return MM_ERROR_NONE;
1400 int mm_evas_renderer_set_geometry(MMHandleType handle, int mode)
1404 int ret = MM_ERROR_NONE;
1405 mm_evas_info *evas_info = (mm_evas_info *)handle;
1408 LOGW("skip it. it is not evas surface type or handle is not prepared");
1409 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1411 if (evas_info->display_geometry_method != mode) {
1412 evas_info->update_needed = TRUE;
1413 evas_info->display_geometry_method = mode;
1416 /* ecore_pipe_write is needed, because of setting ratio for letterbox mode */
1417 /* FIXME: pause state only */
1418 if (evas_info->epipe) {
1419 g_mutex_lock(&evas_info->idx_lock);
1420 ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1422 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1423 ret = MM_ERROR_UNKNOWN;
1425 ret = MM_ERROR_NONE;
1427 g_mutex_unlock(&evas_info->idx_lock);
1434 int mm_evas_renderer_get_geometry(MMHandleType handle, int *mode)
1438 mm_evas_info *evas_info = (mm_evas_info *)handle;
1441 LOGW("skip it. it is not evas surface type or handle is not prepared");
1442 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1444 *mode = evas_info->display_geometry_method;
1448 return MM_ERROR_NONE;
1451 int mm_evas_renderer_set_roi_area(MMHandleType handle, int x, int y, int w, int h)
1455 int ret = MM_ERROR_NONE;
1456 mm_evas_info *evas_info = (mm_evas_info *)handle;
1459 LOGW("skip it. it is not evas surface type or handle is not prepared");
1460 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1463 LOGW("invalid resolution");
1464 return MM_ERROR_INVALID_ARGUMENT;
1467 /* display mode is set to DISP_GEO_METHOD_CUSTOM_ROI internally */
1468 if (evas_info->display_geometry_method != DISP_GEO_METHOD_CUSTOM_ROI)
1469 evas_info->update_needed = TRUE;
1470 evas_info->display_geometry_method = DISP_GEO_METHOD_CUSTOM_ROI;
1471 evas_info->dst_roi.x = x;
1472 evas_info->dst_roi.y = y;
1473 evas_info->dst_roi.w = w;
1474 evas_info->dst_roi.h = h;
1476 /* pipe_write could be needed because ratio can be changed on pause state */
1477 if (evas_info->epipe) {
1478 g_mutex_lock(&evas_info->idx_lock);
1479 ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1481 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1482 ret = MM_ERROR_UNKNOWN;
1484 ret = MM_ERROR_NONE;
1486 g_mutex_unlock(&evas_info->idx_lock);
1494 int mm_evas_renderer_get_roi_area(MMHandleType handle, int *x, int *y, int *w, int *h)
1498 mm_evas_info *evas_info = (mm_evas_info *)handle;
1501 LOGW("skip it. it is not evas surface type or handle is not prepared");
1502 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1504 if (evas_info->display_geometry_method != DISP_GEO_METHOD_CUSTOM_ROI) {
1505 LOGW("invalid mode");
1506 return MM_ERROR_INVALID_ARGUMENT;
1509 *x = evas_info->dst_roi.x;
1510 *y = evas_info->dst_roi.y;
1511 *w = evas_info->dst_roi.w;
1512 *h = evas_info->dst_roi.h;
1516 return MM_ERROR_NONE;
1519 int mm_evas_renderer_set_flip(MMHandleType handle, int flip)
1523 int ret = MM_ERROR_NONE;
1524 mm_evas_info *evas_info = (mm_evas_info *)handle;
1528 LOGW("skip it. it is not evas surface type or handle is not prepared");
1529 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1534 value = EVAS_IMAGE_ORIENT_NONE;
1536 case FLIP_HORIZONTAL:
1537 value = EVAS_IMAGE_FLIP_HORIZONTAL;
1540 value = EVAS_IMAGE_FLIP_VERTICAL;
1543 value = EVAS_IMAGE_ORIENT_180;
1546 return MM_ERROR_INVALID_ARGUMENT;
1548 if (evas_info->flip != value) {
1549 evas_info->update_needed = TRUE;
1550 evas_info->flip = value;
1553 /* FIXME: pause state only */
1554 if (evas_info->epipe) {
1555 g_mutex_lock(&evas_info->idx_lock);
1556 ret = ecore_pipe_write(evas_info->epipe, evas_info, UPDATE_TBM_SURF);
1558 LOGW("fail to ecore_pipe_write() for updating visibility\n");
1559 ret = MM_ERROR_UNKNOWN;
1561 ret = MM_ERROR_NONE;
1563 g_mutex_unlock(&evas_info->idx_lock);
1571 int mm_evas_renderer_get_flip(MMHandleType handle, int *flip)
1575 mm_evas_info *evas_info = (mm_evas_info *)handle;
1578 LOGW("skip it. it is not evas surface type or handle is not prepared");
1579 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1582 switch (evas_info->flip) {
1583 case EVAS_IMAGE_ORIENT_NONE:
1586 case EVAS_IMAGE_FLIP_HORIZONTAL:
1587 *flip = FLIP_HORIZONTAL;
1589 case EVAS_IMAGE_FLIP_VERTICAL:
1590 *flip = FLIP_VERTICAL;
1592 case EVAS_IMAGE_ORIENT_180:
1596 return MM_ERROR_INVALID_ARGUMENT;
1601 return MM_ERROR_NONE;
1604 int mm_evas_renderer_retrieve_all_packets(MMHandleType handle, bool keep_screen)
1608 int ret = MM_ERROR_NONE;
1609 mm_evas_info *evas_info = (mm_evas_info*) handle;
1612 LOGW("skip it. it is not evas surface type or player is not prepared");
1613 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1615 ret = _mm_evas_renderer_retrieve_all_packets(evas_info, keep_screen);
1622 int mm_evas_renderer_set_packet_rendered_callback(MMHandleType handle, mm_evas_renderer_media_packet_rendered_cb callback, void *user_data)
1626 mm_evas_info *evas_info = (mm_evas_info*) handle;
1629 LOGW("skip it. it is not evas surface type or player is not prepared");
1630 return MM_ERROR_RESOURCE_NOT_INITIALIZED;
1632 evas_info->packet_rendered_cb = callback;
1633 evas_info->packet_rendered_cb_user = user_data;
1635 LOGW("set rendered callback %p, user_data %p", evas_info->packet_rendered_cb, evas_info->packet_rendered_cb_user);
1639 return MM_ERROR_NONE;