Hello everyone !<br><br>I&#39;m trying to develop an image-processing application for the nokia N810 using gstreamer. I have made the structure of this application using an example which display the image of the camera on the screen.<br>


<br>I tweaked a bit this code for my need, and it is working, I can actually display the picture from the camera, start/stop the media pipeline... But I don&#39;t find where to put the image processing code (which is working alone on the nokia).<br>


<br>What I want is that when the program receive a frame from the camera, it has to do some calculation with the current frame buffer, and during these calculations, I&#39;d like it to ignore the other frame coming from the camera. (I don&#39;t think that the processor will be able to handle realtime processing).<br>


When the calculation is done, it should start again with the next coming frame.<br><br>I managed to do it, but I had to press a button each time I wanted to process a frame. I&#39;d like the program to do it continuously.<br>


<br>Here is my code :<br><br><br><br>#define VIDEO_SRC &quot;v4l2src&quot;<br>#define VIDEO_SINK &quot;xvimagesink&quot;<br><br><br><br>typedef struct<br>{<br>&nbsp;&nbsp;&nbsp; HildonProgram *program;<br>&nbsp;&nbsp;&nbsp; HildonWindow *window;<br><br>

&nbsp;&nbsp;&nbsp; GstElement *pipeline;<br>&nbsp;&nbsp;&nbsp; GtkWidget *screen;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; guint buffer_cb_id;<br>} AppData;<br><br><br><br><br>
/* Callback that gets called when user clicks the &quot;START/STOP&quot; button */<br>static void button1_pressed(GtkWidget *widget,AppData *appdata)<br>{<br>&nbsp;&nbsp;&nbsp; if (GTK_TOGGLE_BUTTON(widget)-&gt;active) <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Display a note to the user */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Running ...&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gst_element_set_state(appdata-&gt;pipeline, GST_STATE_PLAYING);<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Display a note to the user */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Stopped ...&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gst_element_set_state(appdata-&gt;pipeline, GST_STATE_PAUSED);&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>}<br><br><br><br><br>/* Callback that gets called when user clicks the &quot;Expression ON/OFF&quot; button */<br>static void button2_pressed(GtkWidget *widget, AppData *appdata)<br>{<br>&nbsp;&nbsp;&nbsp; if (GTK_TOGGLE_BUTTON(widget)-&gt;active) <br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Display a note to the user */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Expressions ON&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; else<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Display a note to the user */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Expressions OFF&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>}<br><br><br>

<br>
<br><br><br><br><br><br><br>/* Callback that gets called whenever pipeline&#39;s message bus has<br>&nbsp;* a message */<br>static void bus_callback(GstBus *bus, GstMessage *message, AppData *appdata)<br>{<br>&nbsp;&nbsp;&nbsp; gchar *message_str;<br>


&nbsp;&nbsp;&nbsp; const gchar *message_name;<br>&nbsp;&nbsp;&nbsp; GError *error;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; /* Report errors to the console */<br>&nbsp;&nbsp;&nbsp; if(GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR)<br>&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gst_message_parse_error(message, &amp;error, &amp;message_str);<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g_error(&quot;GST error: %s\n&quot;, message_str);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g_free(error);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g_free(message_str);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; /* Report warnings to the console */<br>&nbsp;&nbsp;&nbsp; if(GST_MESSAGE_TYPE(message) == GST_MESSAGE_WARNING)<br>


&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; gst_message_parse_warning(message, &amp;error, &amp;message_str);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g_warning(&quot;GST warning: %s\n&quot;, message_str);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g_free(error);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g_free(message_str);<br>&nbsp;&nbsp;&nbsp; }<br>


<br>&nbsp;&nbsp;&nbsp; /* See if the message type is GST_MESSAGE_APPLICATION which means<br>&nbsp;&nbsp;&nbsp; &nbsp;* thet the message is sent by the client code (this program) and<br>&nbsp;&nbsp;&nbsp; &nbsp;* not by gstreamer. */<br>&nbsp;&nbsp;&nbsp; if(GST_MESSAGE_TYPE(message) == GST_MESSAGE_APPLICATION)<br>


&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Get name of the message&#39;s structure */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; message_name = gst_structure_get_name(gst_message_get_structure(message));<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* The hildon banner must be shown in here, because the bus callback is<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* called in the main thread and calling GUI-functions in gstreamer threads<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;* usually leads to problems with X-server */<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!strcmp(message_name, &quot;anger&quot;))<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Anger&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!strcmp(message_name, &quot;disgust&quot;))<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Disgust&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!strcmp(message_name, &quot;fear&quot;))<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Fear&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!strcmp(message_name, &quot;happy&quot;))<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Happy&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!strcmp(message_name, &quot;neutral&quot;))<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Neutral&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!strcmp(message_name, &quot;sad&quot;))<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Sad&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!strcmp(message_name, &quot;surprise&quot;))<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Surprise&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if(!strcmp(message_name, &quot;unknown&quot;))<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata-&gt;window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL, &quot;Unknown !&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>}<br><br><br><br>


<br><br><br><br><br><br><br>/* Callback to be called when the screen-widget is exposed */<br>static gboolean expose_cb(GtkWidget * widget, GdkEventExpose * event, gpointer data)<br>{<br>&nbsp;&nbsp;&nbsp; /* Tell the xvimagesink/ximagesink the x-window-id of the screen<br>


&nbsp;&nbsp;&nbsp; &nbsp;* widget in which the video is shown. After this the video<br>&nbsp;&nbsp;&nbsp; &nbsp;* is shown in the correct widget */<br>&nbsp;&nbsp;&nbsp; gst_x_overlay_set_xwindow_id(GST_X_OVERLAY(data),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; GDK_WINDOW_XWINDOW(widget-&gt;window));<br>


&nbsp;&nbsp;&nbsp; return FALSE;<br>}<br><br><br><br><br><br><br><br>/* Initialize the the Gstreamer pipeline. Below is a diagram<br>&nbsp;* of the pipeline that will be created:<br>&nbsp;* <br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -<br>


&nbsp;* |Camera|&nbsp; |CSP&nbsp;&nbsp; |&nbsp; |Screen|&nbsp; |Screen|&nbsp;&nbsp; |Image&nbsp;&nbsp;&nbsp;&nbsp; |<br>&nbsp;* |src&nbsp;&nbsp; |-&gt;|Filter|-&gt;|queue |-&gt;|sink&nbsp; |-&gt; |processing|-&gt;&nbsp; Display<br>&nbsp;*/<br>static gboolean initialize_pipeline(AppData *appdata,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; int *argc, char ***argv)<br>


{<br>&nbsp;&nbsp;&nbsp; GstElement *pipeline, *camera_src, *screen_sink;<br>&nbsp;&nbsp;&nbsp; GstElement *screen_queue;<br>&nbsp;&nbsp;&nbsp; GstElement *csp_filter;<br>&nbsp;&nbsp;&nbsp; GstCaps *caps;<br>&nbsp;&nbsp;&nbsp; GstBus *bus;<br><br><br>&nbsp;&nbsp;&nbsp; /* Initialize Gstreamer */<br>&nbsp;&nbsp;&nbsp; gst_init(argc, argv);<br>


&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; /* Create pipeline and attach a callback to it&#39;s<br>&nbsp;&nbsp;&nbsp; &nbsp;* message bus */<br>&nbsp;&nbsp;&nbsp; pipeline = gst_pipeline_new(&quot;test-camera&quot;);<br><br>&nbsp;&nbsp;&nbsp; bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));<br>&nbsp;&nbsp;&nbsp; gst_bus_add_watch(bus, (GstBusFunc)bus_callback, appdata);<br>


&nbsp;&nbsp;&nbsp; gst_object_unref(GST_OBJECT(bus));<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; /* Save pipeline to the AppData structure */<br>&nbsp;&nbsp;&nbsp; appdata-&gt;pipeline = pipeline;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; /* Create elements */<br>&nbsp;&nbsp;&nbsp; /* Camera video stream comes from a Video4Linux driver */<br>


&nbsp;&nbsp;&nbsp; camera_src = gst_element_factory_make(VIDEO_SRC, &quot;camera_src&quot;);<br>&nbsp;&nbsp;&nbsp; /* Colorspace filter is needed to make sure that sinks understands<br>&nbsp;&nbsp;&nbsp; &nbsp;* the stream coming from the camera */<br>&nbsp;&nbsp;&nbsp; csp_filter = gst_element_factory_make(&quot;ffmpegcolorspace&quot;, &quot;csp_filter&quot;);<br>


&nbsp;&nbsp;&nbsp; /* Queue creates new thread for the stream */<br>&nbsp;&nbsp;&nbsp; screen_queue = gst_element_factory_make(&quot;queue&quot;, &quot;screen_queue&quot;);<br>&nbsp;&nbsp;&nbsp; /* Sink that shows the image on screen. Xephyr doesn&#39;t support XVideo<br>


&nbsp;&nbsp;&nbsp; &nbsp;* extension, so it needs to use ximagesink, but the device uses<br>&nbsp;&nbsp;&nbsp; &nbsp;* xvimagesink */<br>&nbsp;&nbsp;&nbsp; screen_sink = gst_element_factory_make(VIDEO_SINK, &quot;screen_sink&quot;);<br><br><br>&nbsp;&nbsp;&nbsp; /* Check that elements are correctly initialized */<br>


&nbsp;&nbsp;&nbsp; if(!(pipeline &amp;&amp; camera_src &amp;&amp; screen_sink &amp;&amp; csp_filter &amp;&amp; screen_queue))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; g_critical(&quot;Couldn&#39;t create pipeline elements&quot;);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return FALSE;<br>


&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; /* Add elements to the pipeline. This has to be done prior to<br>&nbsp;&nbsp;&nbsp; &nbsp;* linking them */<br>&nbsp;&nbsp;&nbsp; gst_bin_add_many(GST_BIN(pipeline), camera_src, csp_filter,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; screen_queue, screen_sink, NULL);<br>


&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; /* Specify what kind of video is wanted from the camera */<br>&nbsp;&nbsp;&nbsp; caps = gst_caps_new_simple(&quot;video/x-raw-rgb&quot;,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &quot;width&quot;, G_TYPE_INT, 640,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &quot;height&quot;, G_TYPE_INT, 480,<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &quot;framerate&quot;, GST_TYPE_FRACTION, 25, 1,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; NULL);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br><br>&nbsp;&nbsp;&nbsp; /* Link the camera source and colorspace filter using capabilities<br>&nbsp;&nbsp;&nbsp; &nbsp;* specified */<br>&nbsp;&nbsp;&nbsp; if(!gst_element_link_filtered(camera_src, csp_filter, caps))<br>


&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return FALSE;<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; gst_caps_unref(caps);<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; /* Connect Colorspace Filter -&gt; Screen Queue -&gt; Screen Sink<br>&nbsp;&nbsp;&nbsp; &nbsp;* This finalizes the initialization of the screen-part of the pipeline */<br>


&nbsp;&nbsp;&nbsp; if(!gst_element_link_many(csp_filter, screen_queue, screen_sink, NULL))<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return FALSE;<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; /* As soon as screen is exposed, window ID will be advised to the sink */<br>&nbsp;&nbsp;&nbsp; g_signal_connect(appdata-&gt;screen, &quot;expose-event&quot;, G_CALLBACK(expose_cb),<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;screen_sink);<br>&nbsp;&nbsp;&nbsp; <br><br><br>&nbsp;&nbsp;&nbsp; gst_element_set_state(pipeline, GST_STATE_PAUSED);&nbsp;&nbsp;&nbsp; <br><br>&nbsp;&nbsp;&nbsp; return TRUE;<br>}<br><br><br><br><br><br><br><br><br><br><br><br>/* Destroy the pipeline on exit */<br>static void destroy_pipeline(GtkWidget *widget, AppData *appdata)<br>


{<br>&nbsp;&nbsp;&nbsp; /* Free the pipeline. This automatically also unrefs all elements<br>&nbsp;&nbsp;&nbsp; &nbsp;* added to the pipeline */<br>&nbsp;&nbsp;&nbsp; gst_element_set_state(appdata-&gt;pipeline, GST_STATE_NULL);<br>&nbsp;&nbsp;&nbsp; gst_object_unref(GST_OBJECT(appdata-&gt;pipeline));<br>


}<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>int main(int argc, char **argv)<br>{<br>// variables for face detection<br>&nbsp;&nbsp;&nbsp; // main structure for vjdetect<br>&nbsp;&nbsp;&nbsp; pdata = (mainstruct*) calloc(1, sizeof(mainstruct));<br>


&nbsp;&nbsp;&nbsp; // Allocate memory for array of face detections returned by facedetector (VjDetect).<br>&nbsp;&nbsp;&nbsp; pdata-&gt;pFaceDetections = (FLY_Rect *)calloc(MAX_NUMBER_OF_FACE_DETECTIONS, sizeof(FLY_Rect));<br>&nbsp;&nbsp;&nbsp; init(pdata);<br><br>

&nbsp;&nbsp;&nbsp; AppData appdata;<br>
&nbsp;&nbsp;&nbsp; GtkWidget *hbox, *vbox_button, *vbox, *button1, *button2;<br><br>&nbsp;&nbsp;&nbsp; /* Initialize and create the GUI */<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; example_gui_initialize(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;appdata.program, &amp;appdata.window,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &amp;argc, &amp;argv, &quot;Expression Detector&quot;);<br>


<br>&nbsp;&nbsp;&nbsp; vbox = gtk_vbox_new(FALSE, 0);<br>&nbsp;&nbsp;&nbsp; hbox = gtk_hbox_new(FALSE, 0);<br>&nbsp;&nbsp;&nbsp; vbox_button = gtk_vbox_new(FALSE, 0);<br><br>&nbsp;&nbsp;&nbsp; gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);<br>&nbsp;&nbsp;&nbsp; gtk_box_pack_start(GTK_BOX(hbox), vbox_button, FALSE, FALSE, 0);<br>


<br>&nbsp;&nbsp;&nbsp; appdata.screen = gtk_drawing_area_new();<br>&nbsp;&nbsp;&nbsp; gtk_widget_set_size_request(appdata.screen, 500, 380);<br>&nbsp;&nbsp;&nbsp; gtk_box_pack_start(GTK_BOX(vbox), appdata.screen, FALSE, FALSE, 0);<br><br>&nbsp;&nbsp;&nbsp; button1 = gtk_toggle_button_new_with_label(&quot;Run/Stop&quot;);<br>


&nbsp;&nbsp;&nbsp; gtk_widget_set_size_request(button1, 170, 75);<br>&nbsp;&nbsp;&nbsp; gtk_box_pack_start(GTK_BOX(vbox_button), button1, FALSE, FALSE, 0);<br><br>&nbsp;&nbsp;&nbsp; button2 = gtk_toggle_button_new_with_label(&quot;Expressions ON/OFF&quot;);<br>&nbsp;&nbsp;&nbsp; gtk_widget_set_size_request(button2, 170, 75);<br>


&nbsp;&nbsp;&nbsp; gtk_box_pack_start(GTK_BOX(vbox_button), button2, FALSE, FALSE, 0);<br><br>&nbsp;&nbsp;&nbsp; g_signal_connect(G_OBJECT(button1), &quot;clicked&quot;,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;G_CALLBACK(button1_pressed), &amp;appdata);<br><br>&nbsp;&nbsp;&nbsp; g_signal_connect(G_OBJECT(button2), &quot;clicked&quot;,<br>


&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;G_CALLBACK(button2_pressed), &amp;appdata);<br><br><br>&nbsp;&nbsp;&nbsp; gtk_container_add(GTK_CONTAINER(appdata.window), hbox);<br><br>&nbsp;&nbsp;&nbsp; /* Initialize the GTK pipeline */<br>&nbsp;&nbsp;&nbsp; if(!initialize_pipeline(&amp;appdata, &amp;argc, &amp;argv))<br>


&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; hildon_banner_show_information(<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; GTK_WIDGET(appdata.window),<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &quot;gtk-dialog-error&quot;,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &quot;Failed to initialize pipeline&quot;);<br>&nbsp;&nbsp;&nbsp; }<br>

<br>
<br>&nbsp;&nbsp;&nbsp; g_signal_connect(G_OBJECT(appdata.window), &quot;destroy&quot;,<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; G_CALLBACK(destroy_pipeline), &amp;appdata);<br><br>&nbsp;&nbsp;&nbsp; /* Begin the main application */<br>&nbsp;&nbsp;&nbsp; example_gui_run(appdata.program, appdata.window);<br>


<br>&nbsp;&nbsp;&nbsp; /* Free the gstreamer resources. Elements added<br>&nbsp;&nbsp;&nbsp; &nbsp;* to the pipeline will be freed automatically */<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; return 0;<br>}<br><br><br><br><br>I removed the image processing functions to have a better clarity.<br>


I tried to put a printf in the exposecb functions, in the main and in the pipeline, with the hope that it will display the text each time a new frame is displayed on the screen. That didn&#39;t work, it appears only once. I read tutorials about gstreamer but couldn&#39;t find how to do something continously. Maybe I should write a image_processing callback, and put in my main a g_signal_connect call that start this callback each time a new frame is displayed ? But what would be the correct signal to use ?<br>


<br>Any idea welcome.<br><br>Thanks in advance !<br><span class="sg">Bruno<br>
</span>