diff --git a/webrtc/modules/video_coding/main/interface/video_coding.h b/webrtc/modules/video_coding/main/interface/video_coding.h index 41b16c22e..94e8f9de0 100644 --- a/webrtc/modules/video_coding/main/interface/video_coding.h +++ b/webrtc/modules/video_coding/main/interface/video_coding.h @@ -582,8 +582,6 @@ public: EncodedImageCallback* observer) = 0; virtual void RegisterPostEncodeImageCallback( EncodedImageCallback* post_encode_callback) = 0; - virtual void RegisterReceiveFrameCountObserver( - FrameCountObserver* frame_count_observer) = 0; }; } // namespace webrtc diff --git a/webrtc/modules/video_coding/main/interface/video_coding_defines.h b/webrtc/modules/video_coding/main/interface/video_coding_defines.h index 1bf3d6fdc..976a1761c 100644 --- a/webrtc/modules/video_coding/main/interface/video_coding_defines.h +++ b/webrtc/modules/video_coding/main/interface/video_coding_defines.h @@ -109,8 +109,9 @@ class VCMSendStatisticsCallback { // Callback class used for informing the user of the incoming bit rate and frame rate. class VCMReceiveStatisticsCallback { public: - virtual int32_t OnReceiveStatisticsUpdate(const uint32_t bitRate, - const uint32_t frameRate) = 0; + virtual void OnReceiveRatesUpdated(uint32_t bitRate, uint32_t frameRate) = 0; + virtual void OnDiscardedPacketsUpdated(int discarded_packets) = 0; + virtual void OnFrameCountsUpdated(const FrameCounts& frame_counts) = 0; protected: virtual ~VCMReceiveStatisticsCallback() { diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.cc b/webrtc/modules/video_coding/main/source/jitter_buffer.cc index 6da342dba..2a590df69 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer.cc +++ b/webrtc/modules/video_coding/main/source/jitter_buffer.cc @@ -124,7 +124,7 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock, EventFactory* event_factory) incomplete_frames_(), last_decoded_state_(), first_packet_since_reset_(true), - frame_count_observer_(NULL), + stats_callback_(NULL), incoming_frame_rate_(0), incoming_frame_count_(0), time_last_incoming_frame_count_(0), @@ -570,6 +570,8 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(const VCMPacket& packet, if (packet.sizeBytes > 0) { num_discarded_packets_++; num_consecutive_old_packets_++; + if (stats_callback_ != NULL) + stats_callback_->OnDiscardedPacketsUpdated(num_discarded_packets_); } // Update last decoded sequence number if the packet arrived late and // belongs to a frame with a timestamp equal to the last decoded @@ -1040,10 +1042,10 @@ void VCMJitterBuffer::RenderBufferSize(uint32_t* timestamp_start, *timestamp_end = decodable_frames_.Back()->TimeStamp(); } -void VCMJitterBuffer::RegisterFrameCountObserver( - FrameCountObserver* frame_count_observer) { +void VCMJitterBuffer::RegisterStatsCallback( + VCMReceiveStatisticsCallback* callback) { CriticalSectionScoped cs(crit_sect_); - frame_count_observer_ = frame_count_observer; + stats_callback_ = callback; } VCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() { @@ -1118,8 +1120,8 @@ void VCMJitterBuffer::CountFrame(const VCMFrameBuffer& frame) { } else { ++receive_statistics_.delta_frames; } - if (frame_count_observer_ != NULL) - frame_count_observer_->FrameCountUpdated(receive_statistics_, 0); + if (stats_callback_ != NULL) + stats_callback_->OnFrameCountsUpdated(receive_statistics_); } } diff --git a/webrtc/modules/video_coding/main/source/jitter_buffer.h b/webrtc/modules/video_coding/main/source/jitter_buffer.h index c2833f08d..5ac2b7aab 100644 --- a/webrtc/modules/video_coding/main/source/jitter_buffer.h +++ b/webrtc/modules/video_coding/main/source/jitter_buffer.h @@ -184,7 +184,7 @@ class VCMJitterBuffer { // corresponding to the start and end of the continuous complete buffer. void RenderBufferSize(uint32_t* timestamp_start, uint32_t* timestamp_end); - void RegisterFrameCountObserver(FrameCountObserver* observer); + void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback); private: class SequenceNumberLessThan { @@ -303,8 +303,8 @@ class VCMJitterBuffer { bool first_packet_since_reset_; // Statistics. + VCMReceiveStatisticsCallback* stats_callback_ GUARDED_BY(crit_sect_); // Frame counts for each type (key, delta, ...) - FrameCountObserver* frame_count_observer_ GUARDED_BY(crit_sect_); FrameCounts receive_statistics_; // Latest calculated frame rates of incoming stream. unsigned int incoming_frame_rate_; diff --git a/webrtc/modules/video_coding/main/source/receiver.cc b/webrtc/modules/video_coding/main/source/receiver.cc index a18488d56..e1a4e2ff1 100644 --- a/webrtc/modules/video_coding/main/source/receiver.cc +++ b/webrtc/modules/video_coding/main/source/receiver.cc @@ -270,9 +270,9 @@ int VCMReceiver::RenderBufferSizeMs() { return render_end - render_start; } -void VCMReceiver::RegisterFrameCountObserver( - FrameCountObserver* frame_count_observer) { - jitter_buffer_.RegisterFrameCountObserver(frame_count_observer); +void VCMReceiver::RegisterStatsCallback( + VCMReceiveStatisticsCallback* callback) { + jitter_buffer_.RegisterStatsCallback(callback); } } // namespace webrtc diff --git a/webrtc/modules/video_coding/main/source/receiver.h b/webrtc/modules/video_coding/main/source/receiver.h index bfe510cf8..068715f79 100644 --- a/webrtc/modules/video_coding/main/source/receiver.h +++ b/webrtc/modules/video_coding/main/source/receiver.h @@ -79,7 +79,7 @@ class VCMReceiver { // the time this function is called. int RenderBufferSizeMs(); - void RegisterFrameCountObserver(FrameCountObserver* frame_count_observer); + void RegisterStatsCallback(VCMReceiveStatisticsCallback* callback); private: static int32_t GenerateReceiverId(); 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 08e7e7327..ac938e686 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.cc +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.cc @@ -278,11 +278,6 @@ class VideoCodingModuleImpl : public VideoCodingModule { return receiver_->RegisterRenderBufferSizeCallback(callback); } - virtual void RegisterReceiveFrameCountObserver( - FrameCountObserver* frame_count_observer) OVERRIDE { - receiver_->RegisterFrameCountObserver(frame_count_observer); - } - virtual int32_t Decode(uint16_t maxWaitTimeMs) OVERRIDE { return receiver_->Decode(maxWaitTimeMs); } 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 ed50ef4fd..3454e9cf1 100644 --- a/webrtc/modules/video_coding/main/source/video_coding_impl.h +++ b/webrtc/modules/video_coding/main/source/video_coding_impl.h @@ -182,7 +182,6 @@ class VideoReceiver { int32_t Process(); void RegisterPreDecodeImageCallback(EncodedImageCallback* observer); - void RegisterFrameCountObserver(FrameCountObserver* frame_count_observer); protected: int32_t Decode(const webrtc::VCMEncodedFrame& frame) diff --git a/webrtc/modules/video_coding/main/source/video_receiver.cc b/webrtc/modules/video_coding/main/source/video_receiver.cc index 3813205cb..f623c7deb 100644 --- a/webrtc/modules/video_coding/main/source/video_receiver.cc +++ b/webrtc/modules/video_coding/main/source/video_receiver.cc @@ -74,7 +74,7 @@ int32_t VideoReceiver::Process() { uint32_t bitRate; uint32_t frameRate; _receiver.ReceiveStatistics(&bitRate, &frameRate); - _receiveStatsCallback->OnReceiveStatisticsUpdate(bitRate, frameRate); + _receiveStatsCallback->OnReceiveRatesUpdated(bitRate, frameRate); } if (_decoderTimingCallback != NULL) { @@ -284,6 +284,7 @@ int32_t VideoReceiver::RegisterReceiveCallback( int32_t VideoReceiver::RegisterReceiveStatisticsCallback( VCMReceiveStatisticsCallback* receiveStats) { CriticalSectionScoped cs(process_crit_sect_.get()); + _receiver.RegisterStatsCallback(receiveStats); _receiveStatsCallback = receiveStats; return VCM_OK; } @@ -666,10 +667,6 @@ void VideoReceiver::RegisterPreDecodeImageCallback( CriticalSectionScoped cs(_receiveCritSect); pre_decode_image_callback_ = observer; } -void VideoReceiver::RegisterFrameCountObserver( - FrameCountObserver* frame_count_observer) { - _receiver.RegisterFrameCountObserver(frame_count_observer); -} } // namespace vcm } // namespace webrtc diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc index 9d1589d50..15238f6d0 100644 --- a/webrtc/video/receive_statistics_proxy.cc +++ b/webrtc/video/receive_statistics_proxy.cc @@ -15,13 +15,8 @@ namespace webrtc { -ReceiveStatisticsProxy::ReceiveStatisticsProxy(uint32_t ssrc, - Clock* clock, - ViECodec* codec, - int channel) - : channel_(channel), - clock_(clock), - codec_(codec), +ReceiveStatisticsProxy::ReceiveStatisticsProxy(uint32_t ssrc, Clock* clock) + : clock_(clock), crit_(CriticalSectionWrapper::CreateCriticalSection()), // 1000ms window, scale 1000 for ms to s. decode_fps_estimator_(1000, 1000), @@ -32,14 +27,8 @@ ReceiveStatisticsProxy::ReceiveStatisticsProxy(uint32_t ssrc, ReceiveStatisticsProxy::~ReceiveStatisticsProxy() {} VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const { - VideoReceiveStream::Stats stats; - { - CriticalSectionScoped lock(crit_.get()); - stats = stats_; - } - stats.discarded_packets = codec_->GetNumDiscardedPackets(channel_); - - return stats; + CriticalSectionScoped lock(crit_.get()); + return stats_; } void ReceiveStatisticsProxy::IncomingRate(const int video_channel, @@ -98,10 +87,19 @@ void ReceiveStatisticsProxy::OnRenderedFrame() { stats_.render_frame_rate = renders_fps_estimator_.Rate(now); } -void ReceiveStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts, - uint32_t ssrc) { +void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate, + uint32_t frameRate) { +} + +void ReceiveStatisticsProxy::OnFrameCountsUpdated( + const FrameCounts& frame_counts) { CriticalSectionScoped lock(crit_.get()); stats_.frame_counts = frame_counts; } +void ReceiveStatisticsProxy::OnDiscardedPacketsUpdated(int discarded_packets) { + CriticalSectionScoped lock(crit_.get()); + stats_.discarded_packets = discarded_packets; +} + } // namespace webrtc diff --git a/webrtc/video/receive_statistics_proxy.h b/webrtc/video/receive_statistics_proxy.h index c61d6eaac..2286d0815 100644 --- a/webrtc/video/receive_statistics_proxy.h +++ b/webrtc/video/receive_statistics_proxy.h @@ -17,6 +17,7 @@ #include "webrtc/common_types.h" #include "webrtc/frame_callback.h" #include "webrtc/modules/remote_bitrate_estimator/rate_statistics.h" +#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h" #include "webrtc/video_engine/include/vie_codec.h" #include "webrtc/video_engine/include/vie_rtp_rtcp.h" #include "webrtc/video_receive_stream.h" @@ -30,14 +31,11 @@ class ViECodec; class ViEDecoderObserver; class ReceiveStatisticsProxy : public ViEDecoderObserver, + public VCMReceiveStatisticsCallback, public RtcpStatisticsCallback, - public StreamDataCountersCallback, - public FrameCountObserver { + public StreamDataCountersCallback { public: - ReceiveStatisticsProxy(uint32_t ssrc, - Clock* clock, - ViECodec* codec, - int channel); + ReceiveStatisticsProxy(uint32_t ssrc, Clock* clock); virtual ~ReceiveStatisticsProxy(); VideoReceiveStream::Stats GetStats() const; @@ -45,6 +43,12 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver, void OnDecodedFrame(); void OnRenderedFrame(); + // Overrides VCMReceiveStatisticsCallback + virtual void OnReceiveRatesUpdated(uint32_t bitRate, + uint32_t frameRate) OVERRIDE; + virtual void OnFrameCountsUpdated(const FrameCounts& frame_counts) OVERRIDE; + virtual void OnDiscardedPacketsUpdated(int discarded_packets) OVERRIDE; + // Overrides ViEDecoderObserver. virtual void IncomingCodecChanged(const int video_channel, const VideoCodec& video_codec) OVERRIDE {} @@ -69,14 +73,8 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver, virtual void DataCountersUpdated(const webrtc::StreamDataCounters& counters, uint32_t ssrc) OVERRIDE; - // Overrides FrameCountObserver. - virtual void FrameCountUpdated(const FrameCounts& frame_counts, - uint32_t ssrc) OVERRIDE; - private: - const int channel_; Clock* const clock_; - ViECodec* const codec_; scoped_ptr crit_; VideoReceiveStream::Stats stats_ GUARDED_BY(crit_); diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc index 55e086774..73f6e7c83 100644 --- a/webrtc/video/video_receive_stream.cc +++ b/webrtc/video/video_receive_stream.cc @@ -148,8 +148,8 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine, } } - stats_proxy_.reset(new ReceiveStatisticsProxy(config_.rtp.local_ssrc, clock_, - codec_, channel_)); + stats_proxy_.reset( + new ReceiveStatisticsProxy(config_.rtp.local_ssrc, clock_)); if (rtp_rtcp_->RegisterReceiveChannelRtcpStatisticsCallback( channel_, stats_proxy_.get()) != 0) { diff --git a/webrtc/video_engine/vie_channel.cc b/webrtc/video_engine/vie_channel.cc index 24805ae9f..e9be29ff2 100644 --- a/webrtc/video_engine/vie_channel.cc +++ b/webrtc/video_engine/vie_channel.cc @@ -129,6 +129,7 @@ ViEChannel::ViEChannel(int32_t channel_id, vie_sender_(channel_id), vie_sync_(vcm_, this), stats_observer_(new ChannelStatsObserver(this)), + vcm_receive_stats_callback_(NULL), module_process_thread_(module_process_thread), codec_observer_(NULL), do_key_frame_callbackRequest_(false), @@ -156,7 +157,6 @@ ViEChannel::ViEChannel(int32_t channel_id, rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration)); vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get()); vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0); - vcm_->RegisterReceiveFrameCountObserver(&receive_frame_count_observer_); } int32_t ViEChannel::Init() { @@ -576,7 +576,9 @@ int32_t ViEChannel::DeRegisterExternalDecoder(const uint8_t pl_type) { int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames, uint32_t* num_delta_frames) { - receive_frame_count_observer_.GetFrameCount(num_key_frames, num_delta_frames); + CriticalSectionScoped cs(callback_cs_.get()); + *num_key_frames = receive_frame_counts_.key_frames; + *num_delta_frames = receive_frame_counts_.delta_frames; return 0; } @@ -1568,13 +1570,23 @@ void ViEChannel::IncomingCodecChanged(const VideoCodec& codec) { receive_codec_ = codec; } -int32_t ViEChannel::OnReceiveStatisticsUpdate(const uint32_t bit_rate, - const uint32_t frame_rate) { +void ViEChannel::OnReceiveRatesUpdated(uint32_t bit_rate, uint32_t frame_rate) { CriticalSectionScoped cs(callback_cs_.get()); - if (codec_observer_) { + if (codec_observer_) codec_observer_->IncomingRate(channel_id_, frame_rate, bit_rate); - } - return 0; +} + +void ViEChannel::OnDiscardedPacketsUpdated(int discarded_packets) { + CriticalSectionScoped cs(callback_cs_.get()); + if (vcm_receive_stats_callback_ != NULL) + vcm_receive_stats_callback_->OnDiscardedPacketsUpdated(discarded_packets); +} + +void ViEChannel::OnFrameCountsUpdated(const FrameCounts& frame_counts) { + CriticalSectionScoped cs(callback_cs_.get()); + receive_frame_counts_ = frame_counts; + if (vcm_receive_stats_callback_ != NULL) + vcm_receive_stats_callback_->OnFrameCountsUpdated(frame_counts); } void ViEChannel::OnDecoderTiming(int decode_ms, @@ -1820,7 +1832,8 @@ void ViEChannel::RegisterSendFrameCountObserver( void ViEChannel::RegisterReceiveStatisticsProxy( ReceiveStatisticsProxy* receive_statistics_proxy) { - receive_frame_count_observer_.Set(receive_statistics_proxy); + CriticalSectionScoped cs(callback_cs_.get()); + vcm_receive_stats_callback_ = receive_statistics_proxy; } void ViEChannel::ReceivedBWEPacket(int64_t arrival_time_ms, diff --git a/webrtc/video_engine/vie_channel.h b/webrtc/video_engine/vie_channel.h index 5c85b5b42..3bc659720 100644 --- a/webrtc/video_engine/vie_channel.h +++ b/webrtc/video_engine/vie_channel.h @@ -314,8 +314,10 @@ class ViEChannel virtual void IncomingCodecChanged(const VideoCodec& codec); // Implements VCMReceiveStatisticsCallback. - virtual int32_t OnReceiveStatisticsUpdate(const uint32_t bit_rate, - const uint32_t frame_rate); + virtual void OnReceiveRatesUpdated(uint32_t bit_rate, + uint32_t frame_rate) OVERRIDE; + virtual void OnDiscardedPacketsUpdated(int discarded_packets) OVERRIDE; + virtual void OnFrameCountsUpdated(const FrameCounts& frame_counts) OVERRIDE; // Implements VCMDecoderTimingCallback. virtual void OnDecoderTiming(int decode_ms, @@ -431,20 +433,12 @@ class ViEChannel virtual void FrameCountUpdated(const FrameCounts& frame_counts, uint32_t ssrc) { CriticalSectionScoped cs(critsect_.get()); - frame_counts_ = frame_counts; if (callback_) callback_->FrameCountUpdated(frame_counts, ssrc); } - void GetFrameCount(uint32_t* num_key_frames, uint32_t* num_delta_frames) { - CriticalSectionScoped cs(critsect_.get()); - *num_key_frames = frame_counts_.key_frames; - *num_delta_frames = frame_counts_.delta_frames; - } - private: - FrameCounts frame_counts_ GUARDED_BY(critsect_); - } send_frame_count_observer_, receive_frame_count_observer_; + } send_frame_count_observer_; class RegisterableSendSideDelayObserver : public RegisterableCallback { @@ -481,6 +475,9 @@ class ViEChannel scoped_ptr stats_observer_; // Not owned. + VCMReceiveStatisticsCallback* vcm_receive_stats_callback_ + GUARDED_BY(callback_cs_); + FrameCounts receive_frame_counts_ GUARDED_BY(callback_cs_); ProcessThread& module_process_thread_; ViEDecoderObserver* codec_observer_; bool do_key_frame_callbackRequest_;