Skip to content

Commit ade1739

Browse files
Ahmad-S792Ahmad Saleem
authored andcommitted
RTCRtpSynchronizationSource.timestamp should use wall time, not monotonic time
https://bugs.webkit.org/show_bug.cgi?id=307036 rdar://169679084 Reviewed by Youenn Fablet. This patch aligns WebKit with Gecko / Firefox and Blink / Chromium. The timestamp field in RTCRtpSynchronizationSource and RTCRtpContributingSource was using libwebrtc's monotonic timestamp directly, but the WebRTC spec requires DOMHighResTimeStamp which is relative to the Unix epoch (wall time). This caused test failures where timestamps were not comparable to performance.timeOrigin + performance.now(). Fix by converting from libwebrtc's monotonic time to wall time using the offset between webrtc::TimeMillis() and WallTime::now(). The offset is computed once per LibWebRTCRtpReceiverBackend instance and cached to avoid repeated calculations. * Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverBackend.cpp: (WebCore::LibWebRTCRtpReceiverBackend::webrtcToWallTimeOffset const): (WebCore::fillRTCRtpContributingSource): (WebCore::toRTCRtpContributingSource): (WebCore::toRTCRtpSynchronizationSource): (WebCore::LibWebRTCRtpReceiverBackend::getContributingSources const): (WebCore::LibWebRTCRtpReceiverBackend::getSynchronizationSources const): * Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverBackend.h: * LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https-expected.txt: Progressions Canonical link: https://commits.webkit.org/307063@main
1 parent 34bbf22 commit ade1739

File tree

3 files changed

+29
-12
lines changed

3 files changed

+29
-12
lines changed

LayoutTests/imported/w3c/web-platform-tests/webrtc/RTCRtpReceiver-getSynchronizationSources.https-expected.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ PASS [audio] getSynchronizationSources() eventually returns a non-empty list
33
PASS [audio] RTCRtpSynchronizationSource.timestamp is a number
44
PASS [audio] RTCRtpSynchronizationSource.rtpTimestamp is a number [0, 2^32-1]
55
PASS [audio] getSynchronizationSources() does not contain SSRCs older than 10 seconds
6-
FAIL [audio] RTCRtpSynchronizationSource.timestamp is comparable to performance.timeOrigin + performance.now() assert_true: expected true got false
6+
PASS [audio] RTCRtpSynchronizationSource.timestamp is comparable to performance.timeOrigin + performance.now()
77
PASS [audio] RTCRtpSynchronizationSource.source is a number
88
PASS [video] getSynchronizationSources() eventually returns a non-empty list
99
PASS [video] RTCRtpSynchronizationSource.timestamp is a number
1010
PASS [video] RTCRtpSynchronizationSource.rtpTimestamp is a number [0, 2^32-1]
1111
PASS [video] getSynchronizationSources() does not contain SSRCs older than 10 seconds
12-
FAIL [video] RTCRtpSynchronizationSource.timestamp is comparable to performance.timeOrigin + performance.now() assert_true: expected true got false
12+
PASS [video] RTCRtpSynchronizationSource.timestamp is comparable to performance.timeOrigin + performance.now()
1313
PASS [video] RTCRtpSynchronizationSource.source is a number
1414
PASS [audio-only] RTCRtpSynchronizationSource.audioLevel is a number [0, 1]
1515

Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverBackend.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2018 Apple Inc. All rights reserved.
2+
* Copyright (C) 2018-2026 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -39,7 +39,9 @@
3939
#include "RealtimeIncomingAudioSource.h"
4040
#include "RealtimeIncomingVideoSource.h"
4141
#include "Settings.h"
42+
#include <wtf/MonotonicTime.h>
4243
#include <wtf/TZoneMallocInlines.h>
44+
#include <wtf/WallTime.h>
4345

4446
namespace WebCore {
4547

@@ -57,45 +59,57 @@ RTCRtpParameters LibWebRTCRtpReceiverBackend::getParameters()
5759
return toRTCRtpParameters(m_rtcReceiver->GetParameters());
5860
}
5961

60-
static inline void fillRTCRtpContributingSource(RTCRtpContributingSource& source, const webrtc::RtpSource& rtcSource)
62+
double LibWebRTCRtpReceiverBackend::webrtcToWallTimeOffset() const
6163
{
62-
source.timestamp = rtcSource.timestamp().ms();
64+
if (!m_webrtcToWallTimeOffset) {
65+
auto currentWebRTCTime = webrtc::TimeMillis();
66+
auto currentWallTime = WallTime::now();
67+
m_webrtcToWallTimeOffset = currentWallTime.secondsSinceEpoch().milliseconds() - currentWebRTCTime;
68+
}
69+
return *m_webrtcToWallTimeOffset;
70+
}
71+
72+
static inline void fillRTCRtpContributingSource(RTCRtpContributingSource& source, const webrtc::RtpSource& rtcSource, double webrtcToWallTimeOffset)
73+
{
74+
source.timestamp = rtcSource.timestamp().ms() + webrtcToWallTimeOffset;
6375
source.rtpTimestamp = rtcSource.rtp_timestamp();
6476
source.source = rtcSource.source_id();
6577
if (rtcSource.audio_level())
6678
source.audioLevel = (*rtcSource.audio_level() == 127) ? 0 : pow(10, -*rtcSource.audio_level() / 20);
6779
}
6880

69-
static inline RTCRtpContributingSource toRTCRtpContributingSource(const webrtc::RtpSource& rtcSource)
81+
static inline RTCRtpContributingSource toRTCRtpContributingSource(const webrtc::RtpSource& rtcSource, double webrtcToWallTimeOffset)
7082
{
7183
RTCRtpContributingSource source;
72-
fillRTCRtpContributingSource(source, rtcSource);
84+
fillRTCRtpContributingSource(source, rtcSource, webrtcToWallTimeOffset);
7385
return source;
7486
}
7587

76-
static inline RTCRtpSynchronizationSource toRTCRtpSynchronizationSource(const webrtc::RtpSource& rtcSource)
88+
static inline RTCRtpSynchronizationSource toRTCRtpSynchronizationSource(const webrtc::RtpSource& rtcSource, double webrtcToWallTimeOffset)
7789
{
7890
RTCRtpSynchronizationSource source;
79-
fillRTCRtpContributingSource(source, rtcSource);
91+
fillRTCRtpContributingSource(source, rtcSource, webrtcToWallTimeOffset);
8092
return source;
8193
}
8294

8395
Vector<RTCRtpContributingSource> LibWebRTCRtpReceiverBackend::getContributingSources() const
8496
{
8597
Vector<RTCRtpContributingSource> sources;
98+
auto offset = webrtcToWallTimeOffset();
8699
for (auto& rtcSource : m_rtcReceiver->GetSources()) {
87100
if (rtcSource.source_type() == webrtc::RtpSourceType::CSRC)
88-
sources.append(toRTCRtpContributingSource(rtcSource));
101+
sources.append(toRTCRtpContributingSource(rtcSource, offset));
89102
}
90103
return sources;
91104
}
92105

93106
Vector<RTCRtpSynchronizationSource> LibWebRTCRtpReceiverBackend::getSynchronizationSources() const
94107
{
95108
Vector<RTCRtpSynchronizationSource> sources;
109+
auto offset = webrtcToWallTimeOffset();
96110
for (auto& rtcSource : m_rtcReceiver->GetSources()) {
97111
if (rtcSource.source_type() == webrtc::RtpSourceType::SSRC)
98-
sources.append(toRTCRtpSynchronizationSource(rtcSource));
112+
sources.append(toRTCRtpSynchronizationSource(rtcSource, offset));
99113
}
100114
return sources;
101115
}

Source/WebCore/Modules/mediastream/libwebrtc/LibWebRTCRtpReceiverBackend.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2018 Apple Inc. All rights reserved.
2+
* Copyright (C) 2018-2026 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -55,8 +55,11 @@ class LibWebRTCRtpReceiverBackend final : public RTCRtpReceiverBackend {
5555
Ref<RTCRtpTransformBackend> rtcRtpTransformBackend() final;
5656
std::unique_ptr<RTCDtlsTransportBackend> dtlsTransportBackend() final;
5757

58+
double webrtcToWallTimeOffset() const;
59+
5860
const Ref<webrtc::RtpReceiverInterface> m_rtcReceiver;
5961
const RefPtr<RTCRtpTransformBackend> m_transformBackend;
62+
mutable std::optional<double> m_webrtcToWallTimeOffset;
6063
};
6164

6265
} // namespace WebCore

0 commit comments

Comments
 (0)