blob: a6cb5b38e6bddd3d312f8c9b3d455acee9103cf6 [file] [log] [blame]
sprang@webrtc.orgccd42842014-01-07 09:54:34 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/video/send_statistics_proxy.h"
12
13#include <map>
14
pbos@webrtc.org49096de2015-02-24 22:37:52 +000015#include "webrtc/base/checks.h"
16
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000017#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
pbos@webrtc.org273a4142014-12-01 15:23:21 +000018#include "webrtc/system_wrappers/interface/logging.h"
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000019
20namespace webrtc {
21
pbos@webrtc.org273a4142014-12-01 15:23:21 +000022const int SendStatisticsProxy::kStatsTimeoutMs = 5000;
23
24SendStatisticsProxy::SendStatisticsProxy(Clock* clock,
25 const VideoSendStream::Config& config)
26 : clock_(clock),
Peter Boströmf2f82832015-05-01 13:00:41 +020027 config_(config) {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +000028}
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000029
30SendStatisticsProxy::~SendStatisticsProxy() {}
31
32void SendStatisticsProxy::OutgoingRate(const int video_channel,
33 const unsigned int framerate,
34 const unsigned int bitrate) {
Peter Boströmf2f82832015-05-01 13:00:41 +020035 rtc::CritScope lock(&crit_);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000036 stats_.encode_frame_rate = framerate;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +000037 stats_.media_bitrate_bps = bitrate;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000038}
39
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +000040void SendStatisticsProxy::CpuOveruseMetricsUpdated(
41 const CpuOveruseMetrics& metrics) {
Peter Boströmf2f82832015-05-01 13:00:41 +020042 rtc::CritScope lock(&crit_);
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +000043 stats_.avg_encode_time_ms = metrics.avg_encode_time_ms;
44 stats_.encode_usage_percent = metrics.encode_usage_percent;
45}
46
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +000047void SendStatisticsProxy::SuspendChange(int video_channel, bool is_suspended) {
Peter Boströmf2f82832015-05-01 13:00:41 +020048 rtc::CritScope lock(&crit_);
henrik.lundin@webrtc.orgb10363f2014-03-13 13:31:21 +000049 stats_.suspended = is_suspended;
50}
51
pbos@webrtc.org273a4142014-12-01 15:23:21 +000052VideoSendStream::Stats SendStatisticsProxy::GetStats() {
Peter Boströmf2f82832015-05-01 13:00:41 +020053 rtc::CritScope lock(&crit_);
pbos@webrtc.org273a4142014-12-01 15:23:21 +000054 PurgeOldStats();
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +000055 stats_.input_frame_rate =
56 static_cast<int>(input_frame_rate_tracker_.units_second());
stefan@webrtc.org168f23f2014-07-11 13:44:02 +000057 return stats_;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000058}
59
pbos@webrtc.org273a4142014-12-01 15:23:21 +000060void SendStatisticsProxy::PurgeOldStats() {
Peter Boström20f3f942015-05-15 11:33:39 +020061 int64_t old_stats_ms = clock_->TimeInMilliseconds() - kStatsTimeoutMs;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +000062 for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
63 stats_.substreams.begin();
pbos@webrtc.org273a4142014-12-01 15:23:21 +000064 it != stats_.substreams.end(); ++it) {
65 uint32_t ssrc = it->first;
Peter Boström20f3f942015-05-15 11:33:39 +020066 if (update_times_[ssrc].resolution_update_ms <= old_stats_ms) {
67 it->second.width = 0;
68 it->second.height = 0;
69 }
pbos@webrtc.org273a4142014-12-01 15:23:21 +000070 }
71}
72
pbos@webrtc.org09c77b92015-02-25 10:42:16 +000073VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
74 uint32_t ssrc) {
75 std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
76 stats_.substreams.find(ssrc);
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000077 if (it != stats_.substreams.end())
78 return &it->second;
79
80 if (std::find(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end(), ssrc) ==
stefan@webrtc.org58e2d262014-08-14 15:10:49 +000081 config_.rtp.ssrcs.end() &&
82 std::find(config_.rtp.rtx.ssrcs.begin(),
83 config_.rtp.rtx.ssrcs.end(),
84 ssrc) == config_.rtp.rtx.ssrcs.end()) {
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +000085 return nullptr;
stefan@webrtc.org58e2d262014-08-14 15:10:49 +000086 }
sprang@webrtc.orgccd42842014-01-07 09:54:34 +000087
88 return &stats_.substreams[ssrc]; // Insert new entry and return ptr.
89}
90
Peter Boström20f3f942015-05-15 11:33:39 +020091void SendStatisticsProxy::OnInactiveSsrc(uint32_t ssrc) {
92 rtc::CritScope lock(&crit_);
93 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
94 if (stats == nullptr)
95 return;
96
97 stats->total_bitrate_bps = 0;
98 stats->retransmit_bitrate_bps = 0;
99 stats->height = 0;
100 stats->width = 0;
101}
102
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000103void SendStatisticsProxy::OnSetRates(uint32_t bitrate_bps, int framerate) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200104 rtc::CritScope lock(&crit_);
pbos@webrtc.org891d4832015-02-26 13:15:22 +0000105 stats_.target_media_bitrate_bps = bitrate_bps;
106}
107
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000108void SendStatisticsProxy::OnSendEncodedImage(
109 const EncodedImage& encoded_image,
110 const RTPVideoHeader* rtp_video_header) {
111 size_t simulcast_idx =
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000112 rtp_video_header != nullptr ? rtp_video_header->simulcastIdx : 0;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000113 if (simulcast_idx >= config_.rtp.ssrcs.size()) {
114 LOG(LS_ERROR) << "Encoded image outside simulcast range (" << simulcast_idx
115 << " >= " << config_.rtp.ssrcs.size() << ").";
116 return;
117 }
118 uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx];
119
Peter Boströmf2f82832015-05-01 13:00:41 +0200120 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000121 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000122 if (stats == nullptr)
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000123 return;
124
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000125 stats->width = encoded_image._encodedWidth;
126 stats->height = encoded_image._encodedHeight;
pbos@webrtc.org273a4142014-12-01 15:23:21 +0000127 update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
128}
129
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000130void SendStatisticsProxy::OnIncomingFrame() {
Peter Boströmf2f82832015-05-01 13:00:41 +0200131 rtc::CritScope lock(&crit_);
perkj@webrtc.orgaf612d52015-03-18 09:51:05 +0000132 input_frame_rate_tracker_.Update(1);
133}
134
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000135void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
136 uint32_t ssrc,
137 const RtcpPacketTypeCounter& packet_counter) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200138 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000139 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000140 if (stats == nullptr)
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +0000141 return;
142
143 stats->rtcp_packet_type_counts = packet_counter;
144}
145
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000146void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics,
147 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200148 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000149 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000150 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000151 return;
152
153 stats->rtcp_stats = statistics;
154}
155
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000156void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {
157}
158
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000159void SendStatisticsProxy::DataCountersUpdated(
160 const StreamDataCounters& counters,
161 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200162 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000163 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000164 DCHECK(stats != nullptr) << "DataCountersUpdated reported for unknown ssrc: "
165 << ssrc;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000166
167 stats->rtp_stats = counters;
168}
169
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000170void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
171 const BitrateStatistics& retransmit_stats,
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000172 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200173 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000174 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000175 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000176 return;
177
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +0000178 stats->total_bitrate_bps = total_stats.bitrate_bps;
179 stats->retransmit_bitrate_bps = retransmit_stats.bitrate_bps;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000180}
181
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000182void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
183 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200184 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000185 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000186 if (stats == nullptr)
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000187 return;
188
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +0000189 stats->frame_counts = frame_counts;
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000190}
191
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000192void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
193 int max_delay_ms,
194 uint32_t ssrc) {
Peter Boströmf2f82832015-05-01 13:00:41 +0200195 rtc::CritScope lock(&crit_);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +0000196 VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +0000197 if (stats == nullptr)
stefan@webrtc.org168f23f2014-07-11 13:44:02 +0000198 return;
199 stats->avg_delay_ms = avg_delay_ms;
200 stats->max_delay_ms = max_delay_ms;
201}
202
sprang@webrtc.orgccd42842014-01-07 09:54:34 +0000203} // namespace webrtc