<div dir="ltr"><font face="arial, sans-serif">I am experiencing an issue when streaming from a live camera source to a client over a proxy</font><br><font face="arial, sans-serif">server. My current setup is the following:</font><br><br><font face="arial, sans-serif">[Live555 camera server]  <-> [Live555 Proxy server]  <-> [Client (vlc)]</font><br><br><font face="arial, sans-serif">I register a media session in the proxy. Later, the client will connect to that session via the proxy.</font><br><br><font face="arial, sans-serif">When the client connects to the server for the first time everything goes smoothly. However when I disconnect</font><br><font face="arial, sans-serif">the client and </font>re-connect<font face="arial, sans-serif"> a few times the playback will halt for an arbitrary period of time (until the client</font><br><font face="arial, sans-serif">gives up and reconnects).</font><br><br><font face="arial, sans-serif">I have tracked this problem to the proxy server starting to send RTP packets to the client with an old RTP timestamp</font><br><font face="arial, sans-serif">after an RTCP SR is sent from the server to the proxy. Without going into many details I think the core problem is</font><br><font face="arial, sans-serif">that the FramedSource I implemented for the camera is using an H264VideoStreamFramer for parsing and framing</font><br><font face="arial, sans-serif">the incoming H264 data from the camera:</font><br><br><font face="monospace">FramedSource *H264CameraMediaSubsession::createNewStreamSource(<br>    unsigned /*clientSessionId*/,<br>    unsigned &estBitrate<br>) {<br>    estBitrate = 500;  // kbps, estimate<br><br>    FramedSource *transportStreamSource = CameraDeviceSource::createNew(<br>        envir(),<br>        fFrameReader<br>    );<br><br>    return H264VideoStreamFramer::createNew(envir(), transportStreamSource);<br>}<br></font><br><font face="arial, sans-serif">I think that the problem is with the H264VideoStreamFramer passing consecutive presentation timestamps</font><br><font face="arial, sans-serif">(using the wall clock as base) to the RTPSink regardless of the PTS I set in my implementation of</font><br><font face="arial, sans-serif">CameraDeviceSource::doGetNextFrame(). I added some debug prints for figuring out what's going on the</font><br><font face="arial, sans-serif">server side:</font><br><br><font face="monospace">[Streaming is ongoing]<br>Frame PTS is 381398.975357                        [This is the PTS I pass in CameraDeviceSource::doGetNextFrame()]<br>fTimestampBase: 0x51879d3e, tv: 1582406442.526492 [This is the PTS that is passed to the RTPSink]<br>        => RTP timestamp: 1127101430 (0x432e33f6)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1127101430 (frame PTS 1582406442.526492<br>Frame PTS is 381399.055351<br>fTimestampBase: 0x51879d3e, tv: 1582406442.566492<br>        => RTP timestamp: 1127105030 (0x432e4206)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1127105030 (frame PTS 1582406442.566492<br>Frame PTS is 381399.135529<br>fTimestampBase: 0x51879d3e, tv: 1582406442.606492<br>        => RTP timestamp: 1127108630 (0x432e5016)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1127108630 (frame PTS 1582406442.606492<br>fTimestampBase: 0x51879d3e, tv: 1582406492.200539<br>        => RTP timestamp: 1131572095 (0x43726b7f)<br>SR: rtp timestamp 1131572095<br><br>[The client disconnects from proxy, a PAUSE is sent from proxy to server. Only RTCP SR packets are sent.]<br>fTimestampBase: 0x51879d3e, tv: 1582406497.240983<br>        => RTP timestamp: 1132025734 (0x43795786)<br>SR: rtp timestamp 1132025734<br>fTimestampBase: 0x51879d3e, tv: 1582406501.872705<br>        => RTP timestamp: 1132442589 (0x437fb3dd)<br>SR: rtp timestamp 1132442589<br>fTimestampBase: 0x51879d3e, tv: 1582406507.372838<br>        => RTP timestamp: 1132937601 (0x43874181)<br>SR: rtp timestamp 1132937601<br>fTimestampBase: 0x51879d3e, tv: 1582406512.151478<br>        => RTP timestamp: 1133367679 (0x438dd17f)<br>SR: rtp timestamp 1133367679<br>fTimestampBase: 0x51879d3e, tv: 1582406513.312512<br>        => RTP timestamp: 1133472172 (0x438f69ac)<br>SR: rtp timestamp 1133472172<br><br>[Client connects again to proxy. A PLAY is sent.]<br>RTPSink::presetNextTimestamp() 1582406513.313628    [The RTPSink timestamp is preset using the wall clock time]<br>fTimestampBase: 0x51879d3e, tv: 1582406513.313628<br>        => RTP timestamp: 1133472273 (0x438f6a11)<br>RTPSink::presetNextTimestamp() is adjusting timestamp<br>Frame PTS is 381421.734938                          [The PTS passed by CameraDeviceSource::doGetNextFrame() have advanced in time]<br>Frame PTS is 381421.734938<br>fTimestampBase: 0x51e8a929, tv: 1582406442.646492   [But they're ignored and the PTS used for the packet are as before the PAUSE]<br>        => RTP timestamp: 1133472273 (0x438f6a11)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1133472273 (frame PTS 1582406442.646492<br><br>[The RTP timestamps of the packet have advanced significantly from 1131572095 ->  1133472273. The proxy<br> side will simply do the increment on the frames it sends to the client so there's a discontinuity in<br> what the client sees but it doesn't care since it's a fast forward. Packets will continue to be relayed.]<br><br>Frame PTS is 381421.734938<br>fTimestampBase: 0x51e8a929, tv: 1582406442.646492<br>        => RTP timestamp: 1133472273 (0x438f6a11)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1133472273 (frame PTS 1582406442.646492<br>Frame PTS is 381421.734938<br>fTimestampBase: 0x51e8a929, tv: 1582406442.646492<br>        => RTP timestamp: 1133472273 (0x438f6a11)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1133472273 (frame PTS 1582406442.646492<br><br>...<br>[Things go bad on the next RTCP SR.]<br>fTimestampBase: 0x51e8a929, tv: 1582406517.681249<br>        => RTP timestamp: 1140225401 (0x43f67579)<br>SR: rtp timestamp 1140225401                         [The SR is computed from wall clock time. The proxy updates its fSyncTime and fSyncTimestamp with those values.]<br>Frame PTS is 381426.054815<br>fTimestampBase: 0x51e8a929, tv: 1582406445.206480<br>        => RTP timestamp: 1133702672 (0x4392ee10)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1133702672 (frame PTS 1582406445.206480<br>Frame PTS is 381426.135018<br>fTimestampBase: 0x51e8a929, tv: 1582406445.246480<br>        => RTP timestamp: 1133706272 (0x4392fc20)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1133706272 (frame PTS 1582406445.246480<br>Frame PTS is 381426.174876<br>fTimestampBase: 0x51e8a929, tv: 1582406445.286480<br>        => RTP timestamp: 1133709872 (0x43930a30)<br>MultiFramedRTPSink::setTimestamp(): RTP Packet timestamp = 1133709872 (frame PTS 1582406445.286480</font><br><br><font face="monospace">[Now the RTP packets received by the proxy are considered to be 72 seconds in the past. The normalizer employed by the proxy<br> will account for this change relaying older packets to the client as well. The client will refuse accepting those as they're<br> considered to be late. You may notice the time diff between CameraDeviceSource::doGetNextFrame() PTS and the one derived<br> by the H264VideoStreamFramer is actually less than 72s (~22s) - I believe this is because the sample I pasted here<br> is actually after running the client a few times and the delay is aggregated on each PAUSE sent to the server.]<br><br></font><br><font face="arial, sans-serif">I may have been misusing the H264or5VideoStreamFramer for streaming from a live source. If that is the case</font><br><font face="arial, sans-serif">I would appreciate some guidance in how things should be done differently. If H264or5VideoStreamFramer is</font><br><font face="arial, sans-serif">the way to go for live H264 sources as well then it may be missing an API that should be invoked when streaming</font><br><font face="arial, sans-serif">is </font>paused<font face="arial, sans-serif">/resumed in order to make it update its own time base. I would appreciate some guidance on this issue.</font><br><br><br><font face="arial, sans-serif">Thanks,</font><br><font face="arial, sans-serif">Micha</font><br clear="all"><div><font face="arial, sans-serif"><br></font></div><font face="arial, sans-serif">-- <br></font><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><p class="MsoNormal"><span lang="en-IL" style="font-size:12pt;color:rgb(2,2,6)"><font face="arial, sans-serif">Micha Kalfon</font></span></p><p class="MsoNormal"><span lang="en-IL" style="font-size:12pt;color:rgb(2,2,6)"><font face="arial, sans-serif">Software Engineer</font></span></p><div style="direction:ltr"><p class="MsoNormal"><font face="arial, sans-serif"><span lang="en-IL" style="font-size:12pt;color:rgb(2,2,6)">Toka - Cyber Builders</span><span lang="en-IL" style="font-size:12pt"><u></u><u></u></span></font></p><p class="MsoNormal"><span lang="en-IL" style="font-size:12pt;color:rgb(2,2,6)"><font face="arial, sans-serif">(CyberToka Ltd.)</font></span></p><p class="MsoNormal"><span lang="en-IL" style="font-size:12pt;color:rgb(2,2,6)"><font face="arial, sans-serif">Mail: <a href="mailto:micha@tokagroup.com" target="_blank">micha@tokagroup.com</a></font></span></p><p class="MsoNormal"><span lang="en-IL" style="font-size:12pt;color:rgb(2,2,6)"><font face="arial, sans-serif">Mobile: +972-52-6086486</font></span></p></div></div></div></div>