<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=us-ascii" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.6001.23415"></HEAD>
<BODY
style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
<DIV dir=ltr align=left><FONT color=#0000ff size=2
face=Arial></FONT> </DIV>
<DIV></DIV>
<DIV>
<BLOCKQUOTE type="cite">
<DIV>
<DIV><FONT face=Arial>
<DIV><FONT size=2 face=Arial><SPAN class=580024614-05112012>we want to use
live555 in one of our products on the WinCE platform and we have some
issues with timestamp calculation.</SPAN></FONT></DIV>
<DIV><FONT size=2 face=Arial><SPAN class=580024614-05112012>From file
liveMedia/RTPSink.cpp:</SPAN></FONT></DIV>
<DIV><SPAN class=580024614-05112012>
<P><FONT size=2 face="Courier New">u_int32_t
RTPSink::convertToRTPTimestamp(<FONT color=#0000ff><FONT
color=#0000ff>struct</FONT></FONT> timeval tv) {</FONT></P>
<P><FONT color=#008000><FONT color=#008000><FONT size=2 face="Courier New">//
Begin by converting from "struct timeval" units to RTP timestamp
units:</FONT></FONT></FONT></P>
<P><FONT size=2 face="Courier New">u_int32_t timestampIncrement =
(fTimestampFrequency*tv.tv_sec);</FONT></P>
<P><FONT size=2 face="Courier New"><U>timestampIncrement +=
(u_int32_t)((2.0*fTimestampFrequency*tv.tv_usec +
1000000.0)/2000000);</U></FONT></P>
<P><FONT color=#008000><FONT color=#008000 size=2 face="Courier New">// note:
rounding</FONT></FONT></P>
<P><SPAN class=580024614-05112012><FONT color=#008000
size=2>...</FONT></SPAN></P></SPAN></DIV>
<DIV><FONT size=2><SPAN class=580024614-05112012>Could you tell me why you are
calculation the timstampIncrement like
this?</SPAN></FONT></DIV></FONT></DIV></DIV></BLOCKQUOTE>
<DIV><BR></DIV>It's done this way so that the result is rounded to the nearest
integer. Suppose, for example, that "fTimestampFrequency*tv.tv_usec" is
1990000. Computing "tv.tv_usec*fTimestampFrequency/1000000.0" will give
you 1 (when converted back to an "int"). However, computing
"(2.0*fTimestampFrequency*tv.tv_usec + 1000000.0)/2000000" will give you 2,
which is more accurate.</DIV>
<DIV><BR></DIV>
<DIV>What specific 'issues' do you think you are having with timestamp
calculation? Are you having a problem specifically with this line of
code?? If not, then your 'issues' are probably not with timestamp
calculation. Note that developers usually don't need to concern themselves
with RTP timestamps; our software automatically converts presentation times to
RTP timestamps (on transmission), and then back to presentation times (on
reception). As a developer, the important thing that you need to concern
yourself with is ***presentation times***. Your data sources' frames
*must* have accurate presentation times, and they must be aligned to 'wall
clock' time (i.e., the time that you would get by calling
"gettimeofday()".)</DIV>
<DIV><FONT color=#0000ff size=2 face=Arial></FONT><BR><SPAN
class=719273517-05112012> </SPAN></DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2><FONT face=Arial>Thank you very
much for your answer. Your words make sense concerning the
calculation!</FONT> </FONT></SPAN></DIV>
<DIV><FONT face=Arial><FONT size=2><FONT color=#0000ff><SPAN
class=719273517-05112012><FONT color=#000000>There were two different
(independent) problems:</FONT></SPAN></FONT></FONT></FONT></DIV>
<DIV><FONT face=Arial><FONT size=2><FONT color=#0000ff><SPAN
class=719273517-05112012><FONT color=#000000>1 the underlined line returns 0
on Freescale's I.MX53 ARM cpu, the reason: </FONT> </SPAN><SPAN
class=719273517-05112012> </SPAN><SPAN
class=719273517-05112012> "<FONT color=#000000
face="Courier New">fTimestampFrequency*tv.tv_usec" <FONT face=Arial>is too large
for 32bit. As the datatype of "timestampIncrement" is u_int32_t the calculation
is performed with 32 bit width. On a 64bit PC this seems not to be a problem
because it calculates automatically with 64bit. The fix for this is to use a
u_int64_t variable which is casted back to 32bit in the addition of
TimestampBase and
incrementTimestamp.</FONT></FONT></SPAN></FONT></FONT></FONT></DIV>
<DIV><FONT face=Arial><FONT size=2><SPAN
class=719273517-05112012></SPAN></FONT></FONT> </DIV>
<DIV><SPAN class=719273517-05112012></SPAN><SPAN
class=719273517-05112012></SPAN><FONT face=Arial><FONT size=2>2<SPAN
class=719273517-05112012> in the gettimeofday function in
GroupSockHelper.cpp (line 700):</SPAN></FONT></FONT></DIV>
<DIV><SPAN class=719273517-05112012></SPAN><SPAN class=719273517-05112012><FONT
size=2 face=Arial> Theres a define for WinCE, but
unfortunately the WinCE version oft gettimeofday is not working properly, I
assume that it wasn't tested? You can find alot occurences of this problem in
WinCE world. The problem is the "GetSystemTime()" call, which should fill the
SYSTEMTIME struct, but it does not, at least not the milliseconds field (which
is always 0). The solution I used:</FONT></SPAN></DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face=Arial></FONT></SPAN> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2 face="Courier New">int
gettimeofday(struct timeval* tp, int* /*tz*/) {<BR>#if
defined(_WIN32_WCE)<BR> /* FILETIME of Jan 1 1970 00:00:00. */<BR>
static const unsigned __int64 epoch = 116444736000000000LL;<BR> static
Boolean isFirstCall = True;<BR> static LONGLONG unixStartTime =
0;<BR> static DWORD firstTickCount=0;</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2 face="Courier New"> if
(isFirstCall) {</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face="Courier New"> FILETIME fileTime;</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face="Courier New">
GetSystemTimeAsFileTime(&fileTime);</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face="Courier New"> LARGE_INTEGER date;<BR>
date.HighPart = fileTime.dwHighDateTime;<BR> date.LowPart =
fileTime.dwLowDateTime;</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face="Courier New"> unixStartTime= (date.QuadPart - epoch) /
10000000L;</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face="Courier New"> firstTickCount =
GetTickCount();</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face="Courier New">
tp->tv_sec=(long)unixStartTime;<BR> tp->tv_usec=
0L;</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face="Courier New"> isFirstCall = False; // for next
time</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2 face="Courier New"> }
else {<BR> // add elapsed seconds<BR>
tp->tv_sec= (long)unixStartTime +
(GetTickCount()-firstTickCount)/1000;<BR>
tp->tv_usec=(GetTickCount()-firstTickCount)%1000 *
1000;<BR>}</FONT></SPAN></DIV>
<DIV><FONT face="Courier New"></FONT> </DIV>
<DIV><SPAN class=719273517-05112012><FONT size=2
face="Courier New">#else</FONT></SPAN></DIV>
<DIV><SPAN class=719273517-05112012></SPAN><FONT face=Arial><FONT size=2>.<SPAN
class=719273517-05112012>..</SPAN></FONT></FONT><BR><BR></DIV></BODY></HTML>