Playback issue with GST_STATE_CHANGE_ASYNC and gst_element_set_state()

karimchtx karim_atiki at
Tue Jun 15 15:54:26 UTC 2021


I wrote a pipeline in order to perform playback.
The pipeline is managed dynamically in order to manage for example, audio
track switching.
As the player is asked to change the audio track, the current audio_bin
element is unlinked from the demuxer audio_% pad, a new audio sink is built
and linked.
This task is performed in the pad_probe_block_cb() set on the demuxer
audio_x pad.

As the task is finished, the new audiosink state is set to
GST_STATE_PLAYING...and there, I receive  GST_STATE_CHANGE_ASYNC  and the
pipeline is frozen...
The only think that unblocks the pipeline is to perform a seek operation.

The code in the pad prob cb looks like:
audio_pad_probe_cb(GstPad* pad, GstPadProbeInfo* info, gpointer user_data)
    GstPad* srcpad, * sinkpad;

    GstState state, pending;

    GStreamerPlayerPrivate* p = static_cast<GStreamerPlayer*>(user_data);

    AudioTrack* oldAudio = p->currentAudio;

    GST_DEBUG_OBJECT(p->pipeline, "pad is blocked now");

    // Remove the probe first
    gst_pad_remove_probe(pad, GST_PAD_PROBE_INFO_ID(info));

    // get the related audio_sink bin
    auto audio_sink = p->audio_sinks[p->currentAudio->index()];

    auto st = gst_element_get_state(audio_sink, &state, &pending, 1000);

    st = gst_element_set_state(audio_sink, GST_STATE_NULL);

    sinkpad = gst_element_get_static_pad(audio_sink, "sink");
    srcpad = p->audio_blocking_pad;

    // Unlink pad from audio sink
    gst_pad_unlink(srcpad, sinkpad);

    gst_bin_remove(GST_BIN(p->pipeline), audio_sink);
    audio_sink = nullptr;

    // get new sink
    audio_sink = p->audio_sinks[p->pendingAudio->index()];
    gst_bin_add(GST_BIN(p->pipeline), audio_sink);

    QByteArray padname =
    sinkpad = gst_element_get_static_pad(audio_sink, "sink");
    srcpad = gst_element_get_static_pad(p->demuxer, padname.constData());

    auto ret = gst_pad_link(srcpad, sinkpad);

    p->currentAudio = p->pendingAudio;
    p->pendingAudio = nullptr;
    p->audio_blocking_pad = srcpad;


    st = gst_element_set_state(audio_sink, GST_STATE_PLAYING);

   return GST_PAD_PROBE_OK;

I really don't understand why the pipeline is hanging this way.
I have also dumped the pipeline and check the SVG result, and it's in
playing state..
Maybe I missed something or I've misunderstood some concept, but any
suggestion is welcome.


Sent from:

More information about the gstreamer-devel mailing list