2014-01-07 09:54:34 +00:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2013 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "webrtc/video/send_statistics_proxy.h"
|
|
|
|
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
2015-02-24 22:37:52 +00:00
|
|
|
#include "webrtc/base/checks.h"
|
|
|
|
|
|
2014-01-07 09:54:34 +00:00
|
|
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
2014-12-01 15:23:21 +00:00
|
|
|
#include "webrtc/system_wrappers/interface/logging.h"
|
2014-01-07 09:54:34 +00:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
2014-12-01 15:23:21 +00:00
|
|
|
const int SendStatisticsProxy::kStatsTimeoutMs = 5000;
|
|
|
|
|
|
|
|
|
|
SendStatisticsProxy::SendStatisticsProxy(Clock* clock,
|
|
|
|
|
const VideoSendStream::Config& config)
|
|
|
|
|
: clock_(clock),
|
|
|
|
|
config_(config),
|
2014-04-28 13:00:21 +00:00
|
|
|
crit_(CriticalSectionWrapper::CreateCriticalSection()) {
|
|
|
|
|
}
|
2014-01-07 09:54:34 +00:00
|
|
|
|
|
|
|
|
SendStatisticsProxy::~SendStatisticsProxy() {}
|
|
|
|
|
|
|
|
|
|
void SendStatisticsProxy::OutgoingRate(const int video_channel,
|
|
|
|
|
const unsigned int framerate,
|
|
|
|
|
const unsigned int bitrate) {
|
2014-04-28 13:00:21 +00:00
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2014-01-07 09:54:34 +00:00
|
|
|
stats_.encode_frame_rate = framerate;
|
2014-11-05 14:05:29 +00:00
|
|
|
stats_.media_bitrate_bps = bitrate;
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2015-02-26 12:19:31 +00:00
|
|
|
void SendStatisticsProxy::CpuOveruseMetricsUpdated(
|
|
|
|
|
const CpuOveruseMetrics& metrics) {
|
|
|
|
|
CriticalSectionScoped lock(crit_.get());
|
|
|
|
|
stats_.avg_encode_time_ms = metrics.avg_encode_time_ms;
|
|
|
|
|
stats_.encode_usage_percent = metrics.encode_usage_percent;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-13 13:31:21 +00:00
|
|
|
void SendStatisticsProxy::SuspendChange(int video_channel, bool is_suspended) {
|
2014-04-28 13:00:21 +00:00
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2014-03-13 13:31:21 +00:00
|
|
|
stats_.suspended = is_suspended;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-10 15:12:26 +00:00
|
|
|
void SendStatisticsProxy::CapturedFrameRate(const int capture_id,
|
|
|
|
|
const unsigned char frame_rate) {
|
|
|
|
|
CriticalSectionScoped lock(crit_.get());
|
|
|
|
|
stats_.input_frame_rate = frame_rate;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-01 15:23:21 +00:00
|
|
|
VideoSendStream::Stats SendStatisticsProxy::GetStats() {
|
2014-07-11 13:44:02 +00:00
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2014-12-01 15:23:21 +00:00
|
|
|
PurgeOldStats();
|
2014-07-11 13:44:02 +00:00
|
|
|
return stats_;
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2014-12-01 15:23:21 +00:00
|
|
|
void SendStatisticsProxy::PurgeOldStats() {
|
|
|
|
|
int64_t current_time_ms = clock_->TimeInMilliseconds();
|
2015-02-25 10:42:16 +00:00
|
|
|
for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
|
|
|
|
|
stats_.substreams.begin();
|
2014-12-01 15:23:21 +00:00
|
|
|
it != stats_.substreams.end(); ++it) {
|
|
|
|
|
uint32_t ssrc = it->first;
|
|
|
|
|
if (update_times_[ssrc].resolution_update_ms + kStatsTimeoutMs >
|
|
|
|
|
current_time_ms)
|
|
|
|
|
continue;
|
|
|
|
|
|
2015-02-25 10:42:16 +00:00
|
|
|
it->second.width = 0;
|
|
|
|
|
it->second.height = 0;
|
2014-12-01 15:23:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
|
|
|
|
|
uint32_t ssrc) {
|
|
|
|
|
std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
|
|
|
|
|
stats_.substreams.find(ssrc);
|
2014-01-07 09:54:34 +00:00
|
|
|
if (it != stats_.substreams.end())
|
|
|
|
|
return &it->second;
|
|
|
|
|
|
|
|
|
|
if (std::find(config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end(), ssrc) ==
|
2014-08-14 15:10:49 +00:00
|
|
|
config_.rtp.ssrcs.end() &&
|
|
|
|
|
std::find(config_.rtp.rtx.ssrcs.begin(),
|
|
|
|
|
config_.rtp.rtx.ssrcs.end(),
|
|
|
|
|
ssrc) == config_.rtp.rtx.ssrcs.end()) {
|
2014-01-07 09:54:34 +00:00
|
|
|
return NULL;
|
2014-08-14 15:10:49 +00:00
|
|
|
}
|
2014-01-07 09:54:34 +00:00
|
|
|
|
|
|
|
|
return &stats_.substreams[ssrc]; // Insert new entry and return ptr.
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-26 13:15:22 +00:00
|
|
|
void SendStatisticsProxy::OnSetRates(uint32_t bitrate_bps, int framerate) {
|
|
|
|
|
CriticalSectionScoped lock(crit_.get());
|
|
|
|
|
stats_.target_media_bitrate_bps = bitrate_bps;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-01 15:23:21 +00:00
|
|
|
void SendStatisticsProxy::OnSendEncodedImage(
|
|
|
|
|
const EncodedImage& encoded_image,
|
|
|
|
|
const RTPVideoHeader* rtp_video_header) {
|
|
|
|
|
size_t simulcast_idx =
|
|
|
|
|
rtp_video_header != NULL ? rtp_video_header->simulcastIdx : 0;
|
|
|
|
|
if (simulcast_idx >= config_.rtp.ssrcs.size()) {
|
|
|
|
|
LOG(LS_ERROR) << "Encoded image outside simulcast range (" << simulcast_idx
|
|
|
|
|
<< " >= " << config_.rtp.ssrcs.size() << ").";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx];
|
|
|
|
|
|
|
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2014-12-01 15:23:21 +00:00
|
|
|
if (stats == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2015-02-25 10:42:16 +00:00
|
|
|
stats->width = encoded_image._encodedWidth;
|
|
|
|
|
stats->height = encoded_image._encodedHeight;
|
2014-12-01 15:23:21 +00:00
|
|
|
update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-19 12:47:00 +00:00
|
|
|
void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
|
|
|
|
|
uint32_t ssrc,
|
|
|
|
|
const RtcpPacketTypeCounter& packet_counter) {
|
|
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2015-02-19 12:47:00 +00:00
|
|
|
if (stats == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
stats->rtcp_packet_type_counts = packet_counter;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-07 09:54:34 +00:00
|
|
|
void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics,
|
|
|
|
|
uint32_t ssrc) {
|
2014-04-28 13:00:21 +00:00
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2014-01-07 09:54:34 +00:00
|
|
|
if (stats == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
stats->rtcp_stats = statistics;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-18 13:50:16 +00:00
|
|
|
void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-07 09:54:34 +00:00
|
|
|
void SendStatisticsProxy::DataCountersUpdated(
|
|
|
|
|
const StreamDataCounters& counters,
|
|
|
|
|
uint32_t ssrc) {
|
2014-04-28 13:00:21 +00:00
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2015-02-24 22:37:52 +00:00
|
|
|
DCHECK(stats != NULL) << "DataCountersUpdated reported for unknown ssrc: "
|
|
|
|
|
<< ssrc;
|
2014-01-07 09:54:34 +00:00
|
|
|
|
|
|
|
|
stats->rtp_stats = counters;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-05 14:05:29 +00:00
|
|
|
void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
|
|
|
|
|
const BitrateStatistics& retransmit_stats,
|
2014-01-07 09:54:34 +00:00
|
|
|
uint32_t ssrc) {
|
2014-04-28 13:00:21 +00:00
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2014-01-07 09:54:34 +00:00
|
|
|
if (stats == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-11-05 14:05:29 +00:00
|
|
|
stats->total_bitrate_bps = total_stats.bitrate_bps;
|
|
|
|
|
stats->retransmit_bitrate_bps = retransmit_stats.bitrate_bps;
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2014-12-18 13:50:16 +00:00
|
|
|
void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
|
|
|
|
|
uint32_t ssrc) {
|
2014-04-28 13:00:21 +00:00
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2014-01-07 09:54:34 +00:00
|
|
|
if (stats == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-12-18 13:50:16 +00:00
|
|
|
stats->frame_counts = frame_counts;
|
2014-01-07 09:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
2014-07-11 13:44:02 +00:00
|
|
|
void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
|
|
|
|
|
int max_delay_ms,
|
|
|
|
|
uint32_t ssrc) {
|
|
|
|
|
CriticalSectionScoped lock(crit_.get());
|
2015-02-25 10:42:16 +00:00
|
|
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
2014-07-11 13:44:02 +00:00
|
|
|
if (stats == NULL)
|
|
|
|
|
return;
|
|
|
|
|
stats->avg_delay_ms = avg_delay_ms;
|
|
|
|
|
stats->max_delay_ms = max_delay_ms;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-07 09:54:34 +00:00
|
|
|
} // namespace webrtc
|