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