Commit 9f7acae4 authored by hubbe's avatar hubbe Committed by Commit bot

Cast: Re-factor rtcp_sender.cc into rtcp_builder.cc and do some cleanup

Review URL: https://codereview.chromium.org/513313004

Cr-Commit-Position: refs/heads/master@{#293787}
parent c4d26a44
...@@ -72,8 +72,8 @@ source_set("net") { ...@@ -72,8 +72,8 @@ source_set("net") {
"net/rtcp/rtcp_defines.h", "net/rtcp/rtcp_defines.h",
"net/rtcp/rtcp.h", "net/rtcp/rtcp.h",
"net/rtcp/rtcp.cc", "net/rtcp/rtcp.cc",
"net/rtcp/rtcp_sender.cc", "net/rtcp/rtcp_builder.cc",
"net/rtcp/rtcp_sender.h", "net/rtcp/rtcp_builder.h",
"net/rtcp/rtcp_utility.cc", "net/rtcp/rtcp_utility.cc",
"net/rtcp/rtcp_utility.h", "net/rtcp/rtcp_utility.h",
"net/rtp/packet_storage.cc", "net/rtp/packet_storage.cc",
...@@ -230,7 +230,7 @@ test("cast_unittests") { ...@@ -230,7 +230,7 @@ test("cast_unittests") {
"net/pacing/mock_paced_packet_sender.cc", "net/pacing/mock_paced_packet_sender.cc",
"net/pacing/mock_paced_packet_sender.h", "net/pacing/mock_paced_packet_sender.h",
"net/pacing/paced_sender_unittest.cc", "net/pacing/paced_sender_unittest.cc",
"net/rtcp/rtcp_sender_unittest.cc", "net/rtcp/rtcp_builder_unittest.cc",
"net/rtcp/rtcp_unittest.cc", "net/rtcp/rtcp_unittest.cc",
"net/rtcp/rtcp_utility_unittest.cc", "net/rtcp/rtcp_utility_unittest.cc",
"net/rtcp/receiver_rtcp_event_subscriber_unittest.cc", "net/rtcp/receiver_rtcp_event_subscriber_unittest.cc",
......
...@@ -184,12 +184,12 @@ ...@@ -184,12 +184,12 @@
'net/pacing/paced_sender.cc', 'net/pacing/paced_sender.cc',
'net/pacing/paced_sender.h', 'net/pacing/paced_sender.h',
'net/rtcp/receiver_rtcp_event_subscriber.cc', 'net/rtcp/receiver_rtcp_event_subscriber.cc',
'net/rtcp/rtcp_builder.cc',
'net/rtcp/rtcp_builder.h',
'net/rtcp/rtcp_defines.cc', 'net/rtcp/rtcp_defines.cc',
'net/rtcp/rtcp_defines.h', 'net/rtcp/rtcp_defines.h',
'net/rtcp/rtcp.h', 'net/rtcp/rtcp.h',
'net/rtcp/rtcp.cc', 'net/rtcp/rtcp.cc',
'net/rtcp/rtcp_sender.cc',
'net/rtcp/rtcp_sender.h',
'net/rtcp/rtcp_utility.cc', 'net/rtcp/rtcp_utility.cc',
'net/rtcp/rtcp_utility.h', 'net/rtcp/rtcp_utility.h',
'net/rtp/packet_storage.cc', 'net/rtp/packet_storage.cc',
......
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
'net/pacing/mock_paced_packet_sender.cc', 'net/pacing/mock_paced_packet_sender.cc',
'net/pacing/mock_paced_packet_sender.h', 'net/pacing/mock_paced_packet_sender.h',
'net/pacing/paced_sender_unittest.cc', 'net/pacing/paced_sender_unittest.cc',
'net/rtcp/rtcp_sender_unittest.cc', 'net/rtcp/rtcp_builder_unittest.cc',
'net/rtcp/rtcp_unittest.cc', 'net/rtcp/rtcp_unittest.cc',
'net/rtcp/rtcp_utility_unittest.cc', 'net/rtcp/rtcp_utility_unittest.cc',
'net/rtcp/receiver_rtcp_event_subscriber_unittest.cc', 'net/rtcp/receiver_rtcp_event_subscriber_unittest.cc',
......
...@@ -8,8 +8,9 @@ ...@@ -8,8 +8,9 @@
#include "media/cast/cast_defines.h" #include "media/cast/cast_defines.h"
#include "media/cast/cast_environment.h" #include "media/cast/cast_environment.h"
#include "media/cast/net/cast_transport_defines.h" #include "media/cast/net/cast_transport_defines.h"
#include "media/cast/net/pacing/paced_sender.h"
#include "media/cast/net/rtcp/rtcp_builder.h"
#include "media/cast/net/rtcp/rtcp_defines.h" #include "media/cast/net/rtcp/rtcp_defines.h"
#include "media/cast/net/rtcp/rtcp_sender.h"
#include "media/cast/net/rtcp/rtcp_utility.h" #include "media/cast/net/rtcp/rtcp_utility.h"
using base::TimeDelta; using base::TimeDelta;
...@@ -64,7 +65,8 @@ Rtcp::Rtcp(const RtcpCastMessageCallback& cast_callback, ...@@ -64,7 +65,8 @@ Rtcp::Rtcp(const RtcpCastMessageCallback& cast_callback,
rtt_callback_(rtt_callback), rtt_callback_(rtt_callback),
log_callback_(log_callback), log_callback_(log_callback),
clock_(clock), clock_(clock),
rtcp_sender_(new RtcpSender(packet_sender, local_ssrc)), rtcp_builder_(local_ssrc),
packet_sender_(packet_sender),
local_ssrc_(local_ssrc), local_ssrc_(local_ssrc),
remote_ssrc_(remote_ssrc), remote_ssrc_(remote_ssrc),
last_report_truncated_ntp_(0), last_report_truncated_ntp_(0),
...@@ -228,12 +230,14 @@ void Rtcp::SendRtcpFromRtpReceiver( ...@@ -228,12 +230,14 @@ void Rtcp::SendRtcpFromRtpReceiver(
report_block.delay_since_last_sr = 0; report_block.delay_since_last_sr = 0;
} }
} }
rtcp_sender_->SendRtcpFromRtpReceiver( packet_sender_->SendRtcpPacket(
rtp_receiver_statistics ? &report_block : NULL, local_ssrc_,
&rrtr, rtcp_builder_.BuildRtcpFromReceiver(
cast_message, rtp_receiver_statistics ? &report_block : NULL,
rtcp_events, &rrtr,
target_delay); cast_message,
rtcp_events,
target_delay));
} }
void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time, void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time,
...@@ -254,7 +258,9 @@ void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time, ...@@ -254,7 +258,9 @@ void Rtcp::SendRtcpFromRtpSender(base::TimeTicks current_time,
sender_info.send_packet_count = send_packet_count; sender_info.send_packet_count = send_packet_count;
sender_info.send_octet_count = send_octet_count; sender_info.send_octet_count = send_octet_count;
rtcp_sender_->SendRtcpFromRtpSender(sender_info); packet_sender_->SendRtcpPacket(
local_ssrc_,
rtcp_builder_.BuildRtcpFromSender(sender_info));
} }
void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) { void Rtcp::OnReceivedNtp(uint32 ntp_seconds, uint32 ntp_fraction) {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "media/cast/net/cast_transport_defines.h" #include "media/cast/net/cast_transport_defines.h"
#include "media/cast/net/cast_transport_sender.h" #include "media/cast/net/cast_transport_sender.h"
#include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h" #include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h"
#include "media/cast/net/rtcp/rtcp_builder.h"
#include "media/cast/net/rtcp/rtcp_defines.h" #include "media/cast/net/rtcp/rtcp_defines.h"
namespace media { namespace media {
...@@ -31,7 +32,7 @@ namespace cast { ...@@ -31,7 +32,7 @@ namespace cast {
class LocalRtcpReceiverFeedback; class LocalRtcpReceiverFeedback;
class PacedPacketSender; class PacedPacketSender;
class RtcpReceiver; class RtcpReceiver;
class RtcpSender; class RtcpBuilder;
typedef std::pair<uint32, base::TimeTicks> RtcpSendTimePair; typedef std::pair<uint32, base::TimeTicks> RtcpSendTimePair;
typedef std::map<uint32, base::TimeTicks> RtcpSendTimeMap; typedef std::map<uint32, base::TimeTicks> RtcpSendTimeMap;
...@@ -138,7 +139,8 @@ class Rtcp { ...@@ -138,7 +139,8 @@ class Rtcp {
const RtcpRttCallback rtt_callback_; const RtcpRttCallback rtt_callback_;
const RtcpLogMessageCallback log_callback_; const RtcpLogMessageCallback log_callback_;
base::TickClock* const clock_; // Not owned by this class. base::TickClock* const clock_; // Not owned by this class.
const scoped_ptr<RtcpSender> rtcp_sender_; RtcpBuilder rtcp_builder_;
PacedPacketSender* packet_sender_; // Not owned.
const uint32 local_ssrc_; const uint32 local_ssrc_;
const uint32 remote_ssrc_; const uint32 remote_ssrc_;
......
...@@ -2,17 +2,15 @@ ...@@ -2,17 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "media/cast/net/rtcp/rtcp_sender.h" #include "media/cast/net/rtcp/rtcp_builder.h"
#include <stdint.h> #include <stdint.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include "base/big_endian.h"
#include "base/logging.h" #include "base/logging.h"
#include "media/cast/net/cast_transport_defines.h" #include "media/cast/net/cast_transport_defines.h"
#include "media/cast/net/pacing/paced_sender.h"
#include "media/cast/net/rtcp/rtcp_defines.h" #include "media/cast/net/rtcp/rtcp_defines.h"
#include "media/cast/net/rtcp/rtcp_utility.h" #include "media/cast/net/rtcp/rtcp_utility.h"
...@@ -46,7 +44,7 @@ bool EventTimestampLessThan(const RtcpReceiverEventLogMessage& lhs, ...@@ -46,7 +44,7 @@ bool EventTimestampLessThan(const RtcpReceiverEventLogMessage& lhs,
return lhs.event_timestamp < rhs.event_timestamp; return lhs.event_timestamp < rhs.event_timestamp;
} }
void AddReceiverLog( void AddReceiverLogEntries(
const RtcpReceiverLogMessage& redundancy_receiver_log_message, const RtcpReceiverLogMessage& redundancy_receiver_log_message,
RtcpReceiverLogMessage* receiver_log_message, RtcpReceiverLogMessage* receiver_log_message,
size_t* remaining_space, size_t* remaining_space,
...@@ -67,7 +65,7 @@ void AddReceiverLog( ...@@ -67,7 +65,7 @@ void AddReceiverLog(
*remaining_space -= kRtcpReceiverFrameLogSize + *remaining_space -= kRtcpReceiverFrameLogSize +
event_log_messages.size() * kRtcpReceiverEventLogSize; event_log_messages.size() * kRtcpReceiverEventLogSize;
++*number_of_frames; ++number_of_frames;
*total_number_of_messages_to_send += event_log_messages.size(); *total_number_of_messages_to_send += event_log_messages.size();
++it; ++it;
} }
...@@ -145,161 +143,139 @@ class NackStringBuilder { ...@@ -145,161 +143,139 @@ class NackStringBuilder {
}; };
} // namespace } // namespace
RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport, RtcpBuilder::RtcpBuilder(uint32 sending_ssrc)
uint32 sending_ssrc) : writer_(NULL, 0),
: ssrc_(sending_ssrc), ssrc_(sending_ssrc),
transport_(outgoing_transport) { ptr_of_length_(NULL) {
} }
RtcpSender::~RtcpSender() {} RtcpBuilder::~RtcpBuilder() {}
void RtcpBuilder::PatchLengthField() {
if (ptr_of_length_) {
// Back-patch the packet length. The client must have taken
// care of proper padding to 32-bit words.
int this_packet_length = (writer_.ptr() - ptr_of_length_ - 2);
DCHECK_EQ(0, this_packet_length % 4)
<< "Packets must be a multiple of 32 bits long";
*ptr_of_length_ = this_packet_length >> 10;
*(ptr_of_length_ + 1) = (this_packet_length >> 2) & 0xFF;
ptr_of_length_ = NULL;
}
}
// Set the 5-bit value in the 1st byte of the header
// and the payload type. Set aside room for the length field,
// and make provision for back-patching it.
void RtcpBuilder::AddRtcpHeader(RtcpPacketFields payload, int format_or_count) {
PatchLengthField();
writer_.WriteU8(0x80 | (format_or_count & 0x1F));
writer_.WriteU8(payload);
ptr_of_length_ = writer_.ptr();
// Initialize length to "clearly illegal".
writer_.WriteU16(0xDEAD);
}
void RtcpBuilder::Start() {
packet_ = new base::RefCountedData<Packet>;
packet_->data.resize(kMaxIpPacketSize);
writer_ = base::BigEndianWriter(
reinterpret_cast<char*>(&(packet_->data[0])), kMaxIpPacketSize);
}
void RtcpSender::SendRtcpFromRtpReceiver( PacketRef RtcpBuilder::Finish() {
PatchLengthField();
packet_->data.resize(kMaxIpPacketSize - writer_.remaining());
writer_ = base::BigEndianWriter(NULL, 0);
PacketRef ret = packet_;
packet_ = NULL;
return ret;
}
PacketRef RtcpBuilder::BuildRtcpFromReceiver(
const RtcpReportBlock* report_block, const RtcpReportBlock* report_block,
const RtcpReceiverReferenceTimeReport* rrtr, const RtcpReceiverReferenceTimeReport* rrtr,
const RtcpCastMessage* cast_message, const RtcpCastMessage* cast_message,
const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events,
base::TimeDelta target_delay) { base::TimeDelta target_delay) {
PacketRef packet(new base::RefCountedData<Packet>); Start();
packet->data.reserve(kMaxIpPacketSize);
if (report_block) if (report_block)
BuildRR(report_block, &packet->data); AddRR(report_block);
if (rrtr) if (rrtr)
BuildRrtr(rrtr, &packet->data); AddRrtr(rrtr);
if (cast_message) if (cast_message)
BuildCast(cast_message, target_delay, &packet->data); AddCast(cast_message, target_delay);
if (rtcp_events) if (rtcp_events)
BuildReceiverLog(*rtcp_events, &packet->data); AddReceiverLog(*rtcp_events);
if (packet->data.empty()) {
NOTREACHED() << "Empty packet.";
return; // Sanity don't send empty packets.
}
transport_->SendRtcpPacket(ssrc_, packet); return Finish();
} }
void RtcpSender::SendRtcpFromRtpSender( PacketRef RtcpBuilder::BuildRtcpFromSender(const RtcpSenderInfo& sender_info) {
const RtcpSenderInfo& sender_info) { Start();
PacketRef packet(new base::RefCountedData<Packet>); AddSR(sender_info);
packet->data.reserve(kMaxIpPacketSize); return Finish();
BuildSR(sender_info, &packet->data);
if (packet->data.empty()) {
NOTREACHED() << "Empty packet.";
return; // Sanity - don't send empty packets.
}
transport_->SendRtcpPacket(ssrc_, packet);
} }
void RtcpSender::BuildRR(const RtcpReportBlock* report_block, void RtcpBuilder::AddRR(const RtcpReportBlock* report_block) {
Packet* packet) const { AddRtcpHeader(kPacketTypeReceiverReport, report_block ? 1 : 0);
size_t start_size = packet->size(); writer_.WriteU32(ssrc_);
DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space";
if (start_size + 32 > kMaxIpPacketSize)
return;
uint16 number_of_rows = (report_block) ? 7 : 1;
packet->resize(start_size + 8);
base::BigEndianWriter big_endian_writer(
reinterpret_cast<char*>(&((*packet)[start_size])), 8);
big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0));
big_endian_writer.WriteU8(kPacketTypeReceiverReport);
big_endian_writer.WriteU16(number_of_rows);
big_endian_writer.WriteU32(ssrc_);
if (report_block) { if (report_block) {
AddReportBlocks(*report_block, packet); // Adds 24 bytes. AddReportBlocks(*report_block); // Adds 24 bytes.
} }
} }
void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block, void RtcpBuilder::AddReportBlocks(const RtcpReportBlock& report_block) {
Packet* packet) const { writer_.WriteU32(report_block.media_ssrc);
size_t start_size = packet->size(); writer_.WriteU8(report_block.fraction_lost);
DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; writer_.WriteU8(report_block.cumulative_lost >> 16);
if (start_size + 24 > kMaxIpPacketSize) writer_.WriteU8(report_block.cumulative_lost >> 8);
return; writer_.WriteU8(report_block.cumulative_lost);
packet->resize(start_size + 24);
base::BigEndianWriter big_endian_writer(
reinterpret_cast<char*>(&((*packet)[start_size])), 24);
big_endian_writer.WriteU32(report_block.media_ssrc);
big_endian_writer.WriteU8(report_block.fraction_lost);
big_endian_writer.WriteU8(report_block.cumulative_lost >> 16);
big_endian_writer.WriteU8(report_block.cumulative_lost >> 8);
big_endian_writer.WriteU8(report_block.cumulative_lost);
// Extended highest seq_no, contain the highest sequence number received. // Extended highest seq_no, contain the highest sequence number received.
big_endian_writer.WriteU32(report_block.extended_high_sequence_number); writer_.WriteU32(report_block.extended_high_sequence_number);
big_endian_writer.WriteU32(report_block.jitter); writer_.WriteU32(report_block.jitter);
// Last SR timestamp; our NTP time when we received the last report. // Last SR timestamp; our NTP time when we received the last report.
// This is the value that we read from the send report packet not when we // This is the value that we read from the send report packet not when we
// received it. // received it.
big_endian_writer.WriteU32(report_block.last_sr); writer_.WriteU32(report_block.last_sr);
// Delay since last received report, time since we received the report. // Delay since last received report, time since we received the report.
big_endian_writer.WriteU32(report_block.delay_since_last_sr); writer_.WriteU32(report_block.delay_since_last_sr);
} }
void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, void RtcpBuilder::AddRrtr(const RtcpReceiverReferenceTimeReport* rrtr) {
Packet* packet) const { AddRtcpHeader(kPacketTypeXr, 0);
size_t start_size = packet->size(); writer_.WriteU32(ssrc_); // Add our own SSRC.
DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; writer_.WriteU8(4); // Add block type.
if (start_size + 20 > kMaxIpPacketSize) writer_.WriteU8(0); // Add reserved.
return; writer_.WriteU16(2); // Block length.
packet->resize(start_size + 20);
base::BigEndianWriter big_endian_writer(
reinterpret_cast<char*>(&((*packet)[start_size])), 20);
big_endian_writer.WriteU8(0x80);
big_endian_writer.WriteU8(kPacketTypeXr);
big_endian_writer.WriteU16(4); // Length.
big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
big_endian_writer.WriteU8(4); // Add block type.
big_endian_writer.WriteU8(0); // Add reserved.
big_endian_writer.WriteU16(2); // Block length.
// Add the media (received RTP) SSRC. // Add the media (received RTP) SSRC.
big_endian_writer.WriteU32(rrtr->ntp_seconds); writer_.WriteU32(rrtr->ntp_seconds);
big_endian_writer.WriteU32(rrtr->ntp_fraction); writer_.WriteU32(rrtr->ntp_fraction);
} }
void RtcpSender::BuildCast(const RtcpCastMessage* cast, void RtcpBuilder::AddCast(const RtcpCastMessage* cast,
base::TimeDelta target_delay, base::TimeDelta target_delay) {
Packet* packet) const { // See RTC 4585 Section 6.4 for application specific feedback messages.
size_t start_size = packet->size(); AddRtcpHeader(kPacketTypePayloadSpecific, 15);
DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; writer_.WriteU32(ssrc_); // Add our own SSRC.
if (start_size + 20 > kMaxIpPacketSize) writer_.WriteU32(cast->media_ssrc); // Remote SSRC.
return; writer_.WriteU32(kCast);
writer_.WriteU8(static_cast<uint8>(cast->ack_frame_id));
packet->resize(start_size + 20); uint8* cast_loss_field_pos = reinterpret_cast<uint8*>(writer_.ptr());
writer_.WriteU8(0); // Overwritten with number_of_loss_fields.
base::BigEndianWriter big_endian_writer(
reinterpret_cast<char*>(&((*packet)[start_size])), 20);
uint8 FMT = 15; // Application layer feedback.
big_endian_writer.WriteU8(0x80 + FMT);
big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
big_endian_writer.WriteU8(0);
size_t cast_size_pos = start_size + 3; // Save length position.
big_endian_writer.WriteU8(4);
big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
big_endian_writer.WriteU32(cast->media_ssrc); // Remote SSRC.
big_endian_writer.WriteU32(kCast);
big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id));
size_t cast_loss_field_pos = start_size + 17; // Save loss field position.
big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields.
DCHECK_LE(target_delay.InMilliseconds(), DCHECK_LE(target_delay.InMilliseconds(),
std::numeric_limits<uint16_t>::max()); std::numeric_limits<uint16_t>::max());
big_endian_writer.WriteU16(target_delay.InMilliseconds()); writer_.WriteU16(target_delay.InMilliseconds());
size_t number_of_loss_fields = 0; size_t number_of_loss_fields = 0;
size_t max_number_of_loss_fields = std::min<size_t>( size_t max_number_of_loss_fields = std::min<size_t>(
kRtcpMaxCastLossFields, (kMaxIpPacketSize - packet->size()) / 4); kRtcpMaxCastLossFields, writer_.remaining() / 4);
MissingFramesAndPacketsMap::const_iterator frame_it = MissingFramesAndPacketsMap::const_iterator frame_it =
cast->missing_frames_and_packets.begin(); cast->missing_frames_and_packets.begin();
...@@ -312,28 +288,18 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast, ...@@ -312,28 +288,18 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast,
// Iterate through all frames with missing packets. // Iterate through all frames with missing packets.
if (frame_it->second.empty()) { if (frame_it->second.empty()) {
// Special case all packets in a frame is missing. // Special case all packets in a frame is missing.
start_size = packet->size(); writer_.WriteU8(static_cast<uint8>(frame_it->first));
packet->resize(start_size + 4); writer_.WriteU16(kRtcpCastAllPacketsLost);
base::BigEndianWriter big_endian_nack_writer( writer_.WriteU8(0);
reinterpret_cast<char*>(&((*packet)[start_size])), 4);
big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first));
big_endian_nack_writer.WriteU16(kRtcpCastAllPacketsLost);
big_endian_nack_writer.WriteU8(0);
nack_string_builder.PushPacket(kRtcpCastAllPacketsLost); nack_string_builder.PushPacket(kRtcpCastAllPacketsLost);
++number_of_loss_fields; ++number_of_loss_fields;
} else { } else {
PacketIdSet::const_iterator packet_it = frame_it->second.begin(); PacketIdSet::const_iterator packet_it = frame_it->second.begin();
while (packet_it != frame_it->second.end()) { while (packet_it != frame_it->second.end()) {
uint16 packet_id = *packet_it; uint16 packet_id = *packet_it;
start_size = packet->size();
packet->resize(start_size + 4);
base::BigEndianWriter big_endian_nack_writer(
reinterpret_cast<char*>(&((*packet)[start_size])), 4);
// Write frame and packet id to buffer before calculating bitmask. // Write frame and packet id to buffer before calculating bitmask.
big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); writer_.WriteU8(static_cast<uint8>(frame_it->first));
big_endian_nack_writer.WriteU16(packet_id); writer_.WriteU16(packet_id);
nack_string_builder.PushPacket(packet_id); nack_string_builder.PushPacket(packet_id);
uint8 bitmask = 0; uint8 bitmask = 0;
...@@ -348,7 +314,7 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast, ...@@ -348,7 +314,7 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast,
break; break;
} }
} }
big_endian_nack_writer.WriteU8(bitmask); writer_.WriteU8(bitmask);
++number_of_loss_fields; ++number_of_loss_fields;
} }
} }
...@@ -358,34 +324,17 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast, ...@@ -358,34 +324,17 @@ void RtcpSender::BuildCast(const RtcpCastMessage* cast,
<< ", ACK: " << cast->ack_frame_id << ", ACK: " << cast->ack_frame_id
<< ", NACK: " << nack_string_builder.GetString(); << ", NACK: " << nack_string_builder.GetString();
DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields);
(*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields); *cast_loss_field_pos = static_cast<uint8>(number_of_loss_fields);
(*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields);
} }
void RtcpSender::BuildSR(const RtcpSenderInfo& sender_info, void RtcpBuilder::AddSR(const RtcpSenderInfo& sender_info) {
Packet* packet) const { AddRtcpHeader(kPacketTypeSenderReport, 0);
// Sender report. writer_.WriteU32(ssrc_);
size_t start_size = packet->size(); writer_.WriteU32(sender_info.ntp_seconds);
if (start_size + 52 > kMaxIpPacketSize) { writer_.WriteU32(sender_info.ntp_fraction);
DLOG(FATAL) << "Not enough buffer space"; writer_.WriteU32(sender_info.rtp_timestamp);
return; writer_.WriteU32(sender_info.send_packet_count);
} writer_.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
uint16 number_of_rows = 6;
packet->resize(start_size + 28);
base::BigEndianWriter big_endian_writer(
reinterpret_cast<char*>(&((*packet)[start_size])), 28);
big_endian_writer.WriteU8(0x80);
big_endian_writer.WriteU8(kPacketTypeSenderReport);
big_endian_writer.WriteU16(number_of_rows);
big_endian_writer.WriteU32(ssrc_);
big_endian_writer.WriteU32(sender_info.ntp_seconds);
big_endian_writer.WriteU32(sender_info.ntp_fraction);
big_endian_writer.WriteU32(sender_info.rtp_timestamp);
big_endian_writer.WriteU32(sender_info.send_packet_count);
big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
return;
} }
/* /*
...@@ -405,58 +354,31 @@ void RtcpSender::BuildSR(const RtcpSenderInfo& sender_info, ...@@ -405,58 +354,31 @@ void RtcpSender::BuildSR(const RtcpSenderInfo& sender_info,
| delay since last RR (DLRR) | | delay since last RR (DLRR) |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*/ */
void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock& dlrr, void RtcpBuilder::AddDlrrRb(const RtcpDlrrReportBlock& dlrr) {
Packet* packet) const { AddRtcpHeader(kPacketTypeXr, 0);
size_t start_size = packet->size(); writer_.WriteU32(ssrc_); // Add our own SSRC.
if (start_size + 24 > kMaxIpPacketSize) { writer_.WriteU8(5); // Add block type.
DLOG(FATAL) << "Not enough buffer space"; writer_.WriteU8(0); // Add reserved.
return; writer_.WriteU16(3); // Block length.
} writer_.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
writer_.WriteU32(dlrr.last_rr);
packet->resize(start_size + 24); writer_.WriteU32(dlrr.delay_since_last_rr);
base::BigEndianWriter big_endian_writer(
reinterpret_cast<char*>(&((*packet)[start_size])), 24);
big_endian_writer.WriteU8(0x80);
big_endian_writer.WriteU8(kPacketTypeXr);
big_endian_writer.WriteU16(5); // Length.
big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
big_endian_writer.WriteU8(5); // Add block type.
big_endian_writer.WriteU8(0); // Add reserved.
big_endian_writer.WriteU16(3); // Block length.
big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
big_endian_writer.WriteU32(dlrr.last_rr);
big_endian_writer.WriteU32(dlrr.delay_since_last_rr);
return;
} }
void RtcpSender::BuildReceiverLog( void RtcpBuilder::AddReceiverLog(
const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events, const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events) {
Packet* packet) {
const size_t packet_start_size = packet->size();
size_t number_of_frames = 0;
size_t total_number_of_messages_to_send = 0; size_t total_number_of_messages_to_send = 0;
size_t rtcp_log_size = 0;
RtcpReceiverLogMessage receiver_log_message; RtcpReceiverLogMessage receiver_log_message;
if (!BuildRtcpReceiverLogMessage(rtcp_events, if (!GetRtcpReceiverLogMessage(rtcp_events,
packet_start_size, &receiver_log_message,
&receiver_log_message, &total_number_of_messages_to_send)) {
&number_of_frames,
&total_number_of_messages_to_send,
&rtcp_log_size)) {
return; return;
} }
packet->resize(packet_start_size + rtcp_log_size);
base::BigEndianWriter big_endian_writer( AddRtcpHeader(kPacketTypeApplicationDefined, kReceiverLogSubtype);
reinterpret_cast<char*>(&((*packet)[packet_start_size])), rtcp_log_size); writer_.WriteU32(ssrc_); // Add our own SSRC.
big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype); writer_.WriteU32(kCast);
big_endian_writer.WriteU8(kPacketTypeApplicationDefined);
big_endian_writer.WriteU16(static_cast<uint16>(
2 + 2 * number_of_frames + total_number_of_messages_to_send));
big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
big_endian_writer.WriteU32(kCast);
while (!receiver_log_message.empty() && while (!receiver_log_message.empty() &&
total_number_of_messages_to_send > 0) { total_number_of_messages_to_send > 0) {
...@@ -464,7 +386,7 @@ void RtcpSender::BuildReceiverLog( ...@@ -464,7 +386,7 @@ void RtcpSender::BuildReceiverLog(
receiver_log_message.front()); receiver_log_message.front());
// Add our frame header. // Add our frame header.
big_endian_writer.WriteU32(frame_log_messages.rtp_timestamp_); writer_.WriteU32(frame_log_messages.rtp_timestamp_);
size_t messages_in_frame = frame_log_messages.event_log_messages_.size(); size_t messages_in_frame = frame_log_messages.event_log_messages_.size();
if (messages_in_frame > total_number_of_messages_to_send) { if (messages_in_frame > total_number_of_messages_to_send) {
// We are running out of space. // We are running out of space.
...@@ -474,15 +396,15 @@ void RtcpSender::BuildReceiverLog( ...@@ -474,15 +396,15 @@ void RtcpSender::BuildReceiverLog(
total_number_of_messages_to_send -= messages_in_frame; total_number_of_messages_to_send -= messages_in_frame;
// On the wire format is number of messages - 1. // On the wire format is number of messages - 1.
big_endian_writer.WriteU8(static_cast<uint8>(messages_in_frame - 1)); writer_.WriteU8(static_cast<uint8>(messages_in_frame - 1));
base::TimeTicks event_timestamp_base = base::TimeTicks event_timestamp_base =
frame_log_messages.event_log_messages_.front().event_timestamp; frame_log_messages.event_log_messages_.front().event_timestamp;
uint32 base_timestamp_ms = uint32 base_timestamp_ms =
(event_timestamp_base - base::TimeTicks()).InMilliseconds(); (event_timestamp_base - base::TimeTicks()).InMilliseconds();
big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms >> 16)); writer_.WriteU8(static_cast<uint8>(base_timestamp_ms >> 16));
big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms >> 8)); writer_.WriteU8(static_cast<uint8>(base_timestamp_ms >> 8));
big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms)); writer_.WriteU8(static_cast<uint8>(base_timestamp_ms));
while (!frame_log_messages.event_log_messages_.empty() && while (!frame_log_messages.event_log_messages_.empty() &&
messages_in_frame > 0) { messages_in_frame > 0) {
...@@ -496,13 +418,13 @@ void RtcpSender::BuildReceiverLog( ...@@ -496,13 +418,13 @@ void RtcpSender::BuildReceiverLog(
case FRAME_ACK_SENT: case FRAME_ACK_SENT:
case FRAME_PLAYOUT: case FRAME_PLAYOUT:
case FRAME_DECODED: case FRAME_DECODED:
big_endian_writer.WriteU16( writer_.WriteU16(
static_cast<uint16>(event_message.delay_delta.InMilliseconds())); static_cast<uint16>(event_message.delay_delta.InMilliseconds()));
big_endian_writer.WriteU16(event_type_and_timestamp_delta); writer_.WriteU16(event_type_and_timestamp_delta);
break; break;
case PACKET_RECEIVED: case PACKET_RECEIVED:
big_endian_writer.WriteU16(event_message.packet_id); writer_.WriteU16(event_message.packet_id);
big_endian_writer.WriteU16(event_type_and_timestamp_delta); writer_.WriteU16(event_type_and_timestamp_delta);
break; break;
default: default:
NOTREACHED(); NOTREACHED();
...@@ -518,15 +440,13 @@ void RtcpSender::BuildReceiverLog( ...@@ -518,15 +440,13 @@ void RtcpSender::BuildReceiverLog(
DCHECK_EQ(total_number_of_messages_to_send, 0u); DCHECK_EQ(total_number_of_messages_to_send, 0u);
} }
bool RtcpSender::BuildRtcpReceiverLogMessage( bool RtcpBuilder::GetRtcpReceiverLogMessage(
const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events, const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events,
size_t start_size,
RtcpReceiverLogMessage* receiver_log_message, RtcpReceiverLogMessage* receiver_log_message,
size_t* number_of_frames, size_t* total_number_of_messages_to_send) {
size_t* total_number_of_messages_to_send, size_t number_of_frames = 0;
size_t* rtcp_log_size) {
size_t remaining_space = size_t remaining_space =
std::min(kMaxReceiverLogBytes, kMaxIpPacketSize - start_size); std::min<size_t>(kMaxReceiverLogBytes, writer_.remaining());
if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize + if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize +
kRtcpReceiverEventLogSize) { kRtcpReceiverEventLogSize) {
return false; return false;
...@@ -548,7 +468,7 @@ bool RtcpSender::BuildRtcpReceiverLogMessage( ...@@ -548,7 +468,7 @@ bool RtcpSender::BuildRtcpReceiverLogMessage(
const RtpTimestamp rtp_timestamp = rit->first; const RtpTimestamp rtp_timestamp = rit->first;
RtcpReceiverFrameLogMessage frame_log(rtp_timestamp); RtcpReceiverFrameLogMessage frame_log(rtp_timestamp);
remaining_space -= kRtcpReceiverFrameLogSize; remaining_space -= kRtcpReceiverFrameLogSize;
++*number_of_frames; ++number_of_frames;
// Get all events of a single frame. // Get all events of a single frame.
sorted_log_messages.clear(); sorted_log_messages.clear();
...@@ -598,20 +518,20 @@ bool RtcpSender::BuildRtcpReceiverLogMessage( ...@@ -598,20 +518,20 @@ bool RtcpSender::BuildRtcpReceiverLogMessage(
// unlikely there will be a match anyway. // unlikely there will be a match anyway.
if (rtcp_events_history_.size() > kFirstRedundancyOffset) { if (rtcp_events_history_.size() > kFirstRedundancyOffset) {
// Add first redundnacy messages, if enough space remaining // Add first redundnacy messages, if enough space remaining
AddReceiverLog(rtcp_events_history_[kFirstRedundancyOffset], AddReceiverLogEntries(rtcp_events_history_[kFirstRedundancyOffset],
receiver_log_message, receiver_log_message,
&remaining_space, &remaining_space,
number_of_frames, &number_of_frames,
total_number_of_messages_to_send); total_number_of_messages_to_send);
} }
if (rtcp_events_history_.size() > kSecondRedundancyOffset) { if (rtcp_events_history_.size() > kSecondRedundancyOffset) {
// Add second redundancy messages, if enough space remaining // Add second redundancy messages, if enough space remaining
AddReceiverLog(rtcp_events_history_[kSecondRedundancyOffset], AddReceiverLogEntries(rtcp_events_history_[kSecondRedundancyOffset],
receiver_log_message, receiver_log_message,
&remaining_space, &remaining_space,
number_of_frames, &number_of_frames,
total_number_of_messages_to_send); total_number_of_messages_to_send);
} }
if (rtcp_events_history_.size() > kReceiveLogMessageHistorySize) { if (rtcp_events_history_.size() > kReceiveLogMessageHistorySize) {
...@@ -620,16 +540,9 @@ bool RtcpSender::BuildRtcpReceiverLogMessage( ...@@ -620,16 +540,9 @@ bool RtcpSender::BuildRtcpReceiverLogMessage(
DCHECK_LE(rtcp_events_history_.size(), kReceiveLogMessageHistorySize); DCHECK_LE(rtcp_events_history_.size(), kReceiveLogMessageHistorySize);
*rtcp_log_size = VLOG(3) << "number of frames: " << number_of_frames;
kRtcpCastLogHeaderSize + *number_of_frames * kRtcpReceiverFrameLogSize +
*total_number_of_messages_to_send * kRtcpReceiverEventLogSize;
DCHECK_GE(kMaxIpPacketSize, start_size + *rtcp_log_size)
<< "Not enough buffer space.";
VLOG(3) << "number of frames: " << *number_of_frames;
VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send;
VLOG(3) << "rtcp log size: " << *rtcp_log_size; return number_of_frames > 0;
return *number_of_frames > 0;
} }
} // namespace cast } // namespace cast
......
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef MEDIA_CAST_NET_RTCP_RTCP_SENDER_H_ #ifndef MEDIA_CAST_NET_RTCP_RTCP_BUILDER_H_
#define MEDIA_CAST_NET_RTCP_RTCP_SENDER_H_ #define MEDIA_CAST_NET_RTCP_RTCP_BUILDER_H_
#include <deque> #include <deque>
#include <list> #include <list>
#include <string> #include <string>
#include "base/big_endian.h"
#include "media/cast/cast_config.h" #include "media/cast/cast_config.h"
#include "media/cast/cast_defines.h" #include "media/cast/cast_defines.h"
#include "media/cast/net/cast_transport_defines.h" #include "media/cast/net/cast_transport_defines.h"
...@@ -38,67 +39,49 @@ COMPILE_ASSERT(kSecondRedundancyOffset > ...@@ -38,67 +39,49 @@ COMPILE_ASSERT(kSecondRedundancyOffset >
kReceiveLogMessageHistorySize, kReceiveLogMessageHistorySize,
redundancy_offset_out_of_range); redundancy_offset_out_of_range);
class PacedPacketSender;
// TODO(hclam): This should be renamed to RtcpPacketBuilder. The function class RtcpBuilder {
// of this class is to only to build a RTCP packet but not to send it.
class RtcpSender {
public: public:
RtcpSender(PacedPacketSender* outgoing_transport, explicit RtcpBuilder(uint32 sending_ssrc);
uint32 sending_ssrc); ~RtcpBuilder();
~RtcpSender();
// TODO(hclam): This method should be to build a packet instead of PacketRef BuildRtcpFromReceiver(
// sending it.
void SendRtcpFromRtpReceiver(
const RtcpReportBlock* report_block, const RtcpReportBlock* report_block,
const RtcpReceiverReferenceTimeReport* rrtr, const RtcpReceiverReferenceTimeReport* rrtr,
const RtcpCastMessage* cast_message, const RtcpCastMessage* cast_message,
const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events,
base::TimeDelta target_delay); base::TimeDelta target_delay);
// TODO(hclam): This method should be to build a packet instead of PacketRef BuildRtcpFromSender(const RtcpSenderInfo& sender_info);
// sending it.
void SendRtcpFromRtpSender(const RtcpSenderInfo& sender_info);
private: private:
void BuildRR(const RtcpReportBlock* report_block, void AddRtcpHeader(RtcpPacketFields payload, int format_or_count);
Packet* packet) const; void PatchLengthField();
void AddRR(const RtcpReportBlock* report_block);
void AddReportBlocks(const RtcpReportBlock& report_block, void AddReportBlocks(const RtcpReportBlock& report_block);
Packet* packet) const; void AddRrtr(const RtcpReceiverReferenceTimeReport* rrtr);
void AddCast(const RtcpCastMessage* cast_message,
void BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, base::TimeDelta target_delay);
Packet* packet) const; void AddSR(const RtcpSenderInfo& sender_info);
void AddDlrrRb(const RtcpDlrrReportBlock& dlrr);
void BuildCast(const RtcpCastMessage* cast_message, void AddReceiverLog(
base::TimeDelta target_delay, const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events);
Packet* packet) const;
bool GetRtcpReceiverLogMessage(
void BuildSR(const RtcpSenderInfo& sender_info, Packet* packet) const;
void BuildDlrrRb(const RtcpDlrrReportBlock& dlrr, Packet* packet) const;
void BuildReceiverLog(
const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events, const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events,
Packet* packet);
bool BuildRtcpReceiverLogMessage(
const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events,
size_t start_size,
RtcpReceiverLogMessage* receiver_log_message, RtcpReceiverLogMessage* receiver_log_message,
size_t* number_of_frames, size_t* total_number_of_messages_to_send);
size_t* total_number_of_messages_to_send,
size_t* rtcp_log_size);
const uint32 ssrc_; void Start();
PacketRef Finish();
// Not owned by this class.
PacedPacketSender* const transport_;
base::BigEndianWriter writer_;
const uint32 ssrc_;
char* ptr_of_length_;
PacketRef packet_;
std::deque<RtcpReceiverLogMessage> rtcp_events_history_; std::deque<RtcpReceiverLogMessage> rtcp_events_history_;
DISALLOW_COPY_AND_ASSIGN(RtcpSender); DISALLOW_COPY_AND_ASSIGN(RtcpBuilder);
}; };
} // namespace cast } // namespace cast
......
...@@ -9,10 +9,9 @@ ...@@ -9,10 +9,9 @@
#include "media/cast/net/cast_transport_defines.h" #include "media/cast/net/cast_transport_defines.h"
#include "media/cast/net/pacing/paced_sender.h" #include "media/cast/net/pacing/paced_sender.h"
#include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h" #include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h"
#include "media/cast/net/rtcp/rtcp_sender.h" #include "media/cast/net/rtcp/rtcp_builder.h"
#include "media/cast/net/rtcp/rtcp_utility.h" #include "media/cast/net/rtcp/rtcp_utility.h"
#include "media/cast/net/rtcp/test_rtcp_packet_builder.h" #include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
#include "media/cast/test/fake_single_thread_task_runner.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
namespace media { namespace media {
...@@ -40,93 +39,50 @@ RtcpReportBlock GetReportBlock() { ...@@ -40,93 +39,50 @@ RtcpReportBlock GetReportBlock() {
} // namespace } // namespace
class TestRtcpTransport : public PacedPacketSender {
public:
TestRtcpTransport() : packet_count_(0) {}
virtual bool SendRtcpPacket(uint32 ssrc,
PacketRef packet) OVERRIDE {
EXPECT_EQ(expected_packet_.size(), packet->data.size());
if (expected_packet_.size() != packet->data.size())
return false;
EXPECT_EQ(0, memcmp(&expected_packet_[0],
&packet->data[0],
packet->data.size()));
packet_count_++;
return true;
}
virtual bool SendPackets(
const SendPacketVector& packets) OVERRIDE {
return false;
}
virtual bool ResendPackets(
const SendPacketVector& packets,
const DedupInfo& dedup_info) OVERRIDE {
return false;
}
virtual void CancelSendingPacket(
const PacketKey& packet_key) OVERRIDE {
}
void SetExpectedRtcpPacket(scoped_ptr<Packet> packet) { class RtcpBuilderTest : public ::testing::Test {
expected_packet_.swap(*packet); protected:
RtcpBuilderTest()
: rtcp_builder_(new RtcpBuilder(kSendingSsrc)) {}
void ExpectPacketEQ(scoped_ptr<Packet> golden_packet,
PacketRef packet) {
EXPECT_EQ(golden_packet->size(), packet->data.size());
if (golden_packet->size() == packet->data.size()) {
for (size_t x = 0; x < golden_packet->size(); x++) {
EXPECT_EQ((*golden_packet)[x], packet->data[x]);
if ((*golden_packet)[x] != packet->data[x])
break;
}
}
} }
int packet_count() const { return packet_count_; } scoped_ptr<RtcpBuilder> rtcp_builder_;
private:
Packet expected_packet_;
int packet_count_;
DISALLOW_COPY_AND_ASSIGN(TestRtcpTransport); DISALLOW_COPY_AND_ASSIGN(RtcpBuilderTest);
};
class RtcpSenderTest : public ::testing::Test {
protected:
RtcpSenderTest()
: testing_clock_(new base::SimpleTestTickClock()),
task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)),
cast_environment_(new CastEnvironment(
scoped_ptr<base::TickClock>(testing_clock_).Pass(),
task_runner_,
task_runner_,
task_runner_)),
rtcp_sender_(new RtcpSender(&test_transport_, kSendingSsrc)) {}
base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment.
TestRtcpTransport test_transport_;
scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
scoped_refptr<CastEnvironment> cast_environment_;
scoped_ptr<RtcpSender> rtcp_sender_;
DISALLOW_COPY_AND_ASSIGN(RtcpSenderTest);
}; };
TEST_F(RtcpSenderTest, RtcpReceiverReport) { TEST_F(RtcpBuilderTest, RtcpReceiverReport) {
// Receiver report with report block. // Receiver report with report block.
TestRtcpPacketBuilder p2; TestRtcpPacketBuilder p2;
p2.AddRr(kSendingSsrc, 1); p2.AddRr(kSendingSsrc, 1);
p2.AddRb(kMediaSsrc); p2.AddRb(kMediaSsrc);
test_transport_.SetExpectedRtcpPacket(p2.GetPacket().Pass());
RtcpReportBlock report_block = GetReportBlock(); RtcpReportBlock report_block = GetReportBlock();
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(
&report_block, NULL, NULL, NULL, kDefaultDelay); p2.GetPacket().Pass(),
rtcp_builder_->BuildRtcpFromReceiver(
EXPECT_EQ(1, test_transport_.packet_count()); &report_block, NULL, NULL, NULL, kDefaultDelay));
} }
TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtr) { TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtr) {
// Receiver report with report block. // Receiver report with report block.
TestRtcpPacketBuilder p; TestRtcpPacketBuilder p;
p.AddRr(kSendingSsrc, 1); p.AddRr(kSendingSsrc, 1);
p.AddRb(kMediaSsrc); p.AddRb(kMediaSsrc);
p.AddXrHeader(kSendingSsrc); p.AddXrHeader(kSendingSsrc);
p.AddXrRrtrBlock(); p.AddXrRrtrBlock();
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
RtcpReportBlock report_block = GetReportBlock(); RtcpReportBlock report_block = GetReportBlock();
...@@ -134,23 +90,21 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtr) { ...@@ -134,23 +90,21 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtr) {
rrtr.ntp_seconds = kNtpHigh; rrtr.ntp_seconds = kNtpHigh;
rrtr.ntp_fraction = kNtpLow; rrtr.ntp_fraction = kNtpLow;
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(p.GetPacket().Pass(),
&report_block, rtcp_builder_->BuildRtcpFromReceiver(
&rrtr, &report_block,
NULL, &rrtr,
NULL, NULL,
kDefaultDelay); NULL,
kDefaultDelay));
EXPECT_EQ(1, test_transport_.packet_count());
} }
TEST_F(RtcpSenderTest, RtcpReceiverReportWithCast) { TEST_F(RtcpBuilderTest, RtcpReceiverReportWithCast) {
// Receiver report with report block. // Receiver report with report block.
TestRtcpPacketBuilder p; TestRtcpPacketBuilder p;
p.AddRr(kSendingSsrc, 1); p.AddRr(kSendingSsrc, 1);
p.AddRb(kMediaSsrc); p.AddRb(kMediaSsrc);
p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay); p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
RtcpReportBlock report_block = GetReportBlock(); RtcpReportBlock report_block = GetReportBlock();
...@@ -165,24 +119,22 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithCast) { ...@@ -165,24 +119,22 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithCast) {
cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] = cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] =
missing_packets; missing_packets;
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(p.GetPacket().Pass(),
&report_block, rtcp_builder_->BuildRtcpFromReceiver(
NULL, &report_block,
&cast_message, NULL,
NULL, &cast_message,
kDefaultDelay); NULL,
kDefaultDelay));
EXPECT_EQ(1, test_transport_.packet_count());
} }
TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtraAndCastMessage) { TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtraAndCastMessage) {
TestRtcpPacketBuilder p; TestRtcpPacketBuilder p;
p.AddRr(kSendingSsrc, 1); p.AddRr(kSendingSsrc, 1);
p.AddRb(kMediaSsrc); p.AddRb(kMediaSsrc);
p.AddXrHeader(kSendingSsrc); p.AddXrHeader(kSendingSsrc);
p.AddXrRrtrBlock(); p.AddXrRrtrBlock();
p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay); p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
RtcpReportBlock report_block = GetReportBlock(); RtcpReportBlock report_block = GetReportBlock();
...@@ -201,17 +153,16 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtraAndCastMessage) { ...@@ -201,17 +153,16 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtraAndCastMessage) {
cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] = cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] =
missing_packets; missing_packets;
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(p.GetPacket().Pass(),
&report_block, rtcp_builder_->BuildRtcpFromReceiver(
&rrtr, &report_block,
&cast_message, &rrtr,
NULL, &cast_message,
kDefaultDelay); NULL,
kDefaultDelay));
EXPECT_EQ(1, test_transport_.packet_count());
} }
TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) { TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) {
static const uint32 kTimeBaseMs = 12345678; static const uint32 kTimeBaseMs = 12345678;
static const uint32 kTimeDelayMs = 10; static const uint32 kTimeDelayMs = 10;
...@@ -221,7 +172,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) { ...@@ -221,7 +172,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) {
p.AddXrHeader(kSendingSsrc); p.AddXrHeader(kSendingSsrc);
p.AddXrRrtrBlock(); p.AddXrRrtrBlock();
p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay); p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
RtcpReportBlock report_block = GetReportBlock(); RtcpReportBlock report_block = GetReportBlock();
...@@ -243,12 +193,13 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) { ...@@ -243,12 +193,13 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) {
ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(p.GetPacket().Pass(),
&report_block, rtcp_builder_->BuildRtcpFromReceiver(
&rrtr, &report_block,
&cast_message, &rrtr,
&rtcp_events, &cast_message,
kDefaultDelay); &rtcp_events,
kDefaultDelay));
base::SimpleTestTickClock testing_clock; base::SimpleTestTickClock testing_clock;
testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs)); testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs));
...@@ -258,8 +209,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) { ...@@ -258,8 +209,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) {
p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0); p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
p.AddReceiverEventLog(kLostPacketId1, PACKET_RECEIVED, kTimeDelayMs); p.AddReceiverEventLog(kLostPacketId1, PACKET_RECEIVED, kTimeDelayMs);
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
FrameEvent frame_event; FrameEvent frame_event;
frame_event.rtp_timestamp = kRtpTimestamp; frame_event.rtp_timestamp = kRtpTimestamp;
frame_event.type = FRAME_ACK_SENT; frame_event.type = FRAME_ACK_SENT;
...@@ -278,17 +227,17 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) { ...@@ -278,17 +227,17 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) {
event_subscriber.GetRtcpEventsAndReset(&rtcp_events); event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
EXPECT_EQ(2u, rtcp_events.size()); EXPECT_EQ(2u, rtcp_events.size());
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(
&report_block, p.GetPacket().Pass(),
&rrtr, rtcp_builder_->BuildRtcpFromReceiver(
&cast_message, &report_block,
&rtcp_events, &rrtr,
kDefaultDelay); &cast_message,
&rtcp_events,
EXPECT_EQ(2, test_transport_.packet_count()); kDefaultDelay));
} }
TEST_F(RtcpSenderTest, RtcpReceiverReportWithOversizedFrameLog) { TEST_F(RtcpBuilderTest, RtcpReceiverReportWithOversizedFrameLog) {
static const uint32 kTimeBaseMs = 12345678; static const uint32 kTimeBaseMs = 12345678;
static const uint32 kTimeDelayMs = 10; static const uint32 kTimeDelayMs = 10;
...@@ -320,7 +269,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithOversizedFrameLog) { ...@@ -320,7 +269,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithOversizedFrameLog) {
static_cast<uint16>(kTimeDelayMs * i)); static_cast<uint16>(kTimeDelayMs * i));
} }
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
FrameEvent frame_event; FrameEvent frame_event;
...@@ -344,17 +292,16 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithOversizedFrameLog) { ...@@ -344,17 +292,16 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithOversizedFrameLog) {
ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
event_subscriber.GetRtcpEventsAndReset(&rtcp_events); event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(p.GetPacket().Pass(),
&report_block, rtcp_builder_->BuildRtcpFromReceiver(
NULL, &report_block,
NULL, NULL,
&rtcp_events, NULL,
kDefaultDelay); &rtcp_events,
kDefaultDelay));
EXPECT_EQ(1, test_transport_.packet_count());
} }
TEST_F(RtcpSenderTest, RtcpReceiverReportWithTooManyLogFrames) { TEST_F(RtcpBuilderTest, RtcpReceiverReportWithTooManyLogFrames) {
static const uint32 kTimeBaseMs = 12345678; static const uint32 kTimeBaseMs = 12345678;
static const uint32 kTimeDelayMs = 10; static const uint32 kTimeDelayMs = 10;
...@@ -382,7 +329,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithTooManyLogFrames) { ...@@ -382,7 +329,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithTooManyLogFrames) {
p.AddReceiverFrameLog(kRtpTimestamp + i, 1, kTimeBaseMs + i * kTimeDelayMs); p.AddReceiverFrameLog(kRtpTimestamp + i, 1, kTimeBaseMs + i * kTimeDelayMs);
p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0); p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
} }
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
...@@ -399,17 +345,16 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithTooManyLogFrames) { ...@@ -399,17 +345,16 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithTooManyLogFrames) {
ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
event_subscriber.GetRtcpEventsAndReset(&rtcp_events); event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(p.GetPacket().Pass(),
&report_block, rtcp_builder_->BuildRtcpFromReceiver(
NULL, &report_block,
NULL, NULL,
&rtcp_events, NULL,
kDefaultDelay); &rtcp_events,
kDefaultDelay));
EXPECT_EQ(1, test_transport_.packet_count());
} }
TEST_F(RtcpSenderTest, RtcpReceiverReportWithOldLogFrames) { TEST_F(RtcpBuilderTest, RtcpReceiverReportWithOldLogFrames) {
static const uint32 kTimeBaseMs = 12345678; static const uint32 kTimeBaseMs = 12345678;
TestRtcpPacketBuilder p; TestRtcpPacketBuilder p;
...@@ -431,7 +376,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithOldLogFrames) { ...@@ -431,7 +376,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithOldLogFrames) {
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
p.AddReceiverEventLog(0, FRAME_ACK_SENT, i * kTimeBetweenEventsMs); p.AddReceiverEventLog(0, FRAME_ACK_SENT, i * kTimeBetweenEventsMs);
} }
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
for (int i = 0; i < 11; ++i) { for (int i = 0; i < 11; ++i) {
...@@ -448,17 +392,16 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithOldLogFrames) { ...@@ -448,17 +392,16 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportWithOldLogFrames) {
ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
event_subscriber.GetRtcpEventsAndReset(&rtcp_events); event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(p.GetPacket().Pass(),
&report_block, rtcp_builder_->BuildRtcpFromReceiver(
NULL, &report_block,
NULL, NULL,
&rtcp_events, NULL,
kDefaultDelay); &rtcp_events,
kDefaultDelay));
EXPECT_EQ(1, test_transport_.packet_count());
} }
TEST_F(RtcpSenderTest, RtcpReceiverReportRedundancy) { TEST_F(RtcpBuilderTest, RtcpReceiverReportRedundancy) {
uint32 time_base_ms = 12345678; uint32 time_base_ms = 12345678;
int kTimeBetweenEventsMs = 10; int kTimeBetweenEventsMs = 10;
...@@ -493,8 +436,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportRedundancy) { ...@@ -493,8 +436,6 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportRedundancy) {
p.AddReceiverFrameLog(kRtpTimestamp, 1, time_base_ms); p.AddReceiverFrameLog(kRtpTimestamp, 1, time_base_ms);
p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0); p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
FrameEvent frame_event; FrameEvent frame_event;
frame_event.rtp_timestamp = kRtpTimestamp; frame_event.rtp_timestamp = kRtpTimestamp;
frame_event.type = FRAME_ACK_SENT; frame_event.type = FRAME_ACK_SENT;
...@@ -505,22 +446,21 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportRedundancy) { ...@@ -505,22 +446,21 @@ TEST_F(RtcpSenderTest, RtcpReceiverReportRedundancy) {
ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
event_subscriber.GetRtcpEventsAndReset(&rtcp_events); event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
rtcp_sender_->SendRtcpFromRtpReceiver( ExpectPacketEQ(p.GetPacket().Pass(),
&report_block, rtcp_builder_->BuildRtcpFromReceiver(
NULL, &report_block,
NULL, NULL,
&rtcp_events, NULL,
kDefaultDelay); &rtcp_events,
kDefaultDelay));
testing_clock.Advance( testing_clock.Advance(
base::TimeDelta::FromMilliseconds(kTimeBetweenEventsMs)); base::TimeDelta::FromMilliseconds(kTimeBetweenEventsMs));
time_base_ms += kTimeBetweenEventsMs; time_base_ms += kTimeBetweenEventsMs;
} }
EXPECT_EQ(static_cast<int>(packet_count), test_transport_.packet_count());
} }
TEST_F(RtcpSenderTest, RtcpSenderReport) { TEST_F(RtcpBuilderTest, RtcpSenderReport) {
RtcpSenderInfo sender_info; RtcpSenderInfo sender_info;
sender_info.ntp_seconds = kNtpHigh; sender_info.ntp_seconds = kNtpHigh;
sender_info.ntp_fraction = kNtpLow; sender_info.ntp_fraction = kNtpLow;
...@@ -531,11 +471,9 @@ TEST_F(RtcpSenderTest, RtcpSenderReport) { ...@@ -531,11 +471,9 @@ TEST_F(RtcpSenderTest, RtcpSenderReport) {
// Sender report. // Sender report.
TestRtcpPacketBuilder p; TestRtcpPacketBuilder p;
p.AddSr(kSendingSsrc, 0); p.AddSr(kSendingSsrc, 0);
test_transport_.SetExpectedRtcpPacket(p.GetPacket().Pass());
rtcp_sender_->SendRtcpFromRtpSender(sender_info);
EXPECT_EQ(1, test_transport_.packet_count()); ExpectPacketEQ(p.GetPacket().Pass(),
rtcp_builder_->BuildRtcpFromSender(sender_info));
} }
} // namespace cast } // namespace cast
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment