OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 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 14 matching lines...) Expand all Loading... |
25 | 25 |
26 VCMSessionInfo::VCMSessionInfo() | 26 VCMSessionInfo::VCMSessionInfo() |
27 : session_nack_(false), | 27 : session_nack_(false), |
28 complete_(false), | 28 complete_(false), |
29 decodable_(false), | 29 decodable_(false), |
30 frame_type_(kVideoFrameDelta), | 30 frame_type_(kVideoFrameDelta), |
31 packets_(), | 31 packets_(), |
32 empty_seq_num_low_(-1), | 32 empty_seq_num_low_(-1), |
33 empty_seq_num_high_(-1), | 33 empty_seq_num_high_(-1), |
34 first_packet_seq_num_(-1), | 34 first_packet_seq_num_(-1), |
35 last_packet_seq_num_(-1) { | 35 last_packet_seq_num_(-1) {} |
36 } | |
37 | 36 |
38 void VCMSessionInfo::UpdateDataPointers(const uint8_t* old_base_ptr, | 37 void VCMSessionInfo::UpdateDataPointers(const uint8_t* old_base_ptr, |
39 const uint8_t* new_base_ptr) { | 38 const uint8_t* new_base_ptr) { |
40 for (PacketIterator it = packets_.begin(); it != packets_.end(); ++it) | 39 for (PacketIterator it = packets_.begin(); it != packets_.end(); ++it) |
41 if ((*it).dataPtr != NULL) { | 40 if ((*it).dataPtr != NULL) { |
42 assert(old_base_ptr != NULL && new_base_ptr != NULL); | 41 assert(old_base_ptr != NULL && new_base_ptr != NULL); |
43 (*it).dataPtr = new_base_ptr + ((*it).dataPtr - old_base_ptr); | 42 (*it).dataPtr = new_base_ptr + ((*it).dataPtr - old_base_ptr); |
44 } | 43 } |
45 } | 44 } |
46 | 45 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 return kNoTemporalIdx; | 80 return kNoTemporalIdx; |
82 } | 81 } |
83 } | 82 } |
84 | 83 |
85 bool VCMSessionInfo::LayerSync() const { | 84 bool VCMSessionInfo::LayerSync() const { |
86 if (packets_.empty()) | 85 if (packets_.empty()) |
87 return false; | 86 return false; |
88 if (packets_.front().codecSpecificHeader.codec == kRtpVideoVp8) { | 87 if (packets_.front().codecSpecificHeader.codec == kRtpVideoVp8) { |
89 return packets_.front().codecSpecificHeader.codecHeader.VP8.layerSync; | 88 return packets_.front().codecSpecificHeader.codecHeader.VP8.layerSync; |
90 } else if (packets_.front().codecSpecificHeader.codec == kRtpVideoVp9) { | 89 } else if (packets_.front().codecSpecificHeader.codec == kRtpVideoVp9) { |
91 return | 90 return packets_.front() |
92 packets_.front().codecSpecificHeader.codecHeader.VP9.temporal_up_switch; | 91 .codecSpecificHeader.codecHeader.VP9.temporal_up_switch; |
93 } else { | 92 } else { |
94 return false; | 93 return false; |
95 } | 94 } |
96 } | 95 } |
97 | 96 |
98 int VCMSessionInfo::Tl0PicId() const { | 97 int VCMSessionInfo::Tl0PicId() const { |
99 if (packets_.empty()) | 98 if (packets_.empty()) |
100 return kNoTl0PicIdx; | 99 return kNoTl0PicIdx; |
101 if (packets_.front().codecSpecificHeader.codec == kRtpVideoVp8) { | 100 if (packets_.front().codecSpecificHeader.codec == kRtpVideoVp8) { |
102 return packets_.front().codecSpecificHeader.codecHeader.VP8.tl0PicIdx; | 101 return packets_.front().codecSpecificHeader.codecHeader.VP8.tl0PicIdx; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 required_length += | 185 required_length += |
187 length + (packet.insertStartCode ? kH264StartCodeLengthBytes : 0); | 186 length + (packet.insertStartCode ? kH264StartCodeLengthBytes : 0); |
188 nalu_ptr += kLengthFieldLength + length; | 187 nalu_ptr += kLengthFieldLength + length; |
189 } | 188 } |
190 ShiftSubsequentPackets(packet_it, required_length); | 189 ShiftSubsequentPackets(packet_it, required_length); |
191 nalu_ptr = packet_buffer + kH264NALHeaderLengthInBytes; | 190 nalu_ptr = packet_buffer + kH264NALHeaderLengthInBytes; |
192 uint8_t* frame_buffer_ptr = frame_buffer + offset; | 191 uint8_t* frame_buffer_ptr = frame_buffer + offset; |
193 while (nalu_ptr < packet_buffer + packet.sizeBytes) { | 192 while (nalu_ptr < packet_buffer + packet.sizeBytes) { |
194 size_t length = BufferToUWord16(nalu_ptr); | 193 size_t length = BufferToUWord16(nalu_ptr); |
195 nalu_ptr += kLengthFieldLength; | 194 nalu_ptr += kLengthFieldLength; |
196 frame_buffer_ptr += Insert(nalu_ptr, | 195 frame_buffer_ptr += Insert(nalu_ptr, length, packet.insertStartCode, |
197 length, | |
198 packet.insertStartCode, | |
199 const_cast<uint8_t*>(frame_buffer_ptr)); | 196 const_cast<uint8_t*>(frame_buffer_ptr)); |
200 nalu_ptr += length; | 197 nalu_ptr += length; |
201 } | 198 } |
202 packet.sizeBytes = required_length; | 199 packet.sizeBytes = required_length; |
203 return packet.sizeBytes; | 200 return packet.sizeBytes; |
204 } | 201 } |
205 ShiftSubsequentPackets( | 202 ShiftSubsequentPackets( |
206 packet_it, | 203 packet_it, packet.sizeBytes + |
207 packet.sizeBytes + | 204 (packet.insertStartCode ? kH264StartCodeLengthBytes : 0)); |
208 (packet.insertStartCode ? kH264StartCodeLengthBytes : 0)); | |
209 | 205 |
210 packet.sizeBytes = Insert(packet_buffer, | 206 packet.sizeBytes = |
211 packet.sizeBytes, | 207 Insert(packet_buffer, packet.sizeBytes, packet.insertStartCode, |
212 packet.insertStartCode, | 208 const_cast<uint8_t*>(packet.dataPtr)); |
213 const_cast<uint8_t*>(packet.dataPtr)); | |
214 return packet.sizeBytes; | 209 return packet.sizeBytes; |
215 } | 210 } |
216 | 211 |
217 size_t VCMSessionInfo::Insert(const uint8_t* buffer, | 212 size_t VCMSessionInfo::Insert(const uint8_t* buffer, |
218 size_t length, | 213 size_t length, |
219 bool insert_start_code, | 214 bool insert_start_code, |
220 uint8_t* frame_buffer) { | 215 uint8_t* frame_buffer) { |
221 if (insert_start_code) { | 216 if (insert_start_code) { |
222 const unsigned char startCode[] = {0, 0, 0, 1}; | 217 const unsigned char startCode[] = {0, 0, 0, 1}; |
223 memcpy(frame_buffer, startCode, kH264StartCodeLengthBytes); | 218 memcpy(frame_buffer, startCode, kH264StartCodeLengthBytes); |
224 } | 219 } |
225 memcpy(frame_buffer + (insert_start_code ? kH264StartCodeLengthBytes : 0), | 220 memcpy(frame_buffer + (insert_start_code ? kH264StartCodeLengthBytes : 0), |
226 buffer, | 221 buffer, length); |
227 length); | |
228 length += (insert_start_code ? kH264StartCodeLengthBytes : 0); | 222 length += (insert_start_code ? kH264StartCodeLengthBytes : 0); |
229 | 223 |
230 return length; | 224 return length; |
231 } | 225 } |
232 | 226 |
233 void VCMSessionInfo::ShiftSubsequentPackets(PacketIterator it, | 227 void VCMSessionInfo::ShiftSubsequentPackets(PacketIterator it, |
234 int steps_to_shift) { | 228 int steps_to_shift) { |
235 ++it; | 229 ++it; |
236 if (it == packets_.end()) | 230 if (it == packets_.end()) |
237 return; | 231 return; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 if (complete_ || decodable_) | 263 if (complete_ || decodable_) |
270 return; | 264 return; |
271 // TODO(agalusza): Account for bursty loss. | 265 // TODO(agalusza): Account for bursty loss. |
272 // TODO(agalusza): Refine these values to better approximate optimal ones. | 266 // TODO(agalusza): Refine these values to better approximate optimal ones. |
273 // Do not decode frames if the RTT is lower than this. | 267 // Do not decode frames if the RTT is lower than this. |
274 const int64_t kRttThreshold = 100; | 268 const int64_t kRttThreshold = 100; |
275 // Do not decode frames if the number of packets is between these two | 269 // Do not decode frames if the number of packets is between these two |
276 // thresholds. | 270 // thresholds. |
277 const float kLowPacketPercentageThreshold = 0.2f; | 271 const float kLowPacketPercentageThreshold = 0.2f; |
278 const float kHighPacketPercentageThreshold = 0.8f; | 272 const float kHighPacketPercentageThreshold = 0.8f; |
279 if (frame_data.rtt_ms < kRttThreshold | 273 if (frame_data.rtt_ms < kRttThreshold || frame_type_ == kVideoFrameKey || |
280 || frame_type_ == kVideoFrameKey | 274 !HaveFirstPacket() || |
281 || !HaveFirstPacket() | 275 (NumPackets() <= kHighPacketPercentageThreshold * |
282 || (NumPackets() <= kHighPacketPercentageThreshold | 276 frame_data.rolling_average_packets_per_frame && |
283 * frame_data.rolling_average_packets_per_frame | 277 NumPackets() > kLowPacketPercentageThreshold * |
284 && NumPackets() > kLowPacketPercentageThreshold | 278 frame_data.rolling_average_packets_per_frame)) |
285 * frame_data.rolling_average_packets_per_frame)) | |
286 return; | 279 return; |
287 | 280 |
288 decodable_ = true; | 281 decodable_ = true; |
289 } | 282 } |
290 | 283 |
291 bool VCMSessionInfo::complete() const { | 284 bool VCMSessionInfo::complete() const { |
292 return complete_; | 285 return complete_; |
293 } | 286 } |
294 | 287 |
295 bool VCMSessionInfo::decodable() const { | 288 bool VCMSessionInfo::decodable() const { |
296 return decodable_; | 289 return decodable_; |
297 } | 290 } |
298 | 291 |
299 // Find the end of the NAL unit which the packet pointed to by |packet_it| | 292 // Find the end of the NAL unit which the packet pointed to by |packet_it| |
300 // belongs to. Returns an iterator to the last packet of the frame if the end | 293 // belongs to. Returns an iterator to the last packet of the frame if the end |
301 // of the NAL unit wasn't found. | 294 // of the NAL unit wasn't found. |
302 VCMSessionInfo::PacketIterator VCMSessionInfo::FindNaluEnd( | 295 VCMSessionInfo::PacketIterator VCMSessionInfo::FindNaluEnd( |
303 PacketIterator packet_it) const { | 296 PacketIterator packet_it) const { |
304 if ((*packet_it).completeNALU == kNaluEnd || | 297 if ((*packet_it).completeNALU == kNaluEnd || |
305 (*packet_it).completeNALU == kNaluComplete) { | 298 (*packet_it).completeNALU == kNaluComplete) { |
306 return packet_it; | 299 return packet_it; |
307 } | 300 } |
308 // Find the end of the NAL unit. | 301 // Find the end of the NAL unit. |
309 for (; packet_it != packets_.end(); ++packet_it) { | 302 for (; packet_it != packets_.end(); ++packet_it) { |
310 if (((*packet_it).completeNALU == kNaluComplete && | 303 if (((*packet_it).completeNALU == kNaluComplete && |
311 (*packet_it).sizeBytes > 0) || | 304 (*packet_it).sizeBytes > 0) || |
312 // Found next NALU. | 305 // Found next NALU. |
313 (*packet_it).completeNALU == kNaluStart) | 306 (*packet_it).completeNALU == kNaluStart) |
314 return --packet_it; | 307 return --packet_it; |
315 if ((*packet_it).completeNALU == kNaluEnd) | 308 if ((*packet_it).completeNALU == kNaluEnd) |
316 return packet_it; | 309 return packet_it; |
317 } | 310 } |
318 // The end wasn't found. | 311 // The end wasn't found. |
319 return --packet_it; | 312 return --packet_it; |
320 } | 313 } |
321 | 314 |
(...skipping 19 matching lines...) Expand all Loading... |
341 uint8_t* frame_buffer, | 334 uint8_t* frame_buffer, |
342 size_t frame_buffer_length, | 335 size_t frame_buffer_length, |
343 RTPFragmentationHeader* fragmentation) { | 336 RTPFragmentationHeader* fragmentation) { |
344 size_t new_length = 0; | 337 size_t new_length = 0; |
345 // Allocate space for max number of partitions | 338 // Allocate space for max number of partitions |
346 fragmentation->VerifyAndAllocateFragmentationHeader(kMaxVP8Partitions); | 339 fragmentation->VerifyAndAllocateFragmentationHeader(kMaxVP8Partitions); |
347 fragmentation->fragmentationVectorSize = 0; | 340 fragmentation->fragmentationVectorSize = 0; |
348 memset(fragmentation->fragmentationLength, 0, | 341 memset(fragmentation->fragmentationLength, 0, |
349 kMaxVP8Partitions * sizeof(size_t)); | 342 kMaxVP8Partitions * sizeof(size_t)); |
350 if (packets_.empty()) | 343 if (packets_.empty()) |
351 return new_length; | 344 return new_length; |
352 PacketIterator it = FindNextPartitionBeginning(packets_.begin()); | 345 PacketIterator it = FindNextPartitionBeginning(packets_.begin()); |
353 while (it != packets_.end()) { | 346 while (it != packets_.end()) { |
354 const int partition_id = | 347 const int partition_id = |
355 (*it).codecSpecificHeader.codecHeader.VP8.partitionId; | 348 (*it).codecSpecificHeader.codecHeader.VP8.partitionId; |
356 PacketIterator partition_end = FindPartitionEnd(it); | 349 PacketIterator partition_end = FindPartitionEnd(it); |
357 fragmentation->fragmentationOffset[partition_id] = | 350 fragmentation->fragmentationOffset[partition_id] = |
358 (*it).dataPtr - frame_buffer; | 351 (*it).dataPtr - frame_buffer; |
359 assert(fragmentation->fragmentationOffset[partition_id] < | 352 assert(fragmentation->fragmentationOffset[partition_id] < |
360 frame_buffer_length); | 353 frame_buffer_length); |
361 fragmentation->fragmentationLength[partition_id] = | 354 fragmentation->fragmentationLength[partition_id] = |
362 (*partition_end).dataPtr + (*partition_end).sizeBytes - (*it).dataPtr; | 355 (*partition_end).dataPtr + (*partition_end).sizeBytes - (*it).dataPtr; |
363 assert(fragmentation->fragmentationLength[partition_id] <= | 356 assert(fragmentation->fragmentationLength[partition_id] <= |
364 frame_buffer_length); | 357 frame_buffer_length); |
365 new_length += fragmentation->fragmentationLength[partition_id]; | 358 new_length += fragmentation->fragmentationLength[partition_id]; |
366 ++partition_end; | 359 ++partition_end; |
367 it = FindNextPartitionBeginning(partition_end); | 360 it = FindNextPartitionBeginning(partition_end); |
368 if (partition_id + 1 > fragmentation->fragmentationVectorSize) | 361 if (partition_id + 1 > fragmentation->fragmentationVectorSize) |
369 fragmentation->fragmentationVectorSize = partition_id + 1; | 362 fragmentation->fragmentationVectorSize = partition_id + 1; |
370 } | 363 } |
371 // Set all empty fragments to start where the previous fragment ends, | 364 // Set all empty fragments to start where the previous fragment ends, |
372 // and have zero length. | 365 // and have zero length. |
373 if (fragmentation->fragmentationLength[0] == 0) | 366 if (fragmentation->fragmentationLength[0] == 0) |
374 fragmentation->fragmentationOffset[0] = 0; | 367 fragmentation->fragmentationOffset[0] = 0; |
375 for (int i = 1; i < fragmentation->fragmentationVectorSize; ++i) { | 368 for (int i = 1; i < fragmentation->fragmentationVectorSize; ++i) { |
376 if (fragmentation->fragmentationLength[i] == 0) | 369 if (fragmentation->fragmentationLength[i] == 0) |
377 fragmentation->fragmentationOffset[i] = | 370 fragmentation->fragmentationOffset[i] = |
378 fragmentation->fragmentationOffset[i - 1] + | 371 fragmentation->fragmentationOffset[i - 1] + |
379 fragmentation->fragmentationLength[i - 1]; | 372 fragmentation->fragmentationLength[i - 1]; |
380 assert(i == 0 || | 373 assert(i == 0 || |
381 fragmentation->fragmentationOffset[i] >= | 374 fragmentation->fragmentationOffset[i] >= |
382 fragmentation->fragmentationOffset[i - 1]); | 375 fragmentation->fragmentationOffset[i - 1]); |
383 } | 376 } |
384 assert(new_length <= frame_buffer_length); | 377 assert(new_length <= frame_buffer_length); |
385 return new_length; | 378 return new_length; |
386 } | 379 } |
387 | 380 |
388 VCMSessionInfo::PacketIterator VCMSessionInfo::FindNextPartitionBeginning( | 381 VCMSessionInfo::PacketIterator VCMSessionInfo::FindNextPartitionBeginning( |
389 PacketIterator it) const { | 382 PacketIterator it) const { |
390 while (it != packets_.end()) { | 383 while (it != packets_.end()) { |
391 if ((*it).codecSpecificHeader.codecHeader.VP8.beginningOfPartition) { | 384 if ((*it).codecSpecificHeader.codecHeader.VP8.beginningOfPartition) { |
392 return it; | 385 return it; |
(...skipping 24 matching lines...) Expand all Loading... |
417 ++it; | 410 ++it; |
418 } | 411 } |
419 return prev_it; | 412 return prev_it; |
420 } | 413 } |
421 | 414 |
422 bool VCMSessionInfo::InSequence(const PacketIterator& packet_it, | 415 bool VCMSessionInfo::InSequence(const PacketIterator& packet_it, |
423 const PacketIterator& prev_packet_it) { | 416 const PacketIterator& prev_packet_it) { |
424 // If the two iterators are pointing to the same packet they are considered | 417 // If the two iterators are pointing to the same packet they are considered |
425 // to be in sequence. | 418 // to be in sequence. |
426 return (packet_it == prev_packet_it || | 419 return (packet_it == prev_packet_it || |
427 (static_cast<uint16_t>((*prev_packet_it).seqNum + 1) == | 420 (static_cast<uint16_t>((*prev_packet_it).seqNum + 1) == |
428 (*packet_it).seqNum)); | 421 (*packet_it).seqNum)); |
429 } | 422 } |
430 | 423 |
431 size_t VCMSessionInfo::MakeDecodable() { | 424 size_t VCMSessionInfo::MakeDecodable() { |
432 size_t return_length = 0; | 425 size_t return_length = 0; |
433 if (packets_.empty()) { | 426 if (packets_.empty()) { |
434 return 0; | 427 return 0; |
435 } | 428 } |
436 PacketIterator it = packets_.begin(); | 429 PacketIterator it = packets_.begin(); |
437 // Make sure we remove the first NAL unit if it's not decodable. | 430 // Make sure we remove the first NAL unit if it's not decodable. |
438 if ((*it).completeNALU == kNaluIncomplete || | 431 if ((*it).completeNALU == kNaluIncomplete || (*it).completeNALU == kNaluEnd) { |
439 (*it).completeNALU == kNaluEnd) { | |
440 PacketIterator nalu_end = FindNaluEnd(it); | 432 PacketIterator nalu_end = FindNaluEnd(it); |
441 return_length += DeletePacketData(it, nalu_end); | 433 return_length += DeletePacketData(it, nalu_end); |
442 it = nalu_end; | 434 it = nalu_end; |
443 } | 435 } |
444 PacketIterator prev_it = it; | 436 PacketIterator prev_it = it; |
445 // Take care of the rest of the NAL units. | 437 // Take care of the rest of the NAL units. |
446 for (; it != packets_.end(); ++it) { | 438 for (; it != packets_.end(); ++it) { |
447 bool start_of_nalu = ((*it).completeNALU == kNaluStart || | 439 bool start_of_nalu = ((*it).completeNALU == kNaluStart || |
448 (*it).completeNALU == kNaluComplete); | 440 (*it).completeNALU == kNaluComplete); |
449 if (!start_of_nalu && !InSequence(it, prev_it)) { | 441 if (!start_of_nalu && !InSequence(it, prev_it)) { |
450 // Found a sequence number gap due to packet loss. | 442 // Found a sequence number gap due to packet loss. |
451 PacketIterator nalu_end = FindNaluEnd(it); | 443 PacketIterator nalu_end = FindNaluEnd(it); |
452 return_length += DeletePacketData(it, nalu_end); | 444 return_length += DeletePacketData(it, nalu_end); |
453 it = nalu_end; | 445 it = nalu_end; |
454 } | 446 } |
455 prev_it = it; | 447 prev_it = it; |
456 } | 448 } |
457 return return_length; | 449 return return_length; |
458 } | 450 } |
459 | 451 |
460 void VCMSessionInfo::SetNotDecodableIfIncomplete() { | 452 void VCMSessionInfo::SetNotDecodableIfIncomplete() { |
461 // We don't need to check for completeness first because the two are | 453 // We don't need to check for completeness first because the two are |
462 // orthogonal. If complete_ is true, decodable_ is irrelevant. | 454 // orthogonal. If complete_ is true, decodable_ is irrelevant. |
463 decodable_ = false; | 455 decodable_ = false; |
464 } | 456 } |
465 | 457 |
466 bool | 458 bool VCMSessionInfo::HaveFirstPacket() const { |
467 VCMSessionInfo::HaveFirstPacket() const { | |
468 return !packets_.empty() && (first_packet_seq_num_ != -1); | 459 return !packets_.empty() && (first_packet_seq_num_ != -1); |
469 } | 460 } |
470 | 461 |
471 bool | 462 bool VCMSessionInfo::HaveLastPacket() const { |
472 VCMSessionInfo::HaveLastPacket() const { | |
473 return !packets_.empty() && (last_packet_seq_num_ != -1); | 463 return !packets_.empty() && (last_packet_seq_num_ != -1); |
474 } | 464 } |
475 | 465 |
476 bool | 466 bool VCMSessionInfo::session_nack() const { |
477 VCMSessionInfo::session_nack() const { | |
478 return session_nack_; | 467 return session_nack_; |
479 } | 468 } |
480 | 469 |
481 int VCMSessionInfo::InsertPacket(const VCMPacket& packet, | 470 int VCMSessionInfo::InsertPacket(const VCMPacket& packet, |
482 uint8_t* frame_buffer, | 471 uint8_t* frame_buffer, |
483 VCMDecodeErrorMode decode_error_mode, | 472 VCMDecodeErrorMode decode_error_mode, |
484 const FrameData& frame_data) { | 473 const FrameData& frame_data) { |
485 if (packet.frameType == kEmptyFrame) { | 474 if (packet.frameType == kEmptyFrame) { |
486 // Update sequence number of an empty packet. | 475 // Update sequence number of an empty packet. |
487 // Only media packets are inserted into the packet list. | 476 // Only media packets are inserted into the packet list. |
488 InformOfEmptyPacket(packet.seqNum); | 477 InformOfEmptyPacket(packet.seqNum); |
489 return 0; | 478 return 0; |
490 } | 479 } |
491 | 480 |
492 if (packets_.size() == kMaxPacketsInSession) { | 481 if (packets_.size() == kMaxPacketsInSession) { |
493 LOG(LS_ERROR) << "Max number of packets per frame has been reached."; | 482 LOG(LS_ERROR) << "Max number of packets per frame has been reached."; |
494 return -1; | 483 return -1; |
495 } | 484 } |
496 | 485 |
497 // Find the position of this packet in the packet list in sequence number | 486 // Find the position of this packet in the packet list in sequence number |
498 // order and insert it. Loop over the list in reverse order. | 487 // order and insert it. Loop over the list in reverse order. |
499 ReversePacketIterator rit = packets_.rbegin(); | 488 ReversePacketIterator rit = packets_.rbegin(); |
500 for (; rit != packets_.rend(); ++rit) | 489 for (; rit != packets_.rend(); ++rit) |
501 if (LatestSequenceNumber(packet.seqNum, (*rit).seqNum) == packet.seqNum) | 490 if (LatestSequenceNumber(packet.seqNum, (*rit).seqNum) == packet.seqNum) |
502 break; | 491 break; |
503 | 492 |
504 // Check for duplicate packets. | 493 // Check for duplicate packets. |
505 if (rit != packets_.rend() && | 494 if (rit != packets_.rend() && (*rit).seqNum == packet.seqNum && |
506 (*rit).seqNum == packet.seqNum && (*rit).sizeBytes > 0) | 495 (*rit).sizeBytes > 0) |
507 return -2; | 496 return -2; |
508 | 497 |
509 if (packet.codec == kVideoCodecH264) { | 498 if (packet.codec == kVideoCodecH264) { |
510 frame_type_ = packet.frameType; | 499 frame_type_ = packet.frameType; |
511 if (packet.isFirstPacket && | 500 if (packet.isFirstPacket && |
512 (first_packet_seq_num_ == -1 || | 501 (first_packet_seq_num_ == -1 || |
513 IsNewerSequenceNumber(first_packet_seq_num_, packet.seqNum))) { | 502 IsNewerSequenceNumber(first_packet_seq_num_, packet.seqNum))) { |
514 first_packet_seq_num_ = packet.seqNum; | 503 first_packet_seq_num_ = packet.seqNum; |
515 } | 504 } |
516 if (packet.markerBit && | 505 if (packet.markerBit && |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 | 554 |
566 void VCMSessionInfo::InformOfEmptyPacket(uint16_t seq_num) { | 555 void VCMSessionInfo::InformOfEmptyPacket(uint16_t seq_num) { |
567 // Empty packets may be FEC or filler packets. They are sequential and | 556 // Empty packets may be FEC or filler packets. They are sequential and |
568 // follow the data packets, therefore, we should only keep track of the high | 557 // follow the data packets, therefore, we should only keep track of the high |
569 // and low sequence numbers and may assume that the packets in between are | 558 // and low sequence numbers and may assume that the packets in between are |
570 // empty packets belonging to the same frame (timestamp). | 559 // empty packets belonging to the same frame (timestamp). |
571 if (empty_seq_num_high_ == -1) | 560 if (empty_seq_num_high_ == -1) |
572 empty_seq_num_high_ = seq_num; | 561 empty_seq_num_high_ = seq_num; |
573 else | 562 else |
574 empty_seq_num_high_ = LatestSequenceNumber(seq_num, empty_seq_num_high_); | 563 empty_seq_num_high_ = LatestSequenceNumber(seq_num, empty_seq_num_high_); |
575 if (empty_seq_num_low_ == -1 || IsNewerSequenceNumber(empty_seq_num_low_, | 564 if (empty_seq_num_low_ == -1 || |
576 seq_num)) | 565 IsNewerSequenceNumber(empty_seq_num_low_, seq_num)) |
577 empty_seq_num_low_ = seq_num; | 566 empty_seq_num_low_ = seq_num; |
578 } | 567 } |
579 | 568 |
580 } // namespace webrtc | 569 } // namespace webrtc |
OLD | NEW |