Split packets/bytes in StreamDataCounter into RtpPacketCounter struct.

Prepares for adding FEC bytes to the StreamDataCounter.

R=mflodman@webrtc.org, stefan@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/37579004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@8122 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
asapersson@webrtc.org 2015-01-22 09:39:59 +00:00
parent 3dd33a6787
commit cfd82dfc11
17 changed files with 297 additions and 258 deletions

View File

@ -2754,8 +2754,8 @@ bool WebRtcVideoMediaChannel::GetStats(const StatsOptions& options,
}
VideoReceiverInfo rinfo;
rinfo.add_ssrc(ssrc);
rinfo.bytes_rcvd = received.bytes;
rinfo.packets_rcvd = received.packets;
rinfo.bytes_rcvd = received.transmitted.payload_bytes;
rinfo.packets_rcvd = received.transmitted.packets;
rinfo.packets_lost = -1;
rinfo.packets_concealed = -1;
rinfo.fraction_lost = -1; // from SentRTCP

View File

@ -1772,10 +1772,10 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() {
++it) {
// TODO(pbos): Wire up additional stats, such as padding bytes.
webrtc::SsrcStats stream_stats = it->second;
info.bytes_sent += stream_stats.rtp_stats.bytes +
stream_stats.rtp_stats.header_bytes +
stream_stats.rtp_stats.padding_bytes;
info.packets_sent += stream_stats.rtp_stats.packets;
info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes +
stream_stats.rtp_stats.transmitted.header_bytes +
stream_stats.rtp_stats.transmitted.padding_bytes;
info.packets_sent += stream_stats.rtp_stats.transmitted.packets;
info.packets_lost += stream_stats.rtcp_stats.cumulative_lost;
if (stream_stats.sent_width > info.send_frame_width)
info.send_frame_width = stream_stats.sent_width;
@ -2020,9 +2020,10 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() {
VideoReceiverInfo info;
info.add_ssrc(config_.rtp.remote_ssrc);
webrtc::VideoReceiveStream::Stats stats = stream_->GetStats();
info.bytes_rcvd = stats.rtp_stats.bytes + stats.rtp_stats.header_bytes +
stats.rtp_stats.padding_bytes;
info.packets_rcvd = stats.rtp_stats.packets;
info.bytes_rcvd = stats.rtp_stats.transmitted.payload_bytes +
stats.rtp_stats.transmitted.header_bytes +
stats.rtp_stats.transmitted.padding_bytes;
info.packets_rcvd = stats.rtp_stats.transmitted.packets;
info.framerate_rcvd = stats.network_frame_rate;
info.framerate_decoded = stats.decode_frame_rate;

View File

@ -241,30 +241,38 @@ struct RtcpPacketTypeCounter {
uint32_t unique_nack_requests; // Number of unique NACKed RTP packets.
};
// Data usage statistics for a (rtp) stream.
struct StreamDataCounters {
StreamDataCounters()
: first_packet_time_ms(-1),
bytes(0),
header_bytes(0),
struct RtpPacketCounter {
RtpPacketCounter()
: header_bytes(0),
payload_bytes(0),
padding_bytes(0),
packets(0),
retransmitted_bytes(0),
retransmitted_header_bytes(0),
retransmitted_padding_bytes(0),
retransmitted_packets(0),
fec_packets(0) {}
packets(0) {}
void Add(const StreamDataCounters& other) {
bytes += other.bytes;
void Add(const RtpPacketCounter& other) {
header_bytes += other.header_bytes;
payload_bytes += other.payload_bytes;
padding_bytes += other.padding_bytes;
packets += other.packets;
retransmitted_bytes += other.retransmitted_bytes;
retransmitted_header_bytes += other.retransmitted_header_bytes;
retransmitted_padding_bytes += other.retransmitted_padding_bytes;
retransmitted_packets += other.retransmitted_packets;
fec_packets += other.fec_packets;
}
size_t TotalBytes() const {
return header_bytes + payload_bytes + padding_bytes;
}
size_t header_bytes; // Number of bytes used by RTP headers.
size_t payload_bytes; // Payload bytes, excluding RTP headers and padding.
size_t padding_bytes; // Number of padding bytes.
uint32_t packets; // Number of packets.
};
// Data usage statistics for a (rtp) stream.
struct StreamDataCounters {
StreamDataCounters() : first_packet_time_ms(-1) {}
void Add(const StreamDataCounters& other) {
transmitted.Add(other.transmitted);
retransmitted.Add(other.retransmitted);
fec.Add(other.fec);
if (other.first_packet_time_ms != -1 &&
(other.first_packet_time_ms < first_packet_time_ms ||
first_packet_time_ms == -1)) {
@ -277,30 +285,18 @@ struct StreamDataCounters {
return (first_packet_time_ms == -1) ? -1 : (now_ms - first_packet_time_ms);
}
size_t TotalBytes() const {
return bytes + header_bytes + padding_bytes;
}
size_t RetransmittedBytes() const {
return retransmitted_bytes + retransmitted_header_bytes +
retransmitted_padding_bytes;
}
// Returns the number of bytes corresponding to the actual media payload (i.e.
// RTP headers, padding and retransmissions are excluded). Note this function
// does not have meaning for an RTX stream.
size_t MediaPayloadBytes() const {
return bytes - retransmitted_bytes;
return transmitted.payload_bytes - retransmitted.payload_bytes;
}
// TODO(pbos): Rename bytes -> media_bytes.
int64_t first_packet_time_ms; // Time when first packet is sent/received.
size_t bytes; // Payload bytes, excluding RTP headers and padding.
size_t header_bytes; // Number of bytes used by RTP headers.
size_t padding_bytes; // Number of padding bytes.
uint32_t packets; // Number of packets.
size_t retransmitted_bytes; // Number of retransmitted payload bytes.
size_t retransmitted_header_bytes; // Retransmitted bytes used by RTP header.
size_t retransmitted_padding_bytes; // Retransmitted padding bytes.
uint32_t retransmitted_packets; // Number of retransmitted packets.
uint32_t fec_packets; // Number of redundancy packets.
RtpPacketCounter transmitted; // Number of transmitted packets/bytes.
RtpPacketCounter retransmitted; // Number of retransmitted packets/bytes.
// TODO(asapersson): add FEC bytes.
RtpPacketCounter fec; // Number of redundancy packets/bytes.
};
// Callback, called whenever byte/packet counts have been updated.

View File

@ -81,20 +81,20 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
bool in_order = InOrderPacketInternal(header.sequenceNumber);
ssrc_ = header.ssrc;
incoming_bitrate_.Update(packet_length);
receive_counters_.bytes +=
receive_counters_.transmitted.payload_bytes +=
packet_length - (header.paddingLength + header.headerLength);
receive_counters_.header_bytes += header.headerLength;
receive_counters_.padding_bytes += header.paddingLength;
++receive_counters_.packets;
receive_counters_.transmitted.header_bytes += header.headerLength;
receive_counters_.transmitted.padding_bytes += header.paddingLength;
++receive_counters_.transmitted.packets;
if (!in_order && retransmitted) {
++receive_counters_.retransmitted_packets;
receive_counters_.retransmitted_bytes +=
++receive_counters_.retransmitted.packets;
receive_counters_.retransmitted.payload_bytes +=
packet_length - (header.paddingLength + header.headerLength);
receive_counters_.retransmitted_header_bytes += header.headerLength;
receive_counters_.retransmitted_padding_bytes += header.paddingLength;
receive_counters_.retransmitted.header_bytes += header.headerLength;
receive_counters_.retransmitted.padding_bytes += header.paddingLength;
}
if (receive_counters_.packets == 1) {
if (receive_counters_.transmitted.packets == 1) {
received_seq_first_ = header.sequenceNumber;
receive_counters_.first_packet_time_ms = clock_->TimeInMilliseconds();
}
@ -108,7 +108,7 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
clock_->CurrentNtp(receive_time_secs, receive_time_frac);
// Wrong if we use RetransmitOfOldPacket.
if (receive_counters_.packets > 1 &&
if (receive_counters_.transmitted.packets > 1 &&
received_seq_max_ > header.sequenceNumber) {
// Wrap around detected.
received_seq_wraps_++;
@ -119,8 +119,8 @@ void StreamStatisticianImpl::UpdateCounters(const RTPHeader& header,
// If new time stamp and more than one in-order packet received, calculate
// new jitter statistics.
if (header.timestamp != last_received_timestamp_ &&
(receive_counters_.packets - receive_counters_.retransmitted_packets) >
1) {
(receive_counters_.transmitted.packets -
receive_counters_.retransmitted.packets) > 1) {
UpdateJitter(header, receive_time_secs, receive_time_frac);
}
last_received_timestamp_ = header.timestamp;
@ -203,7 +203,7 @@ void StreamStatisticianImpl::NotifyRtcpCallback() {
void StreamStatisticianImpl::FecPacketReceived() {
{
CriticalSectionScoped cs(stream_lock_.get());
++receive_counters_.fec_packets;
++receive_counters_.fec.packets;
}
NotifyRtpCallback();
}
@ -218,7 +218,8 @@ bool StreamStatisticianImpl::GetStatistics(RtcpStatistics* statistics,
bool reset) {
{
CriticalSectionScoped cs(stream_lock_.get());
if (received_seq_first_ == 0 && receive_counters_.bytes == 0) {
if (received_seq_first_ == 0 &&
receive_counters_.transmitted.payload_bytes == 0) {
// We have not received anything.
return false;
}
@ -260,8 +261,8 @@ RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
// Number of received RTP packets since last report, counts all packets but
// not re-transmissions.
uint32_t rec_since_last =
(receive_counters_.packets - receive_counters_.retransmitted_packets) -
last_report_inorder_packets_;
(receive_counters_.transmitted.packets -
receive_counters_.retransmitted.packets) - last_report_inorder_packets_;
// With NACK we don't know the expected retransmissions during the last
// second. We know how many "old" packets we have received. We just count
@ -273,7 +274,7 @@ RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
// re-transmitted. We use RTT to decide if a packet is re-ordered or
// re-transmitted.
uint32_t retransmitted_packets =
receive_counters_.retransmitted_packets - last_report_old_packets_;
receive_counters_.retransmitted.packets - last_report_old_packets_;
rec_since_last += retransmitted_packets;
int32_t missing = 0;
@ -301,8 +302,9 @@ RtcpStatistics StreamStatisticianImpl::CalculateRtcpStatistics() {
// Only for report blocks in RTCP SR and RR.
last_report_inorder_packets_ =
receive_counters_.packets - receive_counters_.retransmitted_packets;
last_report_old_packets_ = receive_counters_.retransmitted_packets;
receive_counters_.transmitted.packets -
receive_counters_.retransmitted.packets;
last_report_old_packets_ = receive_counters_.retransmitted.packets;
last_report_seq_max_ = received_seq_max_;
return stats;
@ -312,11 +314,12 @@ void StreamStatisticianImpl::GetDataCounters(
size_t* bytes_received, uint32_t* packets_received) const {
CriticalSectionScoped cs(stream_lock_.get());
if (bytes_received) {
*bytes_received = receive_counters_.bytes + receive_counters_.header_bytes +
receive_counters_.padding_bytes;
*bytes_received = receive_counters_.transmitted.payload_bytes +
receive_counters_.transmitted.header_bytes +
receive_counters_.transmitted.padding_bytes;
}
if (packets_received) {
*packets_received = receive_counters_.packets;
*packets_received = receive_counters_.transmitted.packets;
}
}

View File

@ -141,18 +141,18 @@ TEST_F(ReceiveStatisticsTest, GetReceiveStreamDataCounters) {
StreamDataCounters counters;
statistician->GetReceiveStreamDataCounters(&counters);
EXPECT_GT(counters.first_packet_time_ms, -1);
EXPECT_EQ(1u, counters.packets);
EXPECT_EQ(1u, counters.transmitted.packets);
statistician->ResetStatistics();
// GetReceiveStreamDataCounters includes reset counter values.
statistician->GetReceiveStreamDataCounters(&counters);
EXPECT_GT(counters.first_packet_time_ms, -1);
EXPECT_EQ(1u, counters.packets);
EXPECT_EQ(1u, counters.transmitted.packets);
receive_statistics_->IncomingPacket(header1_, kPacketSize1, false);
statistician->GetReceiveStreamDataCounters(&counters);
EXPECT_GT(counters.first_packet_time_ms, -1);
EXPECT_EQ(2u, counters.packets);
EXPECT_EQ(2u, counters.transmitted.packets);
}
TEST_F(ReceiveStatisticsTest, RtcpCallbacks) {
@ -262,17 +262,21 @@ class RtpTestCallback : public StreamDataCountersCallback {
const StreamDataCounters& expected) {
EXPECT_EQ(num_calls, num_calls_);
EXPECT_EQ(ssrc, ssrc_);
EXPECT_EQ(expected.bytes, stats_.bytes);
EXPECT_EQ(expected.header_bytes, stats_.header_bytes);
EXPECT_EQ(expected.padding_bytes, stats_.padding_bytes);
EXPECT_EQ(expected.packets, stats_.packets);
EXPECT_EQ(expected.retransmitted_bytes, stats_.retransmitted_bytes);
EXPECT_EQ(expected.retransmitted_header_bytes,
stats_.retransmitted_header_bytes);
EXPECT_EQ(expected.retransmitted_padding_bytes,
stats_.retransmitted_padding_bytes);
EXPECT_EQ(expected.retransmitted_packets, stats_.retransmitted_packets);
EXPECT_EQ(expected.fec_packets, stats_.fec_packets);
EXPECT_EQ(expected.transmitted.payload_bytes,
stats_.transmitted.payload_bytes);
EXPECT_EQ(expected.transmitted.header_bytes,
stats_.transmitted.header_bytes);
EXPECT_EQ(expected.transmitted.padding_bytes,
stats_.transmitted.padding_bytes);
EXPECT_EQ(expected.transmitted.packets, stats_.transmitted.packets);
EXPECT_EQ(expected.retransmitted.payload_bytes,
stats_.retransmitted.payload_bytes);
EXPECT_EQ(expected.retransmitted.header_bytes,
stats_.retransmitted.header_bytes);
EXPECT_EQ(expected.retransmitted.padding_bytes,
stats_.retransmitted.padding_bytes);
EXPECT_EQ(expected.retransmitted.packets, stats_.retransmitted.packets);
EXPECT_EQ(expected.fec.packets, stats_.fec.packets);
}
uint32_t num_calls_;
@ -292,15 +296,15 @@ TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength, false);
StreamDataCounters expected;
expected.bytes = kPacketSize1;
expected.header_bytes = kHeaderLength;
expected.padding_bytes = 0;
expected.packets = 1;
expected.retransmitted_bytes = 0;
expected.retransmitted_header_bytes = 0;
expected.retransmitted_padding_bytes = 0;
expected.retransmitted_packets = 0;
expected.fec_packets = 0;
expected.transmitted.payload_bytes = kPacketSize1;
expected.transmitted.header_bytes = kHeaderLength;
expected.transmitted.padding_bytes = 0;
expected.transmitted.packets = 1;
expected.retransmitted.payload_bytes = 0;
expected.retransmitted.header_bytes = 0;
expected.retransmitted.padding_bytes = 0;
expected.retransmitted.packets = 0;
expected.fec.packets = 0;
callback.Matches(1, kSsrc1, expected);
++header1_.sequenceNumber;
@ -309,24 +313,24 @@ TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
// Another packet of size kPacketSize1 with 9 bytes padding.
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength + kPaddingLength, false);
expected.bytes = kPacketSize1 * 2;
expected.header_bytes = kHeaderLength * 2;
expected.padding_bytes = kPaddingLength;
expected.packets = 2;
expected.transmitted.payload_bytes = kPacketSize1 * 2;
expected.transmitted.header_bytes = kHeaderLength * 2;
expected.transmitted.padding_bytes = kPaddingLength;
expected.transmitted.packets = 2;
callback.Matches(2, kSsrc1, expected);
clock_.AdvanceTimeMilliseconds(5);
// Retransmit last packet.
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength + kPaddingLength, true);
expected.bytes = kPacketSize1 * 3;
expected.header_bytes = kHeaderLength * 3;
expected.padding_bytes = kPaddingLength * 2;
expected.packets = 3;
expected.retransmitted_bytes = kPacketSize1;
expected.retransmitted_header_bytes = kHeaderLength;
expected.retransmitted_padding_bytes = kPaddingLength;
expected.retransmitted_packets = 1;
expected.transmitted.payload_bytes = kPacketSize1 * 3;
expected.transmitted.header_bytes = kHeaderLength * 3;
expected.transmitted.padding_bytes = kPaddingLength * 2;
expected.transmitted.packets = 3;
expected.retransmitted.payload_bytes = kPacketSize1;
expected.retransmitted.header_bytes = kHeaderLength;
expected.retransmitted.padding_bytes = kPaddingLength;
expected.retransmitted.packets = 1;
callback.Matches(3, kSsrc1, expected);
header1_.paddingLength = 0;
@ -336,10 +340,10 @@ TEST_F(ReceiveStatisticsTest, RtpCallbacks) {
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength, false);
receive_statistics_->FecPacketReceived(kSsrc1);
expected.bytes = kPacketSize1 * 4;
expected.header_bytes = kHeaderLength * 4;
expected.packets = 4;
expected.fec_packets = 1;
expected.transmitted.payload_bytes = kPacketSize1 * 4;
expected.transmitted.header_bytes = kHeaderLength * 4;
expected.transmitted.packets = 4;
expected.fec.packets = 1;
callback.Matches(5, kSsrc1, expected);
receive_statistics_->RegisterRtpStatisticsCallback(NULL);
@ -366,15 +370,15 @@ TEST_F(ReceiveStatisticsTest, RtpCallbacksFecFirst) {
receive_statistics_->IncomingPacket(
header1_, kPacketSize1 + kHeaderLength, false);
StreamDataCounters expected;
expected.bytes = kPacketSize1;
expected.header_bytes = kHeaderLength;
expected.padding_bytes = 0;
expected.packets = 1;
expected.fec_packets = 0;
expected.transmitted.payload_bytes = kPacketSize1;
expected.transmitted.header_bytes = kHeaderLength;
expected.transmitted.padding_bytes = 0;
expected.transmitted.packets = 1;
expected.fec.packets = 0;
callback.Matches(1, kSsrc1, expected);
receive_statistics_->FecPacketReceived(kSsrc1);
expected.fec_packets = 1;
expected.fec.packets = 1;
callback.Matches(2, kSsrc1, expected);
}
} // namespace webrtc

View File

@ -408,8 +408,10 @@ RTCPSender::FeedbackState ModuleRtpRtcpImpl::GetFeedbackState() {
RTCPSender::FeedbackState state;
state.send_payload_type = SendPayloadType();
state.frequency_hz = CurrentSendFrequencyHz();
state.packets_sent = rtp_stats.packets + rtx_stats.packets;
state.media_bytes_sent = rtp_stats.bytes + rtx_stats.bytes;
state.packets_sent = rtp_stats.transmitted.packets +
rtx_stats.transmitted.packets;
state.media_bytes_sent = rtp_stats.transmitted.payload_bytes +
rtx_stats.transmitted.payload_bytes;
state.module = this;
LastReceivedNTP(&state.last_rr_ntp_secs,
@ -798,12 +800,16 @@ int32_t ModuleRtpRtcpImpl::DataCountersRTP(
rtp_sender_.GetDataCounters(&rtp_stats, &rtx_stats);
if (bytes_sent) {
*bytes_sent = rtp_stats.bytes + rtp_stats.padding_bytes +
rtp_stats.header_bytes + rtx_stats.bytes +
rtx_stats.padding_bytes + rtx_stats.header_bytes;
*bytes_sent = rtp_stats.transmitted.payload_bytes +
rtp_stats.transmitted.padding_bytes +
rtp_stats.transmitted.header_bytes +
rtx_stats.transmitted.payload_bytes +
rtx_stats.transmitted.padding_bytes +
rtx_stats.transmitted.header_bytes;
}
if (packets_sent) {
*packets_sent = rtp_stats.packets + rtx_stats.packets;
*packets_sent = rtp_stats.transmitted.packets +
rtx_stats.transmitted.packets;
}
return 0;
}

View File

@ -364,35 +364,38 @@ TEST_F(RtpRtcpImplTest, AddStreamDataCounters) {
StreamDataCounters rtp;
const int64_t kStartTimeMs = 1;
rtp.first_packet_time_ms = kStartTimeMs;
rtp.packets = 1;
rtp.bytes = 1;
rtp.header_bytes = 2;
rtp.padding_bytes = 3;
EXPECT_EQ(rtp.TotalBytes(), rtp.bytes + rtp.header_bytes + rtp.padding_bytes);
rtp.transmitted.packets = 1;
rtp.transmitted.payload_bytes = 1;
rtp.transmitted.header_bytes = 2;
rtp.transmitted.padding_bytes = 3;
EXPECT_EQ(rtp.transmitted.TotalBytes(), rtp.transmitted.payload_bytes +
rtp.transmitted.header_bytes +
rtp.transmitted.padding_bytes);
StreamDataCounters rtp2;
rtp2.first_packet_time_ms = -1;
rtp2.packets = 10;
rtp2.bytes = 10;
rtp2.retransmitted_header_bytes = 4;
rtp2.retransmitted_bytes = 5;
rtp2.retransmitted_padding_bytes = 6;
rtp2.retransmitted_packets = 7;
rtp2.fec_packets = 8;
rtp2.transmitted.packets = 10;
rtp2.transmitted.payload_bytes = 10;
rtp2.retransmitted.header_bytes = 4;
rtp2.retransmitted.payload_bytes = 5;
rtp2.retransmitted.padding_bytes = 6;
rtp2.retransmitted.packets = 7;
rtp2.fec.packets = 8;
StreamDataCounters sum = rtp;
sum.Add(rtp2);
EXPECT_EQ(kStartTimeMs, sum.first_packet_time_ms);
EXPECT_EQ(11U, sum.packets);
EXPECT_EQ(11U, sum.bytes);
EXPECT_EQ(2U, sum.header_bytes);
EXPECT_EQ(3U, sum.padding_bytes);
EXPECT_EQ(4U, sum.retransmitted_header_bytes);
EXPECT_EQ(5U, sum.retransmitted_bytes);
EXPECT_EQ(6U, sum.retransmitted_padding_bytes);
EXPECT_EQ(7U, sum.retransmitted_packets);
EXPECT_EQ(8U, sum.fec_packets);
EXPECT_EQ(sum.TotalBytes(), rtp.TotalBytes() + rtp2.TotalBytes());
EXPECT_EQ(11U, sum.transmitted.packets);
EXPECT_EQ(11U, sum.transmitted.payload_bytes);
EXPECT_EQ(2U, sum.transmitted.header_bytes);
EXPECT_EQ(3U, sum.transmitted.padding_bytes);
EXPECT_EQ(4U, sum.retransmitted.header_bytes);
EXPECT_EQ(5U, sum.retransmitted.payload_bytes);
EXPECT_EQ(6U, sum.retransmitted.padding_bytes);
EXPECT_EQ(7U, sum.retransmitted.packets);
EXPECT_EQ(8U, sum.fec.packets);
EXPECT_EQ(sum.transmitted.TotalBytes(),
rtp.transmitted.TotalBytes() + rtp2.transmitted.TotalBytes());
StreamDataCounters rtp3;
rtp3.first_packet_time_ms = kStartTimeMs + 10;

View File

@ -894,25 +894,25 @@ void RTPSender::UpdateRtpStats(const uint8_t* buffer,
}
total_bitrate_sent_.Update(packet_length);
++counters->packets;
if (counters->packets == 1) {
++counters->transmitted.packets;
if (counters->first_packet_time_ms == -1) {
counters->first_packet_time_ms = clock_->TimeInMilliseconds();
}
if (IsFecPacket(buffer, header)) {
++counters->fec_packets;
++counters->fec.packets;
}
if (is_retransmit) {
++counters->retransmitted_packets;
counters->retransmitted_bytes +=
++counters->retransmitted.packets;
counters->retransmitted.payload_bytes +=
packet_length - (header.headerLength + header.paddingLength);
counters->retransmitted_header_bytes += header.headerLength;
counters->retransmitted_padding_bytes += header.paddingLength;
counters->retransmitted.header_bytes += header.headerLength;
counters->retransmitted.padding_bytes += header.paddingLength;
}
counters->bytes +=
counters->transmitted.payload_bytes +=
packet_length - (header.headerLength + header.paddingLength);
counters->header_bytes += header.headerLength;
counters->padding_bytes += header.paddingLength;
counters->transmitted.header_bytes += header.headerLength;
counters->transmitted.padding_bytes += header.paddingLength;
if (rtp_stats_callback_) {
rtp_stats_callback_->DataCountersUpdated(*counters, ssrc);

View File

@ -916,18 +916,23 @@ TEST_F(RtpSenderTest, StreamDataCountersCallbacks) {
StreamDataCounters counters_;
void Matches(uint32_t ssrc, const StreamDataCounters& counters) {
EXPECT_EQ(ssrc, ssrc_);
EXPECT_EQ(counters.bytes, counters_.bytes);
EXPECT_EQ(counters.header_bytes, counters_.header_bytes);
EXPECT_EQ(counters.padding_bytes, counters_.padding_bytes);
EXPECT_EQ(counters.packets, counters_.packets);
EXPECT_EQ(counters.retransmitted_bytes, counters_.retransmitted_bytes);
EXPECT_EQ(counters.retransmitted_header_bytes,
counters_.retransmitted_header_bytes);
EXPECT_EQ(counters.retransmitted_padding_bytes,
counters_.retransmitted_padding_bytes);
EXPECT_EQ(counters.retransmitted_packets,
counters_.retransmitted_packets);
EXPECT_EQ(counters.fec_packets, counters_.fec_packets);
EXPECT_EQ(counters.transmitted.payload_bytes,
counters_.transmitted.payload_bytes);
EXPECT_EQ(counters.transmitted.header_bytes,
counters_.transmitted.header_bytes);
EXPECT_EQ(counters.transmitted.padding_bytes,
counters_.transmitted.padding_bytes);
EXPECT_EQ(counters.transmitted.packets,
counters_.transmitted.packets);
EXPECT_EQ(counters.retransmitted.payload_bytes,
counters_.retransmitted.payload_bytes);
EXPECT_EQ(counters.retransmitted.header_bytes,
counters_.retransmitted.header_bytes);
EXPECT_EQ(counters.retransmitted.padding_bytes,
counters_.retransmitted.padding_bytes);
EXPECT_EQ(counters.retransmitted.packets,
counters_.retransmitted.packets);
EXPECT_EQ(counters.fec.packets, counters_.fec.packets);
}
} callback;
@ -949,35 +954,35 @@ TEST_F(RtpSenderTest, StreamDataCountersCallbacks) {
4321, payload, sizeof(payload),
NULL));
StreamDataCounters expected;
expected.bytes = 6;
expected.header_bytes = 12;
expected.padding_bytes = 0;
expected.packets = 1;
expected.retransmitted_bytes = 0;
expected.retransmitted_header_bytes = 0;
expected.retransmitted_padding_bytes = 0;
expected.retransmitted_packets = 0;
expected.fec_packets = 0;
expected.transmitted.payload_bytes = 6;
expected.transmitted.header_bytes = 12;
expected.transmitted.padding_bytes = 0;
expected.transmitted.packets = 1;
expected.retransmitted.payload_bytes = 0;
expected.retransmitted.header_bytes = 0;
expected.retransmitted.padding_bytes = 0;
expected.retransmitted.packets = 0;
expected.fec.packets = 0;
callback.Matches(ssrc, expected);
// Retransmit a frame.
uint16_t seqno = rtp_sender_->SequenceNumber() - 1;
rtp_sender_->ReSendPacket(seqno, 0);
expected.bytes = 12;
expected.header_bytes = 24;
expected.packets = 2;
expected.retransmitted_bytes = 6;
expected.retransmitted_header_bytes = 12;
expected.retransmitted_padding_bytes = 0;
expected.retransmitted_packets = 1;
expected.transmitted.payload_bytes = 12;
expected.transmitted.header_bytes = 24;
expected.transmitted.packets = 2;
expected.retransmitted.payload_bytes = 6;
expected.retransmitted.header_bytes = 12;
expected.retransmitted.padding_bytes = 0;
expected.retransmitted.packets = 1;
callback.Matches(ssrc, expected);
// Send padding.
rtp_sender_->TimeToSendPadding(kMaxPaddingSize);
expected.bytes = 12;
expected.header_bytes = 36;
expected.padding_bytes = kMaxPaddingSize;
expected.packets = 3;
expected.transmitted.payload_bytes = 12;
expected.transmitted.header_bytes = 36;
expected.transmitted.padding_bytes = kMaxPaddingSize;
expected.transmitted.packets = 3;
callback.Matches(ssrc, expected);
// Send FEC.
@ -991,10 +996,10 @@ TEST_F(RtpSenderTest, StreamDataCountersCallbacks) {
ASSERT_EQ(0, rtp_sender_->SendOutgoingData(kVideoFrameDelta, payload_type,
1234, 4321, payload,
sizeof(payload), NULL));
expected.bytes = 40;
expected.header_bytes = 60;
expected.packets = 5;
expected.fec_packets = 1;
expected.transmitted.payload_bytes = 40;
expected.transmitted.header_bytes = 60;
expected.transmitted.packets = 5;
expected.fec.packets = 1;
callback.Matches(ssrc, expected);
rtp_sender_->RegisterRtpStatisticsCallback(NULL);
@ -1150,19 +1155,24 @@ TEST_F(RtpSenderTest, BytesReportedCorrectly) {
// Payload + 1-byte generic header.
EXPECT_GT(rtp_stats.first_packet_time_ms, -1);
EXPECT_EQ(rtp_stats.bytes, sizeof(payload) + 1);
EXPECT_EQ(rtp_stats.header_bytes, 12u);
EXPECT_EQ(rtp_stats.padding_bytes, 0u);
EXPECT_EQ(rtx_stats.bytes, 0u);
EXPECT_EQ(rtx_stats.header_bytes, 24u);
EXPECT_EQ(rtx_stats.padding_bytes, 2 * kMaxPaddingSize);
EXPECT_EQ(rtp_stats.transmitted.payload_bytes, sizeof(payload) + 1);
EXPECT_EQ(rtp_stats.transmitted.header_bytes, 12u);
EXPECT_EQ(rtp_stats.transmitted.padding_bytes, 0u);
EXPECT_EQ(rtx_stats.transmitted.payload_bytes, 0u);
EXPECT_EQ(rtx_stats.transmitted.header_bytes, 24u);
EXPECT_EQ(rtx_stats.transmitted.padding_bytes, 2 * kMaxPaddingSize);
EXPECT_EQ(rtp_stats.TotalBytes(),
rtp_stats.bytes + rtp_stats.header_bytes + rtp_stats.padding_bytes);
EXPECT_EQ(rtx_stats.TotalBytes(),
rtx_stats.bytes + rtx_stats.header_bytes + rtx_stats.padding_bytes);
EXPECT_EQ(rtp_stats.transmitted.TotalBytes(),
rtp_stats.transmitted.payload_bytes +
rtp_stats.transmitted.header_bytes +
rtp_stats.transmitted.padding_bytes);
EXPECT_EQ(rtx_stats.transmitted.TotalBytes(),
rtx_stats.transmitted.payload_bytes +
rtx_stats.transmitted.header_bytes +
rtx_stats.transmitted.padding_bytes);
EXPECT_EQ(transport_.total_bytes_sent_,
rtp_stats.TotalBytes() + rtx_stats.TotalBytes());
rtp_stats.transmitted.TotalBytes() +
rtx_stats.transmitted.TotalBytes());
}
} // namespace webrtc

View File

@ -1490,10 +1490,12 @@ TEST_F(EndToEndTest, GetStats) {
stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0;
receive_stats_filled_["DataCountersUpdated"] |=
stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 ||
stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 ||
stats.rtp_stats.padding_bytes != 0 ||
stats.rtp_stats.retransmitted_packets != 0;
stats.rtp_stats.transmitted.payload_bytes != 0 ||
stats.rtp_stats.fec.packets != 0 ||
stats.rtp_stats.transmitted.header_bytes != 0 ||
stats.rtp_stats.transmitted.packets != 0 ||
stats.rtp_stats.transmitted.padding_bytes != 0 ||
stats.rtp_stats.retransmitted.packets != 0;
receive_stats_filled_["CodecStats"] |=
stats.avg_delay_ms != 0 || stats.discarded_packets != 0;
@ -1532,10 +1534,10 @@ TEST_F(EndToEndTest, GetStats) {
stream_stats.rtcp_stats.fraction_lost != 0;
send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |=
stream_stats.rtp_stats.fec_packets != 0 ||
stream_stats.rtp_stats.padding_bytes != 0 ||
stream_stats.rtp_stats.retransmitted_packets != 0 ||
stream_stats.rtp_stats.packets != 0;
stream_stats.rtp_stats.fec.packets != 0 ||
stream_stats.rtp_stats.transmitted.padding_bytes != 0 ||
stream_stats.rtp_stats.retransmitted.packets != 0 ||
stream_stats.rtp_stats.transmitted.packets != 0;
send_stats_filled_[CompoundKey("BitrateStatisticsObserver",
it->first)] |=
@ -1686,7 +1688,7 @@ TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
if (sent_rtp_ >= kNumRtpPacketsToSend) {
VideoReceiveStream::Stats stats = receive_stream_->GetStats();
if (kNumRtpPacketsToSend == stats.rtp_stats.packets) {
if (kNumRtpPacketsToSend == stats.rtp_stats.transmitted.packets) {
observation_complete_->Set();
}
return DROP_PACKET;

View File

@ -65,13 +65,17 @@ class SendStatisticsProxyTest : public ::testing::Test {
EXPECT_EQ(a.avg_delay_ms, b.avg_delay_ms);
EXPECT_EQ(a.max_delay_ms, b.max_delay_ms);
EXPECT_EQ(a.rtp_stats.bytes, b.rtp_stats.bytes);
EXPECT_EQ(a.rtp_stats.header_bytes, b.rtp_stats.header_bytes);
EXPECT_EQ(a.rtp_stats.padding_bytes, b.rtp_stats.padding_bytes);
EXPECT_EQ(a.rtp_stats.packets, b.rtp_stats.packets);
EXPECT_EQ(a.rtp_stats.retransmitted_packets,
b.rtp_stats.retransmitted_packets);
EXPECT_EQ(a.rtp_stats.fec_packets, b.rtp_stats.fec_packets);
EXPECT_EQ(a.rtp_stats.transmitted.payload_bytes,
b.rtp_stats.transmitted.payload_bytes);
EXPECT_EQ(a.rtp_stats.transmitted.header_bytes,
b.rtp_stats.transmitted.header_bytes);
EXPECT_EQ(a.rtp_stats.transmitted.padding_bytes,
b.rtp_stats.transmitted.padding_bytes);
EXPECT_EQ(a.rtp_stats.transmitted.packets,
b.rtp_stats.transmitted.packets);
EXPECT_EQ(a.rtp_stats.retransmitted.packets,
b.rtp_stats.retransmitted.packets);
EXPECT_EQ(a.rtp_stats.fec.packets, b.rtp_stats.fec.packets);
EXPECT_EQ(a.rtcp_stats.fraction_lost, b.rtcp_stats.fraction_lost);
EXPECT_EQ(a.rtcp_stats.cumulative_lost, b.rtcp_stats.cumulative_lost);
@ -203,12 +207,12 @@ TEST_F(SendStatisticsProxyTest, DataCounters) {
// Add statistics with some arbitrary, but unique, numbers.
size_t offset = ssrc * sizeof(StreamDataCounters);
uint32_t offset_uint32 = static_cast<uint32_t>(offset);
counters.bytes = offset;
counters.header_bytes = offset + 1;
counters.fec_packets = offset_uint32 + 2;
counters.padding_bytes = offset + 3;
counters.retransmitted_packets = offset_uint32 + 4;
counters.packets = offset_uint32 + 5;
counters.transmitted.payload_bytes = offset;
counters.transmitted.header_bytes = offset + 1;
counters.fec.packets = offset_uint32 + 2;
counters.transmitted.padding_bytes = offset + 3;
counters.retransmitted.packets = offset_uint32 + 4;
counters.transmitted.packets = offset_uint32 + 5;
callback->DataCountersUpdated(counters, ssrc);
}
for (std::vector<uint32_t>::const_iterator it = config_.rtp.rtx.ssrcs.begin();
@ -219,12 +223,12 @@ TEST_F(SendStatisticsProxyTest, DataCounters) {
// Add statistics with some arbitrary, but unique, numbers.
size_t offset = ssrc * sizeof(StreamDataCounters);
uint32_t offset_uint32 = static_cast<uint32_t>(offset);
counters.bytes = offset;
counters.header_bytes = offset + 1;
counters.fec_packets = offset_uint32 + 2;
counters.padding_bytes = offset + 3;
counters.retransmitted_packets = offset_uint32 + 4;
counters.packets = offset_uint32 + 5;
counters.transmitted.payload_bytes = offset;
counters.transmitted.header_bytes = offset + 1;
counters.fec.packets = offset_uint32 + 2;
counters.transmitted.padding_bytes = offset + 3;
counters.retransmitted.packets = offset_uint32 + 4;
counters.transmitted.packets = offset_uint32 + 5;
callback->DataCountersUpdated(counters, ssrc);
}

View File

@ -960,7 +960,8 @@ TEST_F(VideoSendStreamTest, ProducesStats) {
const SsrcStats& entry = stats.substreams[ssrc];
if (entry.frame_counts.key_frames > 0 &&
entry.frame_counts.delta_frames > 0 &&
entry.total_bitrate_bps > 0 && entry.rtp_stats.packets > 0u &&
entry.total_bitrate_bps > 0 &&
entry.rtp_stats.transmitted.packets > 0u &&
entry.avg_delay_ms > 0 && entry.max_delay_ms > 0) {
return true;
}

View File

@ -349,10 +349,10 @@ class WEBRTC_DLLEXPORT ViERTP_RTCP {
StreamDataCounters sent;
StreamDataCounters received;
int ret_code = GetRtpStatistics(video_channel, sent, received);
bytes_sent = sent.bytes;
packets_sent = sent.packets;
bytes_received = received.bytes;
packets_received = received.packets;
bytes_sent = sent.transmitted.payload_bytes;
packets_sent = sent.transmitted.packets;
bytes_received = received.transmitted.payload_bytes;
packets_received = received.transmitted.packets;
return ret_code;
}

View File

@ -1564,13 +1564,13 @@ void PrintRTPStatistics(webrtc::ViERTP_RTCP* vie_rtp_rtcp,
"ERROR: %s at line %d",
__FUNCTION__, __LINE__);
std::cout << "\tRTP bytes sent: "
<< sent.bytes << std::endl;
<< sent.transmitted.payload_bytes << std::endl;
std::cout << "\tRTP packets sent: "
<< sent.packets << std::endl;
<< sent.transmitted.packets << std::endl;
std::cout << "\tRTP bytes received: "
<< received.bytes << std::endl;
<< received.transmitted.payload_bytes << std::endl;
std::cout << "\tRTP packets received: "
<< received.packets << std::endl;
<< received.transmitted.packets << std::endl;
}
void PrintBandwidthUsage(webrtc::ViERTP_RTCP* vie_rtp_rtcp,

View File

@ -496,21 +496,24 @@ void ViEAutoTest::ViERtpRtcpStandardTest()
EXPECT_EQ(0, ViE.rtp_rtcp->GetRtpStatistics(tbChannel.videoChannel,
sent_after, received_after));
if (FLAGS_include_timing_dependent_tests) {
EXPECT_GT(received_after.bytes, received_before.bytes);
EXPECT_GT(received_after.transmitted.payload_bytes,
received_before.transmitted.payload_bytes);
}
// Simulate lost reception and verify that nothing is sent during that time.
ViE.network->SetNetworkTransmissionState(tbChannel.videoChannel, false);
// Allow the encoder to finish the current frame before we expect that no
// additional packets will be sent.
AutoTestSleep(kAutoTestSleepTimeMs);
received_before.bytes = received_after.bytes;
received_before.transmitted.payload_bytes =
received_after.transmitted.payload_bytes;
ViETest::Log("Network Down...\n");
AutoTestSleep(kAutoTestSleepTimeMs);
EXPECT_EQ(0, ViE.rtp_rtcp->GetRtpStatistics(tbChannel.videoChannel,
sent_before,
received_before));
if (FLAGS_include_timing_dependent_tests) {
EXPECT_EQ(received_before.bytes, received_after.bytes);
EXPECT_EQ(received_before.transmitted.payload_bytes,
received_after.transmitted.payload_bytes);
}
// Network reception back. Video should now be sent.
@ -521,9 +524,11 @@ void ViEAutoTest::ViERtpRtcpStandardTest()
sent_before,
received_before));
if (FLAGS_include_timing_dependent_tests) {
EXPECT_GT(received_before.bytes, received_after.bytes);
EXPECT_GT(received_before.transmitted.payload_bytes,
received_after.transmitted.payload_bytes);
}
received_after.bytes = received_before.bytes;
received_after.transmitted.payload_bytes =
received_before.transmitted.payload_bytes;
// Buffering mode.
EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel));
EXPECT_EQ(0, ViE.base->StopReceive(tbChannel.videoChannel));
@ -547,15 +552,18 @@ void ViEAutoTest::ViERtpRtcpStandardTest()
sent_before,
received_before));
if (FLAGS_include_timing_dependent_tests) {
EXPECT_GT(received_before.bytes, received_after.bytes);
EXPECT_GT(received_before.transmitted.payload_bytes,
received_after.transmitted.payload_bytes);
}
received_after.bytes = received_before.bytes;
received_after.transmitted.payload_bytes =
received_before.transmitted.payload_bytes;
AutoTestSleep(kAutoTestSleepTimeMs);
EXPECT_EQ(0, ViE.rtp_rtcp->GetRtpStatistics(tbChannel.videoChannel,
sent_before,
received_before));
if (FLAGS_include_timing_dependent_tests) {
EXPECT_EQ(received_after.bytes, received_before.bytes);
EXPECT_EQ(received_after.transmitted.payload_bytes,
received_before.transmitted.payload_bytes);
}
// Network reception back. Video should now be sent.
ViETest::Log("Network Up...\n");
@ -565,7 +573,8 @@ void ViEAutoTest::ViERtpRtcpStandardTest()
sent_before,
received_before));
if (FLAGS_include_timing_dependent_tests) {
EXPECT_GT(received_before.bytes, received_after.bytes);
EXPECT_GT(received_before.transmitted.payload_bytes,
received_after.transmitted.payload_bytes);
}
// TODO(holmer): Verify that the decoded framerate doesn't decrease on an
// outage when in buffering mode. This isn't currently possible because we

View File

@ -248,18 +248,18 @@ void ViEChannel::UpdateHistograms() {
elapsed_sec = rtp_rtx.TimeSinceFirstPacketInMs(now) / 1000;
if (elapsed_sec > metrics::kMinRunTimeInSeconds) {
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.BitrateReceivedInKbps",
rtp_rtx.TotalBytes() * 8 / elapsed_sec / 1000);
rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / 1000);
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.MediaBitrateReceivedInKbps",
rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000);
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PaddingBitrateReceivedInKbps",
rtp_rtx.padding_bytes * 8 / elapsed_sec / 1000);
rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / 1000);
RTC_HISTOGRAM_COUNTS_10000(
"WebRTC.Video.RetransmittedBitrateReceivedInKbps",
rtp_rtx.RetransmittedBytes() * 8 / elapsed_sec / 1000);
rtp_rtx.retransmitted.TotalBytes() * 8 / elapsed_sec / 1000);
uint32_t ssrc = 0;
if (vie_receiver_.GetRtxSsrc(&ssrc)) {
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtxBitrateReceivedInKbps",
rtx.TotalBytes() * 8 / elapsed_sec / 1000);
rtx.transmitted.TotalBytes() * 8 / elapsed_sec / 1000);
}
}
}
@ -278,17 +278,17 @@ void ViEChannel::UpdateHistogramsAtStopSend() {
return;
}
RTC_HISTOGRAM_COUNTS_100000("WebRTC.Video.BitrateSentInKbps",
rtp_rtx.TotalBytes() * 8 / elapsed_sec / 1000);
rtp_rtx.transmitted.TotalBytes() * 8 / elapsed_sec / 1000);
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.MediaBitrateSentInKbps",
rtp.MediaPayloadBytes() * 8 / elapsed_sec / 1000);
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.PaddingBitrateSentInKbps",
rtp_rtx.padding_bytes * 8 / elapsed_sec / 1000);
rtp_rtx.transmitted.padding_bytes * 8 / elapsed_sec / 1000);
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RetransmittedBitrateSentInKbps",
rtp_rtx.RetransmittedBytes() * 8 / elapsed_sec / 1000);
rtp_rtx.retransmitted.TotalBytes() * 8 / elapsed_sec / 1000);
uint32_t ssrc = 0;
if (vie_receiver_.GetRtxSsrc(&ssrc)) {
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.RtxBitrateSentInKbps",
rtx.TotalBytes() * 8 / elapsed_sec / 1000);
rtx.transmitted.TotalBytes() * 8 / elapsed_sec / 1000);
}
}

View File

@ -726,10 +726,10 @@ int ViERTP_RTCPImpl::GetRtpStatistics(const int video_channel,
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
if (vie_channel->GetRtpStatistics(&sent.bytes,
&sent.packets,
&received.bytes,
&received.packets) != 0) {
if (vie_channel->GetRtpStatistics(&sent.transmitted.payload_bytes,
&sent.transmitted.packets,
&received.transmitted.payload_bytes,
&received.transmitted.packets) != 0) {
shared_data_->SetLastError(kViERtpRtcpUnknownError);
return -1;
}