From d29b7694cb99cfcbf9598976733824bea02fa0b8 Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Thu, 25 Sep 2008 23:15:21 +0000 Subject: [PATCH] emotion+visualization: export and reorder. done: * module api changed, vis_set is not close to vis_get, vis_supported was added. * exported these properties in emotion_object. * gstreamer plugin now starts with no visualization. todo: * add xine support. * make gstreamer able to dynamically change visualization. PS: gstreamer module really needs a cleanup, losts of functions need "static" or add proper prefix, including "gst" to avoid it clash with other symbols. SVN revision: 36260 --- legacy/emotion/src/bin/emotion_test_main.c | 40 ++++- legacy/emotion/src/lib/Emotion.h | 29 +++ legacy/emotion/src/lib/emotion_private.h | 27 +-- legacy/emotion/src/lib/emotion_smart.c | 33 ++++ .../src/modules/gstreamer/emotion_gstreamer.c | 58 ++++-- .../gstreamer/emotion_gstreamer_pipeline.c | 170 +++++++++--------- .../gstreamer/emotion_gstreamer_pipeline.h | 2 + .../emotion/src/modules/xine/emotion_xine.c | 33 ++-- 8 files changed, 249 insertions(+), 143 deletions(-) diff --git a/legacy/emotion/src/bin/emotion_test_main.c b/legacy/emotion/src/bin/emotion_test_main.c index 16bb1a5aaa..fbf2a0442f 100644 --- a/legacy/emotion/src/bin/emotion_test_main.c +++ b/legacy/emotion/src/bin/emotion_test_main.c @@ -46,6 +46,7 @@ static int startw = 800; static int starth = 600; static Evas_List *video_objs = NULL; +static Emotion_Vis vis = EMOTION_VIS_NONE; static int main_start(int argc, char **argv) @@ -92,6 +93,11 @@ main_start(int argc, char **argv) { mode = 3; } + else if ((!strcmp(argv[i], "-vis")) && (i < (argc - 1))) + { + vis = atoi(argv[i + 1]); + i++; + } } } #if HAVE_ECORE_EVAS_X @@ -370,6 +376,33 @@ bg_key_down(void *data, Evas * e, Evas_Object * obj, void *event_info) printf("done\n"); } } + else if (!strcmp(ev->keyname, "z")) + { + Evas_List *l; + + vis = (vis + 1) % EMOTION_VIS_LAST; + printf("new visualization: %d\n", vis); + + + for (l = video_objs; l; l = l->next) + { + Evas_Object *obj; + Evas_Bool supported; + + obj = l->data; + supported = emotion_object_vis_supported(obj, vis); + if (supported) + emotion_object_vis_set(obj, vis); + else + { + const char *file; + + file = emotion_object_file_get(obj); + printf("object %p (%s) does not support visualization %d\n", + obj, file, vis); + } + } + } else { printf("UNHANDLED: %s\n", ev->keyname); @@ -736,6 +769,7 @@ init_video_object(char *module_filename, char *filename) o = emotion_object_add(evas); if (!emotion_object_init(o, module_filename)) return; + emotion_object_vis_set(o, vis); emotion_object_file_set(o, filename); emotion_object_play_set(o, 1); evas_object_move(o, 0, 0); @@ -836,7 +870,7 @@ main(int argc, char **argv) (!strcmp(argv[i], "--help")))) { printf("Usage:\n"); - printf(" %s [-gl] [-g WxH] [-xine] [-gstreamer] filename\n", argv[0]); + printf(" %s [-gl] [-g WxH] [-vis NUMBER] [-xine] [-gstreamer] filename\n", argv[0]); exit(-1); } else if (!strcmp(argv[i], "-gl")) @@ -856,6 +890,10 @@ main(int argc, char **argv) { module_filename = "gstreamer"; } + else if ((!strcmp(argv[i], "-vis")) && (i < (argc - 1))) + { + i++; + } else { printf ("module : %s\n", module_filename); diff --git a/legacy/emotion/src/lib/Emotion.h b/legacy/emotion/src/lib/Emotion.h index e55757f0c3..04bd444f3f 100644 --- a/legacy/emotion/src/lib/Emotion.h +++ b/legacy/emotion/src/lib/Emotion.h @@ -74,9 +74,34 @@ enum _Emotion_Meta_Info EMOTION_META_INFO_TRACK_COUNT }; +enum _Emotion_Vis +{ + EMOTION_VIS_NONE, + EMOTION_VIS_GOOM, + EMOTION_VIS_LIBVISUAL_BUMPSCOPE, + EMOTION_VIS_LIBVISUAL_CORONA, + EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES, + EMOTION_VIS_LIBVISUAL_GDKPIXBUF, + EMOTION_VIS_LIBVISUAL_G_FORCE, + EMOTION_VIS_LIBVISUAL_GOOM, + EMOTION_VIS_LIBVISUAL_INFINITE, + EMOTION_VIS_LIBVISUAL_JAKDAW, + EMOTION_VIS_LIBVISUAL_JESS, + EMOTION_VIS_LIBVISUAL_LV_ANALYSER, + EMOTION_VIS_LIBVISUAL_LV_FLOWER, + EMOTION_VIS_LIBVISUAL_LV_GLTEST, + EMOTION_VIS_LIBVISUAL_LV_SCOPE, + EMOTION_VIS_LIBVISUAL_MADSPIN, + EMOTION_VIS_LIBVISUAL_NEBULUS, + EMOTION_VIS_LIBVISUAL_OINKSIE, + EMOTION_VIS_LIBVISUAL_PLASMA, + EMOTION_VIS_LAST /* sentinel */ +}; + typedef enum _Emotion_Module Emotion_Module; typedef enum _Emotion_Event Emotion_Event; typedef enum _Emotion_Meta_Info Emotion_Meta_Info; +typedef enum _Emotion_Vis Emotion_Vis; #define EMOTION_CHANNEL_AUTO -1 #define EMOTION_CHANNEL_DEFAULT 0 @@ -140,6 +165,10 @@ EAPI int emotion_object_spu_button_count_get (Evas_Object *obj); EAPI int emotion_object_spu_button_get (Evas_Object *obj); EAPI const char *emotion_object_meta_info_get (Evas_Object *obj, Emotion_Meta_Info meta); +EAPI void emotion_object_vis_set (Evas_Object *obj, Emotion_Vis visualization); +EAPI Emotion_Vis emotion_object_vis_get (Evas_Object *obj); +EAPI Evas_Bool emotion_object_vis_supported (Evas_Object *obj, Emotion_Vis visualization); + #ifdef __cplusplus } #endif diff --git a/legacy/emotion/src/lib/emotion_private.h b/legacy/emotion/src/lib/emotion_private.h index 4d9256183b..ede8c865c3 100644 --- a/legacy/emotion/src/lib/emotion_private.h +++ b/legacy/emotion/src/lib/emotion_private.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -23,7 +24,6 @@ #define META_TRACK_COUNT 8 typedef enum _Emotion_Format Emotion_Format; -typedef enum _Emotion_Vis Emotion_Vis; typedef struct _Emotion_Video_Module Emotion_Video_Module; typedef struct _Emotion_Module_Options Emotion_Module_Options; @@ -36,28 +36,6 @@ enum _Emotion_Format EMOTION_FORMAT_BGRA }; -enum _Emotion_Vis -{ - EMOTION_VIS_GOOM, - EMOTION_VIS_LIBVISUAL_BUMPSCOPE, - EMOTION_VIS_LIBVISUAL_CORONA, - EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES, - EMOTION_VIS_LIBVISUAL_GDKPIXBUF, - EMOTION_VIS_LIBVISUAL_G_FORCE, - EMOTION_VIS_LIBVISUAL_GOOM, - EMOTION_VIS_LIBVISUAL_INFINITE, - EMOTION_VIS_LIBVISUAL_JAKDAW, - EMOTION_VIS_LIBVISUAL_JESS, - EMOTION_VIS_LIBVISUAL_LV_ANALYSER, - EMOTION_VIS_LIBVISUAL_LV_FLOWER, - EMOTION_VIS_LIBVISUAL_LV_GLTEST, - EMOTION_VIS_LIBVISUAL_LV_SCOPE, - EMOTION_VIS_LIBVISUAL_MADSPIN, - EMOTION_VIS_LIBVISUAL_NEBULUS, - EMOTION_VIS_LIBVISUAL_OINKSIE, - EMOTION_VIS_LIBVISUAL_PLASMA -}; - struct _Emotion_Module_Options { unsigned char no_video : 1; @@ -74,13 +52,14 @@ struct _Emotion_Video_Module void (*stop) (void *ef); void (*size_get) (void *ef, int *w, int *h); void (*pos_set) (void *ef, double pos); - void (*vis_set) (void *ef, Emotion_Vis vis); double (*len_get) (void *ef); int (*fps_num_get) (void *ef); int (*fps_den_get) (void *ef); double (*fps_get) (void *ef); double (*pos_get) (void *ef); + void (*vis_set) (void *ef, Emotion_Vis vis); Emotion_Vis (*vis_get) (void *ef); + Evas_Bool (*vis_supported) (void *ef, Emotion_Vis vis); double (*ratio_get) (void *ef); int (*video_handled) (void *ef); int (*audio_handled) (void *ef); diff --git a/legacy/emotion/src/lib/emotion_smart.c b/legacy/emotion/src/lib/emotion_smart.c index 848bc2ea29..f77ce76fb5 100644 --- a/legacy/emotion/src/lib/emotion_smart.c +++ b/legacy/emotion/src/lib/emotion_smart.c @@ -815,8 +815,41 @@ emotion_object_meta_info_get(Evas_Object *obj, Emotion_Meta_Info meta) return NULL; } +EAPI void +emotion_object_vis_set(Evas_Object *obj, Emotion_Vis visualization) +{ + Smart_Data *sd; + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + if (!sd->module) return; + if (!sd->video) return; + if (!sd->module->vis_set) return; + sd->module->vis_set(sd->video, visualization); +} +EAPI Emotion_Vis +emotion_object_vis_get(Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, EMOTION_VIS_NONE); + if (!sd->module) return EMOTION_VIS_NONE; + if (!sd->video) return EMOTION_VIS_NONE; + if (!sd->module->vis_get) return EMOTION_VIS_NONE; + return sd->module->vis_get(sd->video); +} + +EAPI Evas_Bool +emotion_object_vis_supported(Evas_Object *obj, Emotion_Vis visualization) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); + if (!sd->module) return 0; + if (!sd->video) return 0; + if (!sd->module->vis_supported) return 0; + return sd->module->vis_supported(sd->video, visualization); +} diff --git a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c index f78ecadee5..2ada21518a 100644 --- a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c +++ b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c @@ -42,8 +42,6 @@ static void em_size_get (void *video, static void em_pos_set (void *video, double pos); -static void em_vis_set (void *video, - Emotion_Vis vis); static double em_len_get (void *video); @@ -55,8 +53,14 @@ static double em_fps_get (void *video); static double em_pos_get (void *video); +static void em_vis_set (void *video, + Emotion_Vis vis); + static Emotion_Vis em_vis_get (void *video); +static Evas_Bool em_vis_supported (void *video, + Emotion_Vis vis); + static double em_ratio_get (void *video); static int em_video_handled (void *video); @@ -177,13 +181,14 @@ static Emotion_Video_Module em_module = em_stop, /* stop */ em_size_get, /* size_get */ em_pos_set, /* pos_set */ - em_vis_set, /* vis_set */ em_len_get, /* len_get */ em_fps_num_get, /* fps_num_get */ em_fps_den_get, /* fps_den_get */ em_fps_get, /* fps_get */ em_pos_get, /* pos_get */ + em_vis_set, /* vis_set */ em_vis_get, /* vis_get */ + em_vis_supported, /* vis_supported */ em_ratio_get, /* ratio_get */ em_video_handled, /* video_handled */ em_audio_handled, /* audio_handled */ @@ -265,7 +270,7 @@ em_init(Evas_Object *obj, ev->ratio = 1.0; ev->video_sink_nbr = 0; ev->audio_sink_nbr = 0; - ev->vis = EMOTION_VIS_GOOM; + ev->vis = EMOTION_VIS_NONE; /* Create the file descriptors */ if (pipe(fds) == 0) @@ -581,18 +586,6 @@ em_pos_set(void *video, } } -static void -em_vis_set(void *video, - Emotion_Vis vis) -{ - Emotion_Gstreamer_Video *ev; - - ev = (Emotion_Gstreamer_Video *)video; - - if (ev->vis == vis) return; - ev->vis = vis; -} - static double em_len_get(void *video) { @@ -663,6 +656,18 @@ em_pos_get(void *video) return ev->position; } +static void +em_vis_set(void *video, + Emotion_Vis vis) +{ + Emotion_Gstreamer_Video *ev; + + ev = (Emotion_Gstreamer_Video *)video; + + if (ev->vis == vis) return; + ev->vis = vis; +} + static Emotion_Vis em_vis_get(void *video) { @@ -673,6 +678,27 @@ em_vis_get(void *video) return ev->vis; } +static Evas_Bool +em_vis_supported(void *ef, Emotion_Vis vis) +{ + const char *name; + GstElementFactory *factory; + + if (vis == EMOTION_VIS_NONE) + return 1; + + name = emotion_visualization_element_name_get(vis); + if (!name) + return 0; + + factory = gst_element_factory_find(name); + if (!factory) + return 0; + + gst_object_unref(factory); + return 1; +} + static double em_ratio_get(void *video) { diff --git a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.c b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.c index 4499a86c63..1a921fc7eb 100644 --- a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.c +++ b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.c @@ -249,6 +249,54 @@ emotion_pipeline_cdda_track_count_get(void *video) return tracks_count; } +const char * +emotion_visualization_element_name_get(Emotion_Vis visualisation) +{ + switch (visualisation) + { + case EMOTION_VIS_NONE: + return NULL; + case EMOTION_VIS_GOOM: + return "goom"; + case EMOTION_VIS_LIBVISUAL_BUMPSCOPE: + return "libvisual_bumpscope"; + case EMOTION_VIS_LIBVISUAL_CORONA: + return "libvisual_corona"; + case EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES: + return "libvisual_dancingparticles"; + case EMOTION_VIS_LIBVISUAL_GDKPIXBUF: + return "libvisual_gdkpixbuf"; + case EMOTION_VIS_LIBVISUAL_G_FORCE: + return "libvisual_G-Force"; + case EMOTION_VIS_LIBVISUAL_GOOM: + return "libvisual_goom"; + case EMOTION_VIS_LIBVISUAL_INFINITE: + return "libvisual_infinite"; + case EMOTION_VIS_LIBVISUAL_JAKDAW: + return "libvisual_jakdaw"; + case EMOTION_VIS_LIBVISUAL_JESS: + return "libvisual_jess"; + case EMOTION_VIS_LIBVISUAL_LV_ANALYSER: + return "libvisual_lv_analyzer"; + case EMOTION_VIS_LIBVISUAL_LV_FLOWER: + return "libvisual_lv_flower"; + case EMOTION_VIS_LIBVISUAL_LV_GLTEST: + return "libvisual_lv_gltest"; + case EMOTION_VIS_LIBVISUAL_LV_SCOPE: + return "libvisual_lv_scope"; + case EMOTION_VIS_LIBVISUAL_MADSPIN: + return "libvisual_madspin"; + case EMOTION_VIS_LIBVISUAL_NEBULUS: + return "libvisual_nebulus"; + case EMOTION_VIS_LIBVISUAL_OINKSIE: + return "libvisual_oinksie"; + case EMOTION_VIS_LIBVISUAL_PLASMA: + return "libvisual_plazma"; + default: + return "goom"; + } +} + GstElement * emotion_audio_sink_create(Emotion_Gstreamer_Video *ev, int index) { @@ -302,102 +350,46 @@ emotion_audio_sink_create(Emotion_Gstreamer_Video *ev, int index) /* visualisation part */ { - GstElement *vis = NULL; - char *vis_name; + const char *vis_name = emotion_visualization_element_name_get(ev->vis); - switch (ev->vis) + if (vis_name) { - case EMOTION_VIS_GOOM: - vis_name = "goom"; - break; - case EMOTION_VIS_LIBVISUAL_BUMPSCOPE: - vis_name = "libvisual_bumpscope"; - break; - case EMOTION_VIS_LIBVISUAL_CORONA: - vis_name = "libvisual_corona"; - break; - case EMOTION_VIS_LIBVISUAL_DANCING_PARTICLES: - vis_name = "libvisual_dancingparticles"; - break; - case EMOTION_VIS_LIBVISUAL_GDKPIXBUF: - vis_name = "libvisual_gdkpixbuf"; - break; - case EMOTION_VIS_LIBVISUAL_G_FORCE: - vis_name = "libvisual_G-Force"; - break; - case EMOTION_VIS_LIBVISUAL_GOOM: - vis_name = "libvisual_goom"; - break; - case EMOTION_VIS_LIBVISUAL_INFINITE: - vis_name = "libvisual_infinite"; - break; - case EMOTION_VIS_LIBVISUAL_JAKDAW: - vis_name = "libvisual_jakdaw"; - break; - case EMOTION_VIS_LIBVISUAL_JESS: - vis_name = "libvisual_jess"; - break; - case EMOTION_VIS_LIBVISUAL_LV_ANALYSER: - vis_name = "libvisual_lv_analyzer"; - break; - case EMOTION_VIS_LIBVISUAL_LV_FLOWER: - vis_name = "libvisual_lv_flower"; - break; - case EMOTION_VIS_LIBVISUAL_LV_GLTEST: - vis_name = "libvisual_lv_gltest"; - break; - case EMOTION_VIS_LIBVISUAL_LV_SCOPE: - vis_name = "libvisual_lv_scope"; - break; - case EMOTION_VIS_LIBVISUAL_MADSPIN: - vis_name = "libvisual_madspin"; - break; - case EMOTION_VIS_LIBVISUAL_NEBULUS: - vis_name = "libvisual_nebulus"; - break; - case EMOTION_VIS_LIBVISUAL_OINKSIE: - vis_name = "libvisual_oinksie"; - break; - case EMOTION_VIS_LIBVISUAL_PLASMA: - vis_name = "libvisual_plazma"; - break; - default: - vis_name = "goom"; - break; - } + GstElement *vis; - g_snprintf(buf, 128, "vis%d", index); - if ((vis = gst_element_factory_make(vis_name, buf))) - { - GstElement *queue; - GstElement *conv; - GstElement *cspace; - GstElement *sink; - GstPad *vispad; - GstCaps *caps; + g_snprintf(buf, 128, "vis%d", index); + vis = gst_element_factory_make(vis_name, buf); + if (vis) + { + GstElement *queue; + GstElement *conv; + GstElement *cspace; + GstElement *sink; + GstPad *vispad; + GstCaps *caps; - g_snprintf(buf, 128, "visbin%d", index); - visbin = gst_bin_new(buf); + g_snprintf(buf, 128, "visbin%d", index); + visbin = gst_bin_new(buf); - queue = gst_element_factory_make("queue", NULL); - conv = gst_element_factory_make("audioconvert", NULL); - cspace = gst_element_factory_make("ffmpegcolorspace", NULL); - g_snprintf(buf, 128, "vissink%d", index); - sink = gst_element_factory_make("fakesink", buf); + queue = gst_element_factory_make("queue", NULL); + conv = gst_element_factory_make("audioconvert", NULL); + cspace = gst_element_factory_make("ffmpegcolorspace", NULL); + g_snprintf(buf, 128, "vissink%d", index); + sink = gst_element_factory_make("fakesink", buf); - gst_bin_add_many(GST_BIN(visbin), - queue, conv, vis, cspace, sink, NULL); - gst_element_link_many(queue, conv, vis, cspace, NULL); - caps = gst_caps_new_simple("video/x-raw-rgb", - "bpp", G_TYPE_INT, 32, - "width", G_TYPE_INT, 320, - "height", G_TYPE_INT, 200, - NULL); - gst_element_link_filtered(cspace, sink, caps); + gst_bin_add_many(GST_BIN(visbin), + queue, conv, vis, cspace, sink, NULL); + gst_element_link_many(queue, conv, vis, cspace, NULL); + caps = gst_caps_new_simple("video/x-raw-rgb", + "bpp", G_TYPE_INT, 32, + "width", G_TYPE_INT, 320, + "height", G_TYPE_INT, 200, + NULL); + gst_element_link_filtered(cspace, sink, caps); - vispad = gst_element_get_pad(queue, "sink"); - gst_element_add_pad(visbin, gst_ghost_pad_new("sink", vispad)); - gst_object_unref(vispad); + vispad = gst_element_get_pad(queue, "sink"); + gst_element_add_pad(visbin, gst_ghost_pad_new("sink", vispad)); + gst_object_unref(vispad); + } } } diff --git a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.h b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.h index a5ac8be644..2e8a703294 100644 --- a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.h +++ b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer_pipeline.h @@ -37,5 +37,7 @@ void file_new_decoded_pad_cb (GstElement *decodebin, gboolean last, gpointer user_data); +const char *emotion_visualization_element_name_get(Emotion_Vis visualisation); + #endif /* __EMOTION_GSTREAMER_PIPELINE_H__ */ diff --git a/legacy/emotion/src/modules/xine/emotion_xine.c b/legacy/emotion/src/modules/xine/emotion_xine.c index 657eb5a399..9f902757b0 100644 --- a/legacy/emotion/src/modules/xine/emotion_xine.c +++ b/legacy/emotion/src/modules/xine/emotion_xine.c @@ -11,13 +11,14 @@ static void em_play (void *ef, double pos); static void em_stop (void *ef); static void em_size_get (void *ef, int *w, int *h); static void em_pos_set (void *ef, double pos); -static void em_vis_set (void *ef, Emotion_Vis vis); static double em_len_get (void *ef); static int em_fps_num_get (void *ef); static int em_fps_den_get (void *ef); static double em_fps_get (void *ef); static double em_pos_get (void *ef); +static void em_vis_set (void *ef, Emotion_Vis vis); static Emotion_Vis em_vis_get (void *ef); +static Evas_Bool em_vis_supported (void *ef, Emotion_Vis vis); static double em_ratio_get (void *ef); static int em_seekable (void *ef); static void em_frame_done (void *ef); @@ -508,17 +509,6 @@ em_pos_set(void *ef, double pos) _em_slave_event(ev, 6, ppos); } -static void -em_vis_set(void *ef, - Emotion_Vis vis) -{ - Emotion_Xine_Video *ev; - - ev = (Emotion_Xine_Video *)ef; - if (ev->vis == vis) return; - ev->vis = vis; -} - static double em_len_get(void *ef) { @@ -564,6 +554,16 @@ em_pos_get(void *ef) return ev->pos; } +static void +em_vis_set(void *ef, Emotion_Vis vis) +{ + Emotion_Xine_Video *ev; + + ev = (Emotion_Xine_Video *)ef; + if (ev->vis == vis) return; + ev->vis = vis; +} + static Emotion_Vis em_vis_get(void *ef) { @@ -574,6 +574,12 @@ em_vis_get(void *ef) return ev->vis; } +static Evas_Bool +em_vis_supported(void *ef, Emotion_Vis vis) +{ + return 0; +} + static double em_ratio_get(void *ef) { @@ -1467,13 +1473,14 @@ static Emotion_Video_Module em_module = em_stop, /* stop */ em_size_get, /* size_get */ em_pos_set, /* pos_set */ - em_vis_set, /* vis_set */ em_len_get, /* len_get */ em_fps_num_get, /* fps_num_get */ em_fps_den_get, /* fps_den_get */ em_fps_get, /* fps_get */ em_pos_get, /* pos_get */ + em_vis_set, /* vis_set */ em_vis_get, /* vis_get */ + em_vis_supported, /* vis_supported */ em_ratio_get, /* ratio_get */ em_video_handled, /* video_handled */ em_audio_handled, /* audio_handled */