diff --git a/webrtc/modules/video_coding/main/interface/video_coding.h b/webrtc/modules/video_coding/main/interface/video_coding.h index aeb2f797ef..7fd26273f0 100644 --- a/webrtc/modules/video_coding/main/interface/video_coding.h +++ b/webrtc/modules/video_coding/main/interface/video_coding.h @@ -313,8 +313,6 @@ public: // < 0, on error. virtual int32_t EnableFrameDropper(bool enable) = 0; - // Sent frame counters - virtual int32_t SentFrameCount(VCMFrameCount& frameCount) const = 0; /* * Receiver diff --git a/webrtc/modules/video_coding/main/source/media_optimization.cc b/webrtc/modules/video_coding/main/source/media_optimization.cc index 7f60c6c999..b4c1be2815 100644 --- a/webrtc/modules/video_coding/main/source/media_optimization.cc +++ b/webrtc/modules/video_coding/main/source/media_optimization.cc @@ -351,14 +351,6 @@ uint32_t MediaOptimization::SentBitRate() { return avg_sent_bit_rate_bps_; } -VCMFrameCount MediaOptimization::SentFrameCount() { - CriticalSectionScoped lock(crit_sect_.get()); - VCMFrameCount count; - count.numDeltaFrames = delta_frame_cnt_; - count.numKeyFrames = key_frame_cnt_; - return count; -} - int32_t MediaOptimization::UpdateWithEncodedData( const EncodedImage& encoded_image) { size_t encoded_length = encoded_image._length; diff --git a/webrtc/modules/video_coding/main/source/media_optimization.h b/webrtc/modules/video_coding/main/source/media_optimization.h index c3bb3a8599..d2c07c9794 100644 --- a/webrtc/modules/video_coding/main/source/media_optimization.h +++ b/webrtc/modules/video_coding/main/source/media_optimization.h @@ -83,7 +83,6 @@ class MediaOptimization { uint32_t InputFrameRate(); uint32_t SentFrameRate(); uint32_t SentBitRate(); - VCMFrameCount SentFrameCount(); private: enum { diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.cc b/webrtc/modules/video_coding/main/source/video_coding_impl.cc index e0cf479623..e06484ec30 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc @@ -189,10 +189,6 @@ class VideoCodingModuleImpl : public VideoCodingModule { return sender_->EnableFrameDropper(enable); } - int32_t SentFrameCount(VCMFrameCount& frameCount) const override { - return sender_->SentFrameCount(&frameCount); - } - void SuspendBelowMinBitrate() override { return sender_->SuspendBelowMinBitrate(); } diff --git a/webrtc/modules/video_coding/main/source/video_coding_impl.h b/webrtc/modules/video_coding/main/source/video_coding_impl.h index 86a8ca01cb..6813666bd0 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.h +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h @@ -86,7 +86,6 @@ class VideoSender { bool internalSource); int32_t CodecConfigParameters(uint8_t* buffer, int32_t size) const; - int32_t SentFrameCount(VCMFrameCount* frameCount); int Bitrate(unsigned int* bitrate) const; int FrameRate(unsigned int* framerate) const; diff --git a/webrtc/modules/video_coding/main/source/video_sender.cc b/webrtc/modules/video_coding/main/source/video_sender.cc index c59d05afcd..c5317ec412 100644 --- a/webrtc/modules/video_coding/main/source/video_sender.cc +++ b/webrtc/modules/video_coding/main/source/video_sender.cc @@ -184,13 +184,6 @@ int32_t VideoSender::CodecConfigParameters(uint8_t* buffer, return VCM_UNINITIALIZED; } -// TODO(andresp): Make const once media_opt is thread-safe and this has a -// pointer to it. -int32_t VideoSender::SentFrameCount(VCMFrameCount* frameCount) { - *frameCount = _mediaOpt.SentFrameCount(); - return VCM_OK; -} - // Get encode bitrate int VideoSender::Bitrate(unsigned int* bitrate) const { RTC_DCHECK(main_thread_.CalledOnValidThread()); diff --git a/webrtc/video/send_statistics_proxy.cc b/webrtc/video/send_statistics_proxy.cc index a95ade5d83..7316ee8362 100644 --- a/webrtc/video/send_statistics_proxy.cc +++ b/webrtc/video/send_statistics_proxy.cc @@ -64,6 +64,12 @@ void SendStatisticsProxy::UpdateHistograms() { int encode_ms = encode_time_counter_.Avg(kMinRequiredSamples); if (encode_ms != -1) RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.EncodeTimeInMs", encode_ms); + + int key_frames_permille = key_frame_counter_.Permille(kMinRequiredSamples); + if (key_frames_permille != -1) { + RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesSentInPermille", + key_frames_permille); + } } void SendStatisticsProxy::OnOutgoingRate(uint32_t framerate, uint32_t bitrate) { @@ -162,6 +168,9 @@ void SendStatisticsProxy::OnSendEncodedImage( stats->height = encoded_image._encodedHeight; update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds(); + if (encoded_image._frameType != kSkipFrame) + key_frame_counter_.Add(encoded_image._frameType == kKeyFrame); + // TODO(asapersson): This is incorrect if simulcast layers are encoded on // different threads and there is no guarantee that one frame of all layers // are encoded before the next start. @@ -273,4 +282,27 @@ int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const { return sum / num_samples; } +void SendStatisticsProxy::BoolSampleCounter::Add(bool sample) { + if (sample) + ++sum; + ++num_samples; +} + +int SendStatisticsProxy::BoolSampleCounter::Percent( + int min_required_samples) const { + return Fraction(min_required_samples, 100.0f); +} + +int SendStatisticsProxy::BoolSampleCounter::Permille( + int min_required_samples) const { + return Fraction(min_required_samples, 1000.0f); +} + +int SendStatisticsProxy::BoolSampleCounter::Fraction( + int min_required_samples, float multiplier) const { + if (num_samples < min_required_samples || num_samples == 0) + return -1; + return static_cast((sum * multiplier / num_samples) + 0.5f); +} + } // namespace webrtc diff --git a/webrtc/video/send_statistics_proxy.h b/webrtc/video/send_statistics_proxy.h index 3510ded082..6366e5d945 100644 --- a/webrtc/video/send_statistics_proxy.h +++ b/webrtc/video/send_statistics_proxy.h @@ -96,6 +96,17 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver, int sum; int num_samples; }; + struct BoolSampleCounter { + BoolSampleCounter() : sum(0), num_samples(0) {} + void Add(bool sample); + int Percent(int min_required_samples) const; + int Permille(int min_required_samples) const; + + private: + int Fraction(int min_required_samples, float multiplier) const; + int sum; + int num_samples; + }; struct StatsUpdateTimes { StatsUpdateTimes() : resolution_update_ms(0) {} int64_t resolution_update_ms; @@ -122,6 +133,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver, SampleCounter sent_width_counter_ GUARDED_BY(crit_); SampleCounter sent_height_counter_ GUARDED_BY(crit_); SampleCounter encode_time_counter_ GUARDED_BY(crit_); + BoolSampleCounter key_frame_counter_ GUARDED_BY(crit_); }; } // namespace webrtc diff --git a/webrtc/video_engine/vie_encoder.cc b/webrtc/video_engine/vie_encoder.cc index cc4783f55b..fcdc5bb34e 100644 --- a/webrtc/video_engine/vie_encoder.cc +++ b/webrtc/video_engine/vie_encoder.cc @@ -137,8 +137,7 @@ ViEEncoder::ViEEncoder(int32_t channel_id, picture_id_sli_(0), has_received_rpsi_(false), picture_id_rpsi_(0), - video_suspended_(false), - start_ms_(Clock::GetRealTimeClock()->TimeInMilliseconds()) { + video_suspended_(false) { bitrate_observer_.reset(new ViEBitrateObserver(this)); } @@ -175,25 +174,6 @@ void ViEEncoder::StopThreadsAndRemoveSharedMembers() { } ViEEncoder::~ViEEncoder() { - UpdateHistograms(); -} - -void ViEEncoder::UpdateHistograms() { - int64_t elapsed_sec = - (Clock::GetRealTimeClock()->TimeInMilliseconds() - start_ms_) / 1000; - if (elapsed_sec < metrics::kMinRunTimeInSeconds) { - return; - } - webrtc::VCMFrameCount frames; - if (vcm_->SentFrameCount(frames) != VCM_OK) { - return; - } - uint32_t total_frames = frames.numKeyFrames + frames.numDeltaFrames; - if (total_frames > 0) { - RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesSentInPermille", - static_cast( - (frames.numKeyFrames * 1000.0f / total_frames) + 0.5f)); - } } int ViEEncoder::Owner() const { @@ -493,17 +473,6 @@ int ViEEncoder::SendKeyFrame() { return vcm_->IntraFrameRequest(0); } -int32_t ViEEncoder::SendCodecStatistics( - uint32_t* num_key_frames, uint32_t* num_delta_frames) { - webrtc::VCMFrameCount sent_frames; - if (vcm_->SentFrameCount(sent_frames) != VCM_OK) { - return -1; - } - *num_key_frames = sent_frames.numKeyFrames; - *num_delta_frames = sent_frames.numDeltaFrames; - return 0; -} - uint32_t ViEEncoder::LastObservedBitrateBps() const { CriticalSectionScoped cs(data_cs_.get()); return last_observed_bitrate_bps_; diff --git a/webrtc/video_engine/vie_encoder.h b/webrtc/video_engine/vie_encoder.h index 2221f0781d..ec4a82a634 100644 --- a/webrtc/video_engine/vie_encoder.h +++ b/webrtc/video_engine/vie_encoder.h @@ -102,8 +102,6 @@ class ViEEncoder : public RtcpIntraFrameObserver, void DeliverFrame(VideoFrame video_frame) override; int32_t SendKeyFrame(); - int32_t SendCodecStatistics(uint32_t* num_key_frames, - uint32_t* num_delta_frames); uint32_t LastObservedBitrateBps() const; int CodecTargetBitrate(uint32_t* bitrate) const; @@ -162,8 +160,6 @@ class ViEEncoder : public RtcpIntraFrameObserver, void TraceFrameDropStart() EXCLUSIVE_LOCKS_REQUIRED(data_cs_); void TraceFrameDropEnd() EXCLUSIVE_LOCKS_REQUIRED(data_cs_); - void UpdateHistograms(); - const int channel_id_; const uint32_t number_of_cores_; @@ -206,7 +202,6 @@ class ViEEncoder : public RtcpIntraFrameObserver, std::map ssrc_streams_ GUARDED_BY(data_cs_); bool video_suspended_ GUARDED_BY(data_cs_); - const int64_t start_ms_; }; } // namespace webrtc