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

Side by Side Diff: webrtc/modules/video_coding/packet_buffer.cc

Issue 2399373002: Only advance |first_seq_num_| if packets are explicitly cleared from the PacketBuffer. (Closed)
Patch Set: Created 4 years, 2 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 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 24 matching lines...) Expand all
35 PacketBuffer::PacketBuffer(Clock* clock, 35 PacketBuffer::PacketBuffer(Clock* clock,
36 size_t start_buffer_size, 36 size_t start_buffer_size,
37 size_t max_buffer_size, 37 size_t max_buffer_size,
38 OnReceivedFrameCallback* received_frame_callback) 38 OnReceivedFrameCallback* received_frame_callback)
39 : clock_(clock), 39 : clock_(clock),
40 size_(start_buffer_size), 40 size_(start_buffer_size),
41 max_size_(max_buffer_size), 41 max_size_(max_buffer_size),
42 first_seq_num_(0), 42 first_seq_num_(0),
43 last_seq_num_(0), 43 last_seq_num_(0),
44 first_packet_received_(false), 44 first_packet_received_(false),
45 has_cleared_to_(false),
45 data_buffer_(start_buffer_size), 46 data_buffer_(start_buffer_size),
46 sequence_buffer_(start_buffer_size), 47 sequence_buffer_(start_buffer_size),
47 received_frame_callback_(received_frame_callback) { 48 received_frame_callback_(received_frame_callback) {
48 RTC_DCHECK_LE(start_buffer_size, max_buffer_size); 49 RTC_DCHECK_LE(start_buffer_size, max_buffer_size);
49 // Buffer size must always be a power of 2. 50 // Buffer size must always be a power of 2.
50 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0); 51 RTC_DCHECK((start_buffer_size & (start_buffer_size - 1)) == 0);
51 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0); 52 RTC_DCHECK((max_buffer_size & (max_buffer_size - 1)) == 0);
52 } 53 }
53 54
54 PacketBuffer::~PacketBuffer() {} 55 PacketBuffer::~PacketBuffer() {}
danilchap 2016/10/07 18:25:37 call Clear?
philipel 2016/10/18 12:22:19 Done.
55 56
56 bool PacketBuffer::InsertPacket(const VCMPacket& packet) { 57 bool PacketBuffer::InsertPacket(const VCMPacket& packet) {
57 rtc::CritScope lock(&crit_); 58 rtc::CritScope lock(&crit_);
58 uint16_t seq_num = packet.seqNum; 59 uint16_t seq_num = packet.seqNum;
59 size_t index = seq_num % size_; 60 size_t index = seq_num % size_;
60 61
61 if (!first_packet_received_) { 62 if (!first_packet_received_) {
62 first_seq_num_ = seq_num - 1; 63 first_seq_num_ = seq_num;
63 last_seq_num_ = seq_num; 64 last_seq_num_ = seq_num;
64 first_packet_received_ = true; 65 first_packet_received_ = true;
66 } else if (AheadOf(first_seq_num_, seq_num)) {
67 // If we have explicitly cleared past this packet then it's old,
68 // don't insert it.
69 if (has_cleared_to_)
70 return false;
71
72 first_seq_num_ = seq_num;
65 } 73 }
66 74
67 if (sequence_buffer_[index].used) { 75 if (sequence_buffer_[index].used) {
68 // Duplicate packet, do nothing. 76 // Duplicate packet, do nothing.
69 if (data_buffer_[index].seqNum == packet.seqNum) 77 if (data_buffer_[index].seqNum == packet.seqNum)
70 return true; 78 return true;
danilchap 2016/10/07 18:25:37 what does return false mean for this function? if
philipel 2016/10/18 12:22:19 If |packet| is in the PacketBuffer when this funct
danilchap 2016/10/19 09:25:10 Probably would help to put this comment near Inser
philipel 2016/10/19 13:08:50 Done.
71 79
72 // The packet buffer is full, try to expand the buffer. 80 // The packet buffer is full, try to expand the buffer.
73 while (ExpandBufferSize() && sequence_buffer_[seq_num % size_].used) { 81 while (ExpandBufferSize() && sequence_buffer_[seq_num % size_].used) {
74 } 82 }
75 index = seq_num % size_; 83 index = seq_num % size_;
76 84
77 // Packet buffer is still full. 85 // Packet buffer is still full.
78 if (sequence_buffer_[index].used) 86 if (sequence_buffer_[index].used)
79 return false; 87 return false;
80 } 88 }
81 89
82 if (AheadOf(seq_num, last_seq_num_)) 90 if (AheadOf(seq_num, last_seq_num_))
83 last_seq_num_ = seq_num; 91 last_seq_num_ = seq_num;
84 92
85 sequence_buffer_[index].frame_begin = packet.isFirstPacket; 93 sequence_buffer_[index].frame_begin = packet.isFirstPacket;
86 sequence_buffer_[index].frame_end = packet.markerBit; 94 sequence_buffer_[index].frame_end = packet.markerBit;
87 sequence_buffer_[index].seq_num = packet.seqNum; 95 sequence_buffer_[index].seq_num = packet.seqNum;
88 sequence_buffer_[index].continuous = false; 96 sequence_buffer_[index].continuous = false;
89 sequence_buffer_[index].frame_created = false; 97 sequence_buffer_[index].frame_created = false;
90 sequence_buffer_[index].used = true; 98 sequence_buffer_[index].used = true;
91 data_buffer_[index] = packet; 99 data_buffer_[index] = packet;
92 100
93 // Since the data pointed to by |packet.dataPtr| is non-persistent the 101 // Since the data pointed to by |packet.dataPtr| is non-persistent the
94 // data has to be copied to its own buffer. 102 // data has to be copied to its own buffer.
95 // TODO(philipel): Take ownership instead of copying payload when 103 // TODO(philipel): Take ownership instead of copying payload when
96 // bitstream-fixing has been implemented. 104 // bitstream-fixing has been implemented.
97 if (packet.sizeBytes) { 105 if (packet.sizeBytes) {
danilchap 2016/10/07 18:25:37 if packet.sizeBytes == 0, you will not allocate bu
philipel 2016/10/18 12:22:19 I now set |packet.dataPtr| to nullptr in Clear().
98 uint8_t* payload = new uint8_t[packet.sizeBytes]; 106 uint8_t* payload = new uint8_t[packet.sizeBytes];
99 memcpy(payload, packet.dataPtr, packet.sizeBytes); 107 memcpy(payload, packet.dataPtr, packet.sizeBytes);
100 data_buffer_[index].dataPtr = payload; 108 data_buffer_[index].dataPtr = payload;
101 } 109 }
102 110
103 FindFrames(seq_num); 111 FindFrames(seq_num);
104 return true; 112 return true;
105 } 113 }
106 114
107 void PacketBuffer::ClearTo(uint16_t seq_num) { 115 void PacketBuffer::ClearTo(uint16_t seq_num) {
danilchap 2016/10/07 18:25:37 when this function is called? juts tests for now?
philipel 2016/10/18 12:22:19 For now, just in tests, but it will be used for th
108 rtc::CritScope lock(&crit_); 116 rtc::CritScope lock(&crit_);
117
118 // If the packet buffer was cleared between a frame was created and returned.
119 if (!first_packet_received_)
120 return;
121
122 has_cleared_to_ = true;
109 size_t index = first_seq_num_ % size_; 123 size_t index = first_seq_num_ % size_;
danilchap 2016/10/07 18:25:37 may be move this statement inside while loop. no n
philipel 2016/10/18 12:22:19 Done.
110 while (AheadOf<uint16_t>(seq_num, first_seq_num_ + 1)) { 124 while (AheadOrAt<uint16_t>(seq_num, first_seq_num_)) {
111 index = (index + 1) % size_;
112 ++first_seq_num_;
113 delete[] data_buffer_[index].dataPtr; 125 delete[] data_buffer_[index].dataPtr;
114 data_buffer_[index].dataPtr = nullptr; 126 data_buffer_[index].dataPtr = nullptr;
115 sequence_buffer_[index].used = false; 127 sequence_buffer_[index].used = false;
128 index = (index + 1) % size_;
129 ++first_seq_num_;
116 } 130 }
117 } 131 }
118 132
133 void PacketBuffer::Clear() {
134 rtc::CritScope lock(&crit_);
135 for (size_t i = 0; i < size_; ++i) {
136 if (sequence_buffer_[i].used)
137 delete[] data_buffer_[i].dataPtr;
138 sequence_buffer_[i].used = false;
139 }
140
141 first_packet_received_ = false;
142 has_cleared_to_ = false;
143 }
144
119 bool PacketBuffer::ExpandBufferSize() { 145 bool PacketBuffer::ExpandBufferSize() {
120 if (size_ == max_size_) 146 if (size_ == max_size_) {
147 LOG(LS_WARNING) << "PacketBuffer is already at max size (" << max_size_
148 << "), failed to increase size.";
121 return false; 149 return false;
150 }
122 151
123 size_t new_size = std::min(max_size_, 2 * size_); 152 size_t new_size = std::min(max_size_, 2 * size_);
124 std::vector<VCMPacket> new_data_buffer(new_size); 153 std::vector<VCMPacket> new_data_buffer(new_size);
125 std::vector<ContinuityInfo> new_sequence_buffer(new_size); 154 std::vector<ContinuityInfo> new_sequence_buffer(new_size);
126 for (size_t i = 0; i < size_; ++i) { 155 for (size_t i = 0; i < size_; ++i) {
127 if (sequence_buffer_[i].used) { 156 if (sequence_buffer_[i].used) {
128 size_t index = sequence_buffer_[i].seq_num % new_size; 157 size_t index = sequence_buffer_[i].seq_num % new_size;
129 new_sequence_buffer[index] = sequence_buffer_[i]; 158 new_sequence_buffer[index] = sequence_buffer_[i];
130 new_data_buffer[index] = data_buffer_[i]; 159 new_data_buffer[index] = data_buffer_[i];
131 } 160 }
132 } 161 }
133 size_ = new_size; 162 size_ = new_size;
134 sequence_buffer_ = std::move(new_sequence_buffer); 163 sequence_buffer_ = std::move(new_sequence_buffer);
135 data_buffer_ = std::move(new_data_buffer); 164 data_buffer_ = std::move(new_data_buffer);
165 LOG(LS_INFO) << "PacketBuffer size expanded to " << new_size;
136 return true; 166 return true;
137 } 167 }
138 168
139 bool PacketBuffer::IsContinuous(uint16_t seq_num) const { 169 bool PacketBuffer::PotentialNewFrame(uint16_t seq_num) const {
140 size_t index = seq_num % size_; 170 size_t index = seq_num % size_;
141 int prev_index = index > 0 ? index - 1 : size_ - 1; 171 int prev_index = index > 0 ? index - 1 : size_ - 1;
142 172
143 if (!sequence_buffer_[index].used) 173 if (!sequence_buffer_[index].used)
144 return false; 174 return false;
145 if (sequence_buffer_[index].frame_created) 175 if (sequence_buffer_[index].frame_created)
146 return false; 176 return false;
147 if (sequence_buffer_[index].frame_begin) 177 if (sequence_buffer_[index].frame_begin &&
178 (!sequence_buffer_[prev_index].used ||
179 AheadOf(seq_num, sequence_buffer_[prev_index].seq_num))) {
148 return true; 180 return true;
181 }
149 if (!sequence_buffer_[prev_index].used) 182 if (!sequence_buffer_[prev_index].used)
150 return false; 183 return false;
151 if (sequence_buffer_[prev_index].seq_num != 184 if (sequence_buffer_[prev_index].seq_num !=
152 static_cast<uint16_t>(seq_num - 1)) 185 sequence_buffer_[index].seq_num - 1) {
danilchap 2016/10/07 18:25:37 add some tests to check seq_num = 0 wraps properly
philipel 2016/10/18 12:22:19 Done.
153 return false; 186 return false;
187 }
154 if (sequence_buffer_[prev_index].continuous) 188 if (sequence_buffer_[prev_index].continuous)
155 return true; 189 return true;
156 190
157 return false; 191 return false;
158 } 192 }
159 193
160 void PacketBuffer::FindFrames(uint16_t seq_num) { 194 void PacketBuffer::FindFrames(uint16_t seq_num) {
161 size_t index = seq_num % size_; 195 size_t index = seq_num % size_;
162 while (IsContinuous(seq_num)) { 196 while (PotentialNewFrame(seq_num)) {
163 sequence_buffer_[index].continuous = true; 197 sequence_buffer_[index].continuous = true;
164 198
165 // If all packets of the frame is continuous, find the first packet of the 199 // If all packets of the frame is continuous, find the first packet of the
166 // frame and create an RtpFrameObject. 200 // frame and create an RtpFrameObject.
167 if (sequence_buffer_[index].frame_end) { 201 if (sequence_buffer_[index].frame_end) {
168 size_t frame_size = 0; 202 size_t frame_size = 0;
169 int max_nack_count = -1; 203 int max_nack_count = -1;
170 uint16_t start_seq_num = seq_num; 204 uint16_t start_seq_num = seq_num;
171 205
172 // Find the start index by searching backward until the packet with 206 // Find the start index by searching backward until the packet with
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 while (index != end) { 239 while (index != end) {
206 if (sequence_buffer_[index].seq_num == seq_num) { 240 if (sequence_buffer_[index].seq_num == seq_num) {
207 delete[] data_buffer_[index].dataPtr; 241 delete[] data_buffer_[index].dataPtr;
208 data_buffer_[index].dataPtr = nullptr; 242 data_buffer_[index].dataPtr = nullptr;
209 sequence_buffer_[index].used = false; 243 sequence_buffer_[index].used = false;
210 } 244 }
211 245
212 index = (index + 1) % size_; 246 index = (index + 1) % size_;
213 ++seq_num; 247 ++seq_num;
214 } 248 }
215
216 index = first_seq_num_ % size_;
217 while (AheadOf<uint16_t>(last_seq_num_, first_seq_num_) &&
218 !sequence_buffer_[index].used) {
219 ++first_seq_num_;
220 index = (index + 1) % size_;
221 }
222 } 249 }
223 250
224 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame, 251 bool PacketBuffer::GetBitstream(const RtpFrameObject& frame,
225 uint8_t* destination) { 252 uint8_t* destination) {
226 rtc::CritScope lock(&crit_); 253 rtc::CritScope lock(&crit_);
227 254
228 size_t index = frame.first_seq_num() % size_; 255 size_t index = frame.first_seq_num() % size_;
229 size_t end = (frame.last_seq_num() + 1) % size_; 256 size_t end = (frame.last_seq_num() + 1) % size_;
230 uint16_t seq_num = frame.first_seq_num(); 257 uint16_t seq_num = frame.first_seq_num();
231 while (index != end) { 258 while (index != end) {
(...skipping 15 matching lines...) Expand all
247 VCMPacket* PacketBuffer::GetPacket(uint16_t seq_num) { 274 VCMPacket* PacketBuffer::GetPacket(uint16_t seq_num) {
248 rtc::CritScope lock(&crit_); 275 rtc::CritScope lock(&crit_);
249 size_t index = seq_num % size_; 276 size_t index = seq_num % size_;
250 if (!sequence_buffer_[index].used || 277 if (!sequence_buffer_[index].used ||
251 seq_num != sequence_buffer_[index].seq_num) { 278 seq_num != sequence_buffer_[index].seq_num) {
252 return nullptr; 279 return nullptr;
253 } 280 }
254 return &data_buffer_[index]; 281 return &data_buffer_[index];
255 } 282 }
256 283
257 void PacketBuffer::Clear() {
258 rtc::CritScope lock(&crit_);
259 for (size_t i = 0; i < size_; ++i)
260 sequence_buffer_[i].used = false;
261
262 first_packet_received_ = false;
263 }
264
265 int PacketBuffer::AddRef() const { 284 int PacketBuffer::AddRef() const {
266 return rtc::AtomicOps::Increment(&ref_count_); 285 return rtc::AtomicOps::Increment(&ref_count_);
267 } 286 }
268 287
269 int PacketBuffer::Release() const { 288 int PacketBuffer::Release() const {
270 int count = rtc::AtomicOps::Decrement(&ref_count_); 289 int count = rtc::AtomicOps::Decrement(&ref_count_);
271 if (!count) { 290 if (!count) {
272 delete this; 291 delete this;
273 } 292 }
274 return count; 293 return count;
275 } 294 }
276 295
277 } // namespace video_coding 296 } // namespace video_coding
278 } // namespace webrtc 297 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698