[gst-devel] Unstable segmentation faults.
Kirill Kirichenko
kirill.kirichenko at gmail.com
Fri Jul 4 15:26:10 CEST 2008
Hello everybody. I'm new at this list.
I wrote a function can_play placed below which detects whether
gstreamer is able to play some media content.
I.e. I need to dynamically detect if the current plugins set is
appropriate to play something.
I have a set of different media sources - 30+ files of wav, swf, wmv,
avi, mp3, ogg, mp4, jpg etc formats and couple of http sources.
I'm running my can_play function in stress test mode - for example 100
passes for all those 30+ files.
And I get a Segmantation Fault at a random pass. It can happen during
2-n pass or 73-rd pass.
Any suggestions?
Thanks,
Kirill
[code]
#include <gst/gst.h>
gchar* uri[] = {
"file:///home/user/media/sample.wav", // and more files 30+
"http://ware.catv.ext.ru:8000/moscowecho48.mp3", // http source
// Trully failing tests
"file:///home/user/GStreamer/canplay", // this executable
NULL
};
/***********************************************************************************
* Bus watch callback
***********************************************************************************/
static GMainLoop *loop;
static GstElement *playbin;
static gboolean result;
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
switch (GST_MESSAGE_TYPE (msg))
{
case GST_MESSAGE_EOS:
{
result = TRUE;
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_ERROR:
{
/* gchar *debug;
GError *err;
gst_message_parse_error (msg, &err, &debug);
g_log ("bus-call", G_LOG_LEVEL_MESSAGE, "Error: %s Debug:
%s", err->message, debug);
g_free (debug);
g_error_free (err);*/
result = FALSE;
g_main_loop_quit (loop);
break;
}
case GST_MESSAGE_STATE_CHANGED:
{
GstState old_state, new_state;
gst_message_parse_state_changed (msg, &old_state, &new_state, NULL);
// g_log("\tBUS", G_LOG_LEVEL_MESSAGE, "[%s] %s -> %s",
// GST_OBJECT_NAME(GST_MESSAGE_SRC (msg)),
// gst_element_state_get_name(old_state),
// gst_element_state_get_name(new_state));
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (playbin) &&
old_state == GST_STATE_PAUSED && new_state == GST_STATE_PLAYING)
{
result = TRUE;
g_main_loop_quit (loop);
break;
}
}
default:
break;
}
return TRUE;
}
static gboolean can_play(const gchar* uri)
{
// g_log("Can Play", G_LOG_LEVEL_MESSAGE, "Processing %s", uri);
/*********************************************************************************
* create elements
*********************************************************************************/
loop = g_main_loop_new(NULL, FALSE);
playbin = gst_element_factory_make ("playbin", NULL);
g_object_set (G_OBJECT (playbin), "uri", uri, NULL);
GstBus *bus = gst_pipeline_get_bus (GST_PIPELINE (playbin));
gst_bus_add_watch(bus, (GstBusFunc)bus_call, NULL);
gst_object_unref (bus);
g_object_set(playbin,
"video-sink", gst_element_factory_make ("fakesink", NULL),
"audio-sink", gst_element_factory_make ("fakesink",
NULL), NULL);
/*********************************************************************/
result = FALSE;
gst_element_set_state (playbin, GST_STATE_PLAYING);
g_main_loop_run(loop);
gst_element_set_state (playbin, GST_STATE_NULL);
gst_element_get_state(playbin, NULL, NULL, GST_CLOCK_TIME_NONE);
gst_object_unref(playbin);
g_main_loop_unref(loop);
return result;
}
int main (int argc, char *argv[])
{
if (!g_thread_supported ())
g_thread_init(NULL);
gboolean do_functional = FALSE;
gint stress_amount = 0;
GOptionEntry entries[] =
{
{ "functional", 'f', 0, G_OPTION_ARG_NONE, &do_functional,
"perform functional test", NULL },
{ "stress", 's', 0, G_OPTION_ARG_INT, &stress_amount,
"perform stress test with N stress factor", "N" },
{ NULL }
};
GOptionContext *context = g_option_context_new("[URI] - find type
of the file");
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_add_group (context, gst_init_get_option_group ());
GError *error = NULL;
if (g_option_context_parse (context, &argc, &argv, &error))
{
/*********************************************************************************
* process arguments
*********************************************************************************/
if (argc == 2 && gst_uri_is_valid(argv[1]))
g_print("%s - %s\n", argv[1], can_play(argv[1]) ? "TRUE" : "FALSE");
if (do_functional)
{
g_print("****************************************************************\n");
g_print("*************** PERFORMING FUNCTIONAL TEST
****************\n");
g_print("****************************************************************\n");
int uri_size = g_strv_length(uri);
int u_idx;
for (u_idx = 0; u_idx < uri_size; u_idx++)
g_print("%s - %s\n", uri[u_idx], can_play(uri[u_idx])
? "TRUE" : "FALSE");
}
if (stress_amount > 0)
{
g_print("****************************************************************\n");
g_print("***************** PERFORMING STRESS TEST
******************\n");
g_print("****************************************************************\n");
int uri_size = g_strv_length(uri);
int p_idx, u_idx;
// Create and init weight array
gint8** weights = g_new0(gint8*, uri_size);
for(u_idx = 0; u_idx <uri_size; u_idx++)
weights[u_idx] = g_new0(gint8, stress_amount);
for (p_idx = 0; p_idx < stress_amount; p_idx++)
{
g_print("#### Performing %i-th pass ####\n", p_idx);
for (u_idx = 0; u_idx < uri_size; u_idx++)
weights[u_idx][p_idx] = can_play(uri[u_idx]) ? 1 : 0;
}
g_print ("Calculating deviations\n");
for (u_idx = 0; u_idx < uri_size; u_idx++)
{
gdouble weight = 0;
for (p_idx = 0; p_idx < stress_amount; p_idx++)
weight += weights[u_idx][p_idx];
weight /= stress_amount;
gboolean balanced = weight == 0.0 || weight == 1.0;
g_print("%s - %f [%s]\n", uri[u_idx], weight, balanced
? "OK" : "FAIL");
}
}
}
else
{
g_print ("option parsing failed: %s\n", error->message);
return 1;
}
return 0;
}
[/code]
More information about the gstreamer-devel
mailing list