From e3e1511bacd6f7b528f860408a18dc4fb76f3070 Mon Sep 17 00:00:00 2001 From: Leandro Dorileo Date: Wed, 2 Jan 2013 21:03:30 +0000 Subject: [PATCH] Emotion: introce emotion_object_video_subtitle_file_set() call For setting an arbitrary subtitle file, this patch introduces the emotion_object_video_subtitle_file_set() and its counterpart emotion_object_video_subtitle_file_get(). The tag @sice were added as 1.7.2 since we're preparing a backport to stable tree. SVN revision: 82019 --- legacy/emotion/.gitignore | 6 ++ legacy/emotion/AUTHORS | 1 + legacy/emotion/ChangeLog | 4 + legacy/emotion/NEWS | 8 +- legacy/emotion/src/examples/Makefile.am | 2 + .../emotion_generic_subtitle_example.c | 97 +++++++++++++++++++ .../generic_players/vlc/emotion_generic_vlc.c | 15 +++ legacy/emotion/src/lib/Emotion.h | 32 ++++++ legacy/emotion/src/lib/emotion_private.h | 2 + legacy/emotion/src/lib/emotion_smart.c | 23 +++++ .../modules/generic/Emotion_Generic_Plugin.h | 1 + .../src/modules/generic/emotion_generic.c | 24 +++++ .../src/modules/generic/emotion_generic.h | 1 + .../src/modules/gstreamer/emotion_gstreamer.c | 21 ++++ 14 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 legacy/emotion/src/examples/emotion_generic_subtitle_example.c diff --git a/legacy/emotion/.gitignore b/legacy/emotion/.gitignore index a38523edd2..70e8e3c54d 100644 --- a/legacy/emotion/.gitignore +++ b/legacy/emotion/.gitignore @@ -49,8 +49,14 @@ src/edje_external/Makefile.in src/edje_external/module.la src/edje_external/module_la-emotion.lo src/examples/.deps/ +src/examples/.libs/ src/examples/Makefile src/examples/Makefile.in +src/examples/emotion_basic_example +src/examples/emotion_border_example +src/examples/emotion_generic_example +src/examples/emotion_generic_subtitle_example +src/examples/emotion_signals_example src/generic_players/Makefile src/generic_players/Makefile.in src/generic_players/vlc/.deps/ diff --git a/legacy/emotion/AUTHORS b/legacy/emotion/AUTHORS index c2579a8e4e..0cfd8c62f2 100644 --- a/legacy/emotion/AUTHORS +++ b/legacy/emotion/AUTHORS @@ -8,3 +8,4 @@ Jérôme Pinot Pierre Le Magourou Hugo Camboulive Sohyun Kim +Leandro Dorileo \ No newline at end of file diff --git a/legacy/emotion/ChangeLog b/legacy/emotion/ChangeLog index 36a608d761..3298ea3dee 100644 --- a/legacy/emotion/ChangeLog +++ b/legacy/emotion/ChangeLog @@ -58,3 +58,7 @@ 2012-10-11 Sohyun Kim * Fix to call correct render function based on the format. + +2013-01-02 Leandro Dorileo (dorileo) + + * Add subtitle file API. diff --git a/legacy/emotion/NEWS b/legacy/emotion/NEWS index d3715bdf63..112b405035 100644 --- a/legacy/emotion/NEWS +++ b/legacy/emotion/NEWS @@ -1,4 +1,10 @@ -Emotion 1.7.1 +Emotion 1.7.2 + +Changes since Emotion 1.7.1: +------------------------- + +Additions: + - Add video subtitle file API. Changes since Emotion 1.7.0: ------------------------- diff --git a/legacy/emotion/src/examples/Makefile.am b/legacy/emotion/src/examples/Makefile.am index 7476f08857..5e39adcf7a 100644 --- a/legacy/emotion/src/examples/Makefile.am +++ b/legacy/emotion/src/examples/Makefile.am @@ -17,6 +17,7 @@ LDADD = \ SRCS = \ emotion_basic_example.c \ emotion_generic_example.c \ + emotion_generic_subtitle_example.c \ emotion_border_example.c \ emotion_signals_example.c @@ -33,6 +34,7 @@ if EFL_BUILD_EXAMPLES examples_PROGRAMS += \ emotion_basic_example \ emotion_generic_example \ + emotion_generic_subtitle_example \ emotion_border_example \ emotion_signals_example endif diff --git a/legacy/emotion/src/examples/emotion_generic_subtitle_example.c b/legacy/emotion/src/examples/emotion_generic_subtitle_example.c new file mode 100644 index 0000000000..448b505449 --- /dev/null +++ b/legacy/emotion/src/examples/emotion_generic_subtitle_example.c @@ -0,0 +1,97 @@ +#include +#include +#include +#include +#include + +#define WIDTH (320) +#define HEIGHT (240) + +static void +_playback_started_cb(void *data, Evas_Object *o, void *event_info) +{ + printf("Emotion object started playback.\n"); +} + +static void +_on_delete(Ecore_Evas *ee) +{ + ecore_main_loop_quit(); +} + +int +main(int argc, const char *argv[]) +{ + Ecore_Evas *ee; + Evas *e; + Evas_Object *bg, *em; + const char *filename = NULL; + const char *subtitle_filename = NULL; + + if (argc < 2) + { + printf("At least one argument is necessary. Usage:\n"); + printf("\t%s \n", argv[0]); + return -1; + } + + filename = argv[1]; + + if (argc > 2) + subtitle_filename = argv[2]; + + if (!ecore_evas_init()) + return EXIT_FAILURE; + + /* this will give you a window with an Evas canvas under the first + * engine available */ + ee = ecore_evas_new(NULL, 10, 10, WIDTH, HEIGHT, NULL); + if (!ee) + goto error; + + ecore_evas_callback_delete_request_set(ee, _on_delete); + + ecore_evas_show(ee); + + /* the canvas pointer, de facto */ + e = ecore_evas_get(ee); + + /* adding a background to this example */ + bg = evas_object_rectangle_add(e); + evas_object_name_set(bg, "our dear rectangle"); + evas_object_color_set(bg, 255, 255, 255, 255); /* white bg */ + evas_object_move(bg, 0, 0); /* at canvas' origin */ + evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */ + evas_object_show(bg); + + /* Creating the emotion object */ + em = emotion_object_add(e); + emotion_object_init(em, "generic"); + + if (subtitle_filename) + emotion_object_video_subtitle_file_set(em, subtitle_filename); + + evas_object_smart_callback_add( + em, "playback_started", _playback_started_cb, NULL); + + emotion_object_file_set(em, filename); + + evas_object_move(em, 0, 0); + evas_object_resize(em, WIDTH, HEIGHT); + evas_object_show(em); + + emotion_object_play_set(em, EINA_TRUE); + + ecore_main_loop_begin(); + + ecore_evas_free(ee); + ecore_evas_shutdown(); + return 0; + +error: + fprintf(stderr, "you got to have at least one evas engine built and linked" + " up to ecore-evas for this example to run properly.\n"); + + ecore_evas_shutdown(); + return -1; +} diff --git a/legacy/emotion/src/generic_players/vlc/emotion_generic_vlc.c b/legacy/emotion/src/generic_players/vlc/emotion_generic_vlc.c index 836eda3a45..d15341667a 100644 --- a/legacy/emotion/src/generic_players/vlc/emotion_generic_vlc.c +++ b/legacy/emotion/src/generic_players/vlc/emotion_generic_vlc.c @@ -37,6 +37,7 @@ struct _App { libvlc_event_manager_t *event_mgr; libvlc_event_manager_t *mevent_mgr; char *filename; + char *subtitle_path; char *shmname; void *tmpbuffer; int w, h; @@ -313,6 +314,10 @@ _play(struct _App *app) libvlc_time_t new_time = pos * 1000; libvlc_media_player_set_time(app->mp, new_time); libvlc_media_player_play(app->mp); + + if (app->subtitle_path) + libvlc_video_set_subtitle_file(app->mp, app->subtitle_path); + app->playing = 1; } } @@ -377,6 +382,12 @@ _event_cb(const struct libvlc_event_t *ev, void *data) } } +static void +_subtitle_set(struct _App *app) +{ + _em_str_read(app->em_read, &app->subtitle_path); +} + static void _file_set(struct _App *app) { @@ -585,6 +596,9 @@ _process_emotion_commands(struct _App *app) case EM_CMD_FILE_SET_DONE: _file_set_done(app); break; + case EM_CMD_SUBTITLE_SET: + _subtitle_set(app); + break; case EM_CMD_FILE_CLOSE: _file_close(app); break; @@ -805,6 +819,7 @@ main(int argc, const char *argv[]) app.libvlc = libvlc_new(vlc_argc, vlc_argv); app.mp = NULL; app.filename = NULL; + app.subtitle_path = NULL; app.w = 0; app.h = 0; app.size_sent = 0; diff --git a/legacy/emotion/src/lib/Emotion.h b/legacy/emotion/src/lib/Emotion.h index 361e4e55e5..186144ea4f 100644 --- a/legacy/emotion/src/lib/Emotion.h +++ b/legacy/emotion/src/lib/Emotion.h @@ -979,6 +979,38 @@ EAPI void emotion_object_video_mute_set (Evas_Object *obj, Eina_B */ EAPI Eina_Bool emotion_object_video_mute_get (const Evas_Object *obj); +/** + * @brief Set the video's subtitle file path. + * + * @param obj The object which we are setting a subtitle file path. + * @param filepath The subtitle file path. + * + * This function sets a video's subtitle file path(i.e an .srt file) for + * supported subtitle formats consult the backend's documentation. + * + * @see emotion_object_video_subtitle_file_get(). + * + * @ingroup Emotion_Video + * @since 1.7.2 + */ +EAPI void emotion_object_video_subtitle_file_set (Evas_Object *obj, const char *filepath); + +/** + * @brief Get the video's subtitle file path. + * + * @param obj The object which we are retrieving the subtitle file path from. + * @return The video's subtitle file path previously set, NULL otherwise. + * + * This function returns the video's subtitle file path, if not previously set + * or in error NULL is returned. + * + * @see emotion_object_video_subtitle_file_set(). + * + * @ingroup Emotion_Video + * @since 1.7.2 + */ +EAPI const char *emotion_object_video_subtitle_file_get (const Evas_Object *obj); + /** * @brief Get the number of available video channel * diff --git a/legacy/emotion/src/lib/emotion_private.h b/legacy/emotion/src/lib/emotion_private.h index cf24c7543e..73a1b7ddf0 100644 --- a/legacy/emotion/src/lib/emotion_private.h +++ b/legacy/emotion/src/lib/emotion_private.h @@ -74,6 +74,8 @@ struct _Emotion_Video_Module int (*video_channel_count) (void *ef); void (*video_channel_set) (void *ef, int channel); int (*video_channel_get) (void *ef); + void (*video_subtitle_file_set) (void *ef, const char *filepath); + const char * (*video_subtitle_file_get) (void *ef); const char * (*video_channel_name_get) (void *ef, int channel); void (*video_channel_mute_set) (void *ef, int mute); int (*video_channel_mute_get) (void *ef); diff --git a/legacy/emotion/src/lib/emotion_smart.c b/legacy/emotion/src/lib/emotion_smart.c index 48eafdacc7..8a80f838db 100644 --- a/legacy/emotion/src/lib/emotion_smart.c +++ b/legacy/emotion/src/lib/emotion_smart.c @@ -999,6 +999,29 @@ emotion_object_video_mute_get(const Evas_Object *obj) return sd->module->video_channel_mute_get(sd->video_data); } +EAPI void +emotion_object_video_subtitle_file_set(Evas_Object *obj, const char *filepath) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET(sd, obj, E_OBJ_NAME); + DBG("subtitle=%s", filepath); + if (!sd->module) return; + if (!sd->video_data) return; + sd->module->video_subtitle_file_set(sd->video_data, filepath); +} + +EAPI const char * +emotion_object_video_subtitle_file_get(const Evas_Object *obj) +{ + Smart_Data *sd; + + E_SMART_OBJ_GET_RETURN(sd, obj, E_OBJ_NAME, 0); + if (!sd->module) return EINA_FALSE; + if (!sd->video_data) return EINA_FALSE; + return sd->module->video_subtitle_file_get(sd->video_data); +} + EAPI int emotion_object_video_channel_count(const Evas_Object *obj) { diff --git a/legacy/emotion/src/modules/generic/Emotion_Generic_Plugin.h b/legacy/emotion/src/modules/generic/Emotion_Generic_Plugin.h index 17bd7e9c50..f00ea6e405 100644 --- a/legacy/emotion/src/modules/generic/Emotion_Generic_Plugin.h +++ b/legacy/emotion/src/modules/generic/Emotion_Generic_Plugin.h @@ -35,6 +35,7 @@ enum _Emotion_Generic_Cmd EM_CMD_AUDIO_TRACK_SET, // param: track id (int) EM_CMD_VIDEO_TRACK_SET, // param: track id (int) EM_CMD_SPU_TRACK_SET, // param: track id (int) + EM_CMD_SUBTITLE_SET, // param: subtitle filename (string) EM_CMD_LAST }; diff --git a/legacy/emotion/src/modules/generic/emotion_generic.c b/legacy/emotion/src/modules/generic/emotion_generic.c index e0ff6d9a16..648be6dfd8 100644 --- a/legacy/emotion/src/modules/generic/emotion_generic.c +++ b/legacy/emotion/src/modules/generic/emotion_generic.c @@ -1129,6 +1129,7 @@ em_file_close(void *data) INF("file close: %s", ev->filename); eina_stringshare_replace(&ev->filename, NULL); + eina_stringshare_replace(&ev->subtitle_path, NULL); ev->file_ready = EINA_FALSE; _audio_channels_free(ev); @@ -1175,8 +1176,15 @@ em_play(void *data, double pos) if (ev->ready) { + if (ev->subtitle_path) + { + _player_send_cmd(ev, EM_CMD_SUBTITLE_SET); + _player_send_str(ev, ev->subtitle_path, EINA_TRUE); + } + _player_send_cmd(ev, EM_CMD_PLAY); _player_send_float(ev, ev->pos); + return; } @@ -1392,6 +1400,20 @@ em_video_channel_get(void *data) return ev->video_channel_current; } +static void +em_video_subtitle_file_set(void *data, const char *filepath) +{ + Emotion_Generic_Video *ev = data; + eina_stringshare_replace(&ev->subtitle_path, filepath); +} + +static const char * +em_video_subtitle_file_get(void *data) +{ + Emotion_Generic_Video *ev = data; + return ev->subtitle_path; +} + static const char * em_video_channel_name_get(void *data, int channel) { @@ -1694,6 +1716,8 @@ static Emotion_Video_Module em_module = em_video_channel_count, /* video_channel_count */ em_video_channel_set, /* video_channel_set */ em_video_channel_get, /* video_channel_get */ + em_video_subtitle_file_set, /* video_subtitle_file_set */ + em_video_subtitle_file_get, /* video_subtitle_file_get */ em_video_channel_name_get, /* video_channel_name_get */ em_video_channel_mute_set, /* video_channel_mute_set */ em_video_channel_mute_get, /* video_channel_mute_get */ diff --git a/legacy/emotion/src/modules/generic/emotion_generic.h b/legacy/emotion/src/modules/generic/emotion_generic.h index ed3bdb042e..864abb3f41 100644 --- a/legacy/emotion/src/modules/generic/emotion_generic.h +++ b/legacy/emotion/src/modules/generic/emotion_generic.h @@ -106,6 +106,7 @@ struct _Emotion_Generic_Video int spu_channel_current; Emotion_Generic_Channel *spu_channels; Emotion_Generic_Meta meta; + const char *subtitle_path; }; #endif diff --git a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c index 8ec71fb2c0..395d9310cd 100644 --- a/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c +++ b/legacy/emotion/src/modules/gstreamer/emotion_gstreamer.c @@ -132,6 +132,11 @@ static void em_video_channel_set (void *video, static int em_video_channel_get (void *video); +static void em_video_subtitle_file_set (void *video, + const char *filepath); + +static const char *em_video_subtitle_file_get (void *video); + static const char *em_video_channel_name_get (void *video, int channel); @@ -241,6 +246,8 @@ static Emotion_Video_Module em_module = em_video_channel_count, /* video_channel_count */ em_video_channel_set, /* video_channel_set */ em_video_channel_get, /* video_channel_get */ + em_video_subtitle_file_set, /* video_subtitle_file_set */ + em_video_subtitle_file_get, /* video_subtitle_file_get */ em_video_channel_name_get, /* video_channel_name_get */ em_video_channel_mute_set, /* video_channel_mute_set */ em_video_channel_mute_get, /* video_channel_mute_get */ @@ -1028,6 +1035,20 @@ em_video_channel_get(void *video) return ev->video_stream_nbr; } +static void +em_video_subtitle_file_set(void *video __UNUSED__, + const char *filepath __UNUSED__) +{ + DBG("video_subtitle_file_set not implemented for gstreamer yet."); +} + +static const char * +em_video_subtitle_file_get(void *video __UNUSED__) +{ + DBG("video_subtitle_file_get not implemented for gstreamer yet."); + return NULL; +} + static const char * em_video_channel_name_get(void *video __UNUSED__, int channel __UNUSED__)