Unstable segmentation faults.

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Unstable segmentation faults.

Kirill Kirichenko
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]

-------------------------------------------------------------------------
Sponsored by: SourceForge.net Community Choice Awards: VOTE NOW!
Studies have shown that voting for your favorite open source project,
along with a healthy diet, reduces your potential for chronic lameness
and boredom. Vote Now at http://www.sourceforge.net/community/cca08
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/gstreamer-devel