| Hello all
My name is Corentin and I'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.
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'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)
so here is my code :
#include <gst/gst.h>
/* * Global objects are usually a bad
thing. For the purpose of this * example, we will use them, however. */
GstElement *pipeline, *source, *parser,
*decoder, *csp, *filter, *sink;
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) {
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: g_print ("End-of-streamn"); g_main_loop_quit (loop); break; case GST_MESSAGE_ERROR: { gchar *debug;
GError *err;
gst_message_parse_error (msg,
&err, &debug); g_free (debug); g_print ("Error: %sn",
err->message); g_error_free (err);
g_main_loop_quit (loop); break; } default: break; }
return TRUE; }
// this fonction deals with the pixels
(it should invert the video) static gboolean cb_have_data (GstPad *pad, GstBuffer *buffer, gpointer u_data) {
g_print ("Youpi, you are in the
loop of the frame n"); gint x, y; guint16 *data = (guint16 *)
GST_BUFFER_DATA (buffer), t;
// invert data for (y = 0; y < 288; y++) { for (x = 0; x < 384 / 2; x++) { t = data[384 - 1 - x]; data[384 - 1 - x] = data[x]; data[x] = t; } data += 384; }
return TRUE; }
// add a pad static void new_pad (GstElement *element, GstPad *pad, gpointer data) {
GstPad *sinkpad; /* We can now link this pad with the
audio decoder */ g_print ("Dynamic pad created,
linking parser/decodern"); sinkpad = gst_element_get_pad
(decoder, "sink"); gst_pad_link (pad, sinkpad); gst_object_unref (sinkpad);
}
int main (int argc, char *argv[]) {
GMainLoop *loop; GstBus *bus; GstCaps *filtercaps; GstPad *pad2;
/* initialize GStreamer */ gst_init (&argc, &argv); loop = g_main_loop_new (NULL, FALSE);
/* check input arguments */ if (argc != 2) { g_print ("Usage: %s
<Ogg/Vorbis filename>n", argv[0]); return -1;
}
/* create elements */ pipeline = gst_pipeline_new
("player"); source = gst_element_factory_make
("filesrc", "file-source"); parser = gst_element_factory_make
("oggdemux", "ogg-parser"); decoder = gst_element_factory_make
("theoradec", "theora-decoder"); filter = gst_element_factory_make
("capsfilter", "filter"); csp = gst_element_factory_make
("ffmpegcolorspace", "csp"); g_assert (filter != NULL); /* should
always exist */
sink = gst_element_factory_make
("ximagesink", "sink"); if (!pipeline || !source || !parser
|| !decoder || !csp || !filter ||!sink) { g_print ("One element could
not be createdn");
return -1; }
/* set filename property on the file
source. Also add a message * handler. */ g_object_set (G_OBJECT (source),
"location", argv[1], NULL);
bus = gst_pipeline_get_bus
(GST_PIPELINE (pipeline)); gst_bus_add_watch (bus, bus_call,
loop); gst_object_unref (bus);
/* put all elements in a bin */ gst_bin_add_many (GST_BIN (pipeline), source, parser, decoder,
csp,filter, sink, NULL);
/* link together - note that we
cannot link the parser and * decoder yet, becuse the parser
uses dynamic pads. For that, * we set a pad-added signal handler.
*/ gst_element_link (source, parser); gst_element_link_many (decoder, csp ,
filter, sink, NULL); g_signal_connect (parser,
"pad-added", G_CALLBACK (new_pad), NULL);
// create the filter caps vvith the video caracteristics
filtercaps = gst_caps_new_simple
("video/x-raw-rgb", "width", G_TYPE_INT,
288, "height", G_TYPE_INT,
208, "framerate",
GST_TYPE_FRACTION, 30, 1, //"bpp", G_TYPE_INT,
16, //"depth", G_TYPE_INT,
16, // "endianness",
G_TYPE_INT, G_BYTE_ORDER, NULL);
g_print ("try to set the caps on
the filtern"); g_object_set (G_OBJECT (filter),
"caps", filtercaps, NULL); gst_caps_unref (filtercaps);
g_print ("try to get the
padn"); pad2 = gst_element_get_pad
(csp,"csp"); if ( pad2 == NULL ) { g_print ("could not get the
padn"); }
//pad2 = gst_element_get_pad (csp,
"csp");
//add the probe g_print ("n setting the probe"); gst_pad_add_buffer_probe (pad2,
G_CALLBACK (cb_have_data), NULL); g_print ("nprobe addedn"); gst_object_unref (pad2);
/* Now set to playing and iterate. */ g_print ("Setting to
PLAYINGn"); gst_element_set_state (pipeline,
GST_STATE_PLAYING); g_print ("Runningn"); g_main_loop_run (loop);
/* clean up nicely */ g_print ("Returned, stopping
playbackn"); gst_element_set_state (pipeline,
GST_STATE_NULL); g_print ("Deleting pipelinen"); gst_object_unref (GST_OBJECT
(pipeline)); return 0;
}
To my mind the error comes from getting
the pad. I take a look about this and I tried all the functions :
gst_element_get_static_pad() &
gst_element_get_request_pad().
The fact is I set the filter after the
csp (ffmpegcolorspace) because it think this is here I will find the video data. I tried to set the filter before but
nothing changed. I can't find my error.
If anyone of you knows where I'm wrong
it would be very nice to tell me because i'm getting mad.
You 'll find the little video I use to
test my code at : http://corentino.fr/dl/vid.ogg you'll need it, because some video properties are set in hard, if you try my code ! : )
Thank you by advance, Sincerly
Corentin
|