[M120 Migration][WebRTC][GS] Reduce clock_gettime calls and getting current time... 09/319109/1
authorAdam Bujalski <a.bujalski@samsung.com>
Fri, 11 Oct 2024 07:43:07 +0000 (09:43 +0200)
committerAdam Bujalski <a.bujalski@samsung.com>
Tue, 15 Oct 2024 09:49:11 +0000 (11:49 +0200)
Profiling revealed that processing received RTP stream by WebRTC library
involves hefty amount of `clock_gettime` syscall. Mostly these calls are
used to mark receive time of RTP packet. This patch avoids repeated
calls to get current time by extending `RtpPacketReceived` class,
storing packet receive time there and using this one instead of making
syscall.

Additionally `rtc::SystemTimeNanos()` calls `base::TimeTicks::Now()` which
returns time in microseconds and then converts result to nanoseconds.
After that value in nanoseconds is used by functions getting time in
desired unit (ns, us or ms). This causes that at least two spare
arithmetic operations (one multiplication and one division) are
performed. This patch adds optimizations which gets time form
the system (via `clock_gettime()`) and converts returned result directly
into desired time unit.

Ported patch: https://review.tizen.org/gerrit/297986

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-583
Change-Id: Ibcab6a64ab8d68187f357c3053a130ccbfa64ba7
Signed-off-by: Adam Bujalski <a.bujalski@samsung.com>
28 files changed:
third_party/webrtc/api/rtc_event_log/rtc_event_log.cc
third_party/webrtc/api/rtc_event_log/rtc_event_log.h
third_party/webrtc/audio/channel_receive.cc
third_party/webrtc/call/call.cc
third_party/webrtc/call/rtx_receive_stream.cc
third_party/webrtc/modules/congestion_controller/include/receive_side_congestion_controller.h
third_party/webrtc/modules/congestion_controller/receive_side_congestion_controller.cc
third_party/webrtc/modules/congestion_controller/receive_side_congestion_controller_unittest.cc
third_party/webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h
third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.cc
third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_abs_send_time.h
third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.cc
third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_single_stream.h
third_party/webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.cc
third_party/webrtc/modules/rtp_rtcp/source/absolute_capture_time_interpolator.cc
third_party/webrtc/modules/rtp_rtcp/source/absolute_capture_time_interpolator.h
third_party/webrtc/modules/rtp_rtcp/source/receive_statistics_impl.cc
third_party/webrtc/modules/rtp_rtcp/source/rtp_packet_received.cc
third_party/webrtc/modules/rtp_rtcp/source/rtp_packet_received.h
third_party/webrtc/p2p/base/connection.cc
third_party/webrtc/rtc_base/system_time.cc
third_party/webrtc/rtc_base/thread.cc
third_party/webrtc/rtc_base/time_utils.cc
third_party/webrtc/rtc_base/time_utils.h
third_party/webrtc/video/rtp_video_stream_receiver2.cc
third_party/webrtc/video/stats_counter.cc
third_party/webrtc/video/stats_counter.h
third_party/webrtc_overrides/rtc_base/system_time.cc

index 56189c0ff7ee33d8974d72867c6a86d140ae4944..9acadd245cf42de3e86d7a7d987c8622f37b00f1 100644 (file)
 
 #include "api/rtc_event_log/rtc_event_log.h"
 
+#include <memory>
+
+#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
+
 namespace webrtc {
 
+void RtcEventLog::LogRtpPacket(const RtpPacketReceived& packet) {
+  Log(std::make_unique<RtcEventRtpPacketIncoming>(packet));
+}
+
 bool RtcEventLogNull::StartLogging(
     std::unique_ptr<RtcEventLogOutput> /*output*/,
     int64_t /*output_period_ms*/) {
index 7b42cdc028bf85471e793e88c6cc62adcfbbf90f..9179e43f41e6c11e62ace75de1e15ec48d3427e9 100644 (file)
@@ -22,6 +22,8 @@
 
 namespace webrtc {
 
+class RtpPacketReceived;
+
 class RtcEventLog {
  public:
   enum : size_t { kUnlimitedOutput = 0 };
@@ -53,6 +55,8 @@ class RtcEventLog {
 
   // Log an RTC event (the type of event is determined by the subclass).
   virtual void Log(std::unique_ptr<RtcEvent> event) = 0;
+
+  virtual void LogRtpPacket(const RtpPacketReceived& packet);
 };
 
 // No-op implementation is used if flag is not set, or in tests.
@@ -62,6 +66,7 @@ class RtcEventLogNull final : public RtcEventLog {
                     int64_t output_period_ms) override;
   void StopLogging() override {}
   void Log(std::unique_ptr<RtcEvent> event) override {}
+  void LogRtpPacket(const RtpPacketReceived& packet) override {}
 };
 
 }  // namespace webrtc
index 7436adf71e980fa6bd2e0c0b494f497703458e25..bba8a6326dbe7e8f26c24c0f1295e7853a99451a 100644 (file)
@@ -645,7 +645,10 @@ void ChannelReceive::OnRtpPacket(const RtpPacketReceived& packet) {
   // TODO(bugs.webrtc.org/11993): Expect to be called exclusively on the
   // network thread. Once that's done, the same applies to
   // UpdatePlayoutTimestamp and
-  int64_t now_ms = rtc::TimeMillis();
+  Timestamp now = (!packet.receive_time().IsMinusInfinity()
+                       ? packet.receive_time()
+                       : Timestamp::Micros(rtc::TimeMicros()));
+  int64_t now_ms = now.ms();
 
   last_received_rtp_timestamp_ = packet.Timestamp();
   last_received_rtp_system_time_ms_ = now_ms;
@@ -669,6 +672,7 @@ void ChannelReceive::OnRtpPacket(const RtpPacketReceived& packet) {
   // Interpolates absolute capture timestamp RTP header extension.
   header.extension.absolute_capture_time =
       absolute_capture_time_interpolator_.OnReceivePacket(
+          now,
           AbsoluteCaptureTimeInterpolator::GetSource(header.ssrc,
                                                      header.arrOfCSRCs),
           header.timestamp,
index 6b975edc6ae7c53f90f81b8b629ce73dc23ce12b..c6c0305030c70726b006131274b118066781a908 100644 (file)
@@ -276,8 +276,12 @@ class Call final : public webrtc::Call,
     ~ReceiveStats();
 
     void AddReceivedRtcpBytes(int bytes);
-    void AddReceivedAudioBytes(int bytes, webrtc::Timestamp arrival_time);
-    void AddReceivedVideoBytes(int bytes, webrtc::Timestamp arrival_time);
+    void AddReceivedAudioBytes(int bytes,
+                               webrtc::Timestamp now,
+                               webrtc::Timestamp arrival_time);
+    void AddReceivedVideoBytes(int bytes,
+                               webrtc::Timestamp now,
+                               webrtc::Timestamp arrival_time);
 
    private:
     RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
@@ -332,7 +336,8 @@ class Call final : public webrtc::Call,
       absl::string_view sync_group) RTC_RUN_ON(worker_thread_);
   void ConfigureSync(absl::string_view sync_group) RTC_RUN_ON(worker_thread_);
 
-  void NotifyBweOfReceivedPacket(const RtpPacketReceived& packet,
+  void NotifyBweOfReceivedPacket(Timestamp now,
+                                 const RtpPacketReceived& packet,
                                  MediaType media_type)
       RTC_RUN_ON(worker_thread_);
 
@@ -521,20 +526,22 @@ void Call::ReceiveStats::AddReceivedRtcpBytes(int bytes) {
 }
 
 void Call::ReceiveStats::AddReceivedAudioBytes(int bytes,
+                                               webrtc::Timestamp now,
                                                webrtc::Timestamp arrival_time) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
-  received_bytes_per_second_counter_.Add(bytes);
-  received_audio_bytes_per_second_counter_.Add(bytes);
+  received_bytes_per_second_counter_.Add(now, bytes);
+  received_audio_bytes_per_second_counter_.Add(now, bytes);
   if (!first_received_rtp_audio_timestamp_)
     first_received_rtp_audio_timestamp_ = arrival_time;
   last_received_rtp_audio_timestamp_ = arrival_time;
 }
 
 void Call::ReceiveStats::AddReceivedVideoBytes(int bytes,
+                                               webrtc::Timestamp now,
                                                webrtc::Timestamp arrival_time) {
   RTC_DCHECK_RUN_ON(&sequence_checker_);
-  received_bytes_per_second_counter_.Add(bytes);
-  received_video_bytes_per_second_counter_.Add(bytes);
+  received_bytes_per_second_counter_.Add(now, bytes);
+  received_video_bytes_per_second_counter_.Add(now, bytes);
   if (!first_received_rtp_video_timestamp_)
     first_received_rtp_video_timestamp_ = arrival_time;
   last_received_rtp_video_timestamp_ = arrival_time;
@@ -1373,18 +1380,20 @@ void Call::DeliverRtpPacket(
   RTC_DCHECK_RUN_ON(worker_thread_);
   RTC_DCHECK(packet.arrival_time().IsFinite());
 
+  Timestamp now = clock_->CurrentTime();
   if (receive_time_calculator_) {
     int64_t packet_time_us = packet.arrival_time().us();
     // Repair packet_time_us for clock resets by comparing a new read of
     // the same clock (TimeUTCMicros) to a monotonic clock reading.
     packet_time_us = receive_time_calculator_->ReconcileReceiveTimes(
-        packet_time_us, rtc::TimeUTCMicros(), clock_->TimeInMicroseconds());
+        packet_time_us, rtc::TimeUTCMicros(), now.us());
     packet.set_arrival_time(Timestamp::Micros(packet_time_us));
   }
+  packet.set_receive_time(now);
 
-  NotifyBweOfReceivedPacket(packet, media_type);
+  NotifyBweOfReceivedPacket(now, packet, media_type);
 
-  event_log_->Log(std::make_unique<RtcEventRtpPacketIncoming>(packet));
+  event_log_->LogRtpPacket(packet);
   if (media_type != MediaType::AUDIO && media_type != MediaType::VIDEO) {
     return;
   }
@@ -1411,14 +1420,15 @@ void Call::DeliverRtpPacket(
   // instead of converting each time it is passed to RateCounter::Add below.
   int length = static_cast<int>(packet.size());
   if (media_type == MediaType::AUDIO) {
-    receive_stats_.AddReceivedAudioBytes(length, packet.arrival_time());
+    receive_stats_.AddReceivedAudioBytes(length, now, packet.arrival_time());
   }
   if (media_type == MediaType::VIDEO) {
-    receive_stats_.AddReceivedVideoBytes(length, packet.arrival_time());
+    receive_stats_.AddReceivedVideoBytes(length, now, packet.arrival_time());
   }
 }
 
-void Call::NotifyBweOfReceivedPacket(const RtpPacketReceived& packet,
+void Call::NotifyBweOfReceivedPacket(Timestamp now,
+                                     const RtpPacketReceived& packet,
                                      MediaType media_type) {
   RTC_DCHECK_RUN_ON(worker_thread_);
 
@@ -1431,7 +1441,7 @@ void Call::NotifyBweOfReceivedPacket(const RtpPacketReceived& packet,
   }
   transport_send_->OnReceivedPacket(packet_msg);
 
-  receive_side_cc_.OnReceivedPacket(packet, media_type);
+  receive_side_cc_.OnReceivedPacket(now, packet, media_type);
 }
 
 }  // namespace internal
index 6c5fa3f859a67798328fc263f95b412e619f1a88..0ed71c560a72e9a89408d99aab328d2718bac891 100644 (file)
@@ -73,6 +73,7 @@ void RtxReceiveStream::OnRtpPacket(const RtpPacketReceived& rtx_packet) {
   media_packet.SetPayloadType(it->second);
   media_packet.set_recovered(true);
   media_packet.set_arrival_time(rtx_packet.arrival_time());
+  media_packet.set_receive_time(rtx_packet.receive_time());
 
   // Skip the RTX header.
   rtc::ArrayView<const uint8_t> rtx_payload = payload.subview(kRtxHeaderSize);
index 8d81ccbe699823768a648a6e2ba5971092d8e801..87df94adadc53737e8ac3ed1737ac11cdf7c8259 100644 (file)
@@ -42,7 +42,9 @@ class ReceiveSideCongestionController : public CallStatsObserver {
 
   ~ReceiveSideCongestionController() override {}
 
-  void OnReceivedPacket(const RtpPacketReceived& packet, MediaType media_type);
+  void OnReceivedPacket(Timestamp now,
+                        const RtpPacketReceived& packet,
+                        MediaType media_type);
 
   // Implements CallStatsObserver.
   void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
index e0426788971b7efd3dae6973bf43e26a3f047641..ce1f7426283c963d514cb1db326b50a45b0543b8 100644 (file)
@@ -82,6 +82,7 @@ ReceiveSideCongestionController::ReceiveSideCongestionController(
       packets_since_absolute_send_time_(0) {}
 
 void ReceiveSideCongestionController::OnReceivedPacket(
+    Timestamp now,
     const RtpPacketReceived& packet,
     MediaType media_type) {
   bool has_transport_sequence_number =
@@ -99,7 +100,7 @@ void ReceiveSideCongestionController::OnReceivedPacket(
     // Receive-side BWE.
     MutexLock lock(&mutex_);
     PickEstimator(packet.HasExtension<AbsoluteSendTime>());
-    rbe_->IncomingPacket(packet);
+    rbe_->IncomingPacket(now, packet);
   }
 }
 
index a0658476ca43bdb08056782882e429da5dc18e52..4efd6aa347af338e0d05c1bfd22d2cad74b77a06 100644 (file)
@@ -62,7 +62,7 @@ TEST(ReceiveSideCongestionControllerTest, SendsRembWithAbsSendTime) {
     Timestamp now = clock_.CurrentTime();
     packet.SetExtension<AbsoluteSendTime>(AbsoluteSendTime::To24Bits(now));
     packet.set_arrival_time(now);
-    controller.OnReceivedPacket(packet, MediaType::VIDEO);
+    controller.OnReceivedPacket(now, packet, MediaType::VIDEO);
   }
 }
 
index 14a80111ed8a2aed0fb04d77e1d899ae2df08d20..9af834ff074f953f985a50f852eb25a31330bfec 100644 (file)
@@ -16,6 +16,7 @@
 #include <cstdint>
 #include <vector>
 
+#include "absl/types/optional.h"
 #include "api/units/data_rate.h"
 #include "api/units/time_delta.h"
 #include "modules/include/module_common_types.h"
@@ -44,7 +45,8 @@ class RemoteBitrateEstimator : public CallStatsObserver {
   // Called for each incoming packet. Updates the incoming payload bitrate
   // estimate and the over-use detector. If an over-use is detected the
   // remote bitrate estimate will be updated.
-  virtual void IncomingPacket(const RtpPacketReceived& rtp_packet) = 0;
+  virtual void IncomingPacket(absl::optional<Timestamp> now,
+                              const RtpPacketReceived& rtp_packet) = 0;
 
   // Removes all data for `ssrc`.
   virtual void RemoveStream(uint32_t ssrc) = 0;
index fcfbb2ecb51c65e2ef051d01a42281b2e5f85131..f1e6a884a8290be587f7dd8d171f886c3dc3b8cf 100644 (file)
@@ -201,6 +201,7 @@ bool RemoteBitrateEstimatorAbsSendTime::IsBitrateImproving(
 }
 
 void RemoteBitrateEstimatorAbsSendTime::IncomingPacket(
+    absl::optional<Timestamp> now_cached,
     const RtpPacketReceived& rtp_packet) {
   uint32_t send_time_24bits;
   if (!rtp_packet.GetExtension<AbsoluteSendTime>(&send_time_24bits)) {
@@ -225,7 +226,7 @@ void RemoteBitrateEstimatorAbsSendTime::IncomingPacket(
   Timestamp send_time =
       Timestamp::Millis(static_cast<int64_t>(timestamp) * kTimestampToMs);
 
-  Timestamp now = clock_->CurrentTime();
+  Timestamp now = (now_cached ? *now_cached : clock_->CurrentTime());
   // TODO(holmer): SSRCs are only needed for REMB, should be broken out from
   // here.
 
index 9bcdfb8aff58c9e048f20bceac351985a35b3cfb..7f6691300de828898eff8ee0f6b752d385a903a4 100644 (file)
@@ -49,7 +49,8 @@ class RemoteBitrateEstimatorAbsSendTime : public RemoteBitrateEstimator {
 
   ~RemoteBitrateEstimatorAbsSendTime() override;
 
-  void IncomingPacket(const RtpPacketReceived& rtp_packet) override;
+  void IncomingPacket(absl::optional<Timestamp> now,
+                      const RtpPacketReceived& rtp_packet) override;
   TimeDelta Process() override;
   void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
   void RemoveStream(uint32_t ssrc) override;
index 16050082991e1fb7194e9aa9699a0493e817d920..f4852f4da65001a46c5e67a9751b3dc395c6ca7a 100644 (file)
@@ -55,6 +55,7 @@ RemoteBitrateEstimatorSingleStream::~RemoteBitrateEstimatorSingleStream() =
     default;
 
 void RemoteBitrateEstimatorSingleStream::IncomingPacket(
+    absl::optional<Timestamp> now_cached,
     const RtpPacketReceived& rtp_packet) {
   absl::optional<int32_t> transmission_time_offset =
       rtp_packet.GetExtension<TransmissionOffset>();
@@ -68,7 +69,7 @@ void RemoteBitrateEstimatorSingleStream::IncomingPacket(
   uint32_t ssrc = rtp_packet.Ssrc();
   uint32_t rtp_timestamp =
       rtp_packet.Timestamp() + transmission_time_offset.value_or(0);
-  Timestamp now = clock_->CurrentTime();
+  Timestamp now = (now_cached ? *now_cached : clock_->CurrentTime());
   Detector& estimator = overuse_detectors_[ssrc];
   estimator.last_packet_time = now;
 
index 44976caf5ee39372ceb6e22179cae611bc0b77f6..99ea0640bc3bb76c4e11a71f0c71b0f5760e7f63 100644 (file)
@@ -47,7 +47,8 @@ class RemoteBitrateEstimatorSingleStream : public RemoteBitrateEstimator {
 
   ~RemoteBitrateEstimatorSingleStream() override;
 
-  void IncomingPacket(const RtpPacketReceived& rtp_packet) override;
+  void IncomingPacket(absl::optional<Timestamp> now,
+                      const RtpPacketReceived& rtp_packet) override;
   TimeDelta Process() override;
   void OnRttUpdate(int64_t avg_rtt_ms, int64_t max_rtt_ms) override;
   void RemoveStream(uint32_t ssrc) override;
index f8652b455eb445c718d104a9e82ffd8e507d6c4b..12ef0e5bc352ab5f12bd82aee83b2dee91dc95b8 100644 (file)
@@ -242,7 +242,7 @@ void RemoteBitrateEstimatorTest::IncomingPacket(uint32_t ssrc,
   rtp_packet.set_arrival_time(
       Timestamp::Millis(arrival_time + arrival_time_offset_ms_));
 
-  bitrate_estimator_->IncomingPacket(rtp_packet);
+  bitrate_estimator_->IncomingPacket(absl::nullopt, rtp_packet);
 }
 
 // Generates a frame of packets belonging to a stream at a given bitrate and
index f151084c7da8c3ecce41fc64fb0e3dfe6772df71..767fe7d1820e684143cad724bd4efa47e71393bf 100644 (file)
@@ -35,8 +35,17 @@ AbsoluteCaptureTimeInterpolator::OnReceivePacket(
     uint32_t rtp_timestamp,
     int rtp_clock_frequency_hz,
     const absl::optional<AbsoluteCaptureTime>& received_extension) {
-  const Timestamp receive_time = clock_->CurrentTime();
+  return OnReceivePacket(clock_->CurrentTime(), source, rtp_timestamp,
+                         rtp_clock_frequency_hz, received_extension);
+}
 
+absl::optional<AbsoluteCaptureTime>
+AbsoluteCaptureTimeInterpolator::OnReceivePacket(
+    Timestamp receive_time,
+    uint32_t source,
+    uint32_t rtp_timestamp,
+    uint32_t rtp_clock_frequency_hz,
+    const absl::optional<AbsoluteCaptureTime>& received_extension) {
   MutexLock lock(&mutex_);
 
   if (received_extension == absl::nullopt) {
index c830686359c2705bf5f2a8d01eb95b681c6bc5dc..a9aa7588a13ed16ead9ca47dbdd716dad1dab290 100644 (file)
@@ -50,6 +50,12 @@ class AbsoluteCaptureTimeInterpolator {
       uint32_t rtp_timestamp,
       int rtp_clock_frequency_hz,
       const absl::optional<AbsoluteCaptureTime>& received_extension);
+  absl::optional<AbsoluteCaptureTime> OnReceivePacket(
+      Timestamp receive_time,
+      uint32_t source,
+      uint32_t rtp_timestamp,
+      uint32_t rtp_clock_frequency,
+      const absl::optional<AbsoluteCaptureTime>& received_extension);
 
  private:
   friend class AbsoluteCaptureTimeSender;
index ef314c61428fa82d4ee40f67809df04eded901d6..ce14eefe5b8990b98db825472ae391158c9a2d73 100644 (file)
@@ -121,7 +121,9 @@ bool StreamStatisticianImpl::UpdateOutOfOrder(const RtpPacketReceived& packet,
 
 void StreamStatisticianImpl::UpdateCounters(const RtpPacketReceived& packet) {
   RTC_DCHECK_EQ(ssrc_, packet.Ssrc());
-  Timestamp now = clock_->CurrentTime();
+  Timestamp now =
+      (!packet.receive_time().IsMinusInfinity() ? packet.receive_time()
+                                                : clock_->CurrentTime());
 
   incoming_bitrate_.Update(packet.size(), now);
   receive_counters_.transmitted.AddPacket(packet);
index ffaace6860da563363f8edd7f7f9eac59e55cac4..64d44ac35ba7542e5549654b44b065be697c4314 100644 (file)
@@ -37,7 +37,7 @@ RtpPacketReceived& RtpPacketReceived::operator=(
 RtpPacketReceived& RtpPacketReceived::operator=(RtpPacketReceived&& packet) =
     default;
 
-RtpPacketReceived::~RtpPacketReceived() {}
+RtpPacketReceived::~RtpPacketReceived() = default;
 
 void RtpPacketReceived::GetHeader(RTPHeader* header) const {
   header->markerBit = Marker();
index 966370ae27b736b8eab48167a41f1beac57ca78e..6c578bd5220951b55ccb55b70eea48f7a675a491 100644 (file)
@@ -53,6 +53,10 @@ class RtpPacketReceived : public RtpPacket {
   webrtc::Timestamp arrival_time() const { return arrival_time_; }
   void set_arrival_time(webrtc::Timestamp time) { arrival_time_ = time; }
 
+  // arrival_time() can use non-monotonic clock, this one uses monotonic clock
+  webrtc::Timestamp receive_time() const { return receive_time_; }
+  void set_receive_time(webrtc::Timestamp time) { receive_time_ = time; }
+
   // Flag if packet was recovered via RTX or FEC.
   bool recovered() const { return recovered_; }
   void set_recovered(bool value) { recovered_ = value; }
@@ -73,6 +77,7 @@ class RtpPacketReceived : public RtpPacket {
 
  private:
   webrtc::Timestamp arrival_time_ = Timestamp::MinusInfinity();
+  webrtc::Timestamp receive_time_ = Timestamp::MinusInfinity();
   int payload_type_frequency_ = 0;
   bool recovered_ = false;
   rtc::scoped_refptr<rtc::RefCountedBase> additional_data_;
index 3bdba0e445a1a115d8e1d57deeeead81b1a13687..7c96fc600893b7d041b33eca3fc9fcdba35585da 100644 (file)
@@ -38,6 +38,7 @@
 #include "rtc_base/string_utils.h"
 #include "rtc_base/strings/string_builder.h"
 #include "rtc_base/third_party/base64/base64.h"
+#include "rtc_base/time_utils.h"
 
 namespace cricket {
 namespace {
@@ -473,9 +474,11 @@ void Connection::OnReadPacket(const char* data,
   if (!port_->GetStunMessage(data, size, addr, &msg, &remote_ufrag)) {
     // The packet did not parse as a valid STUN message
     // This is a data packet, pass it along.
-    last_data_received_ = rtc::TimeMillis();
+    last_data_received_ =
+        (packet_time_us > 0 ? packet_time_us / rtc::kNumMicrosecsPerMillisec
+                            : rtc::TimeMillis());
     UpdateReceiving(last_data_received_);
-    recv_rate_tracker_.AddSamples(size);
+    recv_rate_tracker_.AddSamplesAtTime(last_data_received_, size);
     stats_.packets_received++;
     if (received_packet_callback_) {
       RTC_DCHECK(packet_time_us == -1 || packet_time_us >= 0);
index e2dbfef0adfd5e673d9295a1940538bbab9ecb09..31e76084d7e52e1f6788e6938cc981eaa3cd0f8d 100644 (file)
 
 namespace rtc {
 
+// For WEBRTC_TIZEN_TV implemented directly in
+// `third_party/webrtc/rtc_base/time_utils.cc`. See comments there why.
+#if !defined(WEBRTC_TIZEN_TV)
+
 int64_t SystemTimeNanos() {
   int64_t ticks;
 #if defined(WEBRTC_MAC)
@@ -102,5 +106,7 @@ int64_t SystemTimeNanos() {
   return ticks;
 }
 
+#endif
+
 }  // namespace rtc
 #endif  // WEBRTC_EXCLUDE_SYSTEM_TIME
index 6f101ac8f4539ed8b55916cd54a6e0151621aaf8..83c4952d122e857125b14a0b8e41105f1a183f1f 100644 (file)
@@ -521,8 +521,11 @@ int Thread::GetDelay() {
 void Thread::Dispatch(absl::AnyInvocable<void() &&> task) {
   TRACE_EVENT0("webrtc", "Thread::Dispatch");
   RTC_DCHECK_RUN_ON(this);
+#if !defined(WEBRTC_TIZEN_TV)
   int64_t start_time = TimeMillis();
+#endif
   std::move(task)();
+#if !defined(WEBRTC_TIZEN_TV)
   int64_t end_time = TimeMillis();
   int64_t diff = TimeDiff(end_time, start_time);
   if (diff >= dispatch_warning_ms_) {
@@ -532,6 +535,7 @@ void Thread::Dispatch(absl::AnyInvocable<void() &&> task) {
     // for delays that are larger than the one observed.
     dispatch_warning_ms_ = diff + 1;
   }
+#endif
 }
 
 bool Thread::IsCurrent() const {
index 9f112e49c189e32a988eb5683e3cf461041aeba1..04464194cb2a8f0d4a6435ba932b0d0015f23eed 100644 (file)
@@ -147,6 +147,88 @@ int64_t WinUwpSystemTimeNanos() {
 
 #endif  // defined(WINUWP)
 
+#if defined(WEBRTC_TIZEN_TV)
+// For WEBRTC_TIZEN_TV `SystemTimeNanos()` calls
+// `base::TimeTicks::Now()` from chromium, which uses calls
+// `clock_gettime(CLOCK_MONOTONIC, ...)` and converts result to microseconds
+// held in `int64_t` variable. This variable is then converted to
+// nanoseconds (== * 1000) and then this value is converted to desired
+// precision. So implementing this call directly for desired time unit
+// saves at least one multiplication and one integer division
+// (which on ARM EABI may be expensive).
+
+int64_t SystemTimeNanos() {
+  struct timespec ts;
+  clock_gettime(CLOCK_MONOTONIC, &ts);
+
+  int64_t nsec = ts.tv_sec;
+  nsec *= kNumNanosecsPerSec;
+  nsec += ts.tv_nsec;
+  return nsec;
+}
+
+int64_t SystemTimeMicros() {
+  struct timespec ts;
+  clock_gettime(CLOCK_MONOTONIC, &ts);
+
+  int64_t nsec = ts.tv_sec;
+  nsec *= kNumMicrosecsPerSec;
+  nsec += ts.tv_nsec / kNumNanosecsPerMicrosec;
+  return nsec;
+}
+
+int64_t SystemTimeMillis() {
+  struct timespec ts;
+  clock_gettime(CLOCK_MONOTONIC, &ts);
+
+  int64_t nsec = ts.tv_sec;
+  nsec *= kNumMillisecsPerSec;
+  nsec += ts.tv_nsec / kNumNanosecsPerMillisec;
+  return nsec;
+}
+
+int64_t TimeNanos() {
+#if WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS
+  if (g_clock) {
+    return g_clock->TimeNanos();
+  }
+#endif
+
+  return SystemTimeNanos();
+}
+
+uint32_t Time32() {
+#if WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS
+  if (g_clock) {
+    return static_cast<uint32_t>(g_clock->TimeNanos() /
+                                 kNumNanosecsPerMillisec);
+  }
+#endif
+
+  return static_cast<uint32_t>(SystemTimeMillis());
+}
+
+int64_t TimeMillis() {
+#if WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS
+  if (g_clock) {
+    return g_clock->TimeNanos() / kNumNanosecsPerMillisec;
+  }
+#endif
+
+  return SystemTimeMillis();
+}
+
+int64_t TimeMicros() {
+#if WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS
+  if (g_clock) {
+    return g_clock->TimeNanos() / kNumNanosecsPerMicrosec;
+  }
+#endif
+
+  return SystemTimeMicros();
+}
+
+#else
 int64_t SystemTimeMillis() {
   return static_cast<int64_t>(SystemTimeNanos() / kNumNanosecsPerMillisec);
 }
@@ -169,6 +251,7 @@ int64_t TimeMillis() {
 int64_t TimeMicros() {
   return TimeNanos() / kNumNanosecsPerMicrosec;
 }
+#endif
 
 int64_t TimeAfter(int64_t elapsed) {
   RTC_DCHECK_GE(elapsed, 0);
index 271c1d6e938e623ec1296b11f792c62ceea69669..056840f274dc33c11a1cc17608167bd842fd0eda 100644 (file)
 
 namespace rtc {
 
-static const int64_t kNumMillisecsPerSec = INT64_C(1000);
-static const int64_t kNumMicrosecsPerSec = INT64_C(1000000);
-static const int64_t kNumNanosecsPerSec = INT64_C(1000000000);
+static constexpr int64_t kNumMillisecsPerSec = INT64_C(1000);
+static constexpr int64_t kNumMicrosecsPerSec = INT64_C(1000000);
+static constexpr int64_t kNumNanosecsPerSec = INT64_C(1000000000);
 
-static const int64_t kNumMicrosecsPerMillisec =
+static constexpr int64_t kNumMicrosecsPerMillisec =
     kNumMicrosecsPerSec / kNumMillisecsPerSec;
-static const int64_t kNumNanosecsPerMillisec =
+static constexpr int64_t kNumNanosecsPerMillisec =
     kNumNanosecsPerSec / kNumMillisecsPerSec;
-static const int64_t kNumNanosecsPerMicrosec =
+static constexpr int64_t kNumNanosecsPerMicrosec =
     kNumNanosecsPerSec / kNumMicrosecsPerSec;
 
 // Elapsed milliseconds between NTP base, 1900 January 1 00:00 GMT
index c3e971af5a29ec85c27589de70a886d92e5ce1e9..cdb2c2acdd92712831937c57b8d0efb05dd6125c 100644 (file)
@@ -517,14 +517,18 @@ void RtpVideoStreamReceiver2::OnReceivedPayloadData(
   auto packet =
       std::make_unique<video_coding::PacketBuffer::Packet>(rtp_packet, video);
 
+  Timestamp receive_time =
+      (!rtp_packet.receive_time().IsMinusInfinity() ? rtp_packet.receive_time()
+                                                    : clock_->CurrentTime());
   packet->packet_info = RtpPacketInfo(
       rtp_packet.Ssrc(), rtp_packet.Csrcs(), rtp_packet.Timestamp(),
-      /*receive_time_ms=*/clock_->CurrentTime());
+      /*receive_time_ms=*/receive_time);
   auto& packet_info = packet->packet_info;
 
   // Try to extrapolate absolute capture time if it is missing.
   packet_info.set_absolute_capture_time(
       absolute_capture_time_interpolator_.OnReceivePacket(
+          receive_time,
           AbsoluteCaptureTimeInterpolator::GetSource(packet_info.ssrc(),
                                                      packet_info.csrcs()),
           packet_info.rtp_timestamp(),
@@ -1238,7 +1242,9 @@ void RtpVideoStreamReceiver2::InsertSpsPpsIntoTracker(uint8_t payload_type) {
 void RtpVideoStreamReceiver2::UpdatePacketReceiveTimestamps(
     const RtpPacketReceived& packet,
     bool is_keyframe) {
-  Timestamp now = clock_->CurrentTime();
+  Timestamp now =
+      (!packet.receive_time().IsMinusInfinity() ? packet.receive_time()
+                                                : clock_->CurrentTime());
   if (is_keyframe ||
       last_received_keyframe_rtp_timestamp_ == packet.Timestamp()) {
     last_received_keyframe_rtp_timestamp_ = packet.Timestamp();
index dc548ea3c3421d10dab1e29b71c549c205400a17..b7b53e8db5fd2a0adf8048ffc04c1b50e94f9fb7 100644 (file)
@@ -193,7 +193,7 @@ AggregatedStats StatsCounter::GetStats() {
 
 AggregatedStats StatsCounter::ProcessAndGetStats() {
   if (HasSample())
-    TryProcess();
+    TryProcess(clock_->CurrentTime());
   return aggregated_counter_->ComputeStats();
 }
 
@@ -204,14 +204,14 @@ void StatsCounter::ProcessAndPauseForDuration(int64_t min_pause_time_ms) {
 
 void StatsCounter::ProcessAndPause() {
   if (HasSample())
-    TryProcess();
+    TryProcess(clock_->CurrentTime());
   paused_ = true;
   pause_time_ms_ = clock_->TimeInMilliseconds();
 }
 
 void StatsCounter::ProcessAndStopPause() {
   if (HasSample())
-    TryProcess();
+    TryProcess(clock_->CurrentTime());
   Resume();
 }
 
@@ -219,8 +219,8 @@ bool StatsCounter::HasSample() const {
   return last_process_time_ms_ != -1;
 }
 
-bool StatsCounter::TimeToProcess(int* elapsed_intervals) {
-  int64_t now = clock_->TimeInMilliseconds();
+bool StatsCounter::TimeToProcess(Timestamp now_ts, int* elapsed_intervals) {
+  int64_t now = now_ts.ms();  // clock_->TimeInMilliseconds();
   if (last_process_time_ms_ == -1)
     last_process_time_ms_ = now;
 
@@ -237,9 +237,13 @@ bool StatsCounter::TimeToProcess(int* elapsed_intervals) {
 }
 
 void StatsCounter::Add(int sample) {
-  TryProcess();
+  Add(clock_->CurrentTime(), sample);
+}
+
+void StatsCounter::Add(Timestamp now, int sample) {
+  TryProcess(now);
   samples_->Add(sample, kStreamId0);
-  ResumeIfMinTimePassed();
+  ResumeIfMinTimePassed(now);
 }
 
 void StatsCounter::Set(int64_t sample, uint32_t stream_id) {
@@ -247,9 +251,10 @@ void StatsCounter::Set(int64_t sample, uint32_t stream_id) {
     // Do not add same sample while paused (will reset pause).
     return;
   }
-  TryProcess();
+  Timestamp now = clock_->CurrentTime();
+  TryProcess(now);
   samples_->Set(sample, stream_id);
-  ResumeIfMinTimePassed();
+  ResumeIfMinTimePassed(now);
 }
 
 void StatsCounter::SetLast(int64_t sample, uint32_t stream_id) {
@@ -268,9 +273,9 @@ void StatsCounter::ReportMetricToAggregatedCounter(
   }
 }
 
-void StatsCounter::TryProcess() {
+void StatsCounter::TryProcess(Timestamp now) {
   int elapsed_intervals;
-  if (!TimeToProcess(&elapsed_intervals))
+  if (!TimeToProcess(now, &elapsed_intervals))
     return;
 
   // Get and report periodically computed metric.
@@ -295,9 +300,8 @@ void StatsCounter::TryProcess() {
 bool StatsCounter::IncludeEmptyIntervals() const {
   return include_empty_intervals_ && !paused_ && !aggregated_counter_->Empty();
 }
-void StatsCounter::ResumeIfMinTimePassed() {
-  if (paused_ &&
-      (clock_->TimeInMilliseconds() - pause_time_ms_) >= min_pause_time_ms_) {
+void StatsCounter::ResumeIfMinTimePassed(Timestamp now) {
+  if (paused_ && (now.ms() - pause_time_ms_) >= min_pause_time_ms_) {
     Resume();
   }
 }
@@ -418,6 +422,10 @@ void RateCounter::Add(int sample) {
   StatsCounter::Add(sample);
 }
 
+void RateCounter::Add(Timestamp now, int sample) {
+  StatsCounter::Add(now, sample);
+}
+
 bool RateCounter::GetMetric(int* metric) const {
   if (samples_->Empty())
     return false;
index 9e2b8702d6f57748e1eb37dfbb3472b59e8f7199..467b81a7652d63a1f566fdec556d2931c33982ae 100644 (file)
@@ -14,6 +14,8 @@
 #include <memory>
 #include <string>
 
+#include "api/units/timestamp.h"
+
 namespace webrtc {
 
 class AggregatedCounter;
@@ -113,6 +115,7 @@ class StatsCounter {
                StatsCounterObserver* observer);
 
   void Add(int sample);
+  void Add(Timestamp now, int sample);
   void Set(int64_t sample, uint32_t stream_id);
   void SetLast(int64_t sample, uint32_t stream_id);
 
@@ -122,12 +125,12 @@ class StatsCounter {
   const std::unique_ptr<Samples> samples_;
 
  private:
-  bool TimeToProcess(int* num_elapsed_intervals);
-  void TryProcess();
+  bool TimeToProcess(Timestamp now, int* num_elapsed_intervals);
+  void TryProcess(Timestamp now);
   void ReportMetricToAggregatedCounter(int value, int num_values_to_add) const;
   bool IncludeEmptyIntervals() const;
   void Resume();
-  void ResumeIfMinTimePassed();
+  void ResumeIfMinTimePassed(Timestamp now);
 
   Clock* const clock_;
   const std::unique_ptr<StatsCounterObserver> observer_;
@@ -253,6 +256,7 @@ class RateCounter : public StatsCounter {
   RateCounter& operator=(const RateCounter&) = delete;
 
   void Add(int sample);
+  void Add(Timestamp now, int sample);
 
  private:
   bool GetMetric(int* metric) const override;
index 28dd9ecac029ee462bb52da74a84dd49988597aa..e3d1df1127e5ae0e3814c5f9127beb461c69de45 100644 (file)
 
 namespace rtc {
 
+// For Tizen TV profile this is implemented directly in
+// `third_party/webrtc/rtc_base/time_utils.cc`. See comments there why.
+#if !BUILDFLAG(IS_TIZEN_TV)
 int64_t SystemTimeNanos() {
   return (base::TimeTicks::Now() - base::TimeTicks()).InNanoseconds();
 }
+#endif
 
 }  // namespace rtc