Call: prepare receive stats for thread switch.
This change collects the receive stats that Call maintains into a new thread-compatible internal class which can easily be switched to the network thread. Bug: webrtc:11993 Change-Id: I9fa9a7f057149789aa327e5ba8a8cb3379762272 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/220760 Reviewed-by: Tommi <tommi@webrtc.org> Commit-Queue: Markus Handell <handellm@webrtc.org> Cr-Commit-Position: refs/heads/master@{#34158}
This commit is contained in:
parent
22fead3041
commit
c81afe365d
211
call/call.cc
211
call/call.cc
@ -321,6 +321,37 @@ class Call final : public webrtc::Call,
|
||||
void SetClientBitratePreferences(const BitrateSettings& preferences) override;
|
||||
|
||||
private:
|
||||
// Thread-compatible class that collects received packet stats and exposes
|
||||
// them as UMA histograms on destruction.
|
||||
class ReceiveStats {
|
||||
public:
|
||||
explicit ReceiveStats(Clock* clock);
|
||||
~ReceiveStats();
|
||||
|
||||
void AddReceivedRtcpBytes(int bytes);
|
||||
void AddReceivedAudioBytes(int bytes, webrtc::Timestamp arrival_time);
|
||||
void AddReceivedVideoBytes(int bytes, webrtc::Timestamp arrival_time);
|
||||
|
||||
private:
|
||||
SequenceChecker sequence_checker_;
|
||||
RateCounter received_bytes_per_second_counter_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
RateCounter received_audio_bytes_per_second_counter_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
RateCounter received_video_bytes_per_second_counter_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
RateCounter received_rtcp_bytes_per_second_counter_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
absl::optional<Timestamp> first_received_rtp_audio_timestamp_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
absl::optional<Timestamp> last_received_rtp_audio_timestamp_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
absl::optional<Timestamp> first_received_rtp_video_timestamp_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
absl::optional<Timestamp> last_received_rtp_video_timestamp_
|
||||
RTC_GUARDED_BY(sequence_checker_);
|
||||
};
|
||||
|
||||
DeliveryStatus DeliverRtcp(MediaType media_type,
|
||||
const uint8_t* packet,
|
||||
size_t length)
|
||||
@ -336,7 +367,6 @@ class Call final : public webrtc::Call,
|
||||
MediaType media_type)
|
||||
RTC_SHARED_LOCKS_REQUIRED(worker_thread_);
|
||||
|
||||
void UpdateReceiveHistograms();
|
||||
void UpdateAggregateNetworkState();
|
||||
|
||||
// Ensure that necessary process threads are started, and any required
|
||||
@ -433,17 +463,9 @@ class Call final : public webrtc::Call,
|
||||
|
||||
webrtc::RtcEventLog* event_log_;
|
||||
|
||||
// The following members are only accessed (exclusively) from one thread and
|
||||
// from the destructor, and therefore doesn't need any explicit
|
||||
// synchronization.
|
||||
RateCounter received_bytes_per_second_counter_;
|
||||
RateCounter received_audio_bytes_per_second_counter_;
|
||||
RateCounter received_video_bytes_per_second_counter_;
|
||||
RateCounter received_rtcp_bytes_per_second_counter_;
|
||||
absl::optional<int64_t> first_received_rtp_audio_ms_;
|
||||
absl::optional<int64_t> last_received_rtp_audio_ms_;
|
||||
absl::optional<int64_t> first_received_rtp_video_ms_;
|
||||
absl::optional<int64_t> last_received_rtp_video_ms_;
|
||||
// TODO(bugs.webrtc.org/11993) ready to move receive stats access to the
|
||||
// network thread.
|
||||
ReceiveStats receive_stats_ RTC_GUARDED_BY(worker_thread_);
|
||||
|
||||
uint32_t last_bandwidth_bps_ RTC_GUARDED_BY(worker_thread_);
|
||||
// TODO(holmer): Remove this lock once BitrateController no longer calls
|
||||
@ -625,6 +647,94 @@ VideoSendStream* Call::CreateVideoSendStream(
|
||||
|
||||
namespace internal {
|
||||
|
||||
Call::ReceiveStats::ReceiveStats(Clock* clock)
|
||||
: received_bytes_per_second_counter_(clock, nullptr, false),
|
||||
received_audio_bytes_per_second_counter_(clock, nullptr, false),
|
||||
received_video_bytes_per_second_counter_(clock, nullptr, false),
|
||||
received_rtcp_bytes_per_second_counter_(clock, nullptr, false) {
|
||||
sequence_checker_.Detach();
|
||||
}
|
||||
|
||||
void Call::ReceiveStats::AddReceivedRtcpBytes(int bytes) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
if (received_bytes_per_second_counter_.HasSample()) {
|
||||
// First RTP packet has been received.
|
||||
received_bytes_per_second_counter_.Add(static_cast<int>(bytes));
|
||||
received_rtcp_bytes_per_second_counter_.Add(static_cast<int>(bytes));
|
||||
}
|
||||
}
|
||||
|
||||
void Call::ReceiveStats::AddReceivedAudioBytes(int bytes,
|
||||
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);
|
||||
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 arrival_time) {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
received_bytes_per_second_counter_.Add(bytes);
|
||||
received_video_bytes_per_second_counter_.Add(bytes);
|
||||
if (!first_received_rtp_video_timestamp_)
|
||||
first_received_rtp_video_timestamp_ = arrival_time;
|
||||
last_received_rtp_video_timestamp_ = arrival_time;
|
||||
}
|
||||
|
||||
Call::ReceiveStats::~ReceiveStats() {
|
||||
RTC_DCHECK_RUN_ON(&sequence_checker_);
|
||||
if (first_received_rtp_audio_timestamp_) {
|
||||
RTC_HISTOGRAM_COUNTS_100000(
|
||||
"WebRTC.Call.TimeReceivingAudioRtpPacketsInSeconds",
|
||||
(*last_received_rtp_audio_timestamp_ -
|
||||
*first_received_rtp_audio_timestamp_)
|
||||
.seconds());
|
||||
}
|
||||
if (first_received_rtp_video_timestamp_) {
|
||||
RTC_HISTOGRAM_COUNTS_100000(
|
||||
"WebRTC.Call.TimeReceivingVideoRtpPacketsInSeconds",
|
||||
(*last_received_rtp_video_timestamp_ -
|
||||
*first_received_rtp_video_timestamp_)
|
||||
.seconds());
|
||||
}
|
||||
const int kMinRequiredPeriodicSamples = 5;
|
||||
AggregatedStats video_bytes_per_sec =
|
||||
received_video_bytes_per_second_counter_.GetStats();
|
||||
if (video_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.VideoBitrateReceivedInKbps",
|
||||
video_bytes_per_sec.average * 8 / 1000);
|
||||
RTC_LOG(LS_INFO) << "WebRTC.Call.VideoBitrateReceivedInBps, "
|
||||
<< video_bytes_per_sec.ToStringWithMultiplier(8);
|
||||
}
|
||||
AggregatedStats audio_bytes_per_sec =
|
||||
received_audio_bytes_per_second_counter_.GetStats();
|
||||
if (audio_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.AudioBitrateReceivedInKbps",
|
||||
audio_bytes_per_sec.average * 8 / 1000);
|
||||
RTC_LOG(LS_INFO) << "WebRTC.Call.AudioBitrateReceivedInBps, "
|
||||
<< audio_bytes_per_sec.ToStringWithMultiplier(8);
|
||||
}
|
||||
AggregatedStats rtcp_bytes_per_sec =
|
||||
received_rtcp_bytes_per_second_counter_.GetStats();
|
||||
if (rtcp_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.RtcpBitrateReceivedInBps",
|
||||
rtcp_bytes_per_sec.average * 8);
|
||||
RTC_LOG(LS_INFO) << "WebRTC.Call.RtcpBitrateReceivedInBps, "
|
||||
<< rtcp_bytes_per_sec.ToStringWithMultiplier(8);
|
||||
}
|
||||
AggregatedStats recv_bytes_per_sec =
|
||||
received_bytes_per_second_counter_.GetStats();
|
||||
if (recv_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.BitrateReceivedInKbps",
|
||||
recv_bytes_per_sec.average * 8 / 1000);
|
||||
RTC_LOG(LS_INFO) << "WebRTC.Call.BitrateReceivedInBps, "
|
||||
<< recv_bytes_per_sec.ToStringWithMultiplier(8);
|
||||
}
|
||||
}
|
||||
|
||||
Call::Call(Clock* clock,
|
||||
const Call::Config& config,
|
||||
std::unique_ptr<RtpTransportControllerSendInterface> transport_send,
|
||||
@ -646,10 +756,7 @@ Call::Call(Clock* clock,
|
||||
video_network_state_(kNetworkDown),
|
||||
aggregate_network_up_(false),
|
||||
event_log_(config.event_log),
|
||||
received_bytes_per_second_counter_(clock_, nullptr, true),
|
||||
received_audio_bytes_per_second_counter_(clock_, nullptr, true),
|
||||
received_video_bytes_per_second_counter_(clock_, nullptr, true),
|
||||
received_rtcp_bytes_per_second_counter_(clock_, nullptr, true),
|
||||
receive_stats_(clock_),
|
||||
last_bandwidth_bps_(0),
|
||||
min_allocated_send_bitrate_bps_(0),
|
||||
configured_max_padding_bitrate_bps_(0),
|
||||
@ -710,8 +817,6 @@ Call::~Call() {
|
||||
pacer_bitrate_kbps_counter_);
|
||||
}
|
||||
|
||||
UpdateReceiveHistograms();
|
||||
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.LifetimeInSeconds",
|
||||
(now.ms() - start_ms_) / 1000);
|
||||
}
|
||||
@ -737,52 +842,6 @@ void Call::SetClientBitratePreferences(const BitrateSettings& preferences) {
|
||||
GetTransportControllerSend()->SetClientBitratePreferences(preferences);
|
||||
}
|
||||
|
||||
void Call::UpdateReceiveHistograms() {
|
||||
if (first_received_rtp_audio_ms_) {
|
||||
RTC_HISTOGRAM_COUNTS_100000(
|
||||
"WebRTC.Call.TimeReceivingAudioRtpPacketsInSeconds",
|
||||
(*last_received_rtp_audio_ms_ - *first_received_rtp_audio_ms_) / 1000);
|
||||
}
|
||||
if (first_received_rtp_video_ms_) {
|
||||
RTC_HISTOGRAM_COUNTS_100000(
|
||||
"WebRTC.Call.TimeReceivingVideoRtpPacketsInSeconds",
|
||||
(*last_received_rtp_video_ms_ - *first_received_rtp_video_ms_) / 1000);
|
||||
}
|
||||
const int kMinRequiredPeriodicSamples = 5;
|
||||
AggregatedStats video_bytes_per_sec =
|
||||
received_video_bytes_per_second_counter_.GetStats();
|
||||
if (video_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.VideoBitrateReceivedInKbps",
|
||||
video_bytes_per_sec.average * 8 / 1000);
|
||||
RTC_LOG(LS_INFO) << "WebRTC.Call.VideoBitrateReceivedInBps, "
|
||||
<< video_bytes_per_sec.ToStringWithMultiplier(8);
|
||||
}
|
||||
AggregatedStats audio_bytes_per_sec =
|
||||
received_audio_bytes_per_second_counter_.GetStats();
|
||||
if (audio_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.AudioBitrateReceivedInKbps",
|
||||
audio_bytes_per_sec.average * 8 / 1000);
|
||||
RTC_LOG(LS_INFO) << "WebRTC.Call.AudioBitrateReceivedInBps, "
|
||||
<< audio_bytes_per_sec.ToStringWithMultiplier(8);
|
||||
}
|
||||
AggregatedStats rtcp_bytes_per_sec =
|
||||
received_rtcp_bytes_per_second_counter_.GetStats();
|
||||
if (rtcp_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.RtcpBitrateReceivedInBps",
|
||||
rtcp_bytes_per_sec.average * 8);
|
||||
RTC_LOG(LS_INFO) << "WebRTC.Call.RtcpBitrateReceivedInBps, "
|
||||
<< rtcp_bytes_per_sec.ToStringWithMultiplier(8);
|
||||
}
|
||||
AggregatedStats recv_bytes_per_sec =
|
||||
received_bytes_per_second_counter_.GetStats();
|
||||
if (recv_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
|
||||
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.BitrateReceivedInKbps",
|
||||
recv_bytes_per_sec.average * 8 / 1000);
|
||||
RTC_LOG(LS_INFO) << "WebRTC.Call.BitrateReceivedInBps, "
|
||||
<< recv_bytes_per_sec.ToStringWithMultiplier(8);
|
||||
}
|
||||
}
|
||||
|
||||
PacketReceiver* Call::Receiver() {
|
||||
return this;
|
||||
}
|
||||
@ -1381,11 +1440,7 @@ PacketReceiver::DeliveryStatus Call::DeliverRtcp(MediaType media_type,
|
||||
// TODO(pbos): Make sure it's a valid packet.
|
||||
// Return DELIVERY_UNKNOWN_SSRC if it can be determined that
|
||||
// there's no receiver of the packet.
|
||||
if (received_bytes_per_second_counter_.HasSample()) {
|
||||
// First RTP packet has been received.
|
||||
received_bytes_per_second_counter_.Add(static_cast<int>(length));
|
||||
received_rtcp_bytes_per_second_counter_.Add(static_cast<int>(length));
|
||||
}
|
||||
receive_stats_.AddReceivedRtcpBytes(static_cast<int>(length));
|
||||
bool rtcp_delivered = false;
|
||||
if (media_type == MediaType::ANY || media_type == MediaType::VIDEO) {
|
||||
for (VideoReceiveStream2* stream : video_receive_streams_) {
|
||||
@ -1471,29 +1526,19 @@ PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type,
|
||||
int length = static_cast<int>(parsed_packet.size());
|
||||
if (media_type == MediaType::AUDIO) {
|
||||
if (audio_receiver_controller_.OnRtpPacket(parsed_packet)) {
|
||||
received_bytes_per_second_counter_.Add(length);
|
||||
received_audio_bytes_per_second_counter_.Add(length);
|
||||
receive_stats_.AddReceivedAudioBytes(length,
|
||||
parsed_packet.arrival_time());
|
||||
event_log_->Log(
|
||||
std::make_unique<RtcEventRtpPacketIncoming>(parsed_packet));
|
||||
const int64_t arrival_time_ms = parsed_packet.arrival_time().ms();
|
||||
if (!first_received_rtp_audio_ms_) {
|
||||
first_received_rtp_audio_ms_.emplace(arrival_time_ms);
|
||||
}
|
||||
last_received_rtp_audio_ms_.emplace(arrival_time_ms);
|
||||
return DELIVERY_OK;
|
||||
}
|
||||
} else if (media_type == MediaType::VIDEO) {
|
||||
parsed_packet.set_payload_type_frequency(kVideoPayloadTypeFrequency);
|
||||
if (video_receiver_controller_.OnRtpPacket(parsed_packet)) {
|
||||
received_bytes_per_second_counter_.Add(length);
|
||||
received_video_bytes_per_second_counter_.Add(length);
|
||||
receive_stats_.AddReceivedVideoBytes(length,
|
||||
parsed_packet.arrival_time());
|
||||
event_log_->Log(
|
||||
std::make_unique<RtcEventRtpPacketIncoming>(parsed_packet));
|
||||
const int64_t arrival_time_ms = parsed_packet.arrival_time().ms();
|
||||
if (!first_received_rtp_video_ms_) {
|
||||
first_received_rtp_video_ms_.emplace(arrival_time_ms);
|
||||
}
|
||||
last_received_rtp_video_ms_.emplace(arrival_time_ms);
|
||||
return DELIVERY_OK;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user