Zeeshan Ali Khattak wrote: > Hi all! > After I was told about the existence of ClutterGstVideoSink in > reply to my blog entry [1] regarding my little experiment, I spent a > few hours trying to use the sink in my app. but so far no luck. I > don't even get the static image now. I am attaching the latest source > here, if anyone can point out what I am missing here, I'll appreciate > that. Also a hint regarding why my original application didn't work > would be greatly appreciated.
There is a simple ready-made video-actor in toys/table; iirc, you run into all kinds of problems when you try to manipulate the gst texture before it starts playing, notably, you have to make the gst texture play at least briefly before you can call clutter_actor_show(). Tomas > > [1] http://zee-nix.blogspot.com/2007/11/playing-video-on-cluttertexture.html > > > > ------------------------------------------------------------------------ > > /* super-video.c > * > * A modification of super-oh example application that displays video from > * videotestsrc element of gstreamer, instead of hands. > * > * Copyright (C) 2007 Zeeshan Ali Khattak <[EMAIL PROTECTED]> > * Copyright (C) 2006 OpenedHand > * > */ > > #include <clutter-gst/clutter-gst.h> > #include <gst/video/video.h> > #include <string.h> > > #include <math.h> > #include <errno.h> > #include <stdlib.h> > #include <glib.h> > > #define VIDEO_WIDTH 320 > #define VIDEO_HEIGHT 280 > > #define NHANDS 6 > > typedef struct SuperVideo > { > ClutterActor **hand; > ClutterActor *group; > > GstElement *pipeline; > GstElement *source, *sink; > GstElement *colorspace; > > gboolean size_set; > } SuperVideo; > > static gint n_hands = NHANDS; > > static GOptionEntry super_video_entries[] = { > { > "num-hands", 'n', > 0, > G_OPTION_ARG_INT, &n_hands, > "Number of hands", "HANDS" > }, > { NULL } > }; > > static gint > get_radius (void) > { > return (CLUTTER_STAGE_HEIGHT() + CLUTTER_STAGE_HEIGHT()) / n_hands; > } > > void > size_change (ClutterTexture *texture, > gint width, > gint height, > gpointer user_data) > { > SuperVideo *video = (SuperVideo *) user_data; > gint new_width, new_height; > gint i; > > new_height = ( height * CLUTTER_STAGE_WIDTH() ) / width; > if (new_height <= CLUTTER_STAGE_HEIGHT()) { > new_width = CLUTTER_STAGE_WIDTH(); > } else { > new_width = ( width * CLUTTER_STAGE_HEIGHT() ) / height; > new_height = CLUTTER_STAGE_HEIGHT(); > } > > for (i = 0; i < n_hands; i++) { > gint x, y; > gint radius = get_radius (); > > /* Place around a circle */ > x = CLUTTER_STAGE_WIDTH () / 2 > + radius > * cos (i * M_PI / (n_hands / 2)) > - new_width / 2; > y = CLUTTER_STAGE_HEIGHT () / 2 > + radius > * sin (i * M_PI / (n_hands / 2)) > - new_height / 2; > > clutter_actor_set_position (video->hand[i], x, y); > } > > video->size_set = TRUE; > } > > static gboolean > bus_call (GstBus * bus, GstMessage * msg, gpointer data) > { > switch (GST_MESSAGE_TYPE (msg)) { > case GST_MESSAGE_ERROR: > { > gchar *debug; > GError *err; > > gst_message_parse_error (msg, &err, &debug); > g_free (debug); > > g_print ("Error: %s\n", err->message); > g_error_free (err); > > clutter_main_quit (); > break; > } > default: > break; > } > > return TRUE; > } > > /* input handler */ > void > input_cb (ClutterStage *stage, > ClutterEvent *event, > gpointer data) > { > if (event->type == CLUTTER_BUTTON_PRESS) { > ClutterButtonEvent *button_event; > ClutterActor *e; > gint x, y; > > clutter_event_get_coords (event, &x, &y); > > button_event = (ClutterButtonEvent *) event; > g_print ("*** button press event (button:%d) ***\n", > button_event->button); > > e = clutter_stage_get_actor_at_pos (stage, x, y); > > if (e) > clutter_actor_hide (e); > > } else if (event->type == CLUTTER_KEY_RELEASE) { > ClutterKeyEvent *kev = (ClutterKeyEvent *) event; > > g_print ("*** key press event (key:%c) ***\n", > clutter_key_event_symbol (kev)); > > if (clutter_key_event_symbol (kev) == CLUTTER_q) > clutter_main_quit (); > } > } > > > /* Timeline handler */ > void > frame_cb (ClutterTimeline *timeline, > gint frame_num, > gpointer data) > { > SuperVideo *video = (SuperVideo *) data; > gint i; > > if (!video->size_set) > return; > > /* Rotate everything clockwise about stage center*/ > clutter_actor_rotate_z (CLUTTER_ACTOR (video->group), > frame_num, > CLUTTER_STAGE_WIDTH() / 2, > CLUTTER_STAGE_HEIGHT() / 2); > > for (i = 0; i < n_hands; i++) { > gdouble scale_x, scale_y; > > clutter_actor_get_scale (video->hand[i], &scale_x, &scale_y); > > /* Rotate each hand around there centers - to get this we need > * to take into account any scaling. > */ > clutter_actor_rotate_z > (video->hand[i], > - 6.0 * frame_num, > (clutter_actor_get_width (video->hand[i]) / 2), > (clutter_actor_get_height (video->hand[i]) / 2)); > } > } > > int > main (int argc, char *argv[]) > { > ClutterTimeline *timeline; > ClutterActor *stage; > ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff }; > SuperVideo *video; > GstBus *bus; > GstCaps *caps; > gint i; > GError *error; > > error = NULL; > > /* initialize GStreamer */ > gst_init (&argc, &argv); > > clutter_init_with_args (&argc, &argv, > NULL, > super_video_entries, > NULL, > &error); > if (error) { > g_warning ("Unable to initialise Clutter:\n%s", > error->message); > g_error_free (error); > > exit (1); > } > > stage = clutter_stage_get_default (); > clutter_actor_set_size (stage, 800, 600); > > clutter_stage_set_color (CLUTTER_STAGE (stage), > &stage_color); > > video = g_new0 (SuperVideo, 1); > > /* Create a timeline to manage animation */ > timeline = clutter_timeline_new (360, 60); /* num frames, fps */ > g_object_set (timeline, "loop", TRUE, NULL); /* have it loop */ > > /* fire a callback for frame change */ > g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), > video); > > /* create a new group to hold multiple actors in a group */ > video->group = clutter_group_new (); > > video->hand = g_new (ClutterActor*, n_hands); > for (i = 0; i < n_hands; i++) > { > if (i == 0) { > video->hand[i] = g_object_new (CLUTTER_TYPE_TEXTURE, > "sync-size", FALSE, > "tiled", FALSE, > NULL); > > g_signal_connect (video->hand[i], > "size-change", > G_CALLBACK (size_change), > video); > } else { > video->hand[i] = > clutter_clone_texture_new > (CLUTTER_TEXTURE(video->hand[0])); > } > > /* Add to our group group */ > clutter_container_add_actor (CLUTTER_CONTAINER (video->group), > video->hand[i]); > } > > /* create elements */ > video->pipeline = gst_pipeline_new ("super-video"); > video->source = gst_element_factory_make ("videotestsrc", NULL); > video->colorspace = gst_element_factory_make ("ffmpegcolorspace", > NULL); > video->sink = clutter_gst_video_sink_new > (CLUTTER_TEXTURE (video->hand[0])); > > if (!video->pipeline || !video->source ||!video->sink) { > g_print ("One element could not be created\n"); > return -1; > } > > bus = gst_pipeline_get_bus (GST_PIPELINE (video->pipeline)); > gst_bus_add_watch (bus, bus_call, NULL); > gst_object_unref (bus); > > /* put all elements in a bin */ > gst_bin_add_many (GST_BIN (video->pipeline), > video->source, > video->sink, > video->colorspace, > NULL); > > g_assert (gst_element_link_many (video->source, > video->colorspace, > video->sink, > NULL)); > > /* Now set to playing and iterate. */ > gst_element_set_state (video->pipeline, GST_STATE_PLAYING); > > /* and start it */ > clutter_timeline_start (timeline); > > clutter_actor_show_all (video->group); > > /* Add the group to the stage */ > clutter_container_add_actor (CLUTTER_CONTAINER (stage), > CLUTTER_ACTOR (video->group)); > > /* Show everying ( and map window ) */ > clutter_actor_show_all (stage); > > g_signal_connect (stage, "button-press-event", > G_CALLBACK (input_cb), > video); > g_signal_connect (stage, "key-release-event", > G_CALLBACK (input_cb), > video); > > clutter_main (); > > gst_element_set_state (video->pipeline, GST_STATE_NULL); > gst_object_unref (GST_OBJECT (video->pipeline)); > > g_free (video->hand); > g_free (video); > > return 0; > } > -- To unsubscribe send a mail to [EMAIL PROTECTED]
