commit 03d94be6ac1af230a71b5d434316483f4986bd03
parent a374c4a8866ce42e8a013010af41e6442cbb1ae4
Author: Michael Froman <mfroman@mozilla.com>
Date: Wed, 8 Oct 2025 16:49:36 -0500
Bug 1993083 - Vendor libwebrtc from 8c11384a5a
Upstream commit: https://webrtc.googlesource.com/src/+/8c11384a5a19289e7767a01180e988ad8a92df91
Reland "Record audio timestamp across all ObjC ADMs."
This is a reland of commit fa780492c902b0b0079386178b21b9c61221f25e
Original change's description:
> Record audio timestamp across all ObjC ADMs.
>
> Added audio timestamp capture to ObjCAudioDeviceModule and extracted
> nanoseconds from AudioTimeStamp construction into helper function.
>
> The timestamp capture was initially implemented in the CL:
> https://webrtc-review.googlesource.com/c/src/+/334720
>
> No-Try: True
> Bug: webrtc:13609
> Change-Id: I68d5c29ccc98cf817365988fa825875841e32ee7
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/397160
> Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
> Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
> Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
> Cr-Commit-Position: refs/heads/main@{#45000}
Bug: webrtc:13609
Change-Id: I82d753d02b17b917b4d57ce3e466a685ce1c7bca
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/397760
Commit-Queue: Yury Yarashevich <yura.yaroshevich@gmail.com>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#45021}
Diffstat:
10 files changed, 112 insertions(+), 23 deletions(-)
diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor
@@ -1,4 +1,4 @@
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc
-libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-08T21:48:22.055639+00:00.
+libwebrtc updated from /home/mfroman/mozilla/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-10-08T21:49:25.050386+00:00.
# base of lastest vendoring
-0b167190c5
+8c11384a5a
diff --git a/third_party/libwebrtc/moz-patch-stack/s0055.patch b/third_party/libwebrtc/moz-patch-stack/s0055.patch
@@ -26,10 +26,10 @@ index df103651c2..8c481ad633 100644
deps += [ "logging:rtc_event_log_proto" ]
}
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
-index 26fc06efa8..7aa3c3f428 100644
+index 3db2086d9e..06da79a112 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
-@@ -553,6 +553,7 @@ if (is_ios || is_mac) {
+@@ -576,6 +576,7 @@ if (is_ios || is_mac) {
}
}
@@ -37,7 +37,7 @@ index 26fc06efa8..7aa3c3f428 100644
rtc_library("videosource_objc") {
sources = [
"objc/api/peerconnection/RTCVideoSource+Private.h",
-@@ -582,6 +583,7 @@ if (is_ios || is_mac) {
+@@ -605,6 +606,7 @@ if (is_ios || is_mac) {
":used_from_extension",
]
}
@@ -45,7 +45,7 @@ index 26fc06efa8..7aa3c3f428 100644
rtc_library("videoframebuffer_objc") {
visibility = [ "*" ]
-@@ -614,6 +616,7 @@ if (is_ios || is_mac) {
+@@ -637,6 +639,7 @@ if (is_ios || is_mac) {
]
}
@@ -53,7 +53,7 @@ index 26fc06efa8..7aa3c3f428 100644
rtc_library("metal_objc") {
visibility = [ "*" ]
allow_poison = [
-@@ -675,6 +678,7 @@ if (is_ios || is_mac) {
+@@ -698,6 +701,7 @@ if (is_ios || is_mac) {
":videoframebuffer_objc",
]
}
@@ -61,7 +61,7 @@ index 26fc06efa8..7aa3c3f428 100644
rtc_library("videocapture_objc") {
visibility = [ "*" ]
-@@ -703,6 +707,7 @@ if (is_ios || is_mac) {
+@@ -726,6 +730,7 @@ if (is_ios || is_mac) {
]
}
@@ -69,7 +69,7 @@ index 26fc06efa8..7aa3c3f428 100644
rtc_library("videocodec_objc") {
visibility = [ "*" ]
configs += [ "..:no_global_constructors" ]
-@@ -1800,5 +1805,6 @@ if (is_ios || is_mac) {
+@@ -1823,5 +1828,6 @@ if (is_ios || is_mac) {
"VideoToolbox.framework",
]
}
diff --git a/third_party/libwebrtc/moz-patch-stack/s0099.patch b/third_party/libwebrtc/moz-patch-stack/s0099.patch
@@ -61,10 +61,10 @@ index 7cc8f5df17..df08cddc58 100644
}
}
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
-index 7aa3c3f428..2ca0a36dbb 100644
+index 06da79a112..a18d353a0e 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
-@@ -614,6 +614,20 @@ if (is_ios || is_mac) {
+@@ -637,6 +637,20 @@ if (is_ios || is_mac) {
"CoreGraphics.framework",
"CoreVideo.framework",
]
diff --git a/third_party/libwebrtc/moz-patch-stack/s0103.patch b/third_party/libwebrtc/moz-patch-stack/s0103.patch
@@ -702,7 +702,7 @@ index 0947186878..c53c12acc1 100644
output_extension = "so"
}
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
-index 2ca0a36dbb..438bd11d78 100644
+index a18d353a0e..bf3f51badd 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -9,12 +9,12 @@
@@ -731,7 +731,7 @@ index 2ca0a36dbb..438bd11d78 100644
}
}
-@@ -1261,7 +1261,7 @@ if (is_ios || is_mac) {
+@@ -1284,7 +1284,7 @@ if (is_ios || is_mac) {
}
public_deps = [
diff --git a/third_party/libwebrtc/sdk/BUILD.gn b/third_party/libwebrtc/sdk/BUILD.gn
@@ -184,6 +184,27 @@ if (is_ios || is_mac) {
}
}
+ rtc_library("core_audio_helpers_objc") {
+ sources = [
+ "objc/helpers/AudioTimeStamp+Nanoseconds.h",
+ "objc/helpers/AudioTimeStamp+Nanoseconds.mm",
+ ]
+
+ deps = [
+ ":base_objc",
+ "../rtc_base:checks",
+ ]
+
+ frameworks = [ "CoreAudio.framework" ]
+
+ configs += [
+ "..:common_objc",
+ ":used_from_extension",
+ ]
+
+ public_configs = [ ":common_config_objc" ]
+ }
+
if (!build_with_chromium) {
rtc_library("callback_logger_objc") {
sources = [
@@ -310,6 +331,7 @@ if (is_ios || is_mac) {
":audio_objc",
":audio_session_observer",
":base_objc",
+ ":core_audio_helpers_objc",
"../api:array_view",
"../api:scoped_refptr",
"../api:sequence_checker",
@@ -501,6 +523,7 @@ if (is_ios || is_mac) {
deps = [
":audio_device_api_objc",
+ ":core_audio_helpers_objc",
"../api:array_view",
"../api:make_ref_counted",
"../api:refcountedbase",
diff --git a/third_party/libwebrtc/sdk/objc/helpers/AudioTimeStamp+Nanoseconds.h b/third_party/libwebrtc/sdk/objc/helpers/AudioTimeStamp+Nanoseconds.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2025 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import <CoreAudioTypes/CoreAudioTypes.h>
+
+#include <optional>
+
+std::optional<int64_t> AudioTimeStampGetNanoseconds(
+ const AudioTimeStamp* timeStamp);
diff --git a/third_party/libwebrtc/sdk/objc/helpers/AudioTimeStamp+Nanoseconds.mm b/third_party/libwebrtc/sdk/objc/helpers/AudioTimeStamp+Nanoseconds.mm
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2025 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#import "AudioTimeStamp+Nanoseconds.h"
+
+#include <mach/mach_time.h>
+#include "rtc_base/checks.h"
+
+std::optional<int64_t> AudioTimeStampGetNanoseconds(
+ const AudioTimeStamp* timeStamp) {
+ if (!timeStamp || ((timeStamp->mFlags & kAudioTimeStampHostTimeValid) == 0) ||
+ timeStamp->mHostTime == 0) {
+ return std::nullopt;
+ }
+
+ static mach_timebase_info_data_t mach_timebase;
+ if (mach_timebase.denom == 0) {
+ if (mach_timebase_info(&mach_timebase) != KERN_SUCCESS) {
+ RTC_DCHECK_NOTREACHED() << "mach_timebase_info bad return code";
+ return std::nullopt;
+ }
+ }
+
+ if (mach_timebase.denom == 0 || mach_timebase.numer == 0) {
+ RTC_DCHECK_NOTREACHED() << "mach_timebase_info provided bad data";
+ return std::nullopt;
+ }
+
+ uint64_t time_scaled = 0;
+ if (__builtin_umulll_overflow(
+ timeStamp->mHostTime, mach_timebase.numer, &time_scaled)) {
+ RTC_DCHECK_NOTREACHED() << "numeric overflow computing scaled host time";
+ return std::nullopt;
+ }
+
+ uint64_t nanoseconds = time_scaled / mach_timebase.denom;
+ if (nanoseconds >
+ static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
+ RTC_DCHECK_NOTREACHED() << "numeric overflow computing nanoseconds";
+ return std::nullopt;
+ }
+
+ return static_cast<int64_t>(nanoseconds);
+}
diff --git a/third_party/libwebrtc/sdk/objc/native/src/audio/audio_device_ios.h b/third_party/libwebrtc/sdk/objc/native/src/audio/audio_device_ios.h
@@ -333,9 +333,6 @@ class AudioDeviceIOS : public AudioDeviceGeneric,
std::atomic<uint64_t> total_playout_delay_ms_;
std::atomic<double> hw_output_latency_;
int last_hw_output_latency_update_sample_count_;
- // Ratio between mach tick units and nanosecond. Used to change mach tick
- // units to nanoseconds.
- double machTickUnitsToNanoseconds_;
};
} // namespace ios_adm
} // namespace webrtc
diff --git a/third_party/libwebrtc/sdk/objc/native/src/audio/audio_device_ios.mm b/third_party/libwebrtc/sdk/objc/native/src/audio/audio_device_ios.mm
@@ -33,6 +33,7 @@
#import "components/audio/RTCAudioSession.h"
#import "components/audio/RTCAudioSessionConfiguration.h"
#import "components/audio/RTCNativeAudioSessionDelegateAdapter.h"
+#import "helpers/AudioTimeStamp+Nanoseconds.h"
namespace webrtc {
namespace ios_adm {
@@ -130,9 +131,6 @@ AudioDeviceIOS::AudioDeviceIOS(
audio_session_observer_ =
[[RTCNativeAudioSessionDelegateAdapter alloc] initWithObserver:this];
- mach_timebase_info_data_t tinfo;
- mach_timebase_info(&tinfo);
- machTickUnitsToNanoseconds_ = (double)tinfo.numer / tinfo.denom;
}
AudioDeviceIOS::~AudioDeviceIOS() {
@@ -417,8 +415,8 @@ OSStatus AudioDeviceIOS::OnDeliverRecordedData(
// Get audio timestamp for the audio.
// The timestamp will not have NTP time epoch, but that will be addressed by
// the TimeStampAligner in AudioDeviceBuffer::SetRecordedBuffer().
- SInt64 capture_timestamp_ns =
- time_stamp->mHostTime * machTickUnitsToNanoseconds_;
+ std::optional<int64_t> capture_timestamp_ns =
+ AudioTimeStampGetNanoseconds(time_stamp);
// Allocate AudioBuffers to be used as storage for the received audio.
// The AudioBufferList structure works as a placeholder for the
diff --git a/third_party/libwebrtc/sdk/objc/native/src/objc_audio_device.mm b/third_party/libwebrtc/sdk/objc/native/src/objc_audio_device.mm
@@ -13,6 +13,7 @@
#include <memory>
#import "components/audio/RTCAudioDevice.h"
+#import "helpers/AudioTimeStamp+Nanoseconds.h"
#include "modules/audio_device/fine_audio_buffer.h"
#include "objc_audio_device_delegate.h"
#include "rtc_base/logging.h"
@@ -449,7 +450,8 @@ OSStatus ObjCAudioDeviceModule::OnDeliverRecordedData(
record_fine_audio_buffer_->DeliverRecordedData(
webrtc::ArrayView<const int16_t>(
static_cast<int16_t*>(audio_buffer->mData), num_frames),
- cached_recording_delay_ms_.load());
+ cached_recording_delay_ms_.load(),
+ AudioTimeStampGetNanoseconds(time_stamp));
return noErr;
}
RTC_DCHECK(render_block != nullptr)
@@ -492,7 +494,9 @@ OSStatus ObjCAudioDeviceModule::OnDeliverRecordedData(
// Use the FineAudioBuffer instance to convert between native buffer size
// and the 10ms buffer size used by WebRTC.
record_fine_audio_buffer_->DeliverRecordedData(
- record_audio_buffer_, cached_recording_delay_ms_.load());
+ record_audio_buffer_,
+ cached_recording_delay_ms_.load(),
+ AudioTimeStampGetNanoseconds(time_stamp));
return noErr;
}