Gstreamer 0.10 function gst_element_set_state hang

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Gstreamer 0.10 function gst_element_set_state hang

9,562 Views
francoisrey
Contributor III

Hi,

I use the I.MX6Q in our custom board based on sabrelite. In my software, I use the gstreamer library.

Sometimes when I call the function gst_element_set_state to put the pipeline in GST_STATE_PAUSED or in GST_STATE_NULL this function doesn't return and block my software. Did someone know why ?

I call all gstreamer function only in my main thread.

Labels (6)
Tags (1)
0 Kudos
13 Replies

3,889 Views
javiervalcarce
Contributor I

Hi.

I'm experiecing this same problem (kernel 4.1), I have found a weird workaround: g_usleep(500000) before set pipeline to GST_STATE_NULL. I don't know why but it works.

0 Kudos

3,889 Views
egremillion
Contributor III

Hi francoisrey - did you figure out a solution to this or a good workaround?  Were you using the mfw_v4lsink?

I'm thinking about re-posting this question to see if we can get some attention from Freescale...

Thanks!

Ernie

0 Kudos

3,889 Views
ieio
Contributor IV

I have the same problem but I am not using mfw_4lsink.

I can set the state to GST_STATE_NULL just the first time and then gst_element_set_state hangs, setting state to GST_STATE_PAUSE works, at least twice.

Has someone a solution?


Thanks.  

0 Kudos

3,889 Views
karina_valencia
NXP Apps Support
NXP Apps Support

francoisrey can you let us know the status of this case?

0 Kudos

3,889 Views
egremillion
Contributor III

I've recently encountered the same problem.  I have a pipeline that I construct programmatically.  When it is frequently restarted (torn down and reconstructed) it often locks up when stopping, specifically when attempting to set the mfw_v4lsink from PLAYING to PAUSED.  The hang occurs in gst_element_set_state(...) and gdb reveals that the video sink thread is stuck in ioctl.

Any ideas of what's happening and/or how to avoid this problem?  So far the best we can come up with is to detect when the process locks up and restart it...

Thanks,

Ernie

0 Kudos

3,889 Views
cetzweiler
Contributor II

I am encountering this problem as well, except  I am setting the mfx_v4lsink from PAUSED to PLAYING.

I also have to detect this case and restart by setting the state to NULL then back to PLAYING.

0 Kudos

3,889 Views
LeonardoSandova
Specialist I

Launching the pipeline from command line (gst-launch) and interrupting it (Control + C), does it work? It would be nice if you post the code where you construct the pipeline.

Leo

0 Kudos

3,889 Views
francoisrey
Contributor III

void
GstPlayer::initAviPipeline(char* filePath)
{
    findVideoCompression(filePath);
    if(isAudio)
        findAudioCompression(filePath);

    /* Create gstreamer elements */
    pipeline = gst_pipeline_new ("pipe");
    filesrc = gst_element_factory_make ("filesrc", "source");
    demuxer  = gst_element_factory_make ("avidemux", "avi-demuxer");
    vdec = gst_element_factory_make("vpudec", "vpu-decoder");
    vsink = gst_element_factory_make ("mfw_v4lsink", "sink");

    if (!pipeline || !filesrc || !demuxer || !vdec || !vsink ) {
        g_printerr ("One element could not be created. Exiting.\n");
        return ;
      }
    if(isAudio) {
        aqueue = gst_element_factory_make("queue", "queue audio");
        switch(audioCompression) {
        case AC3 :
            adec = gst_element_factory_make("ffdec_ac3", "ac3 decoder");
            break;
        case RAW_INT :
            adec = gst_element_factory_make("identity", "pass through");
            break;
        default :
            adec = gst_element_factory_make("decodebin", "decodebin decoder");
            break;

        }
        asink = gst_element_factory_make("alsasink", "alsa sink");

        if (!aqueue || !adec || !asink) {
            g_printerr ("One element could not be created. Exiting.\n");
            return ;
        }
    }

    /* Set up the pipeline */

    /* we set the input filename to the source element */
    g_object_set (G_OBJECT (filesrc), "location", filePath, NULL);

    /* we add a message handler */
    bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));

    /* we add all elements into the pipeline */
    /* file-source | avi-demuxer | vpu-decoder | video-output */
    if(!isAudio) {
        gst_bin_add_many (GST_BIN (pipeline), filesrc, demuxer, vdec, vsink, NULL);
    }
    else {
        gst_bin_add_many (GST_BIN (pipeline), filesrc, demuxer, vdec, vsink, aqueue, adec, asink, NULL);
    }

    /* we link the elements together */
    /* file-source -> ogg-demuxer ~> vorbis-decoder -> converter -> alsa-output */
    gst_element_link (filesrc, demuxer);
    gst_element_link(vdec, vsink);
    if(isAudio) {
        if(audioCompression == OTHER) {
            gst_element_link(aqueue, adec);
            g_signal_connect (adec, "pad-added", G_CALLBACK (cb_newpad2), asink);
        }
        else
            gst_element_link_many(aqueue, adec, asink, NULL);
    }

    g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added), this);

    /* note that the demuxer will be linked to the decoder dynamically.
       The reason is that Ogg may contain various streams (for example
       audio and video). The source pad(s) will be created at run time,
       by the demuxer when it detects the amount and nature of streams.
       Therefore we connect a callback function which will be executed
       when the "pad-added" is emitted.*/

    /* Set the pipeline to "Ready" state*/
    g_print ("Now ready: %s\n", filePath);
    gst_element_set_state(pipeline, GST_STATE_READY);
    videoState = READY;
}

0 Kudos

3,889 Views
francoisrey
Contributor III

with

void
GstPlayer::findVideoCompression(char* filePath)
{
    GstBus *intBus;

    isAudio = false;

    /* Create gstreamer elements */
    pipeline = gst_pipeline_new ("pipe");
    filesrc = gst_element_factory_make ("filesrc", "source");
    demuxer  = gst_element_factory_make ("avidemux", "avi-demuxer");
    findtype = gst_element_factory_make ("typefind", "video typefinder");
    vsink = gst_element_factory_make ("fakesink", "vsink");

    if (!pipeline || !filesrc || !demuxer || !findtype || !vsink) {
        g_printerr ("One element could not be created. Exiting.\n");
        return ;
    }

    g_object_set (G_OBJECT (filesrc), "location", filePath, NULL);
    intBus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (intBus, bus_call, loop);
    gst_object_unref (intBus);

    gst_bin_add_many(GST_BIN (pipeline), filesrc, demuxer, findtype, vsink, NULL);
    gst_element_link (filesrc, demuxer);
    gst_element_link(findtype, vsink);

    g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added_fv), this);
    g_signal_connect (findtype, "have-type", G_CALLBACK (cb_typefound_fv), this);

    gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
    g_main_loop_run (loop);

    /* unset */
    gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
    gst_object_unref (GST_OBJECT (pipeline));
}

void
GstPlayer::findAudioCompression(char* filePath)
{
    GstBus *intBus;

    /* Create gstreamer elements */
    pipeline = gst_pipeline_new ("pipe");
    filesrc = gst_element_factory_make ("filesrc", "source");
    demuxer  = gst_element_factory_make ("avidemux", "avi-demuxer");
    findtype = gst_element_factory_make ("typefind", "video typefinder");
    asink = gst_element_factory_make ("fakesink", "asink");

    if (!pipeline || !filesrc || !demuxer || !findtype || !asink) {
        g_printerr ("One element could not be created. Exiting.\n");
        return ;
    }

    g_object_set (G_OBJECT (filesrc), "location", filePath, NULL);
    intBus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (intBus, bus_call, loop);
    gst_object_unref (intBus);

    gst_bin_add_many(GST_BIN (pipeline), filesrc, demuxer, findtype, asink, NULL);
    gst_element_link (filesrc, demuxer);
    gst_element_link(findtype, asink);

    g_signal_connect (demuxer, "pad-added", G_CALLBACK (on_pad_added_fa), this);
    g_signal_connect (findtype, "have-type", G_CALLBACK (cb_typefound_fa), this);

    gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
    g_main_loop_run (loop);

    /* unset */
    gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
    gst_object_unref (GST_OBJECT (pipeline));
}

0 Kudos

3,889 Views
francoisrey
Contributor III

I have an another board which send automatically command to my board to play, set in pause, stop video. My board receive command approximately every 4 seconds. It's only after approximately 5 minutes when the function gst_element_set_state doesn't return even though it was already call with the same state, same pipeline (same video), and works well.

0 Kudos

3,889 Views
LeonardoSandova
Specialist I

Any useful log? enable the most verbose level (5).

0 Kudos

3,889 Views
francoisrey
Contributor III

The last log which I can see is the following :

0:21:22.543127820  1455 default segment start=0, stop=12886009192, last_stop=0, duration=25770984840, rate=0.000000, applied_rate=0.000000, flags=0x00, time=0:02:17.438953600, accum=0:00:04.294967296 WARN mfw_v4lsink mfw_gst_v4l_buffer.c:752:mfw_gst_v4l2_free_buffers: try to free buffer 9 at state 4

0 Kudos

3,889 Views
LeonardoSandova
Specialist I

Not so useful. I would say to try other media files and other demuxers (aiurdemux, this is the one Freescale supports) and see if the issue is reproducible. By the way, For these cases, I suggest --gst-debug=*:5 verbosity.

Leo

0 Kudos