[Live-devel] [PATCH 4/4] StreamReplicator: add frame delivery timeout

Stas Tsymbalov tsymbalov at trueconf.ru
Mon May 25 09:04:20 PDT 2015


>> In our application replicas are being used by RTPSinks, to multiply one source (from encoder) to multiple clients using class derived from OnDemandServerMediaSubsession (we need to support unicast).
> 
> If all of your clients are unicast RTSP clients, all using just one “OnDemandServerMediaSubsession” subclass, then you shouldn’t need to use “StreamReplicator” at all.  Instead, just ensure that your “OnDemandServerMediaSubsession” subclass’s constructor sets the “reuseFirstSource” parameter to True when it calls the parent (“OnDemandServerMediaSubsession”) constructor.  Setting the “reuseFirstSource” parameter to True will ensure that only one instance of your encoder source (your “FramedSource” subclass) is in existence at any time.  (You must still allow for your “FramedSource” subclass to be closed, then later re-opened; however, no more than one object of this class will be in existence at any given time.)
> 
> In this case the ‘replication’ (transmitting packets to the multiple unicast clients) will happen automatically at a lower level, inside the “Groupsock” object.

I have already tried this, and it worked terribly. With StreamReplicator and reuseFirstSource==False I have managed to send VP8 video to about 400 clients for 500-900 Mbit/s total bandwidth. With reuseFirstSource==True after 20 connected  clients send errors have started to appear, and after about 40 clients video on clients became unwatchable due to packet loss. My guess this happened because with reuseFirstSource==True OnDemandServerMediaSubsession uses just one socket to send to all clients and hence all data goes through one OS socket send buffer which is simply not big enough to handle that much data. This happens on Windows by the way (send error is WSAEWOULDBLOCK), maybe on normal operating systems this will work fine, but unfortunately our application has to work on Windows.

>> To summarize: If timeout checks are made independently  for each of N replicas there will be 2*N scheduled tasks for each frame (1 made by RTPSink + 1 for timeout check) and N tasks will get canceled (in the normal mode of operation, when timeouts are never reached). If timeout checks are made in bulk like in proposed patch there will be N+1 scheduled tasks and 1 canceled task for each frame.
> 
> Why not have your application create just one timeout task, but - when this task is run - have it check all of the N replicas at once?

In proposed patch timeout timer starts after frame is received from source, there is no way to hook to this event from outside of StreamReplicator. Starting timer after first replica receives current frame won't work because theoretically all replicas may fail to request frames. Starting timer when first replica requests current frame doesn't make much sense because I don't want delays caused by all source chain to affect this timeout (I want it to be just for StreamReplicator operations, and very small (about 1.5 video frame lengths)).

Anyway, sorry for wasting your time with specifics of my use-case. I just wanted explain why I think that including timeouts in StreamReplicator and not somewhere else is better.

-- 
Stas Tsymbalov
TrueConf LLC
http://trueconf.com/


More information about the live-devel mailing list