Hello all
<p style="margin-bottom: 0cm;"><br>
</p>
<p style="margin-bottom: 0cm;">My name is Corentin and I&#39;m working on
a web multimedia project based on Django frameworkand Gstreamer, and
I want to add a scene change detection fonctionality to my project. 
</p>
<p style="margin-bottom: 0cm;">To do this i need to acces to the video
data so I take a (long..) look at Gstreamer manual and made this
code. It&#39;s made with the Hello world code to read a ogg audio file
(Chapter 10 in the manual), I easily turned to play ogg video file
and with the code from the example of data probing (Chapter 18 in the
manual)</p>
<p style="margin-bottom: 0cm;"><br>
</p>
<p style="margin-bottom: 0cm;">    so here is my code :</p>
<p style="margin-bottom: 0cm;"><br>
</p>

<p style="margin-bottom: 0cm;">#include &lt;gst/gst.h&gt;<br><br>
</p>



<p style="margin-bottom: 0cm;">/*<br>* Global objects are usually a bad
thing. For the purpose of this<br>* example, we will use them, however.<br>*/</p>
<p style="margin-bottom: 0cm;"><br>
</p>

<p style="margin-bottom: 0cm;">GstElement *pipeline, *source, *parser,
*decoder, *csp, *filter, *sink;<br>
</p>




<p style="margin-bottom: 0cm;">static gboolean<br>bus_call (GstBus     *bus,<br>GstMessage *msg,<br>gpointer    data)<br>{</p>

<p style="margin-bottom: 0cm;">  GMainLoop *loop = (GMainLoop *) data;<br>
</p>







<p style="margin-bottom: 0cm;">  switch (GST_MESSAGE_TYPE (msg)) {<br>case GST_MESSAGE_EOS:<br>g_print (&quot;End-of-stream\n&quot;);<br>g_main_loop_quit (loop);<br>break;<br>case GST_MESSAGE_ERROR: {<br>gchar *debug;<br>




GError *err;</p>
<p style="margin-bottom: 0cm;"><br>
</p>





<p style="margin-bottom: 0cm;">      gst_message_parse_error (msg,
&amp;err, &amp;debug);<br>g_free (debug);<br>g_print (&quot;Error: %s\n&quot;,
err-&gt;message);<br>g_error_free (err);<br>
</p>





<p style="margin-bottom: 0cm;">      g_main_loop_quit (loop);<br>break;<br>}<br>default:<br>break;<br>}</p>


<p style="margin-bottom: 0cm;">  return TRUE;<br>}</p>
<p style="margin-bottom: 0cm;"><br>
</p>





<p style="margin-bottom: 0cm;">// this fonction deals with the pixels
(it should invert the video)<br>static gboolean<br>cb_have_data (GstPad    *pad,<br>GstBuffer *buffer,<br>gpointer   u_data)<br>{</p>


<p style="margin-bottom: 0cm;">        g_print (&quot;Youpi, you are in the
loop of the frame \n&quot;);<br>gint x, y;<br>guint16 *data = (guint16 *)
GST_BUFFER_DATA (buffer), t;</p>









<p style="margin-bottom: 0cm;">  // invert data<br>for (y = 0; y &lt; 288; y++) {<br>for (x = 0; x &lt; 384 / 2; x++) {<br>t = data[384 - 1 - x];<br>data[384 - 1 - x] = data[x];<br>data[x] = t;<br>}<br>data += 384;<br>}</p>







<p style="margin-bottom: 0cm;">  return TRUE;<br>}</p>
<p style="margin-bottom: 0cm;"><br>
</p>





<p style="margin-bottom: 0cm;">// add a pad<br>static void<br>new_pad (GstElement *element,<br>GstPad     *pad,<br>gpointer    data)<br>{</p>







<p style="margin-bottom: 0cm;">  GstPad *sinkpad;</p><p style="margin-bottom: 0cm;">/* We can now link this pad with the
audio decoder */<br>g_print (&quot;Dynamic pad created,
linking parser/decoder\n&quot;);<br>sinkpad = gst_element_get_pad
(decoder, &quot;sink&quot;);<br>gst_pad_link (pad, sinkpad);<br>gst_object_unref (sinkpad);</p>
<p style="margin-bottom: 0cm;">}</p>
<p style="margin-bottom: 0cm;"><br>
</p>



<p style="margin-bottom: 0cm;">int<br>main (int   argc,<br>char *argv[])<br>{</p>



<p style="margin-bottom: 0cm;">  GMainLoop *loop;<br>GstBus *bus;<br>GstCaps *filtercaps;<br>GstPad *pad2;</p>
<p style="margin-bottom: 0cm;"><br>
</p>



<p style="margin-bottom: 0cm;">  /* initialize GStreamer */<br>gst_init (&amp;argc, &amp;argv);<br>loop = g_main_loop_new (NULL, FALSE);<br><br>
</p>



<p style="margin-bottom: 0cm;">  /* check input arguments */<br>if (argc != 2) {<br>g_print (&quot;Usage: %s
&lt;Ogg/Vorbis filename&gt;\n&quot;, argv[0]);<br>return -1;</p>
<p style="margin-bottom: 0cm;">  }</p>
<p style="margin-bottom: 0cm;"><br>
</p>








<p style="margin-bottom: 0cm;">  /* create elements */<br>pipeline = gst_pipeline_new
(&quot;player&quot;);<br>source = gst_element_factory_make
(&quot;filesrc&quot;, &quot;file-source&quot;);<br>parser = gst_element_factory_make
(&quot;oggdemux&quot;, &quot;ogg-parser&quot;);<br>decoder = gst_element_factory_make
(&quot;theoradec&quot;, &quot;theora-decoder&quot;);<br>filter = gst_element_factory_make
(&quot;capsfilter&quot;, &quot;filter&quot;);<br>csp = gst_element_factory_make
(&quot;ffmpegcolorspace&quot;, &quot;csp&quot;);<br>g_assert (filter != NULL); /* should
always exist */<br>
</p>



<p style="margin-bottom: 0cm;">  sink = gst_element_factory_make
(&quot;ximagesink&quot;, &quot;sink&quot;);<br>if (!pipeline || !source || !parser
|| !decoder || !csp || !filter ||!sink) {<br>g_print (&quot;One element could
not be created\n&quot;);</p>

<p style="margin-bottom: 0cm;">    return -1;<br>}</p>
<p style="margin-bottom: 0cm;"><br>
</p>



<p style="margin-bottom: 0cm;">  /* set filename property on the file
source. Also add a message<br>* handler. */<br>g_object_set (G_OBJECT (source),
&quot;location&quot;, argv[1], NULL);<br>
</p>



<p style="margin-bottom: 0cm;">  bus = gst_pipeline_get_bus
(GST_PIPELINE (pipeline));<br>gst_bus_add_watch (bus, bus_call,
loop);<br>gst_object_unref (bus);<br><br>
</p>




<p style="margin-bottom: 0cm;">  /* put all elements in a bin */<br>gst_bin_add_many (GST_BIN (pipeline),<br>source, parser, decoder, 
csp,filter, sink, NULL);<br><br>
</p>





<p style="margin-bottom: 0cm;">  /* link together - note that we
cannot link the parser and<br>* decoder yet, becuse the parser
uses dynamic pads. For that,<br>* we set a pad-added signal handler.
*/<br>gst_element_link (source, parser);<br>gst_element_link_many (decoder, csp ,
filter, sink, NULL);<br>g_signal_connect (parser,
&quot;pad-added&quot;, G_CALLBACK (new_pad), NULL);</p>
<p style="margin-bottom: 0cm;"><br>
</p>
<p style="margin-bottom: 0cm;"><br>
</p>
<p style="margin-bottom: 0cm;">  // create the filter caps vvith the video caracteristics<br></p>







<p style="margin-bottom: 0cm;">  filtercaps = gst_caps_new_simple
(&quot;video/x-raw-rgb&quot;,<br>&quot;width&quot;, G_TYPE_INT,
288,<br>&quot;height&quot;, G_TYPE_INT,
208,<br>&quot;framerate&quot;,
GST_TYPE_FRACTION, 30, 1,<br>//&quot;bpp&quot;, G_TYPE_INT,
16,<br>//&quot;depth&quot;, G_TYPE_INT,
16,<br>// &quot;endianness&quot;,
G_TYPE_INT, G_BYTE_ORDER,<br>NULL);</p>



<p style="margin-bottom: 0cm;">  g_print (&quot;try to set the caps on
the filter\n&quot;);<br>g_object_set (G_OBJECT (filter),
&quot;caps&quot;, filtercaps, NULL);<br>gst_caps_unref (filtercaps);</p>
<p style="margin-bottom: 0cm;"><br>
</p>








<p style="margin-bottom: 0cm;">  g_print (&quot;try to get the
pad\n&quot;);<br>pad2 = gst_element_get_pad
(csp,&quot;csp&quot;);<br>if ( pad2 == NULL )<br>{<br>g_print (&quot;could not get the
pad\n&quot;);<br>}<br><br>
</p>

<p style="margin-bottom: 0cm;"> //pad2 = gst_element_get_pad (csp,
&quot;csp&quot;);<br><br>
</p>




<p style="margin-bottom: 0cm;">  //add the probe<br>g_print (&quot;\n setting the probe&quot;);<br>gst_pad_add_buffer_probe (pad2,
G_CALLBACK (cb_have_data), NULL);<br>g_print (&quot;\nprobe added\n&quot;);<br>gst_object_unref (pad2);</p>
<p style="margin-bottom: 0cm;"><br>
</p>
<p style="margin-bottom: 0cm;"><br>
</p>




<p style="margin-bottom: 0cm;">  /* Now set to playing and iterate. */<br>g_print (&quot;Setting to
PLAYING\n&quot;);<br>gst_element_set_state (pipeline,
GST_STATE_PLAYING);<br>g_print (&quot;Running\n&quot;);<br>g_main_loop_run (loop);</p>
<p style="margin-bottom: 0cm;"><br>
</p>




<p style="margin-bottom: 0cm;">  /* clean up nicely */<br>g_print (&quot;Returned, stopping
playback\n&quot;);<br>gst_element_set_state (pipeline,
GST_STATE_NULL);<br>g_print (&quot;Deleting pipeline\n&quot;);<br>gst_object_unref (GST_OBJECT
(pipeline));</p><p style="margin-bottom: 0cm;">  return 0;</p>
<p style="margin-bottom: 0cm;">}</p>
<p style="margin-bottom: 0cm;"><br>
</p>
<p style="margin-bottom: 0cm;">To my mind the error comes from getting
the pad. I take a look about this and I tried all the functions :</p>

<p style="margin-bottom: 0cm;">gst_element_get_static_pad() &amp;
gst_element_get_request_pad().<br>
</p>
<p style="margin-bottom: 0cm;">The fact is I set the filter after the
csp (ffmpegcolorspace) because it think this is here I will find the video data.<br>I tried to set the filter before but
nothing changed.<br>I can&#39;t find my error.</p>
<p style="margin-bottom: 0cm;">If anyone of you knows where I&#39;m wrong
it would be very nice to tell me because i&#39;m getting mad.</p>
<p style="margin-bottom: 0cm;"><br>
</p>


<p style="margin-bottom: 0cm;">You &#39;ll find the little video I use to
test my code at :<br><a href="http://corentino.fr/dl/vid.ogg" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">http://corentino.fr/dl/vid.ogg</a><br>you&#39;ll need it, because some video properties are set in hard, if you try my code ! : )
<br>
</p>
<p style="margin-bottom: 0cm;">Thank you by advance,<br>Sincerly<br></p><span class="sg"><span>

<p style="margin-bottom: 0cm;"><br>Corentin</p>
<p style="margin-bottom: 0cm;"><br>
</p>
<p style="margin-bottom: 0cm;"> 
</p>
</span>
</span>