[maemo-commits] [maemo-commits] r18074 - projects/haf/trunk/hildon-welcome/src
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Thu Apr 16 10:34:21 EEST 2009
- Previous message: [maemo-commits] r18073 - in projects/haf/trunk/clutter0.8: clutter/x11 debian
- Next message: [maemo-commits] r18075 - projects/haf/trunk/hildon-welcome/src
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: schulhof Date: 2009-04-16 10:34:20 +0300 (Thu, 16 Apr 2009) New Revision: 18074 Modified: projects/haf/trunk/hildon-welcome/src/tmp.c Log: Modified: projects/haf/trunk/hildon-welcome/src/tmp.c =================================================================== --- projects/haf/trunk/hildon-welcome/src/tmp.c 2009-04-16 06:21:12 UTC (rev 18073) +++ projects/haf/trunk/hildon-welcome/src/tmp.c 2009-04-16 07:34:20 UTC (rev 18074) @@ -1,9 +1,16 @@ +#include <string.h> #include <stdlib.h> #include <gst/gst.h> -#define HAVE_VIDEO +/* + * Grab the XComposite overlay window or, failing that, the root window, + * instead of having GStreamer create a window. + */ +#define GET_WINDOW #define APP_STATE_STATIC_INIT { \ + .video_src = NULL, \ + .audio_src = NULL, \ .audio_sink = NULL, \ .video_sink = NULL, \ .dst_window = 0, \ @@ -16,6 +23,8 @@ #include <X11/extensions/Xcomposite.h> typedef struct { + GstElement *video_src; + GstElement *audio_src; GstElement *audio_sink; GstElement *video_sink; Window dst_window; @@ -24,35 +33,157 @@ } AppState; static void +my_log_func(const gchar *log_domain, GLogLevelFlags log_level, const char *message, gpointer null) +{ + char *new_msg = NULL; + static GTimer *timer = NULL; + + if (G_UNLIKELY(!timer)) + timer = g_timer_new(); + + 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 +gst_element_get_has_audio_video(GstElement *src, gboolean *p_has_audio, gboolean *p_has_video) +{ + GstIterator *itr = NULL; + GstPad *pad = NULL; + GstCaps *caps = NULL; + GstStructure *cap_struct = NULL; + const char *name = NULL; + + (*p_has_audio) = FALSE; + (*p_has_video) = FALSE; + + if ((itr = gst_element_iterate_src_pads(src)) != NULL) { + while (GST_ITERATOR_OK == gst_iterator_next(itr, ((gpointer *)(&pad)))) { + if ((caps = gst_pad_get_caps(pad)) != NULL) { + if (gst_caps_get_size(caps) > 0) { + if ((cap_struct = gst_caps_get_structure(caps, 0)) != NULL) { + name = gst_structure_get_name(cap_struct); + if (name) { + if (!strncmp(name, "audio", 5)) + (*p_has_audio) = TRUE; + else + if (!strncmp(name, "video", 5)) + (*p_has_video) = TRUE; + } + } + } + gst_caps_unref(caps); + } + gst_object_unref(pad); + } + gst_iterator_free(itr); + } +} + +static void link_to_sink(GstElement *decodebin2, AppState *app_state) { - gst_element_link(decodebin2, app_state->audio_sink); -#ifdef HAVE_VIDEO - gst_element_link(decodebin2, app_state->video_sink); -#endif /* HAVE_VIDEO */ + g_debug("link_to_sink: %s has finished pad creation\n", gst_element_get_name(decodebin2)); + g_object_set_data(G_OBJECT(decodebin2), "pad-creation-finished", GINT_TO_POINTER(1)); + + if (((!(app_state->video_src)) || GPOINTER_TO_INT(g_object_get_data(G_OBJECT(app_state->video_src), "pad-creation-finished"))) && + ((!(app_state->audio_src)) || GPOINTER_TO_INT(g_object_get_data(G_OBJECT(app_state->audio_src), "pad-creation-finished")))) { + gboolean video_has_video = FALSE, video_has_audio = FALSE, + audio_has_video = FALSE, audio_has_audio = FALSE; + + if (app_state->video_src) { + gst_element_get_has_audio_video(app_state->video_src, &video_has_audio, &video_has_video); + g_debug("link_to_sink: video_src A/V status: audio = %s, video = %s\n", video_has_audio ? "TRUE" : "FALSE", video_has_video ? "TRUE" : "FALSE"); + + if (video_has_video) { + g_debug("link_to_sink: Linking video_src to video_sink\n"); + gst_element_link(app_state->video_src, app_state->video_sink); + } + if (video_has_audio) { + g_debug("link_to_sink: Linking video_src to audio_sink\n"); + gst_element_link(app_state->video_src, app_state->audio_sink); + } + } + if (app_state->audio_src) { + gst_element_get_has_audio_video(app_state->audio_src, &audio_has_audio, &audio_has_video); + g_debug("link_to_sink: audio_src A/V status: audio = %s, video = %s\n", audio_has_audio ? "TRUE" : "FALSE", audio_has_video ? "TRUE" : "FALSE"); + + if (audio_has_video && !video_has_video) { + g_debug("link_to_sink: Linking audio_src to video_sink\n"); + gst_element_link(app_state->audio_src, app_state->video_sink); + } + if (audio_has_audio && !video_has_audio) { + g_debug("link_to_sink: Linking audio_src to audio_sink\n"); + gst_element_link(app_state->audio_src, app_state->audio_sink); + } + } + } } static GstElement * -create_bin(char *fname, AppState *app_state) +create_bin(char *video, char *audio, guint duration, AppState *app_state) { static int counter = 0; char *name = NULL; GstElement *bin, *filesrc, *decodebin2; + app_state->video_src = NULL; + app_state->audio_src = NULL; + name = g_strdup_printf("bin%d", counter++); bin = gst_bin_new(name); g_free(name); - filesrc = gst_element_factory_make("filesrc", NULL); - g_object_set(G_OBJECT(filesrc), "location", fname, NULL); - decodebin2 = gst_element_factory_make("decodebin2", NULL); - g_signal_connect(G_OBJECT(decodebin2), "no-more-pads", (GCallback)link_to_sink, app_state); - gst_bin_add_many(GST_BIN(bin), filesrc, decodebin2, NULL); - gst_element_link(filesrc, decodebin2); + if (video && video[0]) { + filesrc = gst_element_factory_make("filesrc", "video-src"); + g_object_set(G_OBJECT(filesrc), "location", video, NULL); + decodebin2 = gst_element_factory_make("decodebin", "video-decoded-src"); + g_signal_connect(G_OBJECT(decodebin2), "no-more-pads", (GCallback)link_to_sink, app_state); + gst_bin_add_many(GST_BIN(bin), filesrc, decodebin2, NULL); + gst_element_link(filesrc, decodebin2); + app_state->video_src = decodebin2; + } + if (audio && audio[0]) { + if (1 == strlen(audio) && 's' == audio[0]) { + filesrc = gst_element_factory_make("audiotestsrc", "audio-src"); + decodebin2 = gst_element_factory_make("volume", "audio-decoded-src"); + g_object_set(G_OBJECT(decodebin2), "volume", 0, NULL); + g_signal_connect(G_OBJECT(decodebin2), "no-more-pads", (GCallback)link_to_sink, app_state); + gst_bin_add_many(GST_BIN(bin), filesrc, decodebin2, NULL); + gst_element_link(filesrc, decodebin2); + } + else { + filesrc = gst_element_factory_make("filesrc", "audio-src"); + g_object_set(G_OBJECT(filesrc), "location", audio, NULL); + decodebin2 = gst_element_factory_make("decodebin", "audio-decoded-src"); + g_signal_connect(G_OBJECT(decodebin2), "no-more-pads", (GCallback)link_to_sink, app_state); + gst_bin_add_many(GST_BIN(bin), filesrc, decodebin2, NULL); + gst_element_link(filesrc, decodebin2); + } + app_state->audio_src = decodebin2; + } + return bin; } +static void +dump_error(GstMessage *msg) { + GError *err = NULL; + gchar *debug = NULL; + + gst_message_parse_error(msg, &err, &debug); + + if (err) { + g_debug("dump_error: error: %s, debug: %s\n", err->message ? err->message : "?", debug ? debug : "?"); + g_error_free(err); + err = NULL; + } + g_free(debug); + debug = NULL;; +} + static gboolean send_seek_event(GstElement *pipeline, const char *message, gboolean seek_sent) { @@ -77,11 +208,11 @@ } static void -play_file(GstElement *pipeline, char *file, AppState *app_state) +play_file(GstElement *pipeline, AppState *app_state, char *video, char *audio, guint duration) { GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); - g_debug("play_file: === Entering with \"%s\"\n", file); + g_debug("play_file: === Entering with (video = \"%s\", audio = \"%s\", duration = %d)\n", video, audio, duration); if (bus) { gboolean seek_sent = FALSE; @@ -89,10 +220,10 @@ GstMessage *msg = NULL; GstElement *new_bin = NULL; - new_bin = create_bin(file, app_state); + new_bin = create_bin(video, audio, duration, app_state); gst_bin_add(GST_BIN(pipeline), new_bin); gst_element_set_state(pipeline, GST_STATE_PAUSED); - seek_sent = send_seek_event(pipeline, "Before loop", seek_sent); +// seek_sent = send_seek_event(pipeline, "Before loop", seek_sent); gst_element_set_state(pipeline, GST_STATE_PLAYING); g_debug("play_file: Entering loop\n"); @@ -102,35 +233,40 @@ if (!msg) break; switch (GST_MESSAGE_TYPE(msg)) { - case GST_MESSAGE_ERROR: + case GST_MESSAGE_ASYNC_DONE: + seek_sent = send_seek_event(pipeline, "ASYNC_DONE", seek_sent); + break; + + case GST_MESSAGE_STATE_CHANGED: + if (GST_OBJECT(pipeline) == GST_MESSAGE_SRC(msg)) { - GError *err = NULL; - gchar *debug = NULL; + GstState oldstate, newstate, pending; + gst_message_parse_state_changed(msg, &oldstate, &newstate, &pending); + g_debug("play_file: %s state-changed: old = %s, new = %s, pending = %s\n", + gst_element_get_name(GST_ELEMENT(GST_MESSAGE_SRC(msg))), + gst_element_state_get_name(oldstate), + gst_element_state_get_name(newstate), + gst_element_state_get_name(pending)); + } + break; - gst_message_parse_error(msg, &err, &debug); - - if (err) { - g_debug("play_file: error: %s, debug: %s\n", err->message ? err->message : "?", debug ? debug : "?"); - g_error_free(err); - err = NULL; - } - g_free(debug); - debug = NULL;; - } + case GST_MESSAGE_ERROR: + dump_error(msg); + GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "sequence-player"); /* fall through */ case GST_MESSAGE_EOS: case GST_MESSAGE_SEGMENT_DONE: g_debug("play_file: %s\n", GST_MESSAGE_TYPE_NAME(msg)); keep_looping = FALSE; break; -#ifdef HAVE_VIDEO +#ifdef GET_WINDOW case GST_MESSAGE_ELEMENT: if (gst_structure_has_name(msg->structure, "prepare-xwindow-id")) { g_debug("play_file: Setting destination window\n"); gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(GST_MESSAGE_SRC(msg)), app_state->dst_window); } break; -#endif /* HAVE_VIDEO */ +#endif /* GET_WINDOW */ default: break; } @@ -138,8 +274,11 @@ gst_message_unref(msg); } + + g_debug("play_file: Removing bin from pipeline\n"); gst_element_set_state(new_bin, GST_STATE_NULL); gst_bin_remove(GST_BIN(pipeline), new_bin); + g_debug("play_file: Removed bin from pipeline\n"); /* Flush the bus before unrefing */ gst_bus_set_flushing(bus, TRUE); @@ -147,12 +286,12 @@ gst_object_unref(bus); } - g_debug("play_file: === Exiting with \"%s\"\n", file); + g_debug("play_file: === Exiting with (video = \"%s\", audio = \"%s\", duration = %d)\n", video, audio, duration); } -#ifdef HAVE_VIDEO void grab_dst_window(AppState *app_state) { +#ifdef GET_WINDOW app_state->display = XOpenDisplay(NULL); if (app_state->display) { app_state->dst_window = DefaultRootWindow(app_state->display); @@ -162,17 +301,19 @@ app_state->dst_window = app_state->overlay_window; } } +#endif /* GET_WINDOW */ } void release_dst_window(AppState *app_state) { +#ifdef GET_WINDOW if (app_state->overlay_window) XCompositeReleaseOverlayWindow(app_state->display, app_state->overlay_window); if (app_state->display) XCloseDisplay(app_state->display); +#endif /* GET_WINDOW */ } -#endif /* HAVE_VIDEO */ int main(int argc, char **argv) { @@ -182,30 +323,23 @@ gst_init(&argc, &argv); -#ifdef HAVE_VIDEO - g_debug("HAVE VIDEO!\n"); -#else /* !HAVE_VIDEO */ - g_debug("NO VIDEO!\n"); -#endif /* HAVE_VIDEO */ + g_log_set_default_handler(my_log_func, NULL); if (argc > 1) if ((pipeline = gst_pipeline_new("sequence-player"))) { app_state.audio_sink = gst_element_factory_make("autoaudiosink", NULL); gst_bin_add(GST_BIN(pipeline), app_state.audio_sink); -#ifdef HAVE_VIDEO app_state.video_sink = gst_element_factory_make("autovideosink", NULL); gst_bin_add(GST_BIN(pipeline), app_state.video_sink); grab_dst_window(&app_state); -#endif /* HAVE_VIDEO */ - for (Nix = 1 ; Nix < argc ; Nix++) - play_file(pipeline, argv[Nix], &app_state); + + for (Nix = 1 ; Nix < argc ; Nix += 3) + play_file(pipeline, &app_state, argv[Nix], argv[Nix + 1], atoi(argv[Nix + 2])); gst_element_set_state(pipeline, GST_STATE_NULL); gst_object_unref(pipeline); -#ifdef HAVE_VIDEO release_dst_window(&app_state); -#endif /* HAVE_VIDEO */ } gst_deinit();
- Previous message: [maemo-commits] r18073 - in projects/haf/trunk/clutter0.8: clutter/x11 debian
- Next message: [maemo-commits] r18075 - projects/haf/trunk/hildon-welcome/src
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]