STREAMER Synchronizing multiple sources to a common receiver

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

STREAMER Synchronizing multiple sources to a common receiver

thiyageshv
I am just adding few stuff for more clarity.

SETUP: So, I have two sender trying to send video from two different devices. I have synced the clocks of both the senders through NTPD daemon. Then I tried executing this pipeline based on the insights from Streamer conference videos and few posts in this forum. I am basically assuming here that the pipeline is going to the use the NTP clock. External clock sync is all I need to do before I implement this. Please correct me if I am wrong.  At the receiver I put both streams into a common RTPbin. 

PROBLEM:  I am not getting the expected results. The frames are stuck most of the time or out of sync.  Please let me know where I am going wrong. I am not exactly sure on where I have to use the Test-Netclocck examples. I thought that was a substitute for NTP daemon based syncing.  
I would be really happy if I could get a pipeline based solution. I am not very familiar with the C API.

Questions I want to be answered:
1.Is my pipeline structure correct? 
2.I am not modifying the pipeline clocks at all. Just assuming that the pipeline clocks of senders and receivers will be 3.synchronized once we sync the devices through NTP. Is this assumption correct?
4.Should I have just one rtpbin or separate rtpbin for each sender?
5.Should i USE RTPJITTERBUFFER? if yes, should the mode be synced? 

The pipeline of both senders look like this
SENDER PIPELINE:
VOFFSET=0
AOFFSET=0

VELEM="v4l2src device=/dev/video1"
VCAPS="video/x-raw,width=352,height=288,framerate=15/1"
VSOURCE="$VELEM ! queue ! videorate ! videoconvert ! $VCAPS"
VENC="vp8enc ! rtpvp8pay"
VRTPSINK="udpsink port=5000 host=$DEST ts-offset=$VOFFSET name=vrtpsink"
VRTCPSINK="udpsink port=5001 host=$DEST sync=false  name=vrtcpsink"
VRTCPSRC="udpsrc port=5005 name=vrtpsrc"

gst-launch-1.0 -v rtpbin name=rtpbin ntp-time-source=clock-time \
    $VSOURCE ! $VENC ! rtpbin.send_rtp_sink_0                                             \
        rtpbin.send_rtp_src_0 ! $VRTPSINK                                                 \
        rtpbin.send_rtcp_src_0 ! $VRTCPSINK                                               \
      $VRTCPSRC ! rtpbin.recv_rtcp_sink_0         

RECEIVER PIPELINE:


VIDEO_CAPS="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)VP8"
VIDEO_CAPS2="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)VP8"

VIDEO_DEC="rtpvp8depay ! vp8dec"
VIDEO_DEC2="rtpvp8depay ! vp8dec"

VIDEO_SINK="videoconvert ! autovideosink"
VIDEO_SINK2="videoconvert ! autovideosink"

gst-launch-1.0 -v rtpbin name=rtpbin ntp-time-source=clock-time ntp-sync=true buffer-mode=synced rtcp-sync-send-time=false\
     udpsrc caps=$VIDEO_CAPS port=5000  ! rtpjitterbuffer mode=synced !  rtpbin.recv_rtp_sink_0                       \
       rtpbin.  ! $VIDEO_DEC ! $VIDEO_SINK                                             \
     udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                                       \
         rtpbin.send_rtcp_src_0 ! udpsink port=5005 host=$DEST sync=false \
     udpsrc caps=$VIDEO_CAPS2 port=6000  ! rtpjitterbuffer mode=synced ! rtpbin.recv_rtp_sink_1                       \
       rtpbin. ! $VIDEO_DEC2 ! $VIDEO_SINK2                                             \
     udpsrc port=6001  ! rtpbin.recv_rtcp_sink_1   \  
rtpbin.send_rtcp_src_1 ! udpsink port=6005 host=$DEST2 sync=false   



Thank you for your time,
Thiyagesh

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: STREAMER Synchronizing multiple sources to a common receiver

Sebastian Dröge-3
On Sa, 2016-05-07 at 14:25 -0400, thiyagesh viswanathan wrote:

> Questions I want to be answered:
> 1.Is my pipeline structure correct? 

Yes, the properties on rtpbin not so much though.

Use ntp-time-source=ntp (or unix). These two are going to use your
system clock, the setting you used will use the pipeline clock. The
pipeline clock is not going to be synchronized between all your
devices.

You might want to use rtcp-sync-send-time=false if both senders of you
have different latencies (camera, encoder, etc).

You might have to adjust the receiver pipeline latency to be high
enough for both senders. See gst_pipeline_set_latency().

ntp-sync=true and buffer-mode=synced are correct for your case.


Independent of that you need to ensure that RTCP between sender and
receiver is actually working, and synchronization will only be correct
after the first RTCP packet is received at the receiver. By default
after about 5 seconds. It can happen immediately if you set
rtp-profile=avpf on the rtpbin (well, not immediately but at some point
in the first second).

> 2.I am not modifying the pipeline clocks at all. Just assuming that
> the pipeline clocks of senders and receivers will be

If your system clocks are synchronized via NTP, then that's indeed not
necessarily needed.

> 3.synchronized once we sync the devices through NTP. Is this
> assumption correct?

> 4.Should I have just one rtpbin or separate rtpbin for each sender?

You can have one rtpbin for multiple sessions, and those sessions are
then all synced together. If you use multiple rtpbins instead, there
won't be any inter-session synchronization happening inside rtpbin.

> 5.Should i USE RTPJITTERBUFFER? if yes, should the mode be synced? 

rtpbin contains an rtpjitterbuffer already. Don't put a separate on
into your pipeline, otherwise you have two and the behaviour is not
very well then.


Does this all work better then? What is the behaviour you're seeing
now? Also does using one sender at a time result in smooth playback?

--
Sebastian Dröge, Centricular Ltd · http://www.centricular.com


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

signature.asc (968 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: STREAMER Synchronizing multiple sources to a common receiver

thiyageshv
Thank you for the quick response. I tested it out and it works very well. Though there are little latency variations. It remains < 30 ms most of the time.Though sometime it extends to more that 60 Frame rate is 15). The video playback is smooth.  I still have few questions though,

1.Will my situation improve even more if I sync pipeline clocks?
2, Is there any way to calculate the relative latency between the streams from both sources? I am assuming that I have to create my own plugin. What methods does streamer allow to achieve what I want. Even better if there is an existing plugin which I can study.
3. For the set_pipeline_latency() element, I just set the rtpbin latency in my pipeline to 500 ms. Is that fine? I mean I am not using c code for now. Just playing with the pipelines.

Thanks in advance.

> On May 10, 2016, at 2:59 AM, Sebastian Dröge <[hidden email]> wrote:
>
> On Sa, 2016-05-07 at 14:25 -0400, thiyagesh viswanathan wrote:
>>  
>> Questions I want to be answered:
>> 1.Is my pipeline structure correct?
>
> Yes, the properties on rtpbin not so much though.
>
> Use ntp-time-source=ntp (or unix). These two are going to use your
> system clock, the setting you used will use the pipeline clock. The
> pipeline clock is not going to be synchronized between all your
> devices.
>
> You might want to use rtcp-sync-send-time=false if both senders of you
> have different latencies (camera, encoder, etc).
>
> You might have to adjust the receiver pipeline latency to be high
> enough for both senders. See gst_pipeline_set_latency().
>
> ntp-sync=true and buffer-mode=synced are correct for your case.
>
>
> Independent of that you need to ensure that RTCP between sender and
> receiver is actually working, and synchronization will only be correct
> after the first RTCP packet is received at the receiver. By default
> after about 5 seconds. It can happen immediately if you set
> rtp-profile=avpf on the rtpbin (well, not immediately but at some point
> in the first second).
>
>> 2.I am not modifying the pipeline clocks at all. Just assuming that
>> the pipeline clocks of senders and receivers will be
>
> If your system clocks are synchronized via NTP, then that's indeed not
> necessarily needed.
>
>> 3.synchronized once we sync the devices through NTP. Is this
>> assumption correct?
>
>> 4.Should I have just one rtpbin or separate rtpbin for each sender?
>
> You can have one rtpbin for multiple sessions, and those sessions are
> then all synced together. If you use multiple rtpbins instead, there
> won't be any inter-session synchronization happening inside rtpbin.
>
>> 5.Should i USE RTPJITTERBUFFER? if yes, should the mode be synced?
>
> rtpbin contains an rtpjitterbuffer already. Don't put a separate on
> into your pipeline, otherwise you have two and the behaviour is not
> very well then.
>
>
> Does this all work better then? What is the behaviour you're seeing
> now? Also does using one sender at a time result in smooth playback?
>
> --
> Sebastian Dröge, Centricular Ltd · http://www.centricular.com
>
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: STREAMER Synchronizing multiple sources to a common receiver

Sebastian Dröge-3
On Mi, 2016-05-11 at 02:12 -0400, thiyagesh viswanathan wrote:
> Thank you for the quick response. I tested it out and it works very
> well. Though there are little latency variations. It remains < 30 ms
> most of the time.Though sometime it extends to more that 60 Frame
> rate is 15). The video playback is smooth.  I still have few
> questions though,

66ms would be one frame in your framerate, so what you get there seems
quite good already. You can get better than that, but going below 1
frame also requires good support from the display system and especially
rendering the right frame properly synchronized to vsync.

> 1.Will my situation improve even more if I sync pipeline clocks? 

Only if your NTP time synchronization is worse than that. You will have
to measure it. And in general you will have to measure how accurate
things are at the various steps (NTP synchronization, RTP timestamp to
pipeline clock timestamps to system time, rendering of a frame until it
gets on the screen, etc).

> 2, Is there any way to calculate the relative latency between the
> streams from both sources? I am assuming that I have to create my own
> plugin. What methods does streamer allow to achieve what I want. Even
> better if there is an existing plugin which I can study. 

The sinks of each pipeline query the latency with the LATENCY query,
and those are the values you can use. For the *sender* latency of each
individual sender. On top of that there is also the network and
receiver latency of course.

> 3. For the set_pipeline_latency() element, I just set the rtpbin
> latency in my pipeline to 500 ms. Is that fine? I mean I am not using
> c code for now. Just playing with the pipelines. 

As long as you don't want to get the "perfect" latency configuration
all this is fine, yes.

--
Sebastian Dröge, Centricular Ltd · http://www.centricular.com


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

signature.asc (968 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: STREAMER Synchronizing multiple sources to a common receiver

llama
This is quite relevant to my needs.

It looks good enough to try.

Actually, I need synchronization to ms of 10^3.

Is it possible to achieve it by here described solution or i need something more accurate like rfc7273-sync ?

And if i should use rfc7273-sync, how it changes the use of rtpbin. Can i use the same session mechanism ?
Reply | Threaded
Open this post in threaded view
|

Re: STREAMER Synchronizing multiple sources to a common receiver

Sebastian Dröge-3
On Mon, 2016-11-28 at 07:20 -0800, LC wrote:
> This is quite relevant to my needs. 
>
> It looks good enough to try. 
>
> Actually, I need synchronization to ms of 10^3. 
>
> Is it possible to achieve it by here described solution or i need
> something more accurate like rfc7273-sync ? 

You can achieve ms-accurate synchronization in either case, RFC7273
just gives you a way of advertising which clocks are used and allows
you to use them automatically without further configuration.

There are also various other ways how you can achieve synchronization,
it all depends on your setup.


The accuracy however mostly depends on a) how accurate you can
synchronize to a clock shared between the senders and receivers, and b)
how accurate the capture time measurements are, and c) how well the
latency of the different parts on the receiver are taken into account
(e.g. if you have two different display paths, you will only get
synchronization in the best case as good as the latency measurement
error between the two).

> And if i should use rfc7273-sync, how it changes the use of rtpbin.

See my other reply to your other mail :)

> Can i use the same session mechanism ?

What session mechanism do you mean?

--
Sebastian Dröge, Centricular Ltd · http://www.centricular.com
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

signature.asc (981 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: STREAMER Synchronizing multiple sources to a common receiver

llama
- RTSP senders are rtspsrc with specified uri.
- Wireless network in most cases.
- those file synchronization ideally could be based on each request. So that if some frame drops, the next request would be sourced synchronously. I expect that both frames on each file captured on separate cameras start with exactly the same frame. Currently i have doubt that this is possible, because if one frames gets dropped, there is automatically different count of frames in each file. Unless dropped frame results in coppy of the last frame.

- i mainly think of scenario like this on receiver side: gst-launch-1.0 -v rtpbin name=rtpbin                                          \
    udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,encoding-name=(string)H263-1998" \
            port=5000 ! rtpbin.recv_rtp_sink_0                                \
        rtpbin. ! ... ! filesink location=file1.mp4                    \
     udpsrc port=5001 ! rtpbin.recv_rtcp_sink_0                               \
     rtpbin.send_rtcp_src_0 ! udpsink port=5005 sync=false async=false        \
    udpsrc caps="application/x-rtp,media=(string)audio,clock-rate=(int)8000,encoding-name=(string)AMR,encoding-params=(string)1,octet-align=(string)1" \
            port=5002 ! rtpbin.recv_rtp_sink_1                                \
        rtpbin. ! ... ! filesink location=file2.mp4                           \
     udpsrc port=5003 ! rtpbin.recv_rtcp_sink_1                               \
     rtpbin.send_rtcp_src_1 ! udpsink port=5007 sync=false async=false

But as you sad, rtspsrc implements it's own rtpbin, this approach described in https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-good-plugins/html/gst-plugins-good-plugins-rtpbin.html should not be used.

As i understood, there is no way to synchronise 2 IP cameras with no reference clock.
Reply | Threaded
Open this post in threaded view
|

Re: STREAMER Synchronizing multiple sources to a common receiver

llama
In reply to this post by Sebastian Dröge-3
Yes, and previously i though to implement something like this:
gst-launch-1.0 rtpbin name=rtpbin \
        rtspsrc uri=rtsp://192.xxx.x.2/file.smp ! videoconvert ! nvh264enc ! rtph264ppay ! rtpbin.send_rtp_sink_0 \
                  rtpbin.send_rtp_src_0 ! udpsink port=5000                            \
                  rtpbin.send_rtcp_src_0 ! udpsink port=5001 sync=false async=false    \
                  udpsrc port=5005 ! rtpbin.recv_rtcp_sink_0                           \
        rtspsrc uri=rtsp://192.xxx.x.1/file2.smp ! videoconvert ! nvh264enc ! rtph264ppay ! rtpbin.send_rtp_sink_1                   \
                  rtpbin.send_rtp_src_1 ! udpsink port=5002                            \
                  rtpbin.send_rtcp_src_1 ! udpsink port=5003 sync=false async=false    \
                  udpsrc port=5007 ! rtpbin.recv_rtcp_sink_1

So, i suppose, this is not the way to go.

But what can i do ?