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.
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.
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
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.
francoisrey can you let us know the status of this case?
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
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.
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
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;
}
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));
}
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.
Any useful log? enable the most verbose level (5).
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
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