[maemo-commits] [maemo-commits] r18082 - projects/haf/trunk/hildon-welcome/src
From: subversion at stage.maemo.org subversion at stage.maemo.orgDate: Thu Apr 16 15:14:51 EEST 2009
- Previous message: [maemo-commits] r18081 - projects/haf/tags/posix-locales
- Next message: [maemo-commits] r18083 - projects/haf/trunk/dbus-glib/debian/patches
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Author: schulhof
Date: 2009-04-16 15:14:50 +0300 (Thu, 16 Apr 2009)
New Revision: 18082
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 12:06:07 UTC (rev 18081)
+++ projects/haf/trunk/hildon-welcome/src/tmp.c 2009-04-16 12:14:50 UTC (rev 18082)
@@ -1,3 +1,4 @@
+#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <gst/gst.h>
@@ -9,8 +10,10 @@
#define GET_WINDOW
#define APP_STATE_STATIC_INIT { \
+ .pipeline = NULL, \
+ .bin = NULL, \
+ .audio_src = NULL, \
.video_src = NULL, \
- .audio_src = NULL, \
.audio_sink = NULL, \
.video_sink = NULL, \
.dst_window = 0, \
@@ -23,8 +26,10 @@
#include <X11/extensions/Xcomposite.h>
typedef struct {
+ GstElement *pipeline;
+ GstElement *bin;
+ GstElement *audio_src;
GstElement *video_src;
- GstElement *audio_src;
GstElement *audio_sink;
GstElement *video_sink;
Window dst_window;
@@ -32,6 +37,8 @@
Display *display;
} AppState;
+static void gst_element_has_src_pad(GstElement *element, ...) G_GNUC_NULL_TERMINATED;
+
static void
my_log_func(const gchar *log_domain, GLogLevelFlags log_level, const char *message, gpointer null)
{
@@ -46,30 +53,33 @@
g_free(new_msg);
}
+/*
+ * gst_element_has_src_pad(element, "cap1", &gboolean, ..., "capn", &gboolean, NULL);
+ */
static void
-gst_element_get_has_audio_video(GstElement *src, gboolean *p_has_audio, gboolean *p_has_video)
+gst_element_has_src_pad(GstElement *element, ...)
{
GstIterator *itr = NULL;
GstPad *pad = NULL;
GstCaps *caps = NULL;
GstStructure *cap_struct = NULL;
- const char *name = NULL;
+ const char *name = NULL, *wanted = NULL;
+ gboolean *p_bwanted = NULL;
+ va_list va;
- (*p_has_audio) = FALSE;
- (*p_has_video) = FALSE;
-
- if ((itr = gst_element_iterate_src_pads(src)) != NULL) {
+ if ((itr = gst_element_iterate_src_pads(element)) != 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;
+ g_debug("gst_element_has_src_pad: Found cap %s.%s.cap-name = %s\n", gst_element_get_name(element), gst_pad_get_name(pad), name);
+ va_start(va, element);
+ for (wanted = va_arg(va, const char *) ; wanted != NULL ; wanted = va_arg(va, const char *)) {
+ p_bwanted = va_arg(va, gboolean *);
+ (*p_bwanted) = (*p_bwanted) || !strncmp(name, wanted, strlen(wanted));
+ }
}
}
}
@@ -81,7 +91,83 @@
}
}
+static GstElement *
+find_typefind(GstElement *element)
+{
+ GstElement *typefind = strcmp(g_type_name(G_TYPE_FROM_INSTANCE(element)), "GstTypeFindElement") ? NULL : element;
+
+ if (!typefind && GST_IS_BIN(element)) {
+ GstIterator *itr = gst_bin_iterate_recurse(GST_BIN(element));
+
+ while ((GST_ITERATOR_OK == gst_iterator_next(itr, ((gpointer *)(&element)))) && NULL == typefind) {
+ if (!strcmp(g_type_name(G_TYPE_FROM_INSTANCE(element)), "GstTypeFindElement"))
+ typefind = element;
+ gst_object_unref(element);
+ }
+ }
+
+ return typefind;
+}
+
+static GstElement *
+maybe_add_freeze(GstBin *bin, GstElement *src)
+{
+ GstElement *ret = src;
+ GstElement *typefind = NULL;
+
+ typefind = find_typefind(src);
+
+ if (typefind) {
+ gboolean is_image = FALSE;
+
+ g_debug("maybe_add_freeze: checking typefind (0x%x)\n", ((int)(typefind)));
+
+ gst_element_has_src_pad(typefind, "image", &is_image, NULL);
+
+ if (is_image) {
+ ret = gst_element_factory_make("freeze", NULL);
+ g_debug("link_to_sink: Shoving freeze after video_src\n");
+ gst_bin_add(bin, ret);
+ gst_element_link(src, ret);
+ }
+ }
+
+ return ret;
+}
+
static void
+do_one_link(GstBin *bin, GstElement *src, gboolean *p_had_audio, gboolean *p_had_video, GstElement *audio_sink, GstElement *video_sink)
+{
+ gboolean src_has_audio = FALSE, src_has_video = FALSE;
+ gst_element_has_src_pad(src, "audio", &src_has_audio, "video", &src_has_video, NULL);
+
+ g_debug("do_one_link: %s A/V status: audio = %s, video = %s\n",
+ gst_element_get_name(src),
+ src_has_audio ? "TRUE" : "FALSE",
+ src_has_video ? "TRUE" : "FALSE");
+
+ if (src_has_video && !(*p_had_video)) {
+ GstElement *real_src = maybe_add_freeze(bin, src);
+
+ if (gst_element_link(real_src, video_sink)) {
+ g_debug("do_one_link: Linked %s to %s\n", gst_element_get_name(real_src), gst_element_get_name(video_sink));
+ (*p_had_video) = TRUE;
+ }
+ else
+ g_debug("do_one_link: Failed to link %s to %s\n", gst_element_get_name(real_src), gst_element_get_name(video_sink));
+ }
+
+ if (src_has_audio && !(*p_had_audio)) {
+ if (gst_element_link(src, audio_sink)) {
+ g_debug("do_one_link: Linked %s to %s\n", gst_element_get_name(src), gst_element_get_name(video_sink));
+ (*p_had_audio) = TRUE;
+ }
+ else
+ g_debug("do_one_link: Failed to link %s to %s\n", gst_element_get_name(src), gst_element_get_name(video_sink));
+ }
+}
+
+static void
link_to_sink(GstElement *decodebin2, AppState *app_state)
{
g_debug("link_to_sink: %s has finished pad creation\n", gst_element_get_name(decodebin2));
@@ -89,83 +175,67 @@
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;
+ gboolean had_audio = FALSE, had_video = 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 (app_state->video_src)
+ do_one_link(GST_BIN(app_state->bin), app_state->video_src, &had_audio, &had_video, app_state->audio_sink, app_state->video_sink);
- 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);
- }
- }
+ if (app_state->audio_src)
+ do_one_link(GST_BIN(app_state->bin), app_state->audio_src, &had_audio, &had_video, app_state->audio_sink, app_state->video_sink);
}
}
static GstElement *
+add_file_play_element(GstBin *bin, char *fname, AppState *app_state, const char *name_prefix)
+{
+ char *str = NULL;
+ GstElement *filesrc, *decodebin2;
+
+ filesrc = gst_element_factory_make("filesrc", str = g_strdup_printf("%s-filesrc", name_prefix));
+ g_free(str);
+ g_object_set(G_OBJECT(filesrc), "location", fname, NULL);
+ decodebin2 = gst_element_factory_make("decodebin", str = g_strdup_printf("%s-decodebin", name_prefix));
+ g_free(str);
+ 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);
+
+ return decodebin2;
+}
+
+static GstElement *
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;
+ app_state->bin = NULL;
name = g_strdup_printf("bin%d", counter++);
- bin = gst_bin_new(name);
+ app_state->bin = gst_bin_new(name);
g_free(name);
- 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 (video && video[0])
+ app_state->video_src = add_file_play_element(GST_BIN(app_state->bin), video, app_state, "video");
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);
+ GstElement *testsrc, *volume;
+ testsrc = gst_element_factory_make("audiotestsrc", "audio-src");
+ volume = gst_element_factory_make("volume", "audio-decoded-src");
+ g_object_set(G_OBJECT(volume), "volume", 0, NULL);
+ g_signal_connect(G_OBJECT(volume), "no-more-pads", (GCallback)link_to_sink, app_state);
+ gst_bin_add_many(GST_BIN(app_state->bin), testsrc, volume, NULL);
+ gst_element_link(testsrc, volume);
+ app_state->audio_src = volume;
}
- 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;
+ else
+ app_state->audio_src = add_file_play_element(GST_BIN(app_state->bin), audio, app_state, "audio");
}
- return bin;
+ return app_state->bin;
}
static void
@@ -189,7 +259,7 @@
{
if (!seek_sent) {
- g_debug("%s: About to send seek\n", message);
+ g_debug("send_seek_event: %s: About to send seek\n", message);
seek_sent = gst_element_send_event(pipeline,
gst_event_new_seek(1.0, GST_FORMAT_TIME,
@@ -197,20 +267,20 @@
GST_SEEK_TYPE_SET, G_GUINT64_CONSTANT(0),
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE));
- g_debug("%s: Sending seek %s\n", message, seek_sent ? "SUCCEEDED" : "FAILED");
+ g_debug("send_seek_event: %s: Sending seek %s\n", message, seek_sent ? "SUCCEEDED" : "FAILED");
return seek_sent;
}
else
- g_debug("%s: Already sent seek\n", message);
+ g_debug("send_seek_event: %s: Already sent seek\n", message);
return TRUE;
}
static void
-play_file(GstElement *pipeline, AppState *app_state, char *video, char *audio, guint duration)
+play_file(AppState *app_state, char *video, char *audio, guint duration)
{
- GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
+ GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(app_state->pipeline));
g_debug("play_file: === Entering with (video = \"%s\", audio = \"%s\", duration = %d)\n", video, audio, duration);
@@ -221,10 +291,10 @@
GstElement *new_bin = NULL;
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);
- gst_element_set_state(pipeline, GST_STATE_PLAYING);
+ gst_bin_add(GST_BIN(app_state->pipeline), new_bin);
+ gst_element_set_state(app_state->pipeline, GST_STATE_PAUSED);
+// seek_sent = send_seek_event(app_state->pipeline, "Before loop", seek_sent);
+ gst_element_set_state(app_state->pipeline, GST_STATE_PLAYING);
g_debug("play_file: Entering loop\n");
@@ -234,11 +304,11 @@
switch (GST_MESSAGE_TYPE(msg)) {
case GST_MESSAGE_ASYNC_DONE:
- seek_sent = send_seek_event(pipeline, "ASYNC_DONE", seek_sent);
+ seek_sent = send_seek_event(app_state->pipeline, "ASYNC_DONE", seek_sent);
break;
case GST_MESSAGE_STATE_CHANGED:
- if (GST_OBJECT(pipeline) == GST_MESSAGE_SRC(msg))
+ if (GST_OBJECT(app_state->pipeline) == GST_MESSAGE_SRC(msg))
{
GstState oldstate, newstate, pending;
gst_message_parse_state_changed(msg, &oldstate, &newstate, &pending);
@@ -252,9 +322,7 @@
case GST_MESSAGE_ERROR:
dump_error(msg);
-
- GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "sequence-player");
-
+ GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(app_state->pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "sequence-player");
/* fall through */
case GST_MESSAGE_EOS:
case GST_MESSAGE_SEGMENT_DONE:
@@ -279,7 +347,7 @@
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);
+ gst_bin_remove(GST_BIN(app_state->pipeline), new_bin);
g_debug("play_file: Removed bin from pipeline\n");
/* Flush the bus before unrefing */
@@ -321,25 +389,24 @@
{
int Nix;
AppState app_state = APP_STATE_STATIC_INIT;
- GstElement *pipeline = NULL;
gst_init(&argc, &argv);
g_log_set_default_handler(my_log_func, NULL);
if (argc > 1)
- if ((pipeline = gst_pipeline_new("sequence-player"))) {
+ if ((app_state.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);
+ gst_bin_add(GST_BIN(app_state.pipeline), app_state.audio_sink);
app_state.video_sink = gst_element_factory_make("autovideosink", NULL);
- gst_bin_add(GST_BIN(pipeline), app_state.video_sink);
+ gst_bin_add(GST_BIN(app_state.pipeline), app_state.video_sink);
grab_dst_window(&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);
+ play_file(&app_state, argv[Nix], argv[Nix + 1], atoi(argv[Nix + 2]));
+ gst_element_set_state(app_state.pipeline, GST_STATE_NULL);
+ gst_object_unref(app_state.pipeline);
release_dst_window(&app_state);
}
- Previous message: [maemo-commits] r18081 - projects/haf/tags/posix-locales
- Next message: [maemo-commits] r18083 - projects/haf/trunk/dbus-glib/debian/patches
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
