Refactor some receive-side stats.
Removes polling of CName as well as receive codec statistics in favor of internal callbacks keeping a statistics struct up to date. R=mflodman@webrtc.org, stefan@webrtc.org BUG=1667 Review URL: https://webrtc-codereview.appspot.com/28259005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7950 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
98c04b38a8
commit
ce4e9a3562
@ -727,6 +727,9 @@ class FakeWebRtcVideoEngine
|
|||||||
WEBRTC_VOID_STUB(RegisterSendStatisticsProxy,
|
WEBRTC_VOID_STUB(RegisterSendStatisticsProxy,
|
||||||
(int, webrtc::SendStatisticsProxy*));
|
(int, webrtc::SendStatisticsProxy*));
|
||||||
|
|
||||||
|
WEBRTC_VOID_STUB(RegisterReceiveStatisticsProxy,
|
||||||
|
(int, webrtc::ReceiveStatisticsProxy*));
|
||||||
|
|
||||||
// webrtc::ViECodec
|
// webrtc::ViECodec
|
||||||
WEBRTC_FUNC_CONST(NumberOfCodecs, ()) {
|
WEBRTC_FUNC_CONST(NumberOfCodecs, ()) {
|
||||||
return num_codecs_;
|
return num_codecs_;
|
||||||
|
@ -188,13 +188,13 @@ struct RtcpStatistics {
|
|||||||
uint32_t jitter;
|
uint32_t jitter;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Callback, called whenever a new rtcp report block is transmitted.
|
|
||||||
class RtcpStatisticsCallback {
|
class RtcpStatisticsCallback {
|
||||||
public:
|
public:
|
||||||
virtual ~RtcpStatisticsCallback() {}
|
virtual ~RtcpStatisticsCallback() {}
|
||||||
|
|
||||||
virtual void StatisticsUpdated(const RtcpStatistics& statistics,
|
virtual void StatisticsUpdated(const RtcpStatistics& statistics,
|
||||||
uint32_t ssrc) = 0;
|
uint32_t ssrc) = 0;
|
||||||
|
virtual void CNameChanged(const char* cname, uint32_t ssrc) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Statistics for RTCP packet types.
|
// Statistics for RTCP packet types.
|
||||||
@ -331,13 +331,18 @@ class BitrateStatisticsObserver {
|
|||||||
uint32_t ssrc) = 0;
|
uint32_t ssrc) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FrameCounts {
|
||||||
|
FrameCounts() : key_frames(0), delta_frames(0) {}
|
||||||
|
int key_frames;
|
||||||
|
int delta_frames;
|
||||||
|
};
|
||||||
|
|
||||||
// Callback, used to notify an observer whenever frame counts have been updated.
|
// Callback, used to notify an observer whenever frame counts have been updated.
|
||||||
class FrameCountObserver {
|
class FrameCountObserver {
|
||||||
public:
|
public:
|
||||||
virtual ~FrameCountObserver() {}
|
virtual ~FrameCountObserver() {}
|
||||||
virtual void FrameCountUpdated(FrameType frame_type,
|
virtual void FrameCountUpdated(const FrameCounts& frame_counts,
|
||||||
uint32_t frame_count,
|
uint32_t ssrc) = 0;
|
||||||
const unsigned int ssrc) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Callback, used to notify an observer whenever the send-side delay is updated.
|
// Callback, used to notify an observer whenever the send-side delay is updated.
|
||||||
|
@ -23,16 +23,13 @@ namespace webrtc {
|
|||||||
|
|
||||||
struct SsrcStats {
|
struct SsrcStats {
|
||||||
SsrcStats()
|
SsrcStats()
|
||||||
: key_frames(0),
|
: sent_width(0),
|
||||||
delta_frames(0),
|
|
||||||
sent_width(0),
|
|
||||||
sent_height(0),
|
sent_height(0),
|
||||||
total_bitrate_bps(0),
|
total_bitrate_bps(0),
|
||||||
retransmit_bitrate_bps(0),
|
retransmit_bitrate_bps(0),
|
||||||
avg_delay_ms(0),
|
avg_delay_ms(0),
|
||||||
max_delay_ms(0) {}
|
max_delay_ms(0) {}
|
||||||
uint32_t key_frames;
|
FrameCounts frame_counts;
|
||||||
uint32_t delta_frames;
|
|
||||||
int sent_width;
|
int sent_width;
|
||||||
int sent_height;
|
int sent_height;
|
||||||
// TODO(holmer): Move bitrate_bps out to the webrtc::Call layer.
|
// TODO(holmer): Move bitrate_bps out to the webrtc::Call layer.
|
||||||
|
@ -586,10 +586,10 @@ class RtpRtcp : public Module {
|
|||||||
virtual bool StorePackets() const = 0;
|
virtual bool StorePackets() const = 0;
|
||||||
|
|
||||||
// Called on receipt of RTCP report block from remote side.
|
// Called on receipt of RTCP report block from remote side.
|
||||||
virtual void RegisterSendChannelRtcpStatisticsCallback(
|
virtual void RegisterRtcpStatisticsCallback(
|
||||||
RtcpStatisticsCallback* callback) = 0;
|
RtcpStatisticsCallback* callback) = 0;
|
||||||
virtual RtcpStatisticsCallback*
|
virtual RtcpStatisticsCallback*
|
||||||
GetSendChannelRtcpStatisticsCallback() = 0;
|
GetRtcpStatisticsCallback() = 0;
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
*
|
*
|
||||||
|
@ -221,10 +221,8 @@ class MockRtpRtcp : public RtpRtcp {
|
|||||||
MOCK_METHOD2(SetStorePacketsStatus,
|
MOCK_METHOD2(SetStorePacketsStatus,
|
||||||
int32_t(const bool enable, const uint16_t numberToStore));
|
int32_t(const bool enable, const uint16_t numberToStore));
|
||||||
MOCK_CONST_METHOD0(StorePackets, bool());
|
MOCK_CONST_METHOD0(StorePackets, bool());
|
||||||
MOCK_METHOD1(RegisterSendChannelRtcpStatisticsCallback,
|
MOCK_METHOD1(RegisterRtcpStatisticsCallback, void(RtcpStatisticsCallback*));
|
||||||
void(RtcpStatisticsCallback*));
|
MOCK_METHOD0(GetRtcpStatisticsCallback, RtcpStatisticsCallback*());
|
||||||
MOCK_METHOD0(GetSendChannelRtcpStatisticsCallback,
|
|
||||||
RtcpStatisticsCallback*());
|
|
||||||
MOCK_METHOD1(RegisterAudioCallback,
|
MOCK_METHOD1(RegisterAudioCallback,
|
||||||
int32_t(RtpAudioFeedback* messagesCallback));
|
int32_t(RtpAudioFeedback* messagesCallback));
|
||||||
MOCK_METHOD1(SetAudioPacketSize,
|
MOCK_METHOD1(SetAudioPacketSize,
|
||||||
|
@ -511,9 +511,14 @@ void ReceiveStatisticsImpl::RegisterRtcpStatisticsCallback(
|
|||||||
void ReceiveStatisticsImpl::StatisticsUpdated(const RtcpStatistics& statistics,
|
void ReceiveStatisticsImpl::StatisticsUpdated(const RtcpStatistics& statistics,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
CriticalSectionScoped cs(receive_statistics_lock_.get());
|
CriticalSectionScoped cs(receive_statistics_lock_.get());
|
||||||
if (rtcp_stats_callback_) {
|
if (rtcp_stats_callback_)
|
||||||
rtcp_stats_callback_->StatisticsUpdated(statistics, ssrc);
|
rtcp_stats_callback_->StatisticsUpdated(statistics, ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReceiveStatisticsImpl::CNameChanged(const char* cname, uint32_t ssrc) {
|
||||||
|
CriticalSectionScoped cs(receive_statistics_lock_.get());
|
||||||
|
if (rtcp_stats_callback_)
|
||||||
|
rtcp_stats_callback_->CNameChanged(cname, ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveStatisticsImpl::RegisterRtpStatisticsCallback(
|
void ReceiveStatisticsImpl::RegisterRtpStatisticsCallback(
|
||||||
|
@ -128,6 +128,7 @@ class ReceiveStatisticsImpl : public ReceiveStatistics,
|
|||||||
private:
|
private:
|
||||||
virtual void StatisticsUpdated(const RtcpStatistics& statistics,
|
virtual void StatisticsUpdated(const RtcpStatistics& statistics,
|
||||||
uint32_t ssrc) OVERRIDE;
|
uint32_t ssrc) OVERRIDE;
|
||||||
|
virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE;
|
||||||
virtual void DataCountersUpdated(const StreamDataCounters& counters,
|
virtual void DataCountersUpdated(const StreamDataCounters& counters,
|
||||||
uint32_t ssrc) OVERRIDE;
|
uint32_t ssrc) OVERRIDE;
|
||||||
|
|
||||||
|
@ -169,6 +169,8 @@ TEST_F(ReceiveStatisticsTest, RtcpCallbacks) {
|
|||||||
++num_calls_;
|
++num_calls_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE {}
|
||||||
|
|
||||||
uint32_t num_calls_;
|
uint32_t num_calls_;
|
||||||
uint32_t ssrc_;
|
uint32_t ssrc_;
|
||||||
RtcpStatistics stats_;
|
RtcpStatistics stats_;
|
||||||
|
@ -809,6 +809,10 @@ void RTCPReceiver::HandleSDESChunk(RTCPUtility::RTCPParserV2& rtcpParser) {
|
|||||||
|
|
||||||
cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
|
cnameInfo->name[RTCP_CNAME_SIZE - 1] = 0;
|
||||||
strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
|
strncpy(cnameInfo->name, rtcpPacket.CName.CName, RTCP_CNAME_SIZE - 1);
|
||||||
|
if (stats_callback_ != NULL) {
|
||||||
|
stats_callback_->CNameChanged(rtcpPacket.CName.CName,
|
||||||
|
rtcpPacket.CName.SenderSSRC);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// no need for critsect we have _criticalSectionRTCPReceiver
|
// no need for critsect we have _criticalSectionRTCPReceiver
|
||||||
|
@ -820,6 +820,8 @@ TEST_F(RtcpReceiverTest, Callbacks) {
|
|||||||
ssrc_ = ssrc;
|
ssrc_ = ssrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE {}
|
||||||
|
|
||||||
bool Matches(uint32_t ssrc, uint32_t extended_max, uint8_t fraction_loss,
|
bool Matches(uint32_t ssrc, uint32_t extended_max, uint8_t fraction_loss,
|
||||||
uint32_t cumulative_loss, uint32_t jitter) {
|
uint32_t cumulative_loss, uint32_t jitter) {
|
||||||
return ssrc_ == ssrc &&
|
return ssrc_ == ssrc &&
|
||||||
|
@ -988,13 +988,13 @@ bool ModuleRtpRtcpImpl::StorePackets() const {
|
|||||||
return rtp_sender_.StorePackets();
|
return rtp_sender_.StorePackets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleRtpRtcpImpl::RegisterSendChannelRtcpStatisticsCallback(
|
void ModuleRtpRtcpImpl::RegisterRtcpStatisticsCallback(
|
||||||
RtcpStatisticsCallback* callback) {
|
RtcpStatisticsCallback* callback) {
|
||||||
rtcp_receiver_.RegisterRtcpStatisticsCallback(callback);
|
rtcp_receiver_.RegisterRtcpStatisticsCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
RtcpStatisticsCallback* ModuleRtpRtcpImpl::
|
RtcpStatisticsCallback*
|
||||||
GetSendChannelRtcpStatisticsCallback() {
|
ModuleRtpRtcpImpl::GetRtcpStatisticsCallback() {
|
||||||
return rtcp_receiver_.GetRtcpStatisticsCallback();
|
return rtcp_receiver_.GetRtcpStatisticsCallback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,10 +247,9 @@ class ModuleRtpRtcpImpl : public RtpRtcp {
|
|||||||
virtual bool StorePackets() const OVERRIDE;
|
virtual bool StorePackets() const OVERRIDE;
|
||||||
|
|
||||||
// Called on receipt of RTCP report block from remote side.
|
// Called on receipt of RTCP report block from remote side.
|
||||||
virtual void RegisterSendChannelRtcpStatisticsCallback(
|
virtual void RegisterRtcpStatisticsCallback(
|
||||||
RtcpStatisticsCallback* callback) OVERRIDE;
|
RtcpStatisticsCallback* callback) OVERRIDE;
|
||||||
virtual RtcpStatisticsCallback*
|
virtual RtcpStatisticsCallback* GetRtcpStatisticsCallback() OVERRIDE;
|
||||||
GetSendChannelRtcpStatisticsCallback() OVERRIDE;
|
|
||||||
|
|
||||||
// (APP) Application specific data.
|
// (APP) Application specific data.
|
||||||
virtual int32_t SetRTCPApplicationSpecificData(
|
virtual int32_t SetRTCPApplicationSpecificData(
|
||||||
|
@ -502,9 +502,14 @@ int32_t RTPSender::SendOutgoingData(
|
|||||||
}
|
}
|
||||||
|
|
||||||
CriticalSectionScoped cs(statistics_crit_.get());
|
CriticalSectionScoped cs(statistics_crit_.get());
|
||||||
uint32_t frame_count = ++frame_counts_[frame_type];
|
// Note: This is currently only counting for video.
|
||||||
|
if (frame_type == kVideoFrameKey) {
|
||||||
|
++frame_counts_.key_frames;
|
||||||
|
} else if (frame_type == kVideoFrameDelta) {
|
||||||
|
++frame_counts_.delta_frames;
|
||||||
|
}
|
||||||
if (frame_count_observer_) {
|
if (frame_count_observer_) {
|
||||||
frame_count_observer_->FrameCountUpdated(frame_type, frame_count, ssrc);
|
frame_count_observer_->FrameCountUpdated(frame_counts_, ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret_val;
|
return ret_val;
|
||||||
|
@ -371,7 +371,7 @@ class RTPSender : public RTPSenderInterface {
|
|||||||
// Statistics
|
// Statistics
|
||||||
scoped_ptr<CriticalSectionWrapper> statistics_crit_;
|
scoped_ptr<CriticalSectionWrapper> statistics_crit_;
|
||||||
SendDelayMap send_delays_ GUARDED_BY(statistics_crit_);
|
SendDelayMap send_delays_ GUARDED_BY(statistics_crit_);
|
||||||
std::map<FrameType, uint32_t> frame_counts_ GUARDED_BY(statistics_crit_);
|
FrameCounts frame_counts_ GUARDED_BY(statistics_crit_);
|
||||||
StreamDataCounters rtp_stats_ GUARDED_BY(statistics_crit_);
|
StreamDataCounters rtp_stats_ GUARDED_BY(statistics_crit_);
|
||||||
StreamDataCounters rtx_rtp_stats_ GUARDED_BY(statistics_crit_);
|
StreamDataCounters rtx_rtp_stats_ GUARDED_BY(statistics_crit_);
|
||||||
StreamDataCountersCallback* rtp_stats_callback_ GUARDED_BY(statistics_crit_);
|
StreamDataCountersCallback* rtp_stats_callback_ GUARDED_BY(statistics_crit_);
|
||||||
|
@ -768,32 +768,19 @@ TEST_F(RtpSenderTest, SendGenericVideo) {
|
|||||||
TEST_F(RtpSenderTest, FrameCountCallbacks) {
|
TEST_F(RtpSenderTest, FrameCountCallbacks) {
|
||||||
class TestCallback : public FrameCountObserver {
|
class TestCallback : public FrameCountObserver {
|
||||||
public:
|
public:
|
||||||
TestCallback()
|
TestCallback() : FrameCountObserver(), num_calls_(0), ssrc_(0) {}
|
||||||
: FrameCountObserver(), num_calls_(0), ssrc_(0),
|
|
||||||
key_frames_(0), delta_frames_(0) {}
|
|
||||||
virtual ~TestCallback() {}
|
virtual ~TestCallback() {}
|
||||||
|
|
||||||
virtual void FrameCountUpdated(FrameType frame_type,
|
virtual void FrameCountUpdated(const FrameCounts& frame_counts,
|
||||||
uint32_t frame_count,
|
uint32_t ssrc) OVERRIDE {
|
||||||
const unsigned int ssrc) OVERRIDE {
|
|
||||||
++num_calls_;
|
++num_calls_;
|
||||||
ssrc_ = ssrc;
|
ssrc_ = ssrc;
|
||||||
switch (frame_type) {
|
frame_counts_ = frame_counts;
|
||||||
case kVideoFrameDelta:
|
|
||||||
delta_frames_ = frame_count;
|
|
||||||
break;
|
|
||||||
case kVideoFrameKey:
|
|
||||||
key_frames_ = frame_count;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t num_calls_;
|
uint32_t num_calls_;
|
||||||
uint32_t ssrc_;
|
uint32_t ssrc_;
|
||||||
uint32_t key_frames_;
|
FrameCounts frame_counts_;
|
||||||
uint32_t delta_frames_;
|
|
||||||
} callback;
|
} callback;
|
||||||
|
|
||||||
rtp_sender_.reset(new RTPSender(0, false, &fake_clock_, &transport_, NULL,
|
rtp_sender_.reset(new RTPSender(0, false, &fake_clock_, &transport_, NULL,
|
||||||
@ -813,8 +800,8 @@ TEST_F(RtpSenderTest, FrameCountCallbacks) {
|
|||||||
|
|
||||||
EXPECT_EQ(1U, callback.num_calls_);
|
EXPECT_EQ(1U, callback.num_calls_);
|
||||||
EXPECT_EQ(ssrc, callback.ssrc_);
|
EXPECT_EQ(ssrc, callback.ssrc_);
|
||||||
EXPECT_EQ(1U, callback.key_frames_);
|
EXPECT_EQ(1, callback.frame_counts_.key_frames);
|
||||||
EXPECT_EQ(0U, callback.delta_frames_);
|
EXPECT_EQ(0, callback.frame_counts_.delta_frames);
|
||||||
|
|
||||||
ASSERT_EQ(0, rtp_sender_->SendOutgoingData(kVideoFrameDelta,
|
ASSERT_EQ(0, rtp_sender_->SendOutgoingData(kVideoFrameDelta,
|
||||||
payload_type, 1234, 4321, payload,
|
payload_type, 1234, 4321, payload,
|
||||||
@ -822,8 +809,8 @@ TEST_F(RtpSenderTest, FrameCountCallbacks) {
|
|||||||
|
|
||||||
EXPECT_EQ(2U, callback.num_calls_);
|
EXPECT_EQ(2U, callback.num_calls_);
|
||||||
EXPECT_EQ(ssrc, callback.ssrc_);
|
EXPECT_EQ(ssrc, callback.ssrc_);
|
||||||
EXPECT_EQ(1U, callback.key_frames_);
|
EXPECT_EQ(1, callback.frame_counts_.key_frames);
|
||||||
EXPECT_EQ(1U, callback.delta_frames_);
|
EXPECT_EQ(1, callback.frame_counts_.delta_frames);
|
||||||
|
|
||||||
rtp_sender_.reset();
|
rtp_sender_.reset();
|
||||||
}
|
}
|
||||||
|
@ -485,16 +485,6 @@ public:
|
|||||||
// < 0, on error.
|
// < 0, on error.
|
||||||
virtual int32_t Delay() const = 0;
|
virtual int32_t Delay() const = 0;
|
||||||
|
|
||||||
// Get the received frame counters. Keeps track of the number of each frame type
|
|
||||||
// received since the start of the call.
|
|
||||||
//
|
|
||||||
// Output:
|
|
||||||
// - frameCount : Struct to be filled with the number of frames received.
|
|
||||||
//
|
|
||||||
// Return value : VCM_OK, on success.
|
|
||||||
// <0, on error.
|
|
||||||
virtual int32_t ReceivedFrameCount(VCMFrameCount& frameCount) const = 0;
|
|
||||||
|
|
||||||
// Returns the number of packets discarded by the jitter buffer due to being
|
// Returns the number of packets discarded by the jitter buffer due to being
|
||||||
// too late. This can include duplicated packets which arrived after the
|
// too late. This can include duplicated packets which arrived after the
|
||||||
// frame was sent to the decoder. Therefore packets which were prematurely
|
// frame was sent to the decoder. Therefore packets which were prematurely
|
||||||
@ -592,6 +582,8 @@ public:
|
|||||||
EncodedImageCallback* observer) = 0;
|
EncodedImageCallback* observer) = 0;
|
||||||
virtual void RegisterPostEncodeImageCallback(
|
virtual void RegisterPostEncodeImageCallback(
|
||||||
EncodedImageCallback* post_encode_callback) = 0;
|
EncodedImageCallback* post_encode_callback) = 0;
|
||||||
|
virtual void RegisterReceiveFrameCountObserver(
|
||||||
|
FrameCountObserver* frame_count_observer) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -124,6 +124,7 @@ VCMJitterBuffer::VCMJitterBuffer(Clock* clock, EventFactory* event_factory)
|
|||||||
incomplete_frames_(),
|
incomplete_frames_(),
|
||||||
last_decoded_state_(),
|
last_decoded_state_(),
|
||||||
first_packet_since_reset_(true),
|
first_packet_since_reset_(true),
|
||||||
|
frame_count_observer_(NULL),
|
||||||
incoming_frame_rate_(0),
|
incoming_frame_rate_(0),
|
||||||
incoming_frame_count_(0),
|
incoming_frame_count_(0),
|
||||||
time_last_incoming_frame_count_(0),
|
time_last_incoming_frame_count_(0),
|
||||||
@ -184,14 +185,15 @@ void VCMJitterBuffer::UpdateHistograms() {
|
|||||||
RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.DuplicatedPacketsInPercent",
|
RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.DuplicatedPacketsInPercent",
|
||||||
num_duplicated_packets_ * 100 / num_packets_);
|
num_duplicated_packets_ * 100 / num_packets_);
|
||||||
|
|
||||||
uint32_t total_frames = receive_statistics_[kVideoFrameKey] +
|
int total_frames =
|
||||||
receive_statistics_[kVideoFrameDelta];
|
receive_statistics_.key_frames + receive_statistics_.delta_frames;
|
||||||
if (total_frames > 0) {
|
if (total_frames > 0) {
|
||||||
RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.CompleteFramesReceivedPerSecond",
|
RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.CompleteFramesReceivedPerSecond",
|
||||||
static_cast<int>((total_frames / elapsed_sec) + 0.5f));
|
static_cast<int>((total_frames / elapsed_sec) + 0.5f));
|
||||||
RTC_HISTOGRAM_COUNTS_1000("WebRTC.Video.KeyFramesReceivedInPermille",
|
RTC_HISTOGRAM_COUNTS_1000(
|
||||||
static_cast<int>((receive_statistics_[kVideoFrameKey] * 1000.0f /
|
"WebRTC.Video.KeyFramesReceivedInPermille",
|
||||||
total_frames) + 0.5f));
|
static_cast<int>(
|
||||||
|
(receive_statistics_.key_frames * 1000.0f / total_frames) + 0.5f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +205,7 @@ void VCMJitterBuffer::Start() {
|
|||||||
incoming_bit_count_ = 0;
|
incoming_bit_count_ = 0;
|
||||||
incoming_bit_rate_ = 0;
|
incoming_bit_rate_ = 0;
|
||||||
time_last_incoming_frame_count_ = clock_->TimeInMilliseconds();
|
time_last_incoming_frame_count_ = clock_->TimeInMilliseconds();
|
||||||
receive_statistics_.clear();
|
receive_statistics_ = FrameCounts();
|
||||||
|
|
||||||
num_consecutive_old_packets_ = 0;
|
num_consecutive_old_packets_ = 0;
|
||||||
num_packets_ = 0;
|
num_packets_ = 0;
|
||||||
@ -269,7 +271,7 @@ void VCMJitterBuffer::Flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get received key and delta frames
|
// Get received key and delta frames
|
||||||
std::map<FrameType, uint32_t> VCMJitterBuffer::FrameStatistics() const {
|
FrameCounts VCMJitterBuffer::FrameStatistics() const {
|
||||||
CriticalSectionScoped cs(crit_sect_);
|
CriticalSectionScoped cs(crit_sect_);
|
||||||
return receive_statistics_;
|
return receive_statistics_;
|
||||||
}
|
}
|
||||||
@ -1038,6 +1040,12 @@ void VCMJitterBuffer::RenderBufferSize(uint32_t* timestamp_start,
|
|||||||
*timestamp_end = decodable_frames_.Back()->TimeStamp();
|
*timestamp_end = decodable_frames_.Back()->TimeStamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VCMJitterBuffer::RegisterFrameCountObserver(
|
||||||
|
FrameCountObserver* frame_count_observer) {
|
||||||
|
CriticalSectionScoped cs(crit_sect_);
|
||||||
|
frame_count_observer_ = frame_count_observer;
|
||||||
|
}
|
||||||
|
|
||||||
VCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() {
|
VCMFrameBuffer* VCMJitterBuffer::GetEmptyFrame() {
|
||||||
if (free_frames_.empty()) {
|
if (free_frames_.empty()) {
|
||||||
if (!TryToIncreaseJitterBufferSize()) {
|
if (!TryToIncreaseJitterBufferSize()) {
|
||||||
@ -1105,7 +1113,13 @@ void VCMJitterBuffer::CountFrame(const VCMFrameBuffer& frame) {
|
|||||||
// Update receive statistics. We count all layers, thus when you use layers
|
// Update receive statistics. We count all layers, thus when you use layers
|
||||||
// adding all key and delta frames might differ from frame count.
|
// adding all key and delta frames might differ from frame count.
|
||||||
if (frame.IsSessionComplete()) {
|
if (frame.IsSessionComplete()) {
|
||||||
++receive_statistics_[frame.FrameType()];
|
if (frame.FrameType() == kVideoFrameKey) {
|
||||||
|
++receive_statistics_.key_frames;
|
||||||
|
} else {
|
||||||
|
++receive_statistics_.delta_frames;
|
||||||
|
}
|
||||||
|
if (frame_count_observer_ != NULL)
|
||||||
|
frame_count_observer_->FrameCountUpdated(receive_statistics_, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ class VCMJitterBuffer {
|
|||||||
|
|
||||||
// Get the number of received frames, by type, since the jitter buffer
|
// Get the number of received frames, by type, since the jitter buffer
|
||||||
// was started.
|
// was started.
|
||||||
std::map<FrameType, uint32_t> FrameStatistics() const;
|
FrameCounts FrameStatistics() const;
|
||||||
|
|
||||||
// The number of packets discarded by the jitter buffer because the decoder
|
// The number of packets discarded by the jitter buffer because the decoder
|
||||||
// won't be able to decode them.
|
// won't be able to decode them.
|
||||||
@ -184,6 +184,8 @@ class VCMJitterBuffer {
|
|||||||
// corresponding to the start and end of the continuous complete buffer.
|
// corresponding to the start and end of the continuous complete buffer.
|
||||||
void RenderBufferSize(uint32_t* timestamp_start, uint32_t* timestamp_end);
|
void RenderBufferSize(uint32_t* timestamp_start, uint32_t* timestamp_end);
|
||||||
|
|
||||||
|
void RegisterFrameCountObserver(FrameCountObserver* observer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class SequenceNumberLessThan {
|
class SequenceNumberLessThan {
|
||||||
public:
|
public:
|
||||||
@ -254,7 +256,8 @@ class VCMJitterBuffer {
|
|||||||
// Updates the frame statistics.
|
// Updates the frame statistics.
|
||||||
// Counts only complete frames, so decodable incomplete frames will not be
|
// Counts only complete frames, so decodable incomplete frames will not be
|
||||||
// counted.
|
// counted.
|
||||||
void CountFrame(const VCMFrameBuffer& frame);
|
void CountFrame(const VCMFrameBuffer& frame)
|
||||||
|
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
|
||||||
|
|
||||||
// Update rolling average of packets per frame.
|
// Update rolling average of packets per frame.
|
||||||
void UpdateAveragePacketsPerFrame(int current_number_packets_);
|
void UpdateAveragePacketsPerFrame(int current_number_packets_);
|
||||||
@ -301,7 +304,8 @@ class VCMJitterBuffer {
|
|||||||
|
|
||||||
// Statistics.
|
// Statistics.
|
||||||
// Frame counts for each type (key, delta, ...)
|
// Frame counts for each type (key, delta, ...)
|
||||||
std::map<FrameType, uint32_t> receive_statistics_;
|
FrameCountObserver* frame_count_observer_ GUARDED_BY(crit_sect_);
|
||||||
|
FrameCounts receive_statistics_;
|
||||||
// Latest calculated frame rates of incoming stream.
|
// Latest calculated frame rates of incoming stream.
|
||||||
unsigned int incoming_frame_rate_;
|
unsigned int incoming_frame_rate_;
|
||||||
unsigned int incoming_frame_count_;
|
unsigned int incoming_frame_count_;
|
||||||
|
@ -1693,9 +1693,9 @@ TEST_F(TestRunningJitterBuffer, EmptyPackets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestRunningJitterBuffer, StatisticsTest) {
|
TEST_F(TestRunningJitterBuffer, StatisticsTest) {
|
||||||
std::map<FrameType, uint32_t> frame_stats(jitter_buffer_->FrameStatistics());
|
FrameCounts frame_stats(jitter_buffer_->FrameStatistics());
|
||||||
EXPECT_EQ(0u, frame_stats[kVideoFrameDelta]);
|
EXPECT_EQ(0, frame_stats.delta_frames);
|
||||||
EXPECT_EQ(0u, frame_stats[kVideoFrameKey]);
|
EXPECT_EQ(0, frame_stats.key_frames);
|
||||||
|
|
||||||
uint32_t framerate = 0;
|
uint32_t framerate = 0;
|
||||||
uint32_t bitrate = 0;
|
uint32_t bitrate = 0;
|
||||||
@ -1714,8 +1714,8 @@ TEST_F(TestRunningJitterBuffer, StatisticsTest) {
|
|||||||
EXPECT_TRUE(DecodeCompleteFrame());
|
EXPECT_TRUE(DecodeCompleteFrame());
|
||||||
EXPECT_TRUE(DecodeCompleteFrame());
|
EXPECT_TRUE(DecodeCompleteFrame());
|
||||||
frame_stats = jitter_buffer_->FrameStatistics();
|
frame_stats = jitter_buffer_->FrameStatistics();
|
||||||
EXPECT_EQ(3u, frame_stats[kVideoFrameDelta]);
|
EXPECT_EQ(3, frame_stats.delta_frames);
|
||||||
EXPECT_EQ(2u, frame_stats[kVideoFrameKey]);
|
EXPECT_EQ(2, frame_stats.key_frames);
|
||||||
|
|
||||||
// Insert 20 more frames to get estimates of bitrate and framerate over
|
// Insert 20 more frames to get estimates of bitrate and framerate over
|
||||||
// 1 second.
|
// 1 second.
|
||||||
|
@ -186,13 +186,6 @@ void VCMReceiver::ReceiveStatistics(uint32_t* bitrate,
|
|||||||
jitter_buffer_.IncomingRateStatistics(framerate, bitrate);
|
jitter_buffer_.IncomingRateStatistics(framerate, bitrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCMReceiver::ReceivedFrameCount(VCMFrameCount* frame_count) const {
|
|
||||||
assert(frame_count);
|
|
||||||
std::map<FrameType, uint32_t> counts(jitter_buffer_.FrameStatistics());
|
|
||||||
frame_count->numDeltaFrames = counts[kVideoFrameDelta];
|
|
||||||
frame_count->numKeyFrames = counts[kVideoFrameKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t VCMReceiver::DiscardedPackets() const {
|
uint32_t VCMReceiver::DiscardedPackets() const {
|
||||||
return jitter_buffer_.num_discarded_packets();
|
return jitter_buffer_.num_discarded_packets();
|
||||||
}
|
}
|
||||||
@ -276,4 +269,10 @@ int VCMReceiver::RenderBufferSizeMs() {
|
|||||||
uint32_t render_end = timing_->RenderTimeMs(timestamp_end, now_ms);
|
uint32_t render_end = timing_->RenderTimeMs(timestamp_end, now_ms);
|
||||||
return render_end - render_start;
|
return render_end - render_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VCMReceiver::RegisterFrameCountObserver(
|
||||||
|
FrameCountObserver* frame_count_observer) {
|
||||||
|
jitter_buffer_.RegisterFrameCountObserver(frame_count_observer);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -53,7 +53,6 @@ class VCMReceiver {
|
|||||||
bool render_timing = true);
|
bool render_timing = true);
|
||||||
void ReleaseFrame(VCMEncodedFrame* frame);
|
void ReleaseFrame(VCMEncodedFrame* frame);
|
||||||
void ReceiveStatistics(uint32_t* bitrate, uint32_t* framerate);
|
void ReceiveStatistics(uint32_t* bitrate, uint32_t* framerate);
|
||||||
void ReceivedFrameCount(VCMFrameCount* frame_count) const;
|
|
||||||
uint32_t DiscardedPackets() const;
|
uint32_t DiscardedPackets() const;
|
||||||
|
|
||||||
// NACK.
|
// NACK.
|
||||||
@ -80,6 +79,8 @@ class VCMReceiver {
|
|||||||
// the time this function is called.
|
// the time this function is called.
|
||||||
int RenderBufferSizeMs();
|
int RenderBufferSizeMs();
|
||||||
|
|
||||||
|
void RegisterFrameCountObserver(FrameCountObserver* frame_count_observer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int32_t GenerateReceiverId();
|
static int32_t GenerateReceiverId();
|
||||||
|
|
||||||
|
@ -278,6 +278,11 @@ class VideoCodingModuleImpl : public VideoCodingModule {
|
|||||||
return receiver_->RegisterRenderBufferSizeCallback(callback);
|
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 {
|
virtual int32_t Decode(uint16_t maxWaitTimeMs) OVERRIDE {
|
||||||
return receiver_->Decode(maxWaitTimeMs);
|
return receiver_->Decode(maxWaitTimeMs);
|
||||||
}
|
}
|
||||||
@ -308,10 +313,6 @@ class VideoCodingModuleImpl : public VideoCodingModule {
|
|||||||
|
|
||||||
virtual int32_t Delay() const OVERRIDE { return receiver_->Delay(); }
|
virtual int32_t Delay() const OVERRIDE { return receiver_->Delay(); }
|
||||||
|
|
||||||
virtual int32_t ReceivedFrameCount(VCMFrameCount& frameCount) const OVERRIDE {
|
|
||||||
return receiver_->ReceivedFrameCount(&frameCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual uint32_t DiscardedPackets() const OVERRIDE {
|
virtual uint32_t DiscardedPackets() const OVERRIDE {
|
||||||
return receiver_->DiscardedPackets();
|
return receiver_->DiscardedPackets();
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,6 @@ class VideoReceiver {
|
|||||||
int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs);
|
int32_t SetMinimumPlayoutDelay(uint32_t minPlayoutDelayMs);
|
||||||
int32_t SetRenderDelay(uint32_t timeMS);
|
int32_t SetRenderDelay(uint32_t timeMS);
|
||||||
int32_t Delay() const;
|
int32_t Delay() const;
|
||||||
int32_t ReceivedFrameCount(VCMFrameCount* frameCount) const;
|
|
||||||
uint32_t DiscardedPackets() const;
|
uint32_t DiscardedPackets() const;
|
||||||
|
|
||||||
int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
|
int SetReceiverRobustnessMode(ReceiverRobustness robustnessMode,
|
||||||
@ -183,6 +182,7 @@ class VideoReceiver {
|
|||||||
int32_t Process();
|
int32_t Process();
|
||||||
|
|
||||||
void RegisterPreDecodeImageCallback(EncodedImageCallback* observer);
|
void RegisterPreDecodeImageCallback(EncodedImageCallback* observer);
|
||||||
|
void RegisterFrameCountObserver(FrameCountObserver* frame_count_observer);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int32_t Decode(const webrtc::VCMEncodedFrame& frame)
|
int32_t Decode(const webrtc::VCMEncodedFrame& frame)
|
||||||
|
@ -592,11 +592,6 @@ int32_t VideoReceiver::NackList(uint16_t* nackList, uint16_t* size) {
|
|||||||
return VCM_OK;
|
return VCM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t VideoReceiver::ReceivedFrameCount(VCMFrameCount* frameCount) const {
|
|
||||||
_receiver.ReceivedFrameCount(frameCount);
|
|
||||||
return VCM_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t VideoReceiver::DiscardedPackets() const {
|
uint32_t VideoReceiver::DiscardedPackets() const {
|
||||||
return _receiver.DiscardedPackets();
|
return _receiver.DiscardedPackets();
|
||||||
}
|
}
|
||||||
@ -671,6 +666,10 @@ void VideoReceiver::RegisterPreDecodeImageCallback(
|
|||||||
CriticalSectionScoped cs(_receiveCritSect);
|
CriticalSectionScoped cs(_receiveCritSect);
|
||||||
pre_decode_image_callback_ = observer;
|
pre_decode_image_callback_ = observer;
|
||||||
}
|
}
|
||||||
|
void VideoReceiver::RegisterFrameCountObserver(
|
||||||
|
FrameCountObserver* frame_count_observer) {
|
||||||
|
_receiver.RegisterFrameCountObserver(frame_count_observer);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace vcm
|
} // namespace vcm
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -1496,8 +1496,13 @@ TEST_F(EndToEndTest, GetStats) {
|
|||||||
stats.rtp_stats.retransmitted_packets != 0;
|
stats.rtp_stats.retransmitted_packets != 0;
|
||||||
|
|
||||||
receive_stats_filled_["CodecStats"] |=
|
receive_stats_filled_["CodecStats"] |=
|
||||||
stats.avg_delay_ms != 0 || stats.discarded_packets != 0 ||
|
stats.avg_delay_ms != 0 || stats.discarded_packets != 0;
|
||||||
stats.key_frames != 0 || stats.delta_frames != 0;
|
|
||||||
|
receive_stats_filled_["FrameCounts"] |=
|
||||||
|
stats.frame_counts.key_frames != 0 ||
|
||||||
|
stats.frame_counts.delta_frames != 0;
|
||||||
|
|
||||||
|
receive_stats_filled_["CName"] |= stats.c_name != "";
|
||||||
|
|
||||||
return AllStatsFilled(receive_stats_filled_);
|
return AllStatsFilled(receive_stats_filled_);
|
||||||
}
|
}
|
||||||
@ -1537,7 +1542,8 @@ TEST_F(EndToEndTest, GetStats) {
|
|||||||
stream_stats.total_bitrate_bps != 0;
|
stream_stats.total_bitrate_bps != 0;
|
||||||
|
|
||||||
send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |=
|
send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |=
|
||||||
stream_stats.delta_frames != 0 || stream_stats.key_frames != 0;
|
stream_stats.frame_counts.delta_frames != 0 ||
|
||||||
|
stream_stats.frame_counts.key_frames != 0;
|
||||||
|
|
||||||
send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |=
|
send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |=
|
||||||
stats.encode_frame_rate != 0;
|
stats.encode_frame_rate != 0;
|
||||||
|
@ -14,17 +14,14 @@
|
|||||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
ReceiveStatisticsProxy::ReceiveStatisticsProxy(uint32_t ssrc,
|
ReceiveStatisticsProxy::ReceiveStatisticsProxy(uint32_t ssrc,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
ViERTP_RTCP* rtp_rtcp,
|
|
||||||
ViECodec* codec,
|
ViECodec* codec,
|
||||||
int channel)
|
int channel)
|
||||||
: channel_(channel),
|
: channel_(channel),
|
||||||
clock_(clock),
|
clock_(clock),
|
||||||
codec_(codec),
|
codec_(codec),
|
||||||
rtp_rtcp_(rtp_rtcp),
|
|
||||||
crit_(CriticalSectionWrapper::CreateCriticalSection()),
|
crit_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
// 1000ms window, scale 1000 for ms to s.
|
// 1000ms window, scale 1000 for ms to s.
|
||||||
decode_fps_estimator_(1000, 1000),
|
decode_fps_estimator_(1000, 1000),
|
||||||
@ -40,24 +37,11 @@ VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const {
|
|||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
stats = stats_;
|
stats = stats_;
|
||||||
}
|
}
|
||||||
stats.c_name = GetCName();
|
|
||||||
stats.discarded_packets = codec_->GetNumDiscardedPackets(channel_);
|
stats.discarded_packets = codec_->GetNumDiscardedPackets(channel_);
|
||||||
codec_->GetReceiveCodecStastistics(
|
|
||||||
channel_, stats.key_frames, stats.delta_frames);
|
|
||||||
|
|
||||||
codec_->GetReceiveCodecStastistics(channel_, stats.key_frames,
|
|
||||||
stats.delta_frames);
|
|
||||||
|
|
||||||
return stats;
|
return stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ReceiveStatisticsProxy::GetCName() const {
|
|
||||||
char rtcp_cname[ViERTP_RTCP::KMaxRTCPCNameLength];
|
|
||||||
if (rtp_rtcp_->GetRemoteRTCPCName(channel_, rtcp_cname) != 0)
|
|
||||||
rtcp_cname[0] = '\0';
|
|
||||||
return rtcp_cname;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReceiveStatisticsProxy::IncomingRate(const int video_channel,
|
void ReceiveStatisticsProxy::IncomingRate(const int video_channel,
|
||||||
const unsigned int framerate,
|
const unsigned int framerate,
|
||||||
const unsigned int bitrate_bps) {
|
const unsigned int bitrate_bps) {
|
||||||
@ -85,6 +69,11 @@ void ReceiveStatisticsProxy::StatisticsUpdated(
|
|||||||
stats_.rtcp_stats = statistics;
|
stats_.rtcp_stats = statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReceiveStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {
|
||||||
|
CriticalSectionScoped lock(crit_.get());
|
||||||
|
stats_.c_name = cname;
|
||||||
|
}
|
||||||
|
|
||||||
void ReceiveStatisticsProxy::DataCountersUpdated(
|
void ReceiveStatisticsProxy::DataCountersUpdated(
|
||||||
const webrtc::StreamDataCounters& counters,
|
const webrtc::StreamDataCounters& counters,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
@ -109,5 +98,10 @@ void ReceiveStatisticsProxy::OnRenderedFrame() {
|
|||||||
stats_.render_frame_rate = renders_fps_estimator_.Rate(now);
|
stats_.render_frame_rate = renders_fps_estimator_.Rate(now);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
void ReceiveStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
|
||||||
|
uint32_t ssrc) {
|
||||||
|
CriticalSectionScoped lock(crit_.get());
|
||||||
|
stats_.frame_counts = frame_counts;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -29,15 +29,13 @@ class CriticalSectionWrapper;
|
|||||||
class ViECodec;
|
class ViECodec;
|
||||||
class ViEDecoderObserver;
|
class ViEDecoderObserver;
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class ReceiveStatisticsProxy : public ViEDecoderObserver,
|
class ReceiveStatisticsProxy : public ViEDecoderObserver,
|
||||||
public RtcpStatisticsCallback,
|
public RtcpStatisticsCallback,
|
||||||
public StreamDataCountersCallback {
|
public StreamDataCountersCallback,
|
||||||
|
public FrameCountObserver {
|
||||||
public:
|
public:
|
||||||
ReceiveStatisticsProxy(uint32_t ssrc,
|
ReceiveStatisticsProxy(uint32_t ssrc,
|
||||||
Clock* clock,
|
Clock* clock,
|
||||||
ViERTP_RTCP* rtp_rtcp,
|
|
||||||
ViECodec* codec,
|
ViECodec* codec,
|
||||||
int channel);
|
int channel);
|
||||||
virtual ~ReceiveStatisticsProxy();
|
virtual ~ReceiveStatisticsProxy();
|
||||||
@ -62,21 +60,23 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver,
|
|||||||
int render_delay_ms) OVERRIDE;
|
int render_delay_ms) OVERRIDE;
|
||||||
virtual void RequestNewKeyFrame(const int video_channel) OVERRIDE {}
|
virtual void RequestNewKeyFrame(const int video_channel) OVERRIDE {}
|
||||||
|
|
||||||
// Overrides RtcpStatisticsBallback.
|
// Overrides RtcpStatisticsCallback.
|
||||||
virtual void StatisticsUpdated(const webrtc::RtcpStatistics& statistics,
|
virtual void StatisticsUpdated(const webrtc::RtcpStatistics& statistics,
|
||||||
uint32_t ssrc) OVERRIDE;
|
uint32_t ssrc) OVERRIDE;
|
||||||
|
virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE;
|
||||||
|
|
||||||
// Overrides StreamDataCountersCallback.
|
// Overrides StreamDataCountersCallback.
|
||||||
virtual void DataCountersUpdated(const webrtc::StreamDataCounters& counters,
|
virtual void DataCountersUpdated(const webrtc::StreamDataCounters& counters,
|
||||||
uint32_t ssrc) OVERRIDE;
|
uint32_t ssrc) OVERRIDE;
|
||||||
|
|
||||||
private:
|
// Overrides FrameCountObserver.
|
||||||
std::string GetCName() const;
|
virtual void FrameCountUpdated(const FrameCounts& frame_counts,
|
||||||
|
uint32_t ssrc) OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
const int channel_;
|
const int channel_;
|
||||||
Clock* const clock_;
|
Clock* const clock_;
|
||||||
ViECodec* const codec_;
|
ViECodec* const codec_;
|
||||||
ViERTP_RTCP* const rtp_rtcp_;
|
|
||||||
|
|
||||||
scoped_ptr<CriticalSectionWrapper> crit_;
|
scoped_ptr<CriticalSectionWrapper> crit_;
|
||||||
VideoReceiveStream::Stats stats_ GUARDED_BY(crit_);
|
VideoReceiveStream::Stats stats_ GUARDED_BY(crit_);
|
||||||
@ -84,6 +84,5 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver,
|
|||||||
RateStatistics renders_fps_estimator_ GUARDED_BY(crit_);
|
RateStatistics renders_fps_estimator_ GUARDED_BY(crit_);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
#endif // WEBRTC_VIDEO_RECEIVE_STATISTICS_PROXY_H_
|
#endif // WEBRTC_VIDEO_RECEIVE_STATISTICS_PROXY_H_
|
||||||
|
@ -115,6 +115,9 @@ void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics,
|
|||||||
stats->rtcp_stats = statistics;
|
stats->rtcp_stats = statistics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SendStatisticsProxy::CNameChanged(const char* cname, uint32_t ssrc) {
|
||||||
|
}
|
||||||
|
|
||||||
void SendStatisticsProxy::DataCountersUpdated(
|
void SendStatisticsProxy::DataCountersUpdated(
|
||||||
const StreamDataCounters& counters,
|
const StreamDataCounters& counters,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
@ -138,26 +141,14 @@ void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
|
|||||||
stats->retransmit_bitrate_bps = retransmit_stats.bitrate_bps;
|
stats->retransmit_bitrate_bps = retransmit_stats.bitrate_bps;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendStatisticsProxy::FrameCountUpdated(FrameType frame_type,
|
void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
|
||||||
uint32_t frame_count,
|
uint32_t ssrc) {
|
||||||
const unsigned int ssrc) {
|
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
SsrcStats* stats = GetStatsEntry(ssrc);
|
SsrcStats* stats = GetStatsEntry(ssrc);
|
||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (frame_type) {
|
stats->frame_counts = frame_counts;
|
||||||
case kVideoFrameDelta:
|
|
||||||
stats->delta_frames = frame_count;
|
|
||||||
break;
|
|
||||||
case kVideoFrameKey:
|
|
||||||
stats->key_frames = frame_count;
|
|
||||||
break;
|
|
||||||
case kFrameEmpty:
|
|
||||||
case kAudioFrameSpeech:
|
|
||||||
case kAudioFrameCN:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
|
void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
|
||||||
|
@ -48,6 +48,7 @@ class SendStatisticsProxy : public RtcpStatisticsCallback,
|
|||||||
// From RtcpStatisticsCallback.
|
// From RtcpStatisticsCallback.
|
||||||
virtual void StatisticsUpdated(const RtcpStatistics& statistics,
|
virtual void StatisticsUpdated(const RtcpStatistics& statistics,
|
||||||
uint32_t ssrc) OVERRIDE;
|
uint32_t ssrc) OVERRIDE;
|
||||||
|
virtual void CNameChanged(const char *cname, uint32_t ssrc) OVERRIDE;
|
||||||
// From StreamDataCountersCallback.
|
// From StreamDataCountersCallback.
|
||||||
virtual void DataCountersUpdated(const StreamDataCounters& counters,
|
virtual void DataCountersUpdated(const StreamDataCounters& counters,
|
||||||
uint32_t ssrc) OVERRIDE;
|
uint32_t ssrc) OVERRIDE;
|
||||||
@ -58,9 +59,8 @@ class SendStatisticsProxy : public RtcpStatisticsCallback,
|
|||||||
uint32_t ssrc) OVERRIDE;
|
uint32_t ssrc) OVERRIDE;
|
||||||
|
|
||||||
// From FrameCountObserver.
|
// From FrameCountObserver.
|
||||||
virtual void FrameCountUpdated(FrameType frame_type,
|
virtual void FrameCountUpdated(const FrameCounts& frame_counts,
|
||||||
uint32_t frame_count,
|
uint32_t ssrc) OVERRIDE;
|
||||||
const unsigned int ssrc) OVERRIDE;
|
|
||||||
|
|
||||||
// From ViEEncoderObserver.
|
// From ViEEncoderObserver.
|
||||||
virtual void OutgoingRate(const int video_channel,
|
virtual void OutgoingRate(const int video_channel,
|
||||||
|
@ -59,8 +59,8 @@ class SendStatisticsProxyTest : public ::testing::Test {
|
|||||||
const SsrcStats& a = it->second;
|
const SsrcStats& a = it->second;
|
||||||
const SsrcStats& b = corresponding_it->second;
|
const SsrcStats& b = corresponding_it->second;
|
||||||
|
|
||||||
EXPECT_EQ(a.key_frames, b.key_frames);
|
EXPECT_EQ(a.frame_counts.key_frames, b.frame_counts.key_frames);
|
||||||
EXPECT_EQ(a.delta_frames, b.delta_frames);
|
EXPECT_EQ(a.frame_counts.delta_frames, b.frame_counts.delta_frames);
|
||||||
EXPECT_EQ(a.total_bitrate_bps, b.total_bitrate_bps);
|
EXPECT_EQ(a.total_bitrate_bps, b.total_bitrate_bps);
|
||||||
EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
|
EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
|
||||||
EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
|
EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
|
||||||
@ -169,10 +169,11 @@ TEST_F(SendStatisticsProxyTest, FrameCounts) {
|
|||||||
// Add statistics with some arbitrary, but unique, numbers.
|
// Add statistics with some arbitrary, but unique, numbers.
|
||||||
SsrcStats& stats = expected_.substreams[ssrc];
|
SsrcStats& stats = expected_.substreams[ssrc];
|
||||||
uint32_t offset = ssrc * sizeof(SsrcStats);
|
uint32_t offset = ssrc * sizeof(SsrcStats);
|
||||||
stats.key_frames = offset;
|
FrameCounts frame_counts;
|
||||||
stats.delta_frames = offset + 1;
|
frame_counts.key_frames = offset;
|
||||||
observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
|
frame_counts.delta_frames = offset + 1;
|
||||||
observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
|
stats.frame_counts = frame_counts;
|
||||||
|
observer->FrameCountUpdated(frame_counts, ssrc);
|
||||||
}
|
}
|
||||||
for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
|
for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
|
||||||
it != config_.rtp.rtx.ssrcs.end();
|
it != config_.rtp.rtx.ssrcs.end();
|
||||||
@ -181,10 +182,11 @@ TEST_F(SendStatisticsProxyTest, FrameCounts) {
|
|||||||
// Add statistics with some arbitrary, but unique, numbers.
|
// Add statistics with some arbitrary, but unique, numbers.
|
||||||
SsrcStats& stats = expected_.substreams[ssrc];
|
SsrcStats& stats = expected_.substreams[ssrc];
|
||||||
uint32_t offset = ssrc * sizeof(SsrcStats);
|
uint32_t offset = ssrc * sizeof(SsrcStats);
|
||||||
stats.key_frames = offset;
|
FrameCounts frame_counts;
|
||||||
stats.delta_frames = offset + 1;
|
frame_counts.key_frames = offset;
|
||||||
observer->FrameCountUpdated(kVideoFrameKey, stats.key_frames, ssrc);
|
frame_counts.delta_frames = offset + 1;
|
||||||
observer->FrameCountUpdated(kVideoFrameDelta, stats.delta_frames, ssrc);
|
stats.frame_counts = frame_counts;
|
||||||
|
observer->FrameCountUpdated(frame_counts, ssrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoSendStream::Stats stats = statistics_proxy_->GetStats();
|
VideoSendStream::Stats stats = statistics_proxy_->GetStats();
|
||||||
@ -318,7 +320,9 @@ TEST_F(SendStatisticsProxyTest, NoSubstreams) {
|
|||||||
|
|
||||||
// From FrameCountObserver.
|
// From FrameCountObserver.
|
||||||
FrameCountObserver* fps_observer = statistics_proxy_.get();
|
FrameCountObserver* fps_observer = statistics_proxy_.get();
|
||||||
fps_observer->FrameCountUpdated(kVideoFrameKey, 1, exluded_ssrc);
|
FrameCounts frame_counts;
|
||||||
|
frame_counts.key_frames = 1;
|
||||||
|
fps_observer->FrameCountUpdated(frame_counts, exluded_ssrc);
|
||||||
|
|
||||||
VideoSendStream::Stats stats = statistics_proxy_->GetStats();
|
VideoSendStream::Stats stats = statistics_proxy_->GetStats();
|
||||||
EXPECT_TRUE(stats.substreams.empty());
|
EXPECT_TRUE(stats.substreams.empty());
|
||||||
|
@ -148,19 +148,25 @@ VideoReceiveStream::VideoReceiveStream(webrtc::VideoEngine* video_engine,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stats_proxy_.reset(new ReceiveStatisticsProxy(
|
stats_proxy_.reset(new ReceiveStatisticsProxy(config_.rtp.local_ssrc, clock_,
|
||||||
config_.rtp.local_ssrc, clock_, rtp_rtcp_, codec_, channel_));
|
codec_, channel_));
|
||||||
|
|
||||||
if (rtp_rtcp_->RegisterReceiveChannelRtcpStatisticsCallback(
|
if (rtp_rtcp_->RegisterReceiveChannelRtcpStatisticsCallback(
|
||||||
channel_, stats_proxy_.get()) != 0)
|
channel_, stats_proxy_.get()) != 0) {
|
||||||
abort();
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
if (rtp_rtcp_->RegisterReceiveChannelRtpStatisticsCallback(
|
if (rtp_rtcp_->RegisterReceiveChannelRtpStatisticsCallback(
|
||||||
channel_, stats_proxy_.get()) != 0)
|
channel_, stats_proxy_.get()) != 0) {
|
||||||
abort();
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
if (codec_->RegisterDecoderObserver(channel_, *stats_proxy_) != 0)
|
if (codec_->RegisterDecoderObserver(channel_, *stats_proxy_) != 0) {
|
||||||
abort();
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
video_engine_base_->RegisterReceiveStatisticsProxy(channel_,
|
||||||
|
stats_proxy_.get());
|
||||||
|
|
||||||
external_codec_ = ViEExternalCodec::GetInterface(video_engine);
|
external_codec_ = ViEExternalCodec::GetInterface(video_engine);
|
||||||
assert(!config_.decoders.empty());
|
assert(!config_.decoders.empty());
|
||||||
|
@ -958,9 +958,10 @@ TEST_F(VideoSendStreamTest, ProducesStats) {
|
|||||||
// Check for data populated by various sources. RTCP excluded as this
|
// Check for data populated by various sources. RTCP excluded as this
|
||||||
// data is received from remote side. Tested in call tests instead.
|
// data is received from remote side. Tested in call tests instead.
|
||||||
const SsrcStats& entry = stats.substreams[ssrc];
|
const SsrcStats& entry = stats.substreams[ssrc];
|
||||||
if (entry.key_frames > 0u && entry.total_bitrate_bps > 0 &&
|
if (entry.frame_counts.key_frames > 0 &&
|
||||||
entry.rtp_stats.packets > 0u && entry.avg_delay_ms > 0 &&
|
entry.frame_counts.delta_frames > 0 &&
|
||||||
entry.max_delay_ms > 0) {
|
entry.total_bitrate_bps > 0 && entry.rtp_stats.packets > 0u &&
|
||||||
|
entry.avg_delay_ms > 0 && entry.max_delay_ms > 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ namespace webrtc {
|
|||||||
|
|
||||||
class Config;
|
class Config;
|
||||||
class VoiceEngine;
|
class VoiceEngine;
|
||||||
|
class ReceiveStatisticsProxy;
|
||||||
class SendStatisticsProxy;
|
class SendStatisticsProxy;
|
||||||
|
|
||||||
// CpuOveruseObserver is called when a system overuse is detected and
|
// CpuOveruseObserver is called when a system overuse is detected and
|
||||||
@ -243,6 +244,10 @@ class WEBRTC_DLLEXPORT ViEBase {
|
|||||||
int channel,
|
int channel,
|
||||||
SendStatisticsProxy* send_statistics_proxy) = 0;
|
SendStatisticsProxy* send_statistics_proxy) = 0;
|
||||||
|
|
||||||
|
virtual void RegisterReceiveStatisticsProxy(
|
||||||
|
int channel,
|
||||||
|
ReceiveStatisticsProxy* receive_statistics_proxy) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ViEBase() {}
|
ViEBase() {}
|
||||||
virtual ~ViEBase() {}
|
virtual ~ViEBase() {}
|
||||||
|
@ -373,4 +373,17 @@ void ViEBaseImpl::RegisterSendStatisticsProxy(
|
|||||||
|
|
||||||
vie_encoder->RegisterSendStatisticsProxy(send_statistics_proxy);
|
vie_encoder->RegisterSendStatisticsProxy(send_statistics_proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViEBaseImpl::RegisterReceiveStatisticsProxy(
|
||||||
|
int channel,
|
||||||
|
ReceiveStatisticsProxy* receive_statistics_proxy) {
|
||||||
|
LOG_F(LS_VERBOSE) << "RegisterReceiveStatisticsProxy on channel " << channel;
|
||||||
|
ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
|
||||||
|
ViEChannel* vie_channel = cs.Channel(channel);
|
||||||
|
if (!vie_channel) {
|
||||||
|
shared_data_.SetLastError(kViEBaseInvalidChannelId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vie_channel->RegisterReceiveStatisticsProxy(receive_statistics_proxy);
|
||||||
|
}
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -70,6 +70,9 @@ class ViEBaseImpl
|
|||||||
virtual void RegisterSendStatisticsProxy(
|
virtual void RegisterSendStatisticsProxy(
|
||||||
int channel,
|
int channel,
|
||||||
SendStatisticsProxy* send_statistics_proxy) OVERRIDE;
|
SendStatisticsProxy* send_statistics_proxy) OVERRIDE;
|
||||||
|
virtual void RegisterReceiveStatisticsProxy(
|
||||||
|
int channel,
|
||||||
|
ReceiveStatisticsProxy* receive_statistics_proxy) OVERRIDE;
|
||||||
// ViEBaseImpl owns ViESharedData used by all interface implementations.
|
// ViEBaseImpl owns ViESharedData used by all interface implementations.
|
||||||
ViESharedData shared_data_;
|
ViESharedData shared_data_;
|
||||||
};
|
};
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "webrtc/common.h"
|
#include "webrtc/common.h"
|
||||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||||
#include "webrtc/experiments.h"
|
#include "webrtc/experiments.h"
|
||||||
|
#include "webrtc/frame_callback.h"
|
||||||
#include "webrtc/modules/pacing/include/paced_sender.h"
|
#include "webrtc/modules/pacing/include/paced_sender.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
|
#include "webrtc/modules/rtp_rtcp/interface/rtp_receiver.h"
|
||||||
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
|
||||||
@ -27,12 +28,12 @@
|
|||||||
#include "webrtc/system_wrappers/interface/logging.h"
|
#include "webrtc/system_wrappers/interface/logging.h"
|
||||||
#include "webrtc/system_wrappers/interface/metrics.h"
|
#include "webrtc/system_wrappers/interface/metrics.h"
|
||||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||||
|
#include "webrtc/video/receive_statistics_proxy.h"
|
||||||
#include "webrtc/video_engine/call_stats.h"
|
#include "webrtc/video_engine/call_stats.h"
|
||||||
#include "webrtc/video_engine/include/vie_codec.h"
|
#include "webrtc/video_engine/include/vie_codec.h"
|
||||||
#include "webrtc/video_engine/include/vie_errors.h"
|
#include "webrtc/video_engine/include/vie_errors.h"
|
||||||
#include "webrtc/video_engine/include/vie_image_process.h"
|
#include "webrtc/video_engine/include/vie_image_process.h"
|
||||||
#include "webrtc/video_engine/include/vie_rtp_rtcp.h"
|
#include "webrtc/video_engine/include/vie_rtp_rtcp.h"
|
||||||
#include "webrtc/frame_callback.h"
|
|
||||||
#include "webrtc/video_engine/vie_defines.h"
|
#include "webrtc/video_engine/vie_defines.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -156,6 +157,7 @@ ViEChannel::ViEChannel(int32_t channel_id,
|
|||||||
rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration));
|
rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(configuration));
|
||||||
vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get());
|
vie_receiver_.SetRtpRtcpModule(rtp_rtcp_.get());
|
||||||
vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
|
vcm_->SetNackSettings(kMaxNackListSize, max_nack_reordering_threshold_, 0);
|
||||||
|
vcm_->RegisterReceiveFrameCountObserver(&receive_frame_count_observer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ViEChannel::Init() {
|
int32_t ViEChannel::Init() {
|
||||||
@ -424,7 +426,7 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
|||||||
module_process_thread_.DeRegisterModule(rtp_rtcp);
|
module_process_thread_.DeRegisterModule(rtp_rtcp);
|
||||||
rtp_rtcp->SetSendingStatus(false);
|
rtp_rtcp->SetSendingStatus(false);
|
||||||
rtp_rtcp->SetSendingMediaStatus(false);
|
rtp_rtcp->SetSendingMediaStatus(false);
|
||||||
rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
|
rtp_rtcp->RegisterRtcpStatisticsCallback(NULL);
|
||||||
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
|
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
|
||||||
simulcast_rtp_rtcp_.pop_back();
|
simulcast_rtp_rtcp_.pop_back();
|
||||||
removed_rtp_rtcp_.push_front(rtp_rtcp);
|
removed_rtp_rtcp_.push_front(rtp_rtcp);
|
||||||
@ -471,8 +473,8 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
|||||||
rtp_rtcp->DeregisterSendRtpHeaderExtension(
|
rtp_rtcp->DeregisterSendRtpHeaderExtension(
|
||||||
kRtpExtensionAbsoluteSendTime);
|
kRtpExtensionAbsoluteSendTime);
|
||||||
}
|
}
|
||||||
rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(
|
rtp_rtcp->RegisterRtcpStatisticsCallback(
|
||||||
rtp_rtcp_->GetSendChannelRtcpStatisticsCallback());
|
rtp_rtcp_->GetRtcpStatisticsCallback());
|
||||||
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(
|
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(
|
||||||
rtp_rtcp_->GetSendChannelRtpStatisticsCallback());
|
rtp_rtcp_->GetSendChannelRtpStatisticsCallback());
|
||||||
}
|
}
|
||||||
@ -485,7 +487,7 @@ int32_t ViEChannel::SetSendCodec(const VideoCodec& video_codec,
|
|||||||
module_process_thread_.DeRegisterModule(rtp_rtcp);
|
module_process_thread_.DeRegisterModule(rtp_rtcp);
|
||||||
rtp_rtcp->SetSendingStatus(false);
|
rtp_rtcp->SetSendingStatus(false);
|
||||||
rtp_rtcp->SetSendingMediaStatus(false);
|
rtp_rtcp->SetSendingMediaStatus(false);
|
||||||
rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
|
rtp_rtcp->RegisterRtcpStatisticsCallback(NULL);
|
||||||
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
|
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
|
||||||
simulcast_rtp_rtcp_.pop_back();
|
simulcast_rtp_rtcp_.pop_back();
|
||||||
removed_rtp_rtcp_.push_front(rtp_rtcp);
|
removed_rtp_rtcp_.push_front(rtp_rtcp);
|
||||||
@ -577,12 +579,7 @@ int32_t ViEChannel::DeRegisterExternalDecoder(const uint8_t pl_type) {
|
|||||||
|
|
||||||
int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames,
|
int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames,
|
||||||
uint32_t* num_delta_frames) {
|
uint32_t* num_delta_frames) {
|
||||||
VCMFrameCount received_frames;
|
receive_frame_count_observer_.GetFrameCount(num_key_frames, num_delta_frames);
|
||||||
if (vcm_->ReceivedFrameCount(received_frames) != VCM_OK) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*num_key_frames = received_frames.numKeyFrames;
|
|
||||||
*num_delta_frames = received_frames.numDeltaFrames;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1127,12 +1124,12 @@ int32_t ViEChannel::GetSendRtcpStatistics(uint16_t* fraction_lost,
|
|||||||
|
|
||||||
void ViEChannel::RegisterSendChannelRtcpStatisticsCallback(
|
void ViEChannel::RegisterSendChannelRtcpStatisticsCallback(
|
||||||
RtcpStatisticsCallback* callback) {
|
RtcpStatisticsCallback* callback) {
|
||||||
rtp_rtcp_->RegisterSendChannelRtcpStatisticsCallback(callback);
|
rtp_rtcp_->RegisterRtcpStatisticsCallback(callback);
|
||||||
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
CriticalSectionScoped cs(rtp_rtcp_cs_.get());
|
||||||
for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
|
for (std::list<RtpRtcp*>::const_iterator it = simulcast_rtp_rtcp_.begin();
|
||||||
it != simulcast_rtp_rtcp_.end();
|
it != simulcast_rtp_rtcp_.end();
|
||||||
++it) {
|
++it) {
|
||||||
(*it)->RegisterSendChannelRtcpStatisticsCallback(callback);
|
(*it)->RegisterRtcpStatisticsCallback(callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1168,6 +1165,7 @@ void ViEChannel::RegisterReceiveChannelRtcpStatisticsCallback(
|
|||||||
RtcpStatisticsCallback* callback) {
|
RtcpStatisticsCallback* callback) {
|
||||||
vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback(
|
vie_receiver_.GetReceiveStatistics()->RegisterRtcpStatisticsCallback(
|
||||||
callback);
|
callback);
|
||||||
|
rtp_rtcp_->RegisterRtcpStatisticsCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ViEChannel::GetRtpStatistics(size_t* bytes_sent,
|
int32_t ViEChannel::GetRtpStatistics(size_t* bytes_sent,
|
||||||
@ -1667,7 +1665,7 @@ void ViEChannel::ReserveRtpRtcpModules(size_t num_modules) {
|
|||||||
RtpRtcp* rtp_rtcp = CreateRtpRtcpModule();
|
RtpRtcp* rtp_rtcp = CreateRtpRtcpModule();
|
||||||
rtp_rtcp->SetSendingStatus(false);
|
rtp_rtcp->SetSendingStatus(false);
|
||||||
rtp_rtcp->SetSendingMediaStatus(false);
|
rtp_rtcp->SetSendingMediaStatus(false);
|
||||||
rtp_rtcp->RegisterSendChannelRtcpStatisticsCallback(NULL);
|
rtp_rtcp->RegisterRtcpStatisticsCallback(NULL);
|
||||||
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
|
rtp_rtcp->RegisterSendChannelRtpStatisticsCallback(NULL);
|
||||||
removed_rtp_rtcp_.push_back(rtp_rtcp);
|
removed_rtp_rtcp_.push_back(rtp_rtcp);
|
||||||
}
|
}
|
||||||
@ -1848,6 +1846,11 @@ void ViEChannel::RegisterSendFrameCountObserver(
|
|||||||
send_frame_count_observer_.Set(observer);
|
send_frame_count_observer_.Set(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ViEChannel::RegisterReceiveStatisticsProxy(
|
||||||
|
ReceiveStatisticsProxy* receive_statistics_proxy) {
|
||||||
|
receive_frame_count_observer_.Set(receive_statistics_proxy);
|
||||||
|
}
|
||||||
|
|
||||||
void ViEChannel::ReceivedBWEPacket(int64_t arrival_time_ms,
|
void ViEChannel::ReceivedBWEPacket(int64_t arrival_time_ms,
|
||||||
size_t payload_size,
|
size_t payload_size,
|
||||||
const RTPHeader& header) {
|
const RTPHeader& header) {
|
||||||
|
@ -39,6 +39,7 @@ class EncodedImageCallback;
|
|||||||
class I420FrameCallback;
|
class I420FrameCallback;
|
||||||
class PacedSender;
|
class PacedSender;
|
||||||
class ProcessThread;
|
class ProcessThread;
|
||||||
|
class ReceiveStatisticsProxy;
|
||||||
class RtcpRttStats;
|
class RtcpRttStats;
|
||||||
class ThreadWrapper;
|
class ThreadWrapper;
|
||||||
class ViEDecoderObserver;
|
class ViEDecoderObserver;
|
||||||
@ -353,7 +354,8 @@ class ViEChannel
|
|||||||
EncodedImageCallback* pre_decode_callback);
|
EncodedImageCallback* pre_decode_callback);
|
||||||
|
|
||||||
void RegisterSendFrameCountObserver(FrameCountObserver* observer);
|
void RegisterSendFrameCountObserver(FrameCountObserver* observer);
|
||||||
|
void RegisterReceiveStatisticsProxy(
|
||||||
|
ReceiveStatisticsProxy* receive_statistics_proxy);
|
||||||
void ReceivedBWEPacket(int64_t arrival_time_ms, size_t payload_size,
|
void ReceivedBWEPacket(int64_t arrival_time_ms, size_t payload_size,
|
||||||
const RTPHeader& header);
|
const RTPHeader& header);
|
||||||
|
|
||||||
@ -427,14 +429,24 @@ class ViEChannel
|
|||||||
|
|
||||||
class RegisterableFrameCountObserver
|
class RegisterableFrameCountObserver
|
||||||
: public RegisterableCallback<FrameCountObserver> {
|
: public RegisterableCallback<FrameCountObserver> {
|
||||||
virtual void FrameCountUpdated(FrameType frame_type,
|
public:
|
||||||
uint32_t frame_count,
|
virtual void FrameCountUpdated(const FrameCounts& frame_counts,
|
||||||
const unsigned int ssrc) {
|
uint32_t ssrc) {
|
||||||
CriticalSectionScoped cs(critsect_.get());
|
CriticalSectionScoped cs(critsect_.get());
|
||||||
|
frame_counts_ = frame_counts;
|
||||||
if (callback_)
|
if (callback_)
|
||||||
callback_->FrameCountUpdated(frame_type, frame_count, ssrc);
|
callback_->FrameCountUpdated(frame_counts, ssrc);
|
||||||
}
|
}
|
||||||
} send_frame_count_observer_;
|
|
||||||
|
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_;
|
||||||
|
|
||||||
class RegisterableSendSideDelayObserver :
|
class RegisterableSendSideDelayObserver :
|
||||||
public RegisterableCallback<SendSideDelayObserver> {
|
public RegisterableCallback<SendSideDelayObserver> {
|
||||||
|
@ -71,6 +71,8 @@ class StatisticsProxy : public RtcpStatisticsCallback {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void CNameChanged(const char* cname, uint32_t ssrc) OVERRIDE {}
|
||||||
|
|
||||||
void ResetStatistics() {
|
void ResetStatistics() {
|
||||||
CriticalSectionScoped cs(stats_lock_.get());
|
CriticalSectionScoped cs(stats_lock_.get());
|
||||||
stats_ = ChannelStatistics();
|
stats_ = ChannelStatistics();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user