<!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><SPAN class=882214715-08112012><FONT color=#0000ff
size=2 face=Arial>The windows (not CE) implementation wasn't threadsafe, so
I've changed that code too.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=882214715-08112012><FONT color=#0000ff
size=2 face=Arial>Find attached the new GroupsockHelper.cpp. This solution is ok
for us, so I won't spend any further time in this topic</FONT></SPAN></DIV><BR>
<DIV dir=ltr lang=en-us class=OutlookMessageHeader align=left>
<HR tabIndex=-1>
<FONT size=2 face=Tahoma><B>From:</B> live-devel-bounces@ns.live555.com
[mailto:live-devel-bounces@ns.live555.com] <B>On Behalf Of </B>Ross
Finlayson<BR><B>Sent:</B> Dienstag, 6. November 2012 16:00<BR><B>To:</B> LIVE555
Streaming Media - development & use<BR><B>Subject:</B> Re: [Live-devel]
Timestamp conversion in RTPSink.cpp<BR></FONT><BR></DIV>
<DIV></DIV>
<DIV>
<BLOCKQUOTE type="cite">
<DIV
style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
<DIV><SPAN style="FONT-FAMILY: Arial; FONT-SIZE: small">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:</SPAN></DIV></DIV></BLOCKQUOTE></DIV>
<DIV>
<BLOCKQUOTE type="cite">
<DIV
style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
<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></BLOCKQUOTE>
<DIV><BR></DIV></DIV>Correction: On further thought, I don't want to make this
change 'as is'. The problem is that it's possible for the "gettimeofday()"
function to be called concurrently from multiple threads. (This is legal
for LIVE555-based systems that use different "UsageEnvironment" and
"TaskScheduler" objects for each thread.) So, the implementation needs to
be 'thread safe'. If the "if" branch of the "if (isFirstCall)" statement
gets executed concurrently by more than one thread, then "unixStartTime" and/or
"firstTickCount" might get set to bad values.
<DIV><BR></DIV>
<DIV>So, please rewrite your implementation to ensure that the "if" branch of
the code (i.e., the part of the code that sets static variables) is executed
only once, even if the code is called by multiple threads. (Because this
code is for WinCE only, it's OK to use some WinCE-specific locking mechanism, if
necessary.)</DIV>
<DIV><BR></DIV>
<DIV>(However, I'll make the change to the timestamp conversion code in the next
release of the software.)<BR><BR>
<DIV apple-content-edited="true"><SPAN
style="BORDER-SPACING: 0px; BORDER-COLLAPSE: separate"
class=Apple-style-span>Ross Finlayson<BR>Live Networks, Inc.<BR><A
href="http://www.live555.com/">http://www.live555.com/</A></SPAN>
</DIV><BR></DIV></BODY></HTML>