Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(928)

Side by Side Diff: media/cast/net/rtcp/rtcp_builder.cc

Issue 513313004: Cast: Re-factor rtcp_sender.cc into rtcp_builder.cc and do some cleanup (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: removed leaky and unused testing_clock_ Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « media/cast/net/rtcp/rtcp_builder.h ('k') | media/cast/net/rtcp/rtcp_builder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/cast/net/rtcp/rtcp_sender.h" 5 #include "media/cast/net/rtcp/rtcp_builder.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/big_endian.h"
13 #include "base/logging.h" 12 #include "base/logging.h"
14 #include "media/cast/net/cast_transport_defines.h" 13 #include "media/cast/net/cast_transport_defines.h"
15 #include "media/cast/net/pacing/paced_sender.h"
16 #include "media/cast/net/rtcp/rtcp_defines.h" 14 #include "media/cast/net/rtcp/rtcp_defines.h"
17 #include "media/cast/net/rtcp/rtcp_utility.h" 15 #include "media/cast/net/rtcp/rtcp_utility.h"
18 16
19 namespace media { 17 namespace media {
20 namespace cast { 18 namespace cast {
21 namespace { 19 namespace {
22 20
23 // Max delta is 4095 milliseconds because we need to be able to encode it in 21 // Max delta is 4095 milliseconds because we need to be able to encode it in
24 // 12 bits. 22 // 12 bits.
25 const int64 kMaxWireFormatTimeDeltaMs = INT64_C(0xfff); 23 const int64 kMaxWireFormatTimeDeltaMs = INT64_C(0xfff);
(...skipping 13 matching lines...) Expand all
39 DCHECK(event_type_4_bits); 37 DCHECK(event_type_4_bits);
40 DCHECK(~(event_type_4_bits & 0xfff0)); 38 DCHECK(~(event_type_4_bits & 0xfff0));
41 return (event_type_4_bits << 12) | time_delta_12_bits; 39 return (event_type_4_bits << 12) | time_delta_12_bits;
42 } 40 }
43 41
44 bool EventTimestampLessThan(const RtcpReceiverEventLogMessage& lhs, 42 bool EventTimestampLessThan(const RtcpReceiverEventLogMessage& lhs,
45 const RtcpReceiverEventLogMessage& rhs) { 43 const RtcpReceiverEventLogMessage& rhs) {
46 return lhs.event_timestamp < rhs.event_timestamp; 44 return lhs.event_timestamp < rhs.event_timestamp;
47 } 45 }
48 46
49 void AddReceiverLog( 47 void AddReceiverLogEntries(
50 const RtcpReceiverLogMessage& redundancy_receiver_log_message, 48 const RtcpReceiverLogMessage& redundancy_receiver_log_message,
51 RtcpReceiverLogMessage* receiver_log_message, 49 RtcpReceiverLogMessage* receiver_log_message,
52 size_t* remaining_space, 50 size_t* remaining_space,
53 size_t* number_of_frames, 51 size_t* number_of_frames,
54 size_t* total_number_of_messages_to_send) { 52 size_t* total_number_of_messages_to_send) {
55 RtcpReceiverLogMessage::const_iterator it = 53 RtcpReceiverLogMessage::const_iterator it =
56 redundancy_receiver_log_message.begin(); 54 redundancy_receiver_log_message.begin();
57 while (it != redundancy_receiver_log_message.end() && 55 while (it != redundancy_receiver_log_message.end() &&
58 *remaining_space >= 56 *remaining_space >=
59 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) { 57 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) {
60 receiver_log_message->push_front(*it); 58 receiver_log_message->push_front(*it);
61 size_t num_event_logs = (*remaining_space - kRtcpReceiverFrameLogSize) / 59 size_t num_event_logs = (*remaining_space - kRtcpReceiverFrameLogSize) /
62 kRtcpReceiverEventLogSize; 60 kRtcpReceiverEventLogSize;
63 RtcpReceiverEventLogMessages& event_log_messages = 61 RtcpReceiverEventLogMessages& event_log_messages =
64 receiver_log_message->front().event_log_messages_; 62 receiver_log_message->front().event_log_messages_;
65 if (num_event_logs < event_log_messages.size()) 63 if (num_event_logs < event_log_messages.size())
66 event_log_messages.resize(num_event_logs); 64 event_log_messages.resize(num_event_logs);
67 65
68 *remaining_space -= kRtcpReceiverFrameLogSize + 66 *remaining_space -= kRtcpReceiverFrameLogSize +
69 event_log_messages.size() * kRtcpReceiverEventLogSize; 67 event_log_messages.size() * kRtcpReceiverEventLogSize;
70 ++*number_of_frames; 68 ++number_of_frames;
71 *total_number_of_messages_to_send += event_log_messages.size(); 69 *total_number_of_messages_to_send += event_log_messages.size();
72 ++it; 70 ++it;
73 } 71 }
74 } 72 }
75 73
76 // A class to build a string representing the NACK list in Cast message. 74 // A class to build a string representing the NACK list in Cast message.
77 // 75 //
78 // The string will look like "23:3-6 25:1,5-6", meaning packets 3 to 6 in frame 76 // The string will look like "23:3-6 25:1,5-6", meaning packets 3 to 6 in frame
79 // 23 are being NACK'ed (i.e. they are missing from the receiver's point of 77 // 23 are being NACK'ed (i.e. they are missing from the receiver's point of
80 // view) and packets 1, 5 and 6 are missing in frame 25. A frame that is 78 // view) and packets 1, 5 and 6 are missing in frame 25. A frame that is
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 private: 136 private:
139 std::ostringstream stream_; 137 std::ostringstream stream_;
140 int frame_count_; 138 int frame_count_;
141 int packet_count_; 139 int packet_count_;
142 int last_frame_id_; 140 int last_frame_id_;
143 int last_packet_id_; 141 int last_packet_id_;
144 bool contiguous_sequence_; 142 bool contiguous_sequence_;
145 }; 143 };
146 } // namespace 144 } // namespace
147 145
148 RtcpSender::RtcpSender(PacedPacketSender* outgoing_transport, 146 RtcpBuilder::RtcpBuilder(uint32 sending_ssrc)
149 uint32 sending_ssrc) 147 : writer_(NULL, 0),
150 : ssrc_(sending_ssrc), 148 ssrc_(sending_ssrc),
151 transport_(outgoing_transport) { 149 ptr_of_length_(NULL) {
152 } 150 }
153 151
154 RtcpSender::~RtcpSender() {} 152 RtcpBuilder::~RtcpBuilder() {}
155 153
156 void RtcpSender::SendRtcpFromRtpReceiver( 154 void RtcpBuilder::PatchLengthField() {
155 if (ptr_of_length_) {
156 // Back-patch the packet length. The client must have taken
157 // care of proper padding to 32-bit words.
158 int this_packet_length = (writer_.ptr() - ptr_of_length_ - 2);
159 DCHECK_EQ(0, this_packet_length % 4)
160 << "Packets must be a multiple of 32 bits long";
161 *ptr_of_length_ = this_packet_length >> 10;
162 *(ptr_of_length_ + 1) = (this_packet_length >> 2) & 0xFF;
163 ptr_of_length_ = NULL;
164 }
165 }
166
167 // Set the 5-bit value in the 1st byte of the header
168 // and the payload type. Set aside room for the length field,
169 // and make provision for back-patching it.
170 void RtcpBuilder::AddRtcpHeader(RtcpPacketFields payload, int format_or_count) {
171 PatchLengthField();
172 writer_.WriteU8(0x80 | (format_or_count & 0x1F));
173 writer_.WriteU8(payload);
174 ptr_of_length_ = writer_.ptr();
175
176 // Initialize length to "clearly illegal".
177 writer_.WriteU16(0xDEAD);
178 }
179
180 void RtcpBuilder::Start() {
181 packet_ = new base::RefCountedData<Packet>;
182 packet_->data.resize(kMaxIpPacketSize);
183 writer_ = base::BigEndianWriter(
184 reinterpret_cast<char*>(&(packet_->data[0])), kMaxIpPacketSize);
185 }
186
187 PacketRef RtcpBuilder::Finish() {
188 PatchLengthField();
189 packet_->data.resize(kMaxIpPacketSize - writer_.remaining());
190 writer_ = base::BigEndianWriter(NULL, 0);
191 PacketRef ret = packet_;
192 packet_ = NULL;
193 return ret;
194 }
195
196 PacketRef RtcpBuilder::BuildRtcpFromReceiver(
157 const RtcpReportBlock* report_block, 197 const RtcpReportBlock* report_block,
158 const RtcpReceiverReferenceTimeReport* rrtr, 198 const RtcpReceiverReferenceTimeReport* rrtr,
159 const RtcpCastMessage* cast_message, 199 const RtcpCastMessage* cast_message,
160 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events, 200 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap* rtcp_events,
161 base::TimeDelta target_delay) { 201 base::TimeDelta target_delay) {
162 PacketRef packet(new base::RefCountedData<Packet>); 202 Start();
163 packet->data.reserve(kMaxIpPacketSize); 203
164 if (report_block) 204 if (report_block)
165 BuildRR(report_block, &packet->data); 205 AddRR(report_block);
166 if (rrtr) 206 if (rrtr)
167 BuildRrtr(rrtr, &packet->data); 207 AddRrtr(rrtr);
168 if (cast_message) 208 if (cast_message)
169 BuildCast(cast_message, target_delay, &packet->data); 209 AddCast(cast_message, target_delay);
170 if (rtcp_events) 210 if (rtcp_events)
171 BuildReceiverLog(*rtcp_events, &packet->data); 211 AddReceiverLog(*rtcp_events);
172 212
173 if (packet->data.empty()) { 213 return Finish();
174 NOTREACHED() << "Empty packet.";
175 return; // Sanity don't send empty packets.
176 }
177
178 transport_->SendRtcpPacket(ssrc_, packet);
179 } 214 }
180 215
181 void RtcpSender::SendRtcpFromRtpSender( 216 PacketRef RtcpBuilder::BuildRtcpFromSender(const RtcpSenderInfo& sender_info) {
182 const RtcpSenderInfo& sender_info) { 217 Start();
183 PacketRef packet(new base::RefCountedData<Packet>); 218 AddSR(sender_info);
184 packet->data.reserve(kMaxIpPacketSize); 219 return Finish();
185 BuildSR(sender_info, &packet->data);
186
187 if (packet->data.empty()) {
188 NOTREACHED() << "Empty packet.";
189 return; // Sanity - don't send empty packets.
190 }
191
192 transport_->SendRtcpPacket(ssrc_, packet);
193 } 220 }
194 221
195 void RtcpSender::BuildRR(const RtcpReportBlock* report_block, 222 void RtcpBuilder::AddRR(const RtcpReportBlock* report_block) {
196 Packet* packet) const { 223 AddRtcpHeader(kPacketTypeReceiverReport, report_block ? 1 : 0);
197 size_t start_size = packet->size(); 224 writer_.WriteU32(ssrc_);
198 DCHECK_LT(start_size + 32, kMaxIpPacketSize) << "Not enough buffer space";
199 if (start_size + 32 > kMaxIpPacketSize)
200 return;
201
202 uint16 number_of_rows = (report_block) ? 7 : 1;
203 packet->resize(start_size + 8);
204
205 base::BigEndianWriter big_endian_writer(
206 reinterpret_cast<char*>(&((*packet)[start_size])), 8);
207 big_endian_writer.WriteU8(0x80 + (report_block ? 1 : 0));
208 big_endian_writer.WriteU8(kPacketTypeReceiverReport);
209 big_endian_writer.WriteU16(number_of_rows);
210 big_endian_writer.WriteU32(ssrc_);
211
212 if (report_block) { 225 if (report_block) {
213 AddReportBlocks(*report_block, packet); // Adds 24 bytes. 226 AddReportBlocks(*report_block); // Adds 24 bytes.
214 } 227 }
215 } 228 }
216 229
217 void RtcpSender::AddReportBlocks(const RtcpReportBlock& report_block, 230 void RtcpBuilder::AddReportBlocks(const RtcpReportBlock& report_block) {
218 Packet* packet) const { 231 writer_.WriteU32(report_block.media_ssrc);
219 size_t start_size = packet->size(); 232 writer_.WriteU8(report_block.fraction_lost);
220 DCHECK_LT(start_size + 24, kMaxIpPacketSize) << "Not enough buffer space"; 233 writer_.WriteU8(report_block.cumulative_lost >> 16);
221 if (start_size + 24 > kMaxIpPacketSize) 234 writer_.WriteU8(report_block.cumulative_lost >> 8);
222 return; 235 writer_.WriteU8(report_block.cumulative_lost);
223
224 packet->resize(start_size + 24);
225
226 base::BigEndianWriter big_endian_writer(
227 reinterpret_cast<char*>(&((*packet)[start_size])), 24);
228 big_endian_writer.WriteU32(report_block.media_ssrc);
229 big_endian_writer.WriteU8(report_block.fraction_lost);
230 big_endian_writer.WriteU8(report_block.cumulative_lost >> 16);
231 big_endian_writer.WriteU8(report_block.cumulative_lost >> 8);
232 big_endian_writer.WriteU8(report_block.cumulative_lost);
233 236
234 // Extended highest seq_no, contain the highest sequence number received. 237 // Extended highest seq_no, contain the highest sequence number received.
235 big_endian_writer.WriteU32(report_block.extended_high_sequence_number); 238 writer_.WriteU32(report_block.extended_high_sequence_number);
236 big_endian_writer.WriteU32(report_block.jitter); 239 writer_.WriteU32(report_block.jitter);
237 240
238 // Last SR timestamp; our NTP time when we received the last report. 241 // Last SR timestamp; our NTP time when we received the last report.
239 // This is the value that we read from the send report packet not when we 242 // This is the value that we read from the send report packet not when we
240 // received it. 243 // received it.
241 big_endian_writer.WriteU32(report_block.last_sr); 244 writer_.WriteU32(report_block.last_sr);
242 245
243 // Delay since last received report, time since we received the report. 246 // Delay since last received report, time since we received the report.
244 big_endian_writer.WriteU32(report_block.delay_since_last_sr); 247 writer_.WriteU32(report_block.delay_since_last_sr);
245 } 248 }
246 249
247 void RtcpSender::BuildRrtr(const RtcpReceiverReferenceTimeReport* rrtr, 250 void RtcpBuilder::AddRrtr(const RtcpReceiverReferenceTimeReport* rrtr) {
248 Packet* packet) const { 251 AddRtcpHeader(kPacketTypeXr, 0);
249 size_t start_size = packet->size(); 252 writer_.WriteU32(ssrc_); // Add our own SSRC.
250 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; 253 writer_.WriteU8(4); // Add block type.
251 if (start_size + 20 > kMaxIpPacketSize) 254 writer_.WriteU8(0); // Add reserved.
252 return; 255 writer_.WriteU16(2); // Block length.
253
254 packet->resize(start_size + 20);
255
256 base::BigEndianWriter big_endian_writer(
257 reinterpret_cast<char*>(&((*packet)[start_size])), 20);
258
259 big_endian_writer.WriteU8(0x80);
260 big_endian_writer.WriteU8(kPacketTypeXr);
261 big_endian_writer.WriteU16(4); // Length.
262 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
263 big_endian_writer.WriteU8(4); // Add block type.
264 big_endian_writer.WriteU8(0); // Add reserved.
265 big_endian_writer.WriteU16(2); // Block length.
266 256
267 // Add the media (received RTP) SSRC. 257 // Add the media (received RTP) SSRC.
268 big_endian_writer.WriteU32(rrtr->ntp_seconds); 258 writer_.WriteU32(rrtr->ntp_seconds);
269 big_endian_writer.WriteU32(rrtr->ntp_fraction); 259 writer_.WriteU32(rrtr->ntp_fraction);
270 } 260 }
271 261
272 void RtcpSender::BuildCast(const RtcpCastMessage* cast, 262 void RtcpBuilder::AddCast(const RtcpCastMessage* cast,
273 base::TimeDelta target_delay, 263 base::TimeDelta target_delay) {
274 Packet* packet) const { 264 // See RTC 4585 Section 6.4 for application specific feedback messages.
275 size_t start_size = packet->size(); 265 AddRtcpHeader(kPacketTypePayloadSpecific, 15);
276 DCHECK_LT(start_size + 20, kMaxIpPacketSize) << "Not enough buffer space"; 266 writer_.WriteU32(ssrc_); // Add our own SSRC.
277 if (start_size + 20 > kMaxIpPacketSize) 267 writer_.WriteU32(cast->media_ssrc); // Remote SSRC.
278 return; 268 writer_.WriteU32(kCast);
279 269 writer_.WriteU8(static_cast<uint8>(cast->ack_frame_id));
280 packet->resize(start_size + 20); 270 uint8* cast_loss_field_pos = reinterpret_cast<uint8*>(writer_.ptr());
281 271 writer_.WriteU8(0); // Overwritten with number_of_loss_fields.
282 base::BigEndianWriter big_endian_writer(
283 reinterpret_cast<char*>(&((*packet)[start_size])), 20);
284 uint8 FMT = 15; // Application layer feedback.
285 big_endian_writer.WriteU8(0x80 + FMT);
286 big_endian_writer.WriteU8(kPacketTypePayloadSpecific);
287 big_endian_writer.WriteU8(0);
288 size_t cast_size_pos = start_size + 3; // Save length position.
289 big_endian_writer.WriteU8(4);
290 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
291 big_endian_writer.WriteU32(cast->media_ssrc); // Remote SSRC.
292 big_endian_writer.WriteU32(kCast);
293 big_endian_writer.WriteU8(static_cast<uint8>(cast->ack_frame_id));
294 size_t cast_loss_field_pos = start_size + 17; // Save loss field position.
295 big_endian_writer.WriteU8(0); // Overwritten with number_of_loss_fields.
296 DCHECK_LE(target_delay.InMilliseconds(), 272 DCHECK_LE(target_delay.InMilliseconds(),
297 std::numeric_limits<uint16_t>::max()); 273 std::numeric_limits<uint16_t>::max());
298 big_endian_writer.WriteU16(target_delay.InMilliseconds()); 274 writer_.WriteU16(target_delay.InMilliseconds());
299 275
300 size_t number_of_loss_fields = 0; 276 size_t number_of_loss_fields = 0;
301 size_t max_number_of_loss_fields = std::min<size_t>( 277 size_t max_number_of_loss_fields = std::min<size_t>(
302 kRtcpMaxCastLossFields, (kMaxIpPacketSize - packet->size()) / 4); 278 kRtcpMaxCastLossFields, writer_.remaining() / 4);
303 279
304 MissingFramesAndPacketsMap::const_iterator frame_it = 280 MissingFramesAndPacketsMap::const_iterator frame_it =
305 cast->missing_frames_and_packets.begin(); 281 cast->missing_frames_and_packets.begin();
306 282
307 NackStringBuilder nack_string_builder; 283 NackStringBuilder nack_string_builder;
308 for (; frame_it != cast->missing_frames_and_packets.end() && 284 for (; frame_it != cast->missing_frames_and_packets.end() &&
309 number_of_loss_fields < max_number_of_loss_fields; 285 number_of_loss_fields < max_number_of_loss_fields;
310 ++frame_it) { 286 ++frame_it) {
311 nack_string_builder.PushFrame(frame_it->first); 287 nack_string_builder.PushFrame(frame_it->first);
312 // Iterate through all frames with missing packets. 288 // Iterate through all frames with missing packets.
313 if (frame_it->second.empty()) { 289 if (frame_it->second.empty()) {
314 // Special case all packets in a frame is missing. 290 // Special case all packets in a frame is missing.
315 start_size = packet->size(); 291 writer_.WriteU8(static_cast<uint8>(frame_it->first));
316 packet->resize(start_size + 4); 292 writer_.WriteU16(kRtcpCastAllPacketsLost);
317 base::BigEndianWriter big_endian_nack_writer( 293 writer_.WriteU8(0);
318 reinterpret_cast<char*>(&((*packet)[start_size])), 4);
319 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first));
320 big_endian_nack_writer.WriteU16(kRtcpCastAllPacketsLost);
321 big_endian_nack_writer.WriteU8(0);
322 nack_string_builder.PushPacket(kRtcpCastAllPacketsLost); 294 nack_string_builder.PushPacket(kRtcpCastAllPacketsLost);
323 ++number_of_loss_fields; 295 ++number_of_loss_fields;
324 } else { 296 } else {
325 PacketIdSet::const_iterator packet_it = frame_it->second.begin(); 297 PacketIdSet::const_iterator packet_it = frame_it->second.begin();
326 while (packet_it != frame_it->second.end()) { 298 while (packet_it != frame_it->second.end()) {
327 uint16 packet_id = *packet_it; 299 uint16 packet_id = *packet_it;
328
329 start_size = packet->size();
330 packet->resize(start_size + 4);
331 base::BigEndianWriter big_endian_nack_writer(
332 reinterpret_cast<char*>(&((*packet)[start_size])), 4);
333
334 // Write frame and packet id to buffer before calculating bitmask. 300 // Write frame and packet id to buffer before calculating bitmask.
335 big_endian_nack_writer.WriteU8(static_cast<uint8>(frame_it->first)); 301 writer_.WriteU8(static_cast<uint8>(frame_it->first));
336 big_endian_nack_writer.WriteU16(packet_id); 302 writer_.WriteU16(packet_id);
337 nack_string_builder.PushPacket(packet_id); 303 nack_string_builder.PushPacket(packet_id);
338 304
339 uint8 bitmask = 0; 305 uint8 bitmask = 0;
340 ++packet_it; 306 ++packet_it;
341 while (packet_it != frame_it->second.end()) { 307 while (packet_it != frame_it->second.end()) {
342 int shift = static_cast<uint8>(*packet_it - packet_id) - 1; 308 int shift = static_cast<uint8>(*packet_it - packet_id) - 1;
343 if (shift >= 0 && shift <= 7) { 309 if (shift >= 0 && shift <= 7) {
344 nack_string_builder.PushPacket(*packet_it); 310 nack_string_builder.PushPacket(*packet_it);
345 bitmask |= (1 << shift); 311 bitmask |= (1 << shift);
346 ++packet_it; 312 ++packet_it;
347 } else { 313 } else {
348 break; 314 break;
349 } 315 }
350 } 316 }
351 big_endian_nack_writer.WriteU8(bitmask); 317 writer_.WriteU8(bitmask);
352 ++number_of_loss_fields; 318 ++number_of_loss_fields;
353 } 319 }
354 } 320 }
355 } 321 }
356 VLOG_IF(1, !nack_string_builder.Empty()) 322 VLOG_IF(1, !nack_string_builder.Empty())
357 << "SSRC: " << cast->media_ssrc 323 << "SSRC: " << cast->media_ssrc
358 << ", ACK: " << cast->ack_frame_id 324 << ", ACK: " << cast->ack_frame_id
359 << ", NACK: " << nack_string_builder.GetString(); 325 << ", NACK: " << nack_string_builder.GetString();
360 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields); 326 DCHECK_LE(number_of_loss_fields, kRtcpMaxCastLossFields);
361 (*packet)[cast_size_pos] = static_cast<uint8>(4 + number_of_loss_fields); 327 *cast_loss_field_pos = static_cast<uint8>(number_of_loss_fields);
362 (*packet)[cast_loss_field_pos] = static_cast<uint8>(number_of_loss_fields);
363 } 328 }
364 329
365 void RtcpSender::BuildSR(const RtcpSenderInfo& sender_info, 330 void RtcpBuilder::AddSR(const RtcpSenderInfo& sender_info) {
366 Packet* packet) const { 331 AddRtcpHeader(kPacketTypeSenderReport, 0);
367 // Sender report. 332 writer_.WriteU32(ssrc_);
368 size_t start_size = packet->size(); 333 writer_.WriteU32(sender_info.ntp_seconds);
369 if (start_size + 52 > kMaxIpPacketSize) { 334 writer_.WriteU32(sender_info.ntp_fraction);
370 DLOG(FATAL) << "Not enough buffer space"; 335 writer_.WriteU32(sender_info.rtp_timestamp);
371 return; 336 writer_.WriteU32(sender_info.send_packet_count);
372 } 337 writer_.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
373
374 uint16 number_of_rows = 6;
375 packet->resize(start_size + 28);
376
377 base::BigEndianWriter big_endian_writer(
378 reinterpret_cast<char*>(&((*packet)[start_size])), 28);
379 big_endian_writer.WriteU8(0x80);
380 big_endian_writer.WriteU8(kPacketTypeSenderReport);
381 big_endian_writer.WriteU16(number_of_rows);
382 big_endian_writer.WriteU32(ssrc_);
383 big_endian_writer.WriteU32(sender_info.ntp_seconds);
384 big_endian_writer.WriteU32(sender_info.ntp_fraction);
385 big_endian_writer.WriteU32(sender_info.rtp_timestamp);
386 big_endian_writer.WriteU32(sender_info.send_packet_count);
387 big_endian_writer.WriteU32(static_cast<uint32>(sender_info.send_octet_count));
388 return;
389 } 338 }
390 339
391 /* 340 /*
392 0 1 2 3 341 0 1 2 3
393 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 342 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
394 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 343 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
395 |V=2|P|reserved | PT=XR=207 | length | 344 |V=2|P|reserved | PT=XR=207 | length |
396 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 345 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
397 | SSRC | 346 | SSRC |
398 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 347 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
399 | BT=5 | reserved | block length | 348 | BT=5 | reserved | block length |
400 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 349 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
401 | SSRC1 (SSRC of first receiver) | sub- 350 | SSRC1 (SSRC of first receiver) | sub-
402 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block 351 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
403 | last RR (LRR) | 1 352 | last RR (LRR) | 1
404 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 353 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
405 | delay since last RR (DLRR) | 354 | delay since last RR (DLRR) |
406 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 355 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
407 */ 356 */
408 void RtcpSender::BuildDlrrRb(const RtcpDlrrReportBlock& dlrr, 357 void RtcpBuilder::AddDlrrRb(const RtcpDlrrReportBlock& dlrr) {
409 Packet* packet) const { 358 AddRtcpHeader(kPacketTypeXr, 0);
410 size_t start_size = packet->size(); 359 writer_.WriteU32(ssrc_); // Add our own SSRC.
411 if (start_size + 24 > kMaxIpPacketSize) { 360 writer_.WriteU8(5); // Add block type.
412 DLOG(FATAL) << "Not enough buffer space"; 361 writer_.WriteU8(0); // Add reserved.
362 writer_.WriteU16(3); // Block length.
363 writer_.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
364 writer_.WriteU32(dlrr.last_rr);
365 writer_.WriteU32(dlrr.delay_since_last_rr);
366 }
367
368 void RtcpBuilder::AddReceiverLog(
369 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events) {
370 size_t total_number_of_messages_to_send = 0;
371 RtcpReceiverLogMessage receiver_log_message;
372
373 if (!GetRtcpReceiverLogMessage(rtcp_events,
374 &receiver_log_message,
375 &total_number_of_messages_to_send)) {
413 return; 376 return;
414 } 377 }
415 378
416 packet->resize(start_size + 24); 379 AddRtcpHeader(kPacketTypeApplicationDefined, kReceiverLogSubtype);
417 380 writer_.WriteU32(ssrc_); // Add our own SSRC.
418 base::BigEndianWriter big_endian_writer( 381 writer_.WriteU32(kCast);
419 reinterpret_cast<char*>(&((*packet)[start_size])), 24);
420 big_endian_writer.WriteU8(0x80);
421 big_endian_writer.WriteU8(kPacketTypeXr);
422 big_endian_writer.WriteU16(5); // Length.
423 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
424 big_endian_writer.WriteU8(5); // Add block type.
425 big_endian_writer.WriteU8(0); // Add reserved.
426 big_endian_writer.WriteU16(3); // Block length.
427 big_endian_writer.WriteU32(ssrc_); // Add the media (received RTP) SSRC.
428 big_endian_writer.WriteU32(dlrr.last_rr);
429 big_endian_writer.WriteU32(dlrr.delay_since_last_rr);
430 return;
431 }
432
433 void RtcpSender::BuildReceiverLog(
434 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events,
435 Packet* packet) {
436 const size_t packet_start_size = packet->size();
437 size_t number_of_frames = 0;
438 size_t total_number_of_messages_to_send = 0;
439 size_t rtcp_log_size = 0;
440 RtcpReceiverLogMessage receiver_log_message;
441
442 if (!BuildRtcpReceiverLogMessage(rtcp_events,
443 packet_start_size,
444 &receiver_log_message,
445 &number_of_frames,
446 &total_number_of_messages_to_send,
447 &rtcp_log_size)) {
448 return;
449 }
450 packet->resize(packet_start_size + rtcp_log_size);
451
452 base::BigEndianWriter big_endian_writer(
453 reinterpret_cast<char*>(&((*packet)[packet_start_size])), rtcp_log_size);
454 big_endian_writer.WriteU8(0x80 + kReceiverLogSubtype);
455 big_endian_writer.WriteU8(kPacketTypeApplicationDefined);
456 big_endian_writer.WriteU16(static_cast<uint16>(
457 2 + 2 * number_of_frames + total_number_of_messages_to_send));
458 big_endian_writer.WriteU32(ssrc_); // Add our own SSRC.
459 big_endian_writer.WriteU32(kCast);
460 382
461 while (!receiver_log_message.empty() && 383 while (!receiver_log_message.empty() &&
462 total_number_of_messages_to_send > 0) { 384 total_number_of_messages_to_send > 0) {
463 RtcpReceiverFrameLogMessage& frame_log_messages( 385 RtcpReceiverFrameLogMessage& frame_log_messages(
464 receiver_log_message.front()); 386 receiver_log_message.front());
465 387
466 // Add our frame header. 388 // Add our frame header.
467 big_endian_writer.WriteU32(frame_log_messages.rtp_timestamp_); 389 writer_.WriteU32(frame_log_messages.rtp_timestamp_);
468 size_t messages_in_frame = frame_log_messages.event_log_messages_.size(); 390 size_t messages_in_frame = frame_log_messages.event_log_messages_.size();
469 if (messages_in_frame > total_number_of_messages_to_send) { 391 if (messages_in_frame > total_number_of_messages_to_send) {
470 // We are running out of space. 392 // We are running out of space.
471 messages_in_frame = total_number_of_messages_to_send; 393 messages_in_frame = total_number_of_messages_to_send;
472 } 394 }
473 // Keep track of how many messages we have left to send. 395 // Keep track of how many messages we have left to send.
474 total_number_of_messages_to_send -= messages_in_frame; 396 total_number_of_messages_to_send -= messages_in_frame;
475 397
476 // On the wire format is number of messages - 1. 398 // On the wire format is number of messages - 1.
477 big_endian_writer.WriteU8(static_cast<uint8>(messages_in_frame - 1)); 399 writer_.WriteU8(static_cast<uint8>(messages_in_frame - 1));
478 400
479 base::TimeTicks event_timestamp_base = 401 base::TimeTicks event_timestamp_base =
480 frame_log_messages.event_log_messages_.front().event_timestamp; 402 frame_log_messages.event_log_messages_.front().event_timestamp;
481 uint32 base_timestamp_ms = 403 uint32 base_timestamp_ms =
482 (event_timestamp_base - base::TimeTicks()).InMilliseconds(); 404 (event_timestamp_base - base::TimeTicks()).InMilliseconds();
483 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms >> 16)); 405 writer_.WriteU8(static_cast<uint8>(base_timestamp_ms >> 16));
484 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms >> 8)); 406 writer_.WriteU8(static_cast<uint8>(base_timestamp_ms >> 8));
485 big_endian_writer.WriteU8(static_cast<uint8>(base_timestamp_ms)); 407 writer_.WriteU8(static_cast<uint8>(base_timestamp_ms));
486 408
487 while (!frame_log_messages.event_log_messages_.empty() && 409 while (!frame_log_messages.event_log_messages_.empty() &&
488 messages_in_frame > 0) { 410 messages_in_frame > 0) {
489 const RtcpReceiverEventLogMessage& event_message = 411 const RtcpReceiverEventLogMessage& event_message =
490 frame_log_messages.event_log_messages_.front(); 412 frame_log_messages.event_log_messages_.front();
491 uint16 event_type_and_timestamp_delta = 413 uint16 event_type_and_timestamp_delta =
492 MergeEventTypeAndTimestampForWireFormat( 414 MergeEventTypeAndTimestampForWireFormat(
493 event_message.type, 415 event_message.type,
494 event_message.event_timestamp - event_timestamp_base); 416 event_message.event_timestamp - event_timestamp_base);
495 switch (event_message.type) { 417 switch (event_message.type) {
496 case FRAME_ACK_SENT: 418 case FRAME_ACK_SENT:
497 case FRAME_PLAYOUT: 419 case FRAME_PLAYOUT:
498 case FRAME_DECODED: 420 case FRAME_DECODED:
499 big_endian_writer.WriteU16( 421 writer_.WriteU16(
500 static_cast<uint16>(event_message.delay_delta.InMilliseconds())); 422 static_cast<uint16>(event_message.delay_delta.InMilliseconds()));
501 big_endian_writer.WriteU16(event_type_and_timestamp_delta); 423 writer_.WriteU16(event_type_and_timestamp_delta);
502 break; 424 break;
503 case PACKET_RECEIVED: 425 case PACKET_RECEIVED:
504 big_endian_writer.WriteU16(event_message.packet_id); 426 writer_.WriteU16(event_message.packet_id);
505 big_endian_writer.WriteU16(event_type_and_timestamp_delta); 427 writer_.WriteU16(event_type_and_timestamp_delta);
506 break; 428 break;
507 default: 429 default:
508 NOTREACHED(); 430 NOTREACHED();
509 } 431 }
510 messages_in_frame--; 432 messages_in_frame--;
511 frame_log_messages.event_log_messages_.pop_front(); 433 frame_log_messages.event_log_messages_.pop_front();
512 } 434 }
513 if (frame_log_messages.event_log_messages_.empty()) { 435 if (frame_log_messages.event_log_messages_.empty()) {
514 // We sent all messages on this frame; pop the frame header. 436 // We sent all messages on this frame; pop the frame header.
515 receiver_log_message.pop_front(); 437 receiver_log_message.pop_front();
516 } 438 }
517 } 439 }
518 DCHECK_EQ(total_number_of_messages_to_send, 0u); 440 DCHECK_EQ(total_number_of_messages_to_send, 0u);
519 } 441 }
520 442
521 bool RtcpSender::BuildRtcpReceiverLogMessage( 443 bool RtcpBuilder::GetRtcpReceiverLogMessage(
522 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events, 444 const ReceiverRtcpEventSubscriber::RtcpEventMultiMap& rtcp_events,
523 size_t start_size,
524 RtcpReceiverLogMessage* receiver_log_message, 445 RtcpReceiverLogMessage* receiver_log_message,
525 size_t* number_of_frames, 446 size_t* total_number_of_messages_to_send) {
526 size_t* total_number_of_messages_to_send, 447 size_t number_of_frames = 0;
527 size_t* rtcp_log_size) {
528 size_t remaining_space = 448 size_t remaining_space =
529 std::min(kMaxReceiverLogBytes, kMaxIpPacketSize - start_size); 449 std::min<size_t>(kMaxReceiverLogBytes, writer_.remaining());
530 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize + 450 if (remaining_space < kRtcpCastLogHeaderSize + kRtcpReceiverFrameLogSize +
531 kRtcpReceiverEventLogSize) { 451 kRtcpReceiverEventLogSize) {
532 return false; 452 return false;
533 } 453 }
534 454
535 // We use this to do event timestamp sorting and truncating for events of 455 // We use this to do event timestamp sorting and truncating for events of
536 // a single frame. 456 // a single frame.
537 std::vector<RtcpReceiverEventLogMessage> sorted_log_messages; 457 std::vector<RtcpReceiverEventLogMessage> sorted_log_messages;
538 458
539 // Account for the RTCP header for an application-defined packet. 459 // Account for the RTCP header for an application-defined packet.
540 remaining_space -= kRtcpCastLogHeaderSize; 460 remaining_space -= kRtcpCastLogHeaderSize;
541 461
542 ReceiverRtcpEventSubscriber::RtcpEventMultiMap::const_reverse_iterator rit = 462 ReceiverRtcpEventSubscriber::RtcpEventMultiMap::const_reverse_iterator rit =
543 rtcp_events.rbegin(); 463 rtcp_events.rbegin();
544 464
545 while (rit != rtcp_events.rend() && 465 while (rit != rtcp_events.rend() &&
546 remaining_space >= 466 remaining_space >=
547 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) { 467 kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize) {
548 const RtpTimestamp rtp_timestamp = rit->first; 468 const RtpTimestamp rtp_timestamp = rit->first;
549 RtcpReceiverFrameLogMessage frame_log(rtp_timestamp); 469 RtcpReceiverFrameLogMessage frame_log(rtp_timestamp);
550 remaining_space -= kRtcpReceiverFrameLogSize; 470 remaining_space -= kRtcpReceiverFrameLogSize;
551 ++*number_of_frames; 471 ++number_of_frames;
552 472
553 // Get all events of a single frame. 473 // Get all events of a single frame.
554 sorted_log_messages.clear(); 474 sorted_log_messages.clear();
555 do { 475 do {
556 RtcpReceiverEventLogMessage event_log_message; 476 RtcpReceiverEventLogMessage event_log_message;
557 event_log_message.type = rit->second.type; 477 event_log_message.type = rit->second.type;
558 event_log_message.event_timestamp = rit->second.timestamp; 478 event_log_message.event_timestamp = rit->second.timestamp;
559 event_log_message.delay_delta = rit->second.delay_delta; 479 event_log_message.delay_delta = rit->second.delay_delta;
560 event_log_message.packet_id = rit->second.packet_id; 480 event_log_message.packet_id = rit->second.packet_id;
561 sorted_log_messages.push_back(event_log_message); 481 sorted_log_messages.push_back(event_log_message);
(...skipping 29 matching lines...) Expand all
591 } 511 }
592 512
593 rtcp_events_history_.push_front(*receiver_log_message); 513 rtcp_events_history_.push_front(*receiver_log_message);
594 514
595 // We don't try to match RTP timestamps of redundancy frame logs with those 515 // We don't try to match RTP timestamps of redundancy frame logs with those
596 // from the newest set (which would save the space of an extra RTP timestamp 516 // from the newest set (which would save the space of an extra RTP timestamp
597 // over the wire). Unless the redundancy frame logs are very recent, it's 517 // over the wire). Unless the redundancy frame logs are very recent, it's
598 // unlikely there will be a match anyway. 518 // unlikely there will be a match anyway.
599 if (rtcp_events_history_.size() > kFirstRedundancyOffset) { 519 if (rtcp_events_history_.size() > kFirstRedundancyOffset) {
600 // Add first redundnacy messages, if enough space remaining 520 // Add first redundnacy messages, if enough space remaining
601 AddReceiverLog(rtcp_events_history_[kFirstRedundancyOffset], 521 AddReceiverLogEntries(rtcp_events_history_[kFirstRedundancyOffset],
602 receiver_log_message, 522 receiver_log_message,
603 &remaining_space, 523 &remaining_space,
604 number_of_frames, 524 &number_of_frames,
605 total_number_of_messages_to_send); 525 total_number_of_messages_to_send);
606 } 526 }
607 527
608 if (rtcp_events_history_.size() > kSecondRedundancyOffset) { 528 if (rtcp_events_history_.size() > kSecondRedundancyOffset) {
609 // Add second redundancy messages, if enough space remaining 529 // Add second redundancy messages, if enough space remaining
610 AddReceiverLog(rtcp_events_history_[kSecondRedundancyOffset], 530 AddReceiverLogEntries(rtcp_events_history_[kSecondRedundancyOffset],
611 receiver_log_message, 531 receiver_log_message,
612 &remaining_space, 532 &remaining_space,
613 number_of_frames, 533 &number_of_frames,
614 total_number_of_messages_to_send); 534 total_number_of_messages_to_send);
615 } 535 }
616 536
617 if (rtcp_events_history_.size() > kReceiveLogMessageHistorySize) { 537 if (rtcp_events_history_.size() > kReceiveLogMessageHistorySize) {
618 rtcp_events_history_.pop_back(); 538 rtcp_events_history_.pop_back();
619 } 539 }
620 540
621 DCHECK_LE(rtcp_events_history_.size(), kReceiveLogMessageHistorySize); 541 DCHECK_LE(rtcp_events_history_.size(), kReceiveLogMessageHistorySize);
622 542
623 *rtcp_log_size = 543 VLOG(3) << "number of frames: " << number_of_frames;
624 kRtcpCastLogHeaderSize + *number_of_frames * kRtcpReceiverFrameLogSize +
625 *total_number_of_messages_to_send * kRtcpReceiverEventLogSize;
626 DCHECK_GE(kMaxIpPacketSize, start_size + *rtcp_log_size)
627 << "Not enough buffer space.";
628
629 VLOG(3) << "number of frames: " << *number_of_frames;
630 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send; 544 VLOG(3) << "total messages to send: " << *total_number_of_messages_to_send;
631 VLOG(3) << "rtcp log size: " << *rtcp_log_size; 545 return number_of_frames > 0;
632 return *number_of_frames > 0;
633 } 546 }
634 547
635 } // namespace cast 548 } // namespace cast
636 } // namespace media 549 } // namespace media
OLDNEW
« no previous file with comments | « media/cast/net/rtcp/rtcp_builder.h ('k') | media/cast/net/rtcp/rtcp_builder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698