From 735db81d94caa88c075492d76e586ccbc35f61e4 Mon Sep 17 00:00:00 2001 From: cedric Date: Thu, 11 Oct 2012 08:24:31 +0000 Subject: [PATCH] emotion: limit size and format based on the backend with fimc. git-svn-id: http://svn.enlightenment.org/svn/e/trunk/emotion@77852 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- ChangeLog | 4 + NEWS | 1 + src/modules/gstreamer/emotion_gstreamer.c | 16 ++-- src/modules/gstreamer/emotion_sink.c | 143 ++++++++++++++++++++++-------- 4 files changed, 122 insertions(+), 42 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84a5c6a..9cc78bb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -50,3 +50,7 @@ 2012-08-30 Carsten Haitzler (The Rasterman) 1.7.0 release + +2012-09-06 Sohyun Kim + + * Add capsfilter to limit format and size for fimc on device. diff --git a/NEWS b/NEWS index cedcaf4..2a1358b 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ Additions: - Sync rendering with Ecore_Animator. - Track pending object for proper shutdown. - Start handling embedded hardware customization. + - Add fimcconvert and capsfilter element for device Fixes: - build out of tree. diff --git a/src/modules/gstreamer/emotion_gstreamer.c b/src/modules/gstreamer/emotion_gstreamer.c index df29de8..8ec71fb 100644 --- a/src/modules/gstreamer/emotion_gstreamer.c +++ b/src/modules/gstreamer/emotion_gstreamer.c @@ -1662,6 +1662,16 @@ _video_size_get(GstElement *elem, int *width, int *height) } static void +_main_frame_resize(void *data) +{ + Emotion_Gstreamer_Video *ev = data; + double ratio; + + ratio = (double)ev->src_width / (double)ev->src_height; + _emotion_frame_resize(ev->obj, ev->src_width, ev->src_height, ratio); +} + +static void _no_more_pads(GstElement *decodebin, gpointer data) { GstIterator *itr = NULL; @@ -1673,11 +1683,7 @@ _no_more_pads(GstElement *decodebin, gpointer data) { if(_video_size_get(GST_ELEMENT(elem), &ev->src_width, &ev->src_height)) { - double ratio; - - ratio = (double)ev->src_width / (double)ev->src_height; - _emotion_frame_resize(ev->obj, ev->src_width, ev->src_height, ratio); - + ecore_main_loop_thread_safe_call_async(_main_frame_resize, ev); gst_object_unref(elem); break; } diff --git a/src/modules/gstreamer/emotion_sink.c b/src/modules/gstreamer/emotion_sink.c index b9e2e74..433d8dc 100644 --- a/src/modules/gstreamer/emotion_sink.c +++ b/src/modules/gstreamer/emotion_sink.c @@ -881,8 +881,8 @@ _video_resize(void *data, Evas_Object *obj __UNUSED__, const Evas_Video_Surface Emotion_Gstreamer_Video *ev = data; ecore_x_window_resize(ev->win, w, h); -#endif fprintf(stderr, "resize: %i, %i\n", w, h); +#endif } static void @@ -979,6 +979,13 @@ _image_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info int image_area, src_area; double ratio; + GstElementFactory *cfactory = NULL; + GstElement *convert = NULL, *filter = NULL, *queue = NULL; + GstPad *pad = NULL, *teepad = NULL; + GstCaps *caps = NULL; + Eina_List *l, *engines; + const char *ename, *engine = NULL; + evas_object_geometry_get(obj, NULL, NULL, &width, &height); image_area = width * height; src_area = ev->src_width * ev->src_height; @@ -986,50 +993,112 @@ _image_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info // when an image is much smaller than original video size, // add fimcconvert element to the pipeline - if (ratio < 0.8 && !ev->priority && !ev->convert) + if (ratio < 0.8 && ev->stream && !ev->convert) { - GstElementFactory *cfactory = NULL; - cfactory = gst_element_factory_find("fimcconvert"); - if (cfactory) + if (!cfactory) return; + + convert = gst_element_factory_create(cfactory, NULL); + if (!convert) return; + + // add capsfilter to limit size and formats based on the backend + filter = gst_element_factory_make("capsfilter", "fimccapsfilter"); + if (!filter) { - GstElement *convert = NULL; + gst_object_unref(convert); + return; + } - convert = gst_element_factory_create(cfactory, NULL); - if (convert) + engines = evas_render_method_list(); + EINA_LIST_FOREACH(engines, l, ename) + { + if (evas_render_method_lookup(ename) == + evas_output_method_get(evas_object_evas_get(obj))) { - GstElement *queue = NULL; - GstPad *pad, *teepad; - - queue = gst_bin_get_by_name(GST_BIN(ev->sink), "equeue"); - gst_element_unlink(ev->tee, queue); - gst_element_release_request_pad(ev->tee, ev->eteepad); - gst_object_unref(ev->eteepad); - - gst_bin_add(GST_BIN(ev->sink), convert); - gst_element_link_many(ev->tee, convert, queue, NULL); - pad = gst_element_get_pad(convert, "sink"); - teepad = gst_element_get_request_pad(ev->tee, "src%d"); - gst_pad_link(teepad, pad); - gst_object_unref(pad); - - g_object_set(G_OBJECT(convert), "src-width", width, NULL); - g_object_set(G_OBJECT(convert), "src-height", height, NULL); - g_object_set(G_OBJECT(convert), "qos", TRUE, NULL); - gst_element_sync_state_with_parent(convert); - - ev->eteepad = teepad; - ev->convert = convert; + engine = ename; + break; } } + + if (strstr(engine, "software") != NULL) + { + caps = gst_caps_new_simple("video/x-raw-rgb", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + } + else if (strstr(engine, "gl") != NULL) + { + caps = gst_caps_new_simple("video/x-raw-yuv", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + } + g_object_set(G_OBJECT(filter), "caps", caps, NULL); + gst_caps_unref(caps); + + // add new elements to the pipeline + queue = gst_bin_get_by_name(GST_BIN(ev->sink), "equeue"); + gst_element_unlink(ev->tee, queue); + gst_element_release_request_pad(ev->tee, ev->eteepad); + gst_object_unref(ev->eteepad); + + gst_bin_add_many(GST_BIN(ev->sink), convert, filter, NULL); + gst_element_link_many(ev->tee, convert, filter, queue, NULL); + + pad = gst_element_get_pad(convert, "sink"); + teepad = gst_element_get_request_pad(ev->tee, "src%d"); + gst_pad_link(teepad, pad); + gst_object_unref(pad); + + gst_element_sync_state_with_parent(convert); + gst_element_sync_state_with_parent(filter); + + ev->eteepad = teepad; + ev->convert = convert; + evas_render_method_list_free(engines); + + INF("add fimcconvert element. video size: %dx%d. emotion object size: %dx%d", + ev->src_width, ev->src_height, width, height); + } + // set size again to the capsfilter when the image is resized + else if (ev->convert) + { + filter = gst_bin_get_by_name(GST_BIN(ev->sink), "fimccapsfilter"); + + engines = evas_render_method_list(); + EINA_LIST_FOREACH(engines, l, ename) + { + if (evas_render_method_lookup(ename) == + evas_output_method_get(evas_object_evas_get(obj))) + { + engine = ename; + break; + } + } + + if (strstr(engine, "software") != NULL) + { + caps = gst_caps_new_simple("video/x-raw-rgb", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + } + else if (strstr(engine, "gl") != NULL) + { + caps = gst_caps_new_simple("video/x-raw-yuv", + "width", G_TYPE_INT, width, + "height", G_TYPE_INT, height, + NULL); + } + + g_object_set(G_OBJECT(filter), "caps", caps, NULL); + gst_caps_unref(caps); + evas_render_method_list_free(engines); + + INF("set capsfilter size again:. video size: %dx%d. emotion object size: %dx%d", + ev->src_width, ev->src_height, width, height); } - // TODO: when an image is resized(e.g rotation), set size again to fimcconvert - // TODO: fimcconvert has an issue about resetting - //else if (ev->convert) - // { - // g_object_set(G_OBJECT(ev->convert), "src-width", w, NULL); - // g_object_set(G_OBJECT(ev->convert), "src-height", h, NULL); - // } } GstElement * -- 2.7.4