[gst-devel] Dynamic pipelines

Michal Benes michal.benes at itonis.tv
Mon Jul 24 10:42:21 CEST 2006


Hi Sebastin, Rob and Martin,

	I am sorry I found your e-mail a month later than it was posted. But
yes, I have been playing some time before with dynamic pipelines. The
stuff was pretty tricky. I think that your the problem with several
second silence you are experiencing might be
http://bugzilla.gnome.org/show_bug.cgi?id=322929
I have attached a patch for this but it was wrong (although it worked
for me)
It might be possible to do the same as my patch without patching the
baseaudiosink by

GstBaseAudioSink *bsink = GST_BASE_AUDIO_SINK(audio_sink);
gst_ring_buffer_set_sample (bsink->ringbuffer, 0);

Still, I feel this is only a hack.

	Just to make clear what I was working on: I have been writinng a RTSP
client and I wanted to do two things: 

1) show some filler video while the player was buffering
2) joining several streams in such a way, that the player starts
buffering the second stream while the first stream still plays from a
network buffer

The pipe looked like this

+------------+     +-------+
| rtp source | --- | queue |-blocked
+------------+     +-------+          +------+
                                 +----| sink |
+--------------+                 |    +------+
| video filler |-----------------+
+--------------+

When the queue reaches the given threshold I relink the pipe like this

+------------+     +-------+
| rtp source | --- | queue |-----+
+------------+     +-------+     |    +------+
                                 +----| sink |
+--------------+                      +------+
| video filler |-blocked
+--------------+

	The greatest problem was probably the audio/video synchronization. I am
attaching a portion of my code bellow.

	Basically, It worked, but I have not fixed all the deadlocks that
appeared from time to time. Besides, most people use MS Windows and we
were not particularly successful porting GStreamer to Windows at the
time (I hope the situation has changed lately :).

	Hope this helps	

	Cheers,
 
		Michal

Code to unlink video filler and link rtp pipe. It is using our C++
wrapper, but the meaning should be understable anyway

// unlink video filler
unlinkSink(audio_filler_, audio_sink_);
// Change state (wait until the state change finishes)
audio_sink_->setState(GST_STATE_READY, GSTREAMER_STATE_CHANGE_TIMEOUT)
// Link rtp pipe
rtp_pipe->link(audio_sink_);
// Set state to playing (do not wait until the state change finishes)
audio_sink_->setStateAsync(GST_STATE_PLAYING);
rtp_pipe->unblock();


void
PlayerPipeline::unlinkSink(PlayerStreamPipe *pipe, Sink *sink)
{
    GstPad *sink_pad;
    GstPad *src_pad;

    src_pad = pipe->getSource();
    sink_pad = sink->getSink();
    CHECK(sink_pad);

    if (!sink->setState(GST_STATE_READY,
GSTREAMER_STATE_CHANGE_TIMEOUT)) {
        MESSAGE(LEVEL_ERROR, "Can not set sink state to READY,
continuing anyway...");
    }

    if (GST_PAD_PEER(src_pad) == sink_pad) {
        gst_pad_send_event(sink_pad, gst_event_new_flush_start());
        if (pipe)
            pipe->block();
        gst_pad_unlink (src_pad, sink_pad);

        // Adjust base time if unlinking the video sink
        if (sink == video_sink_) {
            GstClockTime base_time = video_sink_base_time_;

            // Adjust base time if video and audio do not start at the
same time
            if (GST_CLOCK_TIME_IS_VALID(video_start_time_)
                && GST_CLOCK_TIME_IS_VALID(audio_start_time_))
            {
                base_time += video_start_time_;
                base_time -= audio_start_time_;
            }

            g_object_set(G_OBJECT(video_sink_->getBin()),
                                   "base-time", base_time, NULL);
        }

        // Get the base time if unlinking the audio sink
        if (sink == audio_sink_) {
            GstClock *clock;

            // Get the audio sink clock
            clock = gst_element_provide_clock
(audio_sink_->getDefaultElement());
            if (!clock) {
                MESSAGE(LEVEL_ERROR, "Can not obtain audio sink
clock.");
            } else {
                // Get the video sink base time
                video_sink_base_time_ = gst_clock_get_time (clock);
                gst_object_unref (clock);
            }
        }

        gst_pad_send_event(sink_pad, gst_event_new_flush_stop());
    }
}



Martin Rubli píše v Pá 16. 06. 2006 v 15:51 -0700:
> Sebastian, Rob,
> 
> Thanks for your tips, I've done a little more testing ...
> 
> Setting "sync = false" on the audio sink didn't help for me. If anything,  
> it made the problem slightly worse, but it's really hard to tell because  
> of all the randomness.
> 
> Pausing the pipeline has different effects, depending on what you pause  
> (the entire pipeline, the source, the sink) and what kind of stream (audio  
> or video) it is. For audio I couldn't get it to work with either of those  
> three. For video, however, it helps if I pause the v4l2src. I don't know  
> where these different results come from because the code is basically the  
> same, but if I find out, I'm going to post it here.
> 
> In the meantime I'm going to check out the Farsight source, maybe I'll  
> find something that I do differently.
> 
> Cheers,
> Martin
> 
> 
> On Mon, 12 Jun 2006 04:45:57 -0700, Rob Taylor <robtaylor at floopily.org>  
> wrote:
> 
> > Did you pause the pipeline before linking pads? We do this in Farsight,
> > and it works well for us.
> >
> > Thanks,
> > Rob Taylor
> > Sébastien Moutte wrote:
> >> Hi Martin,
> >>
> >> I already have this kind of discontinuities with a pipeline which has an
> >> audio playback bin (queue ! decoder ! audioconvert ! directsoundsink)
> >> that i was adding and removing from the main pipeline.
> >> after reconnections, i was getting a silence of a few seconds and next
> >> the sound was coming back.
> >> I think your message "resync after discont with previous sample " could
> >> come from the ring buffer of the audio sink base class.
> >> You can try to disable synchronization on the audio sink by setting the
> >> "sync" property to false, it worked for me.
> >>
> >> I hope it will help ...
> >> Sebastien
> >>
> >> Martin Rubli a écrit :
> >>> Hi,
> >>>
> >>> Given the number of replies I have received (zero ;-), dynamically
> >>> changing pipelines at play time doesn't seem very popular ...
> >>>
> >>> Has anyone tried this before and got it to work properly? If so, I'd be
> >>> very grateful for sample code to compare it with mine, so that I know
> >>> whether my code is wrong or whether I should file a bug against  
> >>> GStreamer.
> >>>
> >>> Thanks!
> >>> Martin
> >>>
> >>>
> >>> On Thu, 25 May 2006 16:02:42 -0700, Martin Rubli
> >>> <martin_rubli at logitech.com> wrote:
> >>>
> >>>
> >>>> Hi all,
> >>>>
> >>>> I've been doing some tests with dynamic insertion and removal of
> >>>> plug-ins.
> >>>>
> >>>> The program I've been using is based on section 17.3 of the  
> >>>> Application
> >>>> Development Manual. (BTW: The sample given on that page needs a few
> >>>> changes to work with GStreamer 0.10.)
> >>>>
> >>>> I have tried different scenarios. In each case the pipeline looks
> >>>> something like this and is automatically created. (Using an .ogg file
> >>>> here
> >>>> but the same thing happens with other audio sources.)
> >>>>
> >>>> filesrc ! oggdemux ! vorbisdec ! audioresample ! audioconvert !  
> >>>> FilterBin
> >>>> ! alsasink
> >>>>
> >>>> The FilterBin is a bin that contains one of the following (defined at
> >>>> compile time):
> >>>> a) identity
> >>>> b) audioresample ! audio/x-raw-int ! identity
> >>>> c) audioresample ! audio/x-raw-int, rate=48000 ! identity
> >>>> d) audioresample ! audio/x-raw-int, rate=8000 ! identity
> >>>>
> >>>> Every 5 seconds the FilterBin is taken out of the pipeline or put back
> >>>> in,
> >>>> so that e.g. in case d) the audio should toggle between normal and  
> >>>> pretty
> >>>> bad quality.
> >>>>
> >>>> The problem is that the behavior is somewhat random for some of the
> >>>> cases.
> >>>> For cases a and b it works consistently well (audioresample should be  
> >>>> a
> >>>> no-op). In cases c and d, however, I sometimes get interruptions of a
> >>>> couple of seconds and the debug log gives lines like:
> >>>>
> >>>> <AlsaSink> resync after discont with previous sample of diff: 425761
> >>>>
> >>>> My questions now: Where do these discontinuities come from and what  
> >>>> can I
> >>>> do about it? Are there any more programs out there that do the same
> >>>> thing?
> >>>>
> >>>> Different variations of changing the pipeline state during the
> >>>> insertion/removal phase didn't help either. The test code is attached.
> >>>>
> >>>> I'd be grateful for any tips ... Cheers,
> >>>> Martin
> >>>>
> >>>
> >>> _______________________________________________
> >>> gstreamer-devel mailing list
> >>> gstreamer-devel at lists.sourceforge.net
> >>> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
> >>>
> >>>
> >>>
> >>
> >>
> >> _______________________________________________
> >> gstreamer-devel mailing list
> >> gstreamer-devel at lists.sourceforge.net
> >> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
> >
> >
> >
> > _______________________________________________
> > gstreamer-devel mailing list
> > gstreamer-devel at lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/gstreamer-devel
> 
> 
> 
> 
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/gstreamer-devel





More information about the gstreamer-devel mailing list