From 1f9e915b5a001b4f4845defda559434b35588e96 Mon Sep 17 00:00:00 2001 From: Al Poole Date: Thu, 12 Jan 2017 14:09:49 -0800 Subject: [PATCH] emotion: add support for obtaining embedded artwork from media files with gstreamer1 backend. Reviewers: raster, cedric Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D4550 Signed-off-by: Cedric BAIL --- m4/emotion_module.m4 | 2 +- src/lib/emotion/Emotion.h | 18 +++++ src/lib/emotion/emotion_modules.c | 6 ++ src/lib/emotion/emotion_modules.h | 1 + src/lib/emotion/emotion_private.h | 3 +- src/lib/emotion/emotion_smart.c | 20 +++++ src/modules/emotion/generic/emotion_generic.c | 3 +- .../emotion/gstreamer/emotion_gstreamer.c | 3 +- .../emotion/gstreamer1/emotion_gstreamer.c | 78 ++++++++++++++++++- .../emotion/gstreamer1/emotion_gstreamer.h | 1 + src/modules/emotion/libvlc/emotion_libvlc.c | 3 +- src/modules/emotion/xine/emotion_xine.c | 3 +- 12 files changed, 132 insertions(+), 9 deletions(-) diff --git a/m4/emotion_module.m4 b/m4/emotion_module.m4 index 51ed0da1e3..184533fcdc 100644 --- a/m4/emotion_module.m4 +++ b/m4/emotion_module.m4 @@ -50,7 +50,7 @@ dnl where want_engine = yes or static AC_DEFUN([EMOTION_MODULE_DEP_CHECK_GSTREAMER1], [dnl GST_VER=1.0 - requirements="gstreamer-1.0 >= ${GST_VER} gstreamer-plugins-base-1.0 >= ${GST_VER} gstreamer-video-1.0 >= ${GST_VER} gstreamer-audio-1.0 >= ${GST_VER} gstreamer-tag-1.0 >= ${GST_VER}" + requirements="gstreamer-1.0 >= ${GST_VER} gstreamer-plugins-base-1.0 >= ${GST_VER} gstreamer-video-1.0 >= ${GST_VER} gstreamer-audio-1.0 >= ${GST_VER} gstreamer-tag-1.0 >= ${GST_VER} gstreamer-pbutils-1.0 >= ${GST_VER}" if test "$1" = "static"; then EFL_DEPEND_PKG([EMOTION], [EMOTION_MODULE_GSTREAMER1], [${requirements}]) else diff --git a/src/lib/emotion/Emotion.h b/src/lib/emotion/Emotion.h index 3ea786391d..b4914d65a5 100644 --- a/src/lib/emotion/Emotion.h +++ b/src/lib/emotion/Emotion.h @@ -196,6 +196,12 @@ enum _Emotion_Meta_Info EMOTION_META_INFO_TRACK_COUNT /**< track count - number of the track in the album */ }; +enum _Emotion_Artwork_Info +{ + EMOTION_ARTWORK_IMAGE, + EMOTION_ARTWORK_PREVIEW_IMAGE +}; + /** * @enum _Emotion_Vis * @@ -266,6 +272,7 @@ typedef enum _Emotion_Event Emotion_Event; typedef enum _Emotion_Meta_Info Emotion_Meta_Info; /**< Meta info type to be retrieved. */ typedef enum _Emotion_Vis Emotion_Vis; /**< Type of visualization. */ typedef enum _Emotion_Aspect Emotion_Aspect; /**< Aspect ratio option. */ +typedef enum _Emotion_Artwork_Info Emotion_Artwork_Info; #define EMOTION_CHANNEL_AUTO -1 #define EMOTION_CHANNEL_DEFAULT 0 @@ -1340,6 +1347,17 @@ EAPI const char *emotion_webcam_name_get(const Emotion_Webcam *ew); */ EAPI const char *emotion_webcam_device_get(const Emotion_Webcam *ew); +/** + * @brief Get the album artwork from file meta data tags. + * + * @param obj The evas object we are working with. + * @param path The local path for the file. + * @param type The metadata location type (GST_IMAGE_PREVIEW_IMAGE or GST_PREVIEW). + * + * @ingroup Emotion_Artwork + */ + +EAPI Evas_Object *emotion_file_meta_artwork_get(const Evas_Object *obj, const char *path, Emotion_Artwork_Info type); /** * @} */ diff --git a/src/lib/emotion/emotion_modules.c b/src/lib/emotion/emotion_modules.c index 273bb9acc4..719b5d3e85 100644 --- a/src/lib/emotion/emotion_modules.c +++ b/src/lib/emotion/emotion_modules.c @@ -791,6 +791,12 @@ emotion_engine_instance_meta_get(const Emotion_Engine_Instance *inst, int meta) EMOTION_ENGINE_INSTANCE_CALL_RET(inst, meta_get, NULL, meta); } +void * +emotion_engine_instance_meta_artwork_get(const Emotion_Engine_Instance *inst, Evas_Object *img, const char *path, Emotion_Artwork_Info type) +{ + EMOTION_ENGINE_INSTANCE_CALL_RET(inst, meta_artwork_get, NULL, img, path, type); +} + void emotion_engine_instance_priority_set(Emotion_Engine_Instance *inst, Eina_Bool priority) { diff --git a/src/lib/emotion/emotion_modules.h b/src/lib/emotion/emotion_modules.h index eb9af156ea..4a0244177d 100644 --- a/src/lib/emotion/emotion_modules.h +++ b/src/lib/emotion/emotion_modules.h @@ -129,6 +129,7 @@ struct _Emotion_Engine const char * (*meta_get) (void *ef, int meta); void (*priority_set) (void *ef, Eina_Bool priority); Eina_Bool (*priority_get) (void *ef); + void * (*meta_artwork_get)(void *ef, Evas_Object *img, const char *path, Emotion_Artwork_Info type); }; EAPI void *_emotion_video_get(const Evas_Object *obj); diff --git a/src/lib/emotion/emotion_private.h b/src/lib/emotion/emotion_private.h index cb66c6a628..e884dc3448 100644 --- a/src/lib/emotion/emotion_private.h +++ b/src/lib/emotion/emotion_private.h @@ -89,6 +89,5 @@ Eina_Bool emotion_engine_instance_eject(Emotion_Engine_Instance *inst); const char * emotion_engine_instance_meta_get(const Emotion_Engine_Instance *inst, int meta); void emotion_engine_instance_priority_set(Emotion_Engine_Instance *inst, Eina_Bool priority); Eina_Bool emotion_engine_instance_priority_get(const Emotion_Engine_Instance *inst); - - +void * emotion_engine_instance_meta_artwork_get(const Emotion_Engine_Instance *inst, Evas_Object *img, const char *path, Emotion_Artwork_Info type); #endif diff --git a/src/lib/emotion/emotion_smart.c b/src/lib/emotion/emotion_smart.c index 8ba69400b7..93cf1975ff 100644 --- a/src/lib/emotion/emotion_smart.c +++ b/src/lib/emotion/emotion_smart.c @@ -1262,6 +1262,26 @@ emotion_object_meta_info_get(const Evas_Object *obj, Emotion_Meta_Info meta) return emotion_engine_instance_meta_get(sd->engine_instance, id); } + +EAPI Evas_Object * +emotion_file_meta_artwork_get(const Evas_Object *obj, const char *path, Emotion_Artwork_Info type) +{ + Efl_Canvas_Video_Data *sd; + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, NULL); + if (!sd->engine_instance) return NULL; + + Evas *ev = evas_object_evas_get(obj); + Evas_Object *artwork = evas_object_image_add(ev); + + Evas_Object *result = emotion_engine_instance_meta_artwork_get(sd->engine_instance, artwork, path, type); + if (!result) return NULL; + + Evas_Load_Error _error = evas_object_image_load_error_get(result); + if (_error != EVAS_LOAD_ERROR_NONE) return NULL; + + return result; +} + EAPI void emotion_object_vis_set(Evas_Object *obj, Emotion_Vis visualization) { diff --git a/src/modules/emotion/generic/emotion_generic.c b/src/modules/emotion/generic/emotion_generic.c index 9b43e87d0a..c3fba86a77 100644 --- a/src/modules/emotion/generic/emotion_generic.c +++ b/src/modules/emotion/generic/emotion_generic.c @@ -1721,7 +1721,8 @@ static const Emotion_Engine em_template_engine = em_eject, /* eject */ em_meta_get, /* meta_get */ NULL, /* priority_set */ - NULL /* priority_get */ + NULL, /* priority_get */ + NULL /* em_meta_artwork_get */ }; static void diff --git a/src/modules/emotion/gstreamer/emotion_gstreamer.c b/src/modules/emotion/gstreamer/emotion_gstreamer.c index 82770b1590..3810401f53 100644 --- a/src/modules/emotion/gstreamer/emotion_gstreamer.c +++ b/src/modules/emotion/gstreamer/emotion_gstreamer.c @@ -1205,7 +1205,8 @@ static const Emotion_Engine em_engine = em_eject, /* eject */ em_meta_get, /* meta_get */ em_priority_set, /* priority_set */ - em_priority_get /* priority_get */ + em_priority_get, /* priority_get */ + NULL /* em_meta_artwork_get */ }; Eina_Bool diff --git a/src/modules/emotion/gstreamer1/emotion_gstreamer.c b/src/modules/emotion/gstreamer1/emotion_gstreamer.c index bb528d4ca6..5fced21b03 100644 --- a/src/modules/emotion/gstreamer1/emotion_gstreamer.c +++ b/src/modules/emotion/gstreamer1/emotion_gstreamer.c @@ -1,7 +1,6 @@ #ifdef HAVE_CONFIG_H # include "config.h" #endif - #include "emotion_gstreamer.h" int _emotion_gstreamer_log_domain = -1; @@ -988,6 +987,80 @@ em_eject(void *video EINA_UNUSED) return 1; } +static void +_img_del_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) +{ + GstBuffer *buffer = data; + + gst_buffer_unref(buffer); +} + +void * +em_meta_artwork_get(void *video, Evas_Object *img, const char *path, Emotion_Artwork_Info type) +{ + Emotion_Gstreamer *ev = video; + GError *err = NULL; + + if (!ev) return NULL; + + gst_init(NULL,NULL); + + gchar *uri = gst_filename_to_uri(path, NULL); + + GstDiscoverer *discoverer = gst_discoverer_new(10 * GST_SECOND, &err); + if (!discoverer) return NULL; + GstDiscovererInfo* info = gst_discoverer_discover_uri(discoverer, + uri, &err); + if (!info) return NULL; + + int ret = gst_discoverer_info_get_result(info); + if (ret != GST_DISCOVERER_OK) goto done; + + const GstTagList *tags = gst_discoverer_info_get_tags(info); + + GstSample *sample; + GstBuffer *buffer; + GstMapInfo map; + + const gchar *tag = GST_TAG_PREVIEW_IMAGE; + if (type == EMOTION_ARTWORK_IMAGE) tag = GST_TAG_IMAGE; + + if (gst_tag_list_get_sample(tags, tag, &sample)) + { + buffer = gst_sample_get_buffer(sample); + if (!buffer) + { + evas_object_del(img); + img = NULL; + goto done; + } + + if (gst_buffer_map(gst_buffer_ref(buffer), &map, GST_MAP_READ)) + { + Eina_File *f = eina_file_virtualize(path, map.data, map.size, EINA_FALSE); + evas_object_image_mmap_set(img, f, NULL); + eina_file_close(f); + evas_object_event_callback_add(img, EVAS_CALLBACK_DEL, _img_del_cb, buffer); + } + gst_buffer_unref(buffer); + gst_sample_unref(sample); + } + else + { + evas_object_del(img); + img = NULL; + } + +done: + if (err) g_error_free(err); + + gst_discoverer_info_unref(info); + g_free(uri); + g_object_unref(discoverer); + + return img; +} + static const char * em_meta_get(void *video, int meta) { @@ -1116,7 +1189,8 @@ static const Emotion_Engine em_engine = em_eject, /* eject */ em_meta_get, /* meta_get */ NULL, /* priority_set */ - NULL /* priority_get */ + NULL, /* priority_get */ + em_meta_artwork_get, }; Eina_Bool diff --git a/src/modules/emotion/gstreamer1/emotion_gstreamer.h b/src/modules/emotion/gstreamer1/emotion_gstreamer.h index a815590d38..c0293dd11e 100644 --- a/src/modules/emotion/gstreamer1/emotion_gstreamer.h +++ b/src/modules/emotion/gstreamer1/emotion_gstreamer.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include diff --git a/src/modules/emotion/libvlc/emotion_libvlc.c b/src/modules/emotion/libvlc/emotion_libvlc.c index 31b47c9e5d..b78769382a 100644 --- a/src/modules/emotion/libvlc/emotion_libvlc.c +++ b/src/modules/emotion/libvlc/emotion_libvlc.c @@ -1382,7 +1382,8 @@ static const Emotion_Engine em_engine = em_eject, /* eject */ em_meta_get, /* meta_get */ NULL, /* priority_set */ - NULL /* priority_get */ + NULL, /* priority_get */ + NULL /* em_meta_artwork_get */ }; static void diff --git a/src/modules/emotion/xine/emotion_xine.c b/src/modules/emotion/xine/emotion_xine.c index b0bca12c1a..852a564c42 100644 --- a/src/modules/emotion/xine/emotion_xine.c +++ b/src/modules/emotion/xine/emotion_xine.c @@ -1556,7 +1556,8 @@ static const Emotion_Engine em_engine = em_eject, /* eject */ em_meta_get, /* meta_get */ NULL, /* priority_set */ - NULL /* priority_get */ + NULL, /* priority_get */ + NULL /* em_meta_artwork_get */ }; Eina_Bool