[Live-devel] Problem with gettimeofday() in GroupsockHelper.cpp

David Arnold darnold at futurec.net
Tue Oct 24 10:50:14 PDT 2006


We have been having many timing and synchonization problems that I believe I
have isolated to a problem in the implementation of gettimeofday() in
groupsockHelper.cpp for Windoze.  The problem is the time returned from
ftime() has a resolution of about 15 milliseconds.  Since the task scheduler
uses this time for scheduling and interval times for frames for our
application are 24000 microseconds and 66667 microseconds, gettimeofday()
needs to return times of higher resolution.  The changes I have made to
gettimeofday() are included below.  As you can see, I use
QueryPerformanceCounter(), which I believe has a resolution of about
100-nanoseconds.  I have tested this change and it has solved our problems.
If you see a problem with this solution or suggest an alternate I would
appreciate your suggestions.

Thank you,

Dave Arnold
Future Concepts, La Verne, CA

--- groupsockHelper.cpp

[...]

int gettimeofday(struct timeval* tp, int* /*tz*/) {
#if defined(_WIN32_WCE)
  /* FILETIME of Jan 1 1970 00:00:00. */
  static const unsigned __int64 epoch = 116444736000000000L;

  FILETIME    file_time;
  SYSTEMTIME  system_time;
  ULARGE_INTEGER ularge;

  GetSystemTime(&system_time);
  SystemTimeToFileTime(&system_time, &file_time);
  ularge.LowPart = file_time.dwLowDateTime;
  ularge.HighPart = file_time.dwHighDateTime;

  tp->tv_sec = (long) ((ularge.QuadPart - epoch) / 10000000L);
  tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
#else
#if 0
  struct timeb tb;
  ftime(&tb);
  tp->tv_sec = tb.time;
  tp->tv_usec = 1000*tb.millitm;
#endif
    LARGE_INTEGER tickNow;
	static LARGE_INTEGER tickFrequency;
	static BOOL tickFrequencySet = FALSE;
	if (tickFrequencySet == FALSE) {
		QueryPerformanceFrequency(&tickFrequency);
		tickFrequencySet = TRUE;
	}
  	QueryPerformanceCounter(&tickNow);
	tp->tv_sec = tickNow.QuadPart / tickFrequency.QuadPart;
	tp->tv_usec =((tickNow.QuadPart % tickFrequency.QuadPart) * 1000000L) /
tickFrequency.QuadPart;
#endif
  return 0;
}
#endif

-----Original Message-----
From: live-devel-bounces at ns.live555.com
[mailto:live-devel-bounces at ns.live555.com]On Behalf Of David Betrand
Sent: Tuesday, October 24, 2006 3:14 AM
To: LIVE555 Streaming Media - development & use
Subject: Re: [Live-devel] Change Request about rtp timestamping when
doing PAUSE/PLAY


Ross,
> > I noted that live555 implementation for this consists of
> setting > in the rtp-info header a rtptime value corresponding to
> the last > RTP timestamp sent for this track
>
> I believe this is correct, because the RTP timestamp *does* increase
> appropriately after a PAUSE/PLAY (see below).

The problem here is not the timestamps present in the RTP packets,
they are correct. It is the "rtptime" value present in the PLAY
Response which is incorrect because it equals to the last rtp
timestamp sent BEFORE the Pause. (see usage of rtpSink()->currentTimestamp()
in OnDemandServerMediaSubsession::startStream())


Following RFC2326bis, the
definition of "rtptime" is the following :
rtptime: SHALL indicate the RTP timestamp value corresponding to
              the start time value in the Range response header, or if
              not explicitly given the implied start point. The client
              uses this value to calculate the mapping of RTP time to NPT
              or other media timescale. This parameter SHOULD be present
              to ensure inter-media synchronization is achieved. There
              exist no requirement that any received RTP packet will have
              the same RTP timestamp value as the one in the parameter
              used to establish synchronization.

You cannot use an old value for this rtptime otherwise players will
think the packets they receive are in the future. That's exactly
what VLC think  (see VLC output message in attachment, starting
from the time I resumed the stream).
In the example sent in my previous email (extracted from the RFC2326bis) you
can see that this rtptime value is coherent with the start time value in the
Range response header (20 seconds elapsed between the PAUSE and the PLAY, so
the rtptime jumps from 2400 to 164400).

To summarize, I would say that -at least in this case- you cannot use
fCurrentTimestamp as rtptime value.
David


--
_______________________________________________
Surf the Web in a faster, safer and easier way:
Download Opera 9 at http://www.opera.com

Powered by Outblaze

The information contained in this electronic mail transmission is intended only for the use of the individual or entity named above and is privileged and confidential. If you are not the intended recipient, please do not read, copy, use or disclose this communication to others. Any dissemination, distribution or copying of this communication other than to the person or entity named above is strictly prohibited. If you have received this communication in error, please immediately delete it from your system.




More information about the live-devel mailing list