[maemo-commits] [maemo-commits] r17865 - projects/haf/trunk/hildon-welcome/src
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Mon Mar 30 15:13:58 EEST 2009
- Previous message: [maemo-commits] r17863 - projects/haf/trunk/hildon-welcome/src
- Next message: [maemo-commits] r17866 - projects/haf/trunk/hildon-welcome/debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: schulhof Date: 2009-03-30 15:13:55 +0300 (Mon, 30 Mar 2009) New Revision: 17865 Modified: projects/haf/trunk/hildon-welcome/src/main.c Log: Absolute timeout is not fatal Modified: projects/haf/trunk/hildon-welcome/src/main.c =================================================================== --- projects/haf/trunk/hildon-welcome/src/main.c 2009-03-30 12:00:26 UTC (rev 17864) +++ projects/haf/trunk/hildon-welcome/src/main.c 2009-03-30 12:13:55 UTC (rev 17865) @@ -34,6 +34,8 @@ #endif /* HAVE_MCE */ #include "conffile.h" +#define KILL_TO_LENGTH_MS 30000 + #define DEFAULT_VIDEO_PIPELINE_STR " playbin2 uri=file://%s " /* " flags=99 " <-- doesn't work with still images */ #define DEFAULT_AUDIO_PIPELINE_STR " filesrc location=%s ! decodebin2 ! autoaudiosink " #define DEFAULT_SHUSH_PIPELINE_STR " audiotestsrc ! volume volume=0 ! autoaudiosink " @@ -41,34 +43,184 @@ static char *video_pipeline_str = DEFAULT_VIDEO_PIPELINE_STR; static char *audio_pipeline_str = DEFAULT_AUDIO_PIPELINE_STR; static char *shush_pipeline_str = DEFAULT_SHUSH_PIPELINE_STR; +static GTimer *global_timer = NULL; +typedef struct +{ + GTimer *timer; + guint to_ms; + GstElement *pipeline; + guint timeout_id; + const char *warning; +} TimeoutParams; + +static gboolean +post_eos(TimeoutParams *tp) +{ + if (tp->timer) { + double diff_ms = ((double)(tp->to_ms)) - (g_timer_elapsed(tp->timer, NULL) * 1000.0); + if (diff_ms > 0) { + g_warning("[%lf]: post_eos: False alarm! %lf ms () left\n", g_timer_elapsed(global_timer, NULL), diff_ms); + tp->timeout_id = g_timeout_add((guint)diff_ms, (GSourceFunc)post_eos, tp); + return FALSE; + } + } + if (tp->warning) + g_warning("[%lf]: post_eos: %s", g_timer_elapsed(global_timer, NULL), tp->warning); + gst_bus_post(gst_pipeline_get_bus(GST_PIPELINE(tp->pipeline)), gst_message_new_eos(GST_OBJECT(tp->pipeline))); + + tp->timeout_id = 0; + if (tp->timer) { + g_timer_destroy(tp->timer); + tp->timer = NULL; + } + return FALSE; +} + static void -my_log_func(const gchar *log_domain, GLogLevelFlags log_level, const char *message, gpointer null) +post_eos_timeout_add(guint to_ms, GstElement *pipeline, char *warning, TimeoutParams *params) { - char *new_msg = NULL; - static GTimer *timer = NULL; + params->to_ms = to_ms; + params->pipeline = pipeline; + params->warning = warning; + params->timer = g_timer_new(); + params->timeout_id = g_timeout_add(to_ms, (GSourceFunc)post_eos, params); +} - if (G_UNLIKELY(!timer)) - timer = g_timer_new(); +static void +post_eos_timeout_remove(TimeoutParams *params) +{ + if (params->timeout_id) { + g_source_remove(params->timeout_id); + params->timeout_id = 0; + } + if (params->timer) { + g_timer_destroy(params->timer); + params->timer = NULL; + } +} - new_msg = g_strdup_printf("[%lf]: %s", timer ? g_timer_elapsed(timer, NULL) : G_MAXDOUBLE, message); - g_log_default_handler (log_domain, log_level, (const char *)new_msg, NULL); - g_free(new_msg); +static void +wait_for_eos(GstElement *pipeline, Window dst_window, int duration, TimeoutParams *play_to) +{ + GError *err = NULL; + char *debug = NULL; + gboolean keep_looping = TRUE; + GstMessage *message = NULL; + + while (keep_looping) { + message = gst_bus_poll(gst_pipeline_get_bus(GST_PIPELINE(pipeline)), GST_MESSAGE_ANY, -1); + if (!message) break; + + switch(GST_MESSAGE_TYPE(message)) { + case GST_MESSAGE_ASYNC_DONE: + g_debug("[%lf]: wait_for_eos: Ready to play: duration = %d\n", g_timer_elapsed(global_timer, NULL), duration); + if ((duration > 500) && !(play_to->timeout_id)) + post_eos_timeout_add(duration, pipeline, NULL, play_to); + break; + + case GST_MESSAGE_ERROR: + gst_message_parse_error(message, &err, &debug); + g_warning("[%lf]: wait_for_eos: %s: %s %s\n", g_timer_elapsed(global_timer, NULL), GST_MESSAGE_TYPE_NAME(message), err ? err->message : "", debug ? debug : ""); + if (err) + g_error_free(err); + g_free(debug); + /* fall through */ + case GST_MESSAGE_EOS: + keep_looping = FALSE; + gst_element_set_state(pipeline, GST_STATE_PAUSED); + g_debug("[%lf]: wait_for_eos: Gst message: %s", g_timer_elapsed(global_timer, NULL), GST_MESSAGE_TYPE_NAME(message)); + break; + + case GST_MESSAGE_ELEMENT: + if (gst_structure_has_name(message->structure, "prepare-xwindow-id")) + gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(message)), dst_window); + break; + + default: + break; + } + gst_message_unref(message); + } } +static void +unblank_screen() +{ +#ifdef HAVE_MCE + DBusConnection *conn = NULL; + + if ((conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL)) != NULL) { + DBusMessage *message, *reply; + + if ((message = dbus_message_new_method_call(MCE_SERVICE, MCE_REQUEST_PATH, MCE_REQUEST_IF, MCE_DISPLAY_ON_REQ)) != NULL) { + if ((reply = dbus_connection_send_with_reply_and_block(conn, message, -1, NULL)) != NULL) + dbus_message_unref(reply); + dbus_message_unref(message); + } + } +#endif /* HAVE_MCE */ +} + static GstElement * -create_pipeline(GstElement **p_audio_bin, GstElement **p_video_bin, GstElement **p_shush_bin) +play_logo(Window dst_window, char *video, char *audio, int duration) { - GstElement *pipeline = NULL; + GstElement* pipeline = NULL; + GString *pipeline_str = g_string_new(""); - pipeline = gst_pipeline_new(); + g_debug("[%lf]: play_logo: playing (video = '%s', audio = '%s', duration = '%d')", g_timer_elapsed(global_timer, NULL), video, audio, duration); - (*p_audio_bin) = gst_element_make("playbin2", "audio_bin"); - (*p_video_bin) = gst_element_make("playbin2", "video_bin"); + if (video && video[0]) + g_string_append_printf(pipeline_str, video_pipeline_str, video); + if (audio && audio[0]) { + if ('s' == audio[0] && 0 == audio[1]) + g_string_append_printf(pipeline_str, shush_pipeline_str); + else + g_string_append_printf(pipeline_str, audio_pipeline_str, audio); + } + + pipeline = gst_parse_launch(pipeline_str->str, NULL); + g_string_free(pipeline_str, TRUE); + + if (pipeline) { + TimeoutParams kill_to, play_to; + + post_eos_timeout_add(KILL_TO_LENGTH_MS, pipeline, "Absolute timeout reached!\n", &kill_to); + + gst_element_set_state(pipeline, GST_STATE_PLAYING); + unblank_screen(); + wait_for_eos(pipeline, dst_window, duration, &play_to); + + post_eos_timeout_remove(&kill_to); + post_eos_timeout_remove(&play_to); + } + return pipeline; } +/* Paint a black filled rectangle over the given window */ +static void +draw_black(Display *dpy, Window dst_window) +{ + XGCValues vals; + Window root_window; + int x, y; + unsigned int cx, cy, cx_border, depth; + + if (!XGetGeometry(dpy, dst_window, &root_window, &x, &y, &cx, &cy, &cx_border, &depth)) { + x = 0; y = 0; + cx = 800; cy = 480; + } + + vals.foreground = BlackPixel(dpy, 0); + vals.background = BlackPixel(dpy, 0); + GC gc = XCreateGC(dpy, dst_window, GCForeground | GCBackground, &vals); + XFillRectangle(dpy, dst_window, gc, x, y, cx, cy); + XFreeGC(dpy, gc); + XFlush(dpy); +} + int main(int argc, char **argv) { @@ -110,11 +262,10 @@ int duration; ConfFileIterator *itr; Window dst_window = 0, xcomposite_window = 0; + GstElement *new_pipeline = NULL, *old_pipeline = NULL; if (!g_thread_supported ()) g_thread_init(NULL); - g_log_set_default_handler(my_log_func, NULL); - ctx = g_option_context_new(NULL); g_option_context_add_main_entries (ctx, options, NULL); g_option_context_add_group (ctx, gst_init_get_option_group()); @@ -124,24 +275,36 @@ gst_init(&argc, &argv); + global_timer = g_timer_new(); + if (!(display = XOpenDisplay(NULL))) - g_error("main: Failed to open display\n"); + g_error("[%lf]: main: Failed to open display\n", g_timer_elapsed(global_timer, NULL)); if ((dst_window = DefaultRootWindow(display)) == 0) - g_error("main: Failed to obtain root window\n"); + g_error("[%lf]: Failed to obtain root window\n", g_timer_elapsed(global_timer, NULL)); if ((xcomposite_window = XCompositeGetOverlayWindow(display, dst_window)) != 0) dst_window = xcomposite_window; if ((itr = conf_file_iterator_new())) { while (conf_file_iterator_get(itr, &video, &audio, &duration)) { - g_debug("main: video = %s, audio = %s, duration = %d\n", video, audio, duration); + new_pipeline = play_logo(dst_window, video, audio, duration); g_free(video); video = NULL; g_free(audio); audio = NULL; duration = 0; + if (old_pipeline) { + gst_element_set_state(old_pipeline, GST_STATE_NULL); + gst_object_unref(old_pipeline); + } + old_pipeline = new_pipeline; } conf_file_iterator_destroy(itr); } + /* Prevent the green flash before the application quits */ + draw_black(display, dst_window); + gst_element_set_state(new_pipeline, GST_STATE_NULL); + gst_object_unref(new_pipeline); + if (xcomposite_window) XCompositeReleaseOverlayWindow(display, xcomposite_window); @@ -149,5 +312,7 @@ gst_deinit(); + g_timer_destroy(global_timer); + return 0; }
- Previous message: [maemo-commits] r17863 - projects/haf/trunk/hildon-welcome/src
- Next message: [maemo-commits] r17866 - projects/haf/trunk/hildon-welcome/debian
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]