[Live-devel] pause issue
Gilles Chanteperdrix
gilles.chanteperdrix at xenomai.org
Sun Feb 22 04:55:15 PST 2015
Hi Ross,
I think I got to the bottom of my issues using RTSP pause with a
server using live555 issue, and I believe there might be an issue
with live555.
The source of the problem is that when resuming from a pause, a few
packets are sent with a date in the past. If you take
MultiFramedRTPSink for instance, when restarting from a pause,
"continuePlaying" gets called, which ends up calling packFrame, and
packFrame will reuse the overflow data presentationTime when there
is some overflow data, and this presentationTime is before the time
of the pause. Even if MultiFramedRTPSink could be fixed to
avoid that (for instance by waiting to have sent all overflow data
before pausing), nothing prevents a framer or filter to do exactly
the same thing.
This has two consequences:
- a frequent one, in MultiFramedRTPSink, fInitialPresentationTime
may be set to this date in the past. But this only has a consequence
when resuming from the next pause (so, you need to pause and resume
twice to observe the problem), that the computed start NPT is wrong.
- a less frequent one, this date in the past is used in
RTPSink::convertToRTPTimestamp to compute the new timestamp base
when resuming, and this value ends up being off as well.
The following patch avoid these issues:
diff --git a/liveMedia/MultiFramedRTPSink.cpp b/liveMedia/MultiFramedRTPSink.cpp
index c86ff03..4e36719 100644
--- a/liveMedia/MultiFramedRTPSink.cpp
+++ b/liveMedia/MultiFramedRTPSink.cpp
@@ -241,7 +241,7 @@ void MultiFramedRTPSink
fMostRecentPresentationTime = presentationTime;
if (fInitialPresentationTime.tv_sec == 0 && fInitialPresentationTime.tv_usec
== 0) {
- fInitialPresentationTime = presentationTime;
+ gettimeofday(&fInitialPresentationTime, NULL);
}
if (numTruncatedBytes > 0) {
diff --git a/liveMedia/RTPSink.cpp b/liveMedia/RTPSink.cpp
index 21e73e9..7ffa4ba 100644
--- a/liveMedia/RTPSink.cpp
+++ b/liveMedia/RTPSink.cpp
@@ -78,9 +78,16 @@ u_int32_t RTPSink::convertToRTPTimestamp(struct timeval tv) {
// Then add this to our 'timestamp base':
if (fNextTimestampHasBeenPreset) {
+ u_int32_t baseIncrement;
+ struct timeval now;
+ gettimeofday(&now, NULL);
+
+ baseIncrement = (fTimestampFrequency*now.tv_sec);
+ baseIncrement += (u_int32_t)(fTimestampFrequency*(now.tv_usec/1000000.0) + 0.5); // note: rounding
+
// Make the returned timestamp the same as the current "fTimestampBase",
// so that timestamps begin with the value that was previously preset:
- fTimestampBase -= timestampIncrement;
+ fTimestampBase -= baseIncrement;
fNextTimestampHasBeenPreset = False;
}
This may be thought as papering over the real bug, but it seems much
easier to me to accept these wrong timestamps and let the client cope
with them (the client will probably let a video with a wrong
timestamp reach the decoder and get rid of it before display, in
case this is a reference frame) than to try and avoid them.
Something I also discovered, is that MultiFramedRTPSink will start
sending packets as soon as StreamState::startPlaying is called, so
that some packets will be sent with the old timestamp base, before
presetNextTimestamp is called in
OnDemandServerMediaSession::startStream, but I have not found any
negative consequences of that (well, except that the client drops the
packets because they have wrong timestamps). I have tried calling
currentSeqNo and presetNextTimestamp before
StreamState::startPlaying, but ended up with de-synchronized audio
and video tracks.
Sorry for the long mail.
Regards.
--
Gilles.
More information about the live-devel
mailing list