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

Side by Side Diff: media/cast/net/pacing/paced_sender.cc

Issue 2048033003: Refactoring: CastTransport InitializeAudio/InitializeVideo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed comments. Rebased. Created 4 years, 5 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
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/pacing/paced_sender.h" 5 #include "media/cast/net/pacing/paced_sender.h"
6 6
7 #include "base/big_endian.h" 7 #include "base/big_endian.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/debug/dump_without_crashing.h" 9 #include "base/debug/dump_without_crashing.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 28 matching lines...) Expand all
39 uint16_t packet_id) 39 uint16_t packet_id)
40 : capture_time(capture_time), 40 : capture_time(capture_time),
41 ssrc(ssrc), 41 ssrc(ssrc),
42 frame_id(frame_id), 42 frame_id(frame_id),
43 packet_id(packet_id) {} 43 packet_id(packet_id) {}
44 44
45 PacketKey::PacketKey(const PacketKey& other) = default; 45 PacketKey::PacketKey(const PacketKey& other) = default;
46 46
47 PacketKey::~PacketKey() {} 47 PacketKey::~PacketKey() {}
48 48
49 PacedSender::PacketSendRecord::PacketSendRecord() 49 struct PacedSender::PacketSendRecord {
50 : last_byte_sent(0), last_byte_sent_for_audio(0), cancel_count(0) {} 50 PacketSendRecord()
51 : last_byte_sent(0), last_byte_sent_for_audio(0), cancel_count(0) {}
52
53 base::TimeTicks time; // Time when the packet was sent.
54 int64_t last_byte_sent; // Number of bytes sent to network just after this
55 // packet was sent.
56 int64_t last_byte_sent_for_audio; // Number of bytes sent to network from
57 // audio stream just before this packet.
58 int cancel_count; // Number of times the packet was canceled (debugging).
59 };
60
61 struct PacedSender::RtpSession {
62 explicit RtpSession(bool is_audio_stream)
63 : last_byte_sent(0), is_audio(is_audio_stream) {}
64 RtpSession() {}
65
66 // Tracks recently-logged RTP timestamps so that it can expand the truncated
67 // values found in packets.
68 RtpTimeTicks last_logged_rtp_timestamp_;
69 int64_t last_byte_sent;
70 bool is_audio;
71 };
51 72
52 PacedSender::PacedSender( 73 PacedSender::PacedSender(
53 size_t target_burst_size, 74 size_t target_burst_size,
54 size_t max_burst_size, 75 size_t max_burst_size,
55 base::TickClock* clock, 76 base::TickClock* clock,
56 std::vector<PacketEvent>* recent_packet_events, 77 std::vector<PacketEvent>* recent_packet_events,
57 PacketTransport* transport, 78 PacketTransport* transport,
58 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner) 79 const scoped_refptr<base::SingleThreadTaskRunner>& transport_task_runner)
59 : clock_(clock), 80 : clock_(clock),
60 recent_packet_events_(recent_packet_events), 81 recent_packet_events_(recent_packet_events),
61 transport_(transport), 82 transport_(transport),
62 transport_task_runner_(transport_task_runner), 83 transport_task_runner_(transport_task_runner),
63 audio_ssrc_(0), 84 last_byte_sent_for_audio_(0),
64 video_ssrc_(0),
65 target_burst_size_(target_burst_size), 85 target_burst_size_(target_burst_size),
66 max_burst_size_(max_burst_size), 86 max_burst_size_(max_burst_size),
67 current_max_burst_size_(target_burst_size_), 87 current_max_burst_size_(target_burst_size_),
68 next_max_burst_size_(target_burst_size_), 88 next_max_burst_size_(target_burst_size_),
69 next_next_max_burst_size_(target_burst_size_), 89 next_next_max_burst_size_(target_burst_size_),
70 current_burst_size_(0), 90 current_burst_size_(0),
71 state_(State_Unblocked), 91 state_(State_Unblocked),
72 has_reached_upper_bound_once_(false), 92 has_reached_upper_bound_once_(false),
73 weak_factory_(this) {} 93 weak_factory_(this) {}
74 94
75 PacedSender::~PacedSender() {} 95 PacedSender::~PacedSender() {}
76 96
77 void PacedSender::RegisterAudioSsrc(uint32_t audio_ssrc) { 97 void PacedSender::RegisterSsrc(uint32_t ssrc, bool is_audio) {
78 audio_ssrc_ = audio_ssrc; 98 if (sessions_.find(ssrc) != sessions_.end())
79 } 99 DVLOG(1) << "Re-register ssrc: " << ssrc;
80 100
81 void PacedSender::RegisterVideoSsrc(uint32_t video_ssrc) { 101 sessions_[ssrc] = RtpSession(is_audio);
82 video_ssrc_ = video_ssrc;
83 } 102 }
84 103
85 void PacedSender::RegisterPrioritySsrc(uint32_t ssrc) { 104 void PacedSender::RegisterPrioritySsrc(uint32_t ssrc) {
86 priority_ssrcs_.push_back(ssrc); 105 priority_ssrcs_.push_back(ssrc);
87 } 106 }
88 107
89 int64_t PacedSender::GetLastByteSentForPacket(const PacketKey& packet_key) { 108 int64_t PacedSender::GetLastByteSentForPacket(const PacketKey& packet_key) {
90 PacketSendHistory::const_iterator it = send_history_.find(packet_key); 109 PacketSendHistory::const_iterator it = send_history_.find(packet_key);
91 if (it == send_history_.end()) 110 if (it == send_history_.end())
92 return 0; 111 return 0;
93 return it->second.last_byte_sent; 112 return it->second.last_byte_sent;
94 } 113 }
95 114
96 int64_t PacedSender::GetLastByteSentForSsrc(uint32_t ssrc) { 115 int64_t PacedSender::GetLastByteSentForSsrc(uint32_t ssrc) {
97 std::map<uint32_t, int64_t>::const_iterator it = last_byte_sent_.find(ssrc); 116 auto it = sessions_.find(ssrc);
98 if (it == last_byte_sent_.end()) 117 if (it == sessions_.end())
99 return 0; 118 return 0;
100 return it->second; 119 return it->second.last_byte_sent;
101 } 120 }
102 121
103 bool PacedSender::SendPackets(const SendPacketVector& packets) { 122 bool PacedSender::SendPackets(const SendPacketVector& packets) {
104 if (packets.empty()) { 123 if (packets.empty()) {
105 return true; 124 return true;
106 } 125 }
107 const bool high_priority = IsHighPriority(packets.begin()->first); 126 const bool high_priority = IsHighPriority(packets.begin()->first);
108 for (size_t i = 0; i < packets.size(); i++) { 127 for (size_t i = 0; i < packets.size(); i++) {
109 if (VLOG_IS_ON(2)) { 128 if (VLOG_IS_ON(2)) {
110 PacketSendHistory::const_iterator history_it = 129 PacketSendHistory::const_iterator history_it =
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 if (it == send_history_.end()) 162 if (it == send_history_.end())
144 return true; 163 return true;
145 164
146 // Suppose there is request to retransmit X and there is an audio 165 // Suppose there is request to retransmit X and there is an audio
147 // packet Y sent just before X. Reject retransmission of X if ACK for 166 // packet Y sent just before X. Reject retransmission of X if ACK for
148 // Y has not been received. 167 // Y has not been received.
149 // Only do this for video packets. 168 // Only do this for video packets.
150 // 169 //
151 // TODO(miu): This sounds wrong. Audio packets are always transmitted first 170 // TODO(miu): This sounds wrong. Audio packets are always transmitted first
152 // (because they are put in |priority_packet_list_|, see PopNextPacket()). 171 // (because they are put in |priority_packet_list_|, see PopNextPacket()).
153 if (packet_key.ssrc == video_ssrc_) { 172 auto session_it = sessions_.find(packet_key.ssrc);
173 DCHECK(session_it != sessions_.end());
dcheng 2016/07/14 03:40:27 The inconsistent handling of ssrc here makes me ne
xjz 2016/07/14 18:29:57 Yes, whenever a session for a RTP stream (with uni
dcheng 2016/07/15 01:21:19 Is it possible to be consistent about DCHECKing()
xjz 2016/07/18 20:21:58 Done. Removed the DCHECK() since it should be guar
dcheng 2016/07/19 05:56:10 To be clear, I think it's better to have the DCHEC
xjz 2016/07/19 18:18:33 Thanks for the clarification. Yes, the sessions sh
xjz 2016/07/19 21:43:19 Changed it back to DCHECK() so that the code will
174 if (!session_it->second.is_audio) {
154 if (dedup_info.last_byte_acked_for_audio && 175 if (dedup_info.last_byte_acked_for_audio &&
155 it->second.last_byte_sent_for_audio && 176 it->second.last_byte_sent_for_audio &&
156 dedup_info.last_byte_acked_for_audio < 177 dedup_info.last_byte_acked_for_audio <
157 it->second.last_byte_sent_for_audio) { 178 it->second.last_byte_sent_for_audio) {
158 return false; 179 return false;
159 } 180 }
160 } 181 }
161 // Retransmission interval has to be greater than |resend_interval|. 182 // Retransmission interval has to be greater than |resend_interval|.
162 if (now - it->second.time < dedup_info.resend_interval) 183 if (now - it->second.time < dedup_info.resend_interval)
163 return false; 184 return false;
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 LogPacketEvent(packet->data, PACKET_SENT_TO_NETWORK); 403 LogPacketEvent(packet->data, PACKET_SENT_TO_NETWORK);
383 break; 404 break;
384 case PacketType_RTCP: 405 case PacketType_RTCP:
385 break; 406 break;
386 } 407 }
387 408
388 const bool socket_blocked = !transport_->SendPacket(packet, cb); 409 const bool socket_blocked = !transport_->SendPacket(packet, cb);
389 410
390 // Save the send record. 411 // Save the send record.
391 send_record->last_byte_sent = transport_->GetBytesSent(); 412 send_record->last_byte_sent = transport_->GetBytesSent();
392 send_record->last_byte_sent_for_audio = GetLastByteSentForSsrc(audio_ssrc_); 413 send_record->last_byte_sent_for_audio = last_byte_sent_for_audio_;
393 send_history_buffer_[packet_key] = *send_record; 414 send_history_buffer_[packet_key] = *send_record;
394 last_byte_sent_[packet_key.ssrc] = send_record->last_byte_sent; 415
416 auto it = sessions_.find(packet_key.ssrc);
417 DCHECK(it != sessions_.end());
418 it->second.last_byte_sent = send_record->last_byte_sent;
419 if (it->second.is_audio)
420 last_byte_sent_for_audio_ = send_record->last_byte_sent;
395 421
396 if (socket_blocked) { 422 if (socket_blocked) {
397 state_ = State_TransportBlocked; 423 state_ = State_TransportBlocked;
398 return; 424 return;
399 } 425 }
400 current_burst_size_++; 426 current_burst_size_++;
401 } 427 }
402 428
403 // Keep ~0.5 seconds of data (1000 packets). 429 // Keep ~0.5 seconds of data (1000 packets).
404 // 430 //
(...skipping 21 matching lines...) Expand all
426 // TODO(miu): This parsing logic belongs in RtpParser. 452 // TODO(miu): This parsing logic belongs in RtpParser.
427 event.timestamp = clock_->NowTicks(); 453 event.timestamp = clock_->NowTicks();
428 event.type = type; 454 event.type = type;
429 base::BigEndianReader reader(reinterpret_cast<const char*>(&packet[0]), 455 base::BigEndianReader reader(reinterpret_cast<const char*>(&packet[0]),
430 packet.size()); 456 packet.size());
431 bool success = reader.Skip(4); 457 bool success = reader.Skip(4);
432 uint32_t truncated_rtp_timestamp; 458 uint32_t truncated_rtp_timestamp;
433 success &= reader.ReadU32(&truncated_rtp_timestamp); 459 success &= reader.ReadU32(&truncated_rtp_timestamp);
434 uint32_t ssrc; 460 uint32_t ssrc;
435 success &= reader.ReadU32(&ssrc); 461 success &= reader.ReadU32(&ssrc);
436 if (ssrc == audio_ssrc_) { 462
437 event.rtp_timestamp = last_logged_audio_rtp_timestamp_ = 463 auto it = sessions_.find(ssrc);
438 last_logged_audio_rtp_timestamp_.Expand(truncated_rtp_timestamp); 464 if (it == sessions_.end()) {
439 event.media_type = AUDIO_EVENT;
440 } else if (ssrc == video_ssrc_) {
441 event.rtp_timestamp = last_logged_video_rtp_timestamp_ =
442 last_logged_video_rtp_timestamp_.Expand(truncated_rtp_timestamp);
443 event.media_type = VIDEO_EVENT;
444 } else {
445 DVLOG(3) << "Got unknown ssrc " << ssrc << " when logging packet event"; 465 DVLOG(3) << "Got unknown ssrc " << ssrc << " when logging packet event";
446 return; 466 return;
447 } 467 }
468 event.rtp_timestamp = it->second.last_logged_rtp_timestamp_ =
469 it->second.last_logged_rtp_timestamp_.Expand(truncated_rtp_timestamp);
470 event.media_type = it->second.is_audio ? AUDIO_EVENT : VIDEO_EVENT;
448 success &= reader.Skip(2); 471 success &= reader.Skip(2);
449 success &= reader.ReadU16(&event.packet_id); 472 success &= reader.ReadU16(&event.packet_id);
450 success &= reader.ReadU16(&event.max_packet_id); 473 success &= reader.ReadU16(&event.max_packet_id);
451 event.size = base::checked_cast<uint32_t>(packet.size()); 474 event.size = base::checked_cast<uint32_t>(packet.size());
452 DCHECK(success); 475 DCHECK(success);
453 } 476 }
454 477
455 } // namespace cast 478 } // namespace cast
456 } // namespace media 479 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698