Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/selkies/webrtc/clock.py: 44%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This Source Code Form is subject to the terms of the Mozilla Public
2# License, v. 2.0. If a copy of the MPL was not distributed with this
3# file, You can obtain one at https://mozilla.org/MPL/2.0/.
4#
5# This file incorporates work covered by the following copyright and
6# permission notice:
7#
8# Copyright (c) Jeremy Lainé.
9# All rights reserved.
10#
11# Redistribution and use in source and binary forms, with or without
12# modification, are permitted provided that the following conditions are met:
13#
14# * Redistributions of source code must retain the above copyright notice,
15# this list of conditions and the following disclaimer.
16# * Redistributions in binary form must reproduce the above copyright notice,
17# this list of conditions and the following disclaimer in the documentation
18# and/or other materials provided with the distribution.
19# * Neither the name of aiortc nor the names of its contributors may
20# be used to endorse or promote products derived from this software without
21# specific prior written permission.
22#
23# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
27# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34import datetime
35import time
37NTP_EPOCH = datetime.datetime(1900, 1, 1, tzinfo=datetime.timezone.utc)
38# Seconds from the NTP epoch to the Unix epoch.
39NTP_UNIX_OFFSET = 2208988800
41# The NTP clock the senders stamp and report is CLOCK_MONOTONIC placed on the
42# wall clock once, as libwebrtc's is: a capture instant the capture library
43# stamped on CLOCK_MONOTONIC maps into it exactly, and a step of the wall clock
44# never moves it between two sender reports.
45_NTP_OFFSET_NS = time.time_ns() + NTP_UNIX_OFFSET * 1_000_000_000 - time.monotonic_ns()
48def current_datetime() -> datetime.datetime:
49 return datetime.datetime.now(datetime.timezone.utc)
52def current_ms() -> int:
53 delta = current_datetime() - NTP_EPOCH
54 return int(delta.total_seconds() * 1000)
57def ntp_from_monotonic_ns(instant_ns: int) -> int:
58 """The 64-bit NTP timestamp of a CLOCK_MONOTONIC instant in nanoseconds."""
59 seconds, rest = divmod(instant_ns + _NTP_OFFSET_NS, 1_000_000_000)
60 return ((seconds & 0xFFFFFFFF) << 32) | ((rest << 32) // 1_000_000_000)
63def current_ntp_time() -> int:
64 """The NTP timestamp now: every RTP packet stamps one, so no datetime is
65 built on the way."""
66 return ntp_from_monotonic_ns(time.monotonic_ns())
69def datetime_from_ntp(ntp: int) -> datetime.datetime:
70 seconds = ntp >> 32
71 microseconds = ((ntp & 0xFFFFFFFF) * 1000000) / (1 << 32)
72 return NTP_EPOCH + datetime.timedelta(seconds=seconds, microseconds=microseconds)
75def datetime_to_ntp(dt: datetime.datetime) -> int:
76 delta = dt - NTP_EPOCH
77 high = int(delta.total_seconds())
78 low = round((delta.microseconds * (1 << 32)) // 1000000)
79 return (high << 32) | low