OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "net/quic/quic_fec_group.h" | 5 #include "net/quic/quic_fec_group.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 | 11 |
12 using base::StringPiece; | 12 using base::StringPiece; |
13 using std::numeric_limits; | 13 using std::numeric_limits; |
14 using std::set; | 14 using std::set; |
15 | 15 |
16 namespace net { | 16 namespace net { |
17 | 17 |
18 namespace { | 18 namespace { |
19 const QuicPacketSequenceNumber kNoSequenceNumber = kuint64max; | 19 const QuicPacketSequenceNumber kNoSequenceNumber = kuint64max; |
20 } // namespace | 20 } // namespace |
21 | 21 |
22 QuicFecGroup::QuicFecGroup() | 22 QuicFecGroup::QuicFecGroup() |
23 : min_protected_packet_(kNoSequenceNumber), | 23 : min_protected_packet_(kNoSequenceNumber), |
24 max_protected_packet_(kNoSequenceNumber), | 24 max_protected_packet_(kNoSequenceNumber), |
25 payload_parity_len_(0) { | 25 payload_parity_len_(0) { |
26 } | 26 } |
27 | 27 |
28 QuicFecGroup::~QuicFecGroup() {} | 28 QuicFecGroup::~QuicFecGroup() { |
| 29 } |
29 | 30 |
30 bool QuicFecGroup::Update(const QuicPacketHeader& header, | 31 bool QuicFecGroup::Update(const QuicPacketHeader& header, |
31 StringPiece decrypted_payload) { | 32 StringPiece decrypted_payload) { |
32 if (received_packets_.count(header.packet_sequence_number) != 0) { | 33 if (received_packets_.count(header.packet_sequence_number) != 0) { |
33 return false; | 34 return false; |
34 } | 35 } |
35 if (min_protected_packet_ != kNoSequenceNumber && | 36 if (min_protected_packet_ != kNoSequenceNumber && |
36 max_protected_packet_ != kNoSequenceNumber && | 37 max_protected_packet_ != kNoSequenceNumber && |
37 (header.packet_sequence_number < min_protected_packet_ || | 38 (header.packet_sequence_number < min_protected_packet_ || |
38 header.packet_sequence_number > max_protected_packet_)) { | 39 header.packet_sequence_number > max_protected_packet_)) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 size_t QuicFecGroup::Revive(QuicPacketHeader* header, | 83 size_t QuicFecGroup::Revive(QuicPacketHeader* header, |
83 char* decrypted_payload, | 84 char* decrypted_payload, |
84 size_t decrypted_payload_len) { | 85 size_t decrypted_payload_len) { |
85 if (!CanRevive()) { | 86 if (!CanRevive()) { |
86 return 0; | 87 return 0; |
87 } | 88 } |
88 | 89 |
89 // Identify the packet sequence number to be resurrected. | 90 // Identify the packet sequence number to be resurrected. |
90 QuicPacketSequenceNumber missing = kNoSequenceNumber; | 91 QuicPacketSequenceNumber missing = kNoSequenceNumber; |
91 for (QuicPacketSequenceNumber i = min_protected_packet_; | 92 for (QuicPacketSequenceNumber i = min_protected_packet_; |
92 i <= max_protected_packet_; ++i) { | 93 i <= max_protected_packet_; |
| 94 ++i) { |
93 // Is this packet missing? | 95 // Is this packet missing? |
94 if (received_packets_.count(i) == 0) { | 96 if (received_packets_.count(i) == 0) { |
95 missing = i; | 97 missing = i; |
96 break; | 98 break; |
97 } | 99 } |
98 } | 100 } |
99 DCHECK_NE(kNoSequenceNumber, missing); | 101 DCHECK_NE(kNoSequenceNumber, missing); |
100 | 102 |
101 DCHECK_LE(payload_parity_len_, decrypted_payload_len); | 103 DCHECK_LE(payload_parity_len_, decrypted_payload_len); |
102 if (payload_parity_len_ > decrypted_payload_len) { | 104 if (payload_parity_len_ > decrypted_payload_len) { |
(...skipping 22 matching lines...) Expand all Loading... |
125 bool QuicFecGroup::UpdateParity(StringPiece payload) { | 127 bool QuicFecGroup::UpdateParity(StringPiece payload) { |
126 DCHECK_LE(payload.size(), kMaxPacketSize); | 128 DCHECK_LE(payload.size(), kMaxPacketSize); |
127 if (payload.size() > kMaxPacketSize) { | 129 if (payload.size() > kMaxPacketSize) { |
128 DLOG(ERROR) << "Illegal payload size: " << payload.size(); | 130 DLOG(ERROR) << "Illegal payload size: " << payload.size(); |
129 return false; | 131 return false; |
130 } | 132 } |
131 if (payload_parity_len_ < payload.size()) { | 133 if (payload_parity_len_ < payload.size()) { |
132 payload_parity_len_ = payload.size(); | 134 payload_parity_len_ = payload.size(); |
133 } | 135 } |
134 DCHECK_LE(payload.size(), kMaxPacketSize); | 136 DCHECK_LE(payload.size(), kMaxPacketSize); |
135 if (received_packets_.empty() && | 137 if (received_packets_.empty() && min_protected_packet_ == kNoSequenceNumber) { |
136 min_protected_packet_ == kNoSequenceNumber) { | |
137 // Initialize the parity to the value of this payload | 138 // Initialize the parity to the value of this payload |
138 memcpy(payload_parity_, payload.data(), payload.size()); | 139 memcpy(payload_parity_, payload.data(), payload.size()); |
139 if (payload.size() < kMaxPacketSize) { | 140 if (payload.size() < kMaxPacketSize) { |
140 // TODO(rch): expand as needed. | 141 // TODO(rch): expand as needed. |
141 memset(payload_parity_ + payload.size(), 0, | 142 memset( |
142 kMaxPacketSize - payload.size()); | 143 payload_parity_ + payload.size(), 0, kMaxPacketSize - payload.size()); |
143 } | 144 } |
144 return true; | 145 return true; |
145 } | 146 } |
146 // Update the parity by XORing in the data (padding with 0s if necessary). | 147 // Update the parity by XORing in the data (padding with 0s if necessary). |
147 for (size_t i = 0; i < kMaxPacketSize; ++i) { | 148 for (size_t i = 0; i < kMaxPacketSize; ++i) { |
148 uint8 byte = i < payload.size() ? payload[i] : 0x00; | 149 uint8 byte = i < payload.size() ? payload[i] : 0x00; |
149 payload_parity_[i] ^= byte; | 150 payload_parity_[i] ^= byte; |
150 } | 151 } |
151 return true; | 152 return true; |
152 } | 153 } |
153 | 154 |
154 size_t QuicFecGroup::NumMissingPackets() const { | 155 size_t QuicFecGroup::NumMissingPackets() const { |
155 if (min_protected_packet_ == kNoSequenceNumber) | 156 if (min_protected_packet_ == kNoSequenceNumber) |
156 return numeric_limits<size_t>::max(); | 157 return numeric_limits<size_t>::max(); |
157 return (max_protected_packet_ - min_protected_packet_ + 1) - | 158 return (max_protected_packet_ - min_protected_packet_ + 1) - |
158 received_packets_.size(); | 159 received_packets_.size(); |
159 } | 160 } |
160 | 161 |
161 } // namespace net | 162 } // namespace net |
OLD | NEW |