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]

Reply via email to