Fix issues with incorrect wrap checks when having big buffers and high bitrate.
Introduces shared functions for timestamp and sequence number wrap checks. BUG=1607 TESTS=trybots Review URL: https://webrtc-codereview.appspot.com/1291005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3833 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -51,16 +51,14 @@ bool VCMDecodingState::IsOldFrame(const VCMFrameBuffer* frame) const {
|
||||
assert(frame != NULL);
|
||||
if (in_initial_state_)
|
||||
return false;
|
||||
return (LatestTimestamp(time_stamp_, frame->TimeStamp(), NULL)
|
||||
== time_stamp_);
|
||||
return !IsNewerTimestamp(frame->TimeStamp(), time_stamp_);
|
||||
}
|
||||
|
||||
bool VCMDecodingState::IsOldPacket(const VCMPacket* packet) const {
|
||||
assert(packet != NULL);
|
||||
if (in_initial_state_)
|
||||
return false;
|
||||
return (LatestTimestamp(time_stamp_, packet->timestamp, NULL)
|
||||
== time_stamp_);
|
||||
return !IsNewerTimestamp(packet->timestamp, time_stamp_);
|
||||
}
|
||||
|
||||
void VCMDecodingState::SetState(const VCMFrameBuffer* frame) {
|
||||
@@ -106,7 +104,7 @@ void VCMDecodingState::UpdateOldPacket(const VCMPacket* packet) {
|
||||
if (packet->timestamp == time_stamp_) {
|
||||
// Late packet belonging to the last decoded frame - make sure we update the
|
||||
// last decoded sequence number.
|
||||
sequence_num_ = LatestSequenceNumber(packet->seqNum, sequence_num_, NULL);
|
||||
sequence_num_ = LatestSequenceNumber(packet->seqNum, sequence_num_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@ class FrameSmallerTimestamp {
|
||||
public:
|
||||
explicit FrameSmallerTimestamp(uint32_t timestamp) : timestamp_(timestamp) {}
|
||||
bool operator()(VCMFrameBuffer* frame) {
|
||||
return (LatestTimestamp(timestamp_, frame->TimeStamp(), NULL) ==
|
||||
timestamp_);
|
||||
return IsNewerTimestamp(timestamp_, frame->TimeStamp());
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -718,7 +717,7 @@ VCMFrameBufferEnum VCMJitterBuffer::InsertPacket(VCMEncodedFrame* encoded_frame,
|
||||
request_key_frame = true;
|
||||
}
|
||||
latest_received_sequence_number_ = LatestSequenceNumber(
|
||||
latest_received_sequence_number_, packet.seqNum, NULL);
|
||||
latest_received_sequence_number_, packet.seqNum);
|
||||
}
|
||||
|
||||
// Empty packets may bias the jitter estimate (lacking size component),
|
||||
@@ -909,12 +908,10 @@ bool VCMJitterBuffer::UpdateNackList(uint16_t sequence_number) {
|
||||
if (!last_decoded_state_.in_initial_state()) {
|
||||
latest_received_sequence_number_ = LatestSequenceNumber(
|
||||
latest_received_sequence_number_,
|
||||
last_decoded_state_.sequence_num(),
|
||||
NULL);
|
||||
last_decoded_state_.sequence_num());
|
||||
}
|
||||
bool in_order = LatestSequenceNumber(sequence_number,
|
||||
latest_received_sequence_number_, NULL) == sequence_number;
|
||||
if (in_order) {
|
||||
if (IsNewerSequenceNumber(sequence_number,
|
||||
latest_received_sequence_number_)) {
|
||||
// Push any missing sequence numbers to the NACK list.
|
||||
for (uint16_t i = latest_received_sequence_number_ + 1;
|
||||
i < sequence_number; ++i) {
|
||||
|
||||
@@ -168,10 +168,7 @@ class VCMJitterBuffer {
|
||||
public:
|
||||
bool operator() (const uint16_t& sequence_number1,
|
||||
const uint16_t& sequence_number2) const {
|
||||
if (sequence_number1 == sequence_number2)
|
||||
return false;
|
||||
return LatestSequenceNumber(sequence_number1, sequence_number2, NULL) ==
|
||||
sequence_number2;
|
||||
return IsNewerSequenceNumber(sequence_number2, sequence_number1);
|
||||
}
|
||||
};
|
||||
typedef std::set<uint16_t, SequenceNumberLessThan> SequenceNumberSet;
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "jitter_buffer_common.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
uint32_t LatestTimestamp(uint32_t timestamp1,
|
||||
uint32_t timestamp2,
|
||||
bool* has_wrapped) {
|
||||
bool wrap = (timestamp2 < 0x0000ffff && timestamp1 > 0xffff0000) ||
|
||||
(timestamp2 > 0xffff0000 && timestamp1 < 0x0000ffff);
|
||||
if (has_wrapped != NULL)
|
||||
*has_wrapped = wrap;
|
||||
if (timestamp1 > timestamp2 && !wrap)
|
||||
return timestamp1;
|
||||
else if (timestamp1 <= timestamp2 && !wrap)
|
||||
return timestamp2;
|
||||
else if (timestamp1 < timestamp2 && wrap)
|
||||
return timestamp1;
|
||||
else
|
||||
return timestamp2;
|
||||
}
|
||||
|
||||
int32_t LatestSequenceNumber(int32_t seq_num1,
|
||||
int32_t seq_num2,
|
||||
bool* has_wrapped) {
|
||||
if (seq_num1 < 0 && seq_num2 < 0)
|
||||
return -1;
|
||||
else if (seq_num1 < 0)
|
||||
return seq_num2;
|
||||
else if (seq_num2 < 0)
|
||||
return seq_num1;
|
||||
|
||||
bool wrap = (seq_num1 < 0x00ff && seq_num2 > 0xff00) ||
|
||||
(seq_num1 > 0xff00 && seq_num2 < 0x00ff);
|
||||
|
||||
if (has_wrapped != NULL)
|
||||
*has_wrapped = wrap;
|
||||
|
||||
if (seq_num2 > seq_num1 && !wrap)
|
||||
return seq_num2;
|
||||
else if (seq_num2 <= seq_num1 && !wrap)
|
||||
return seq_num1;
|
||||
else if (seq_num2 < seq_num1 && wrap)
|
||||
return seq_num2;
|
||||
else
|
||||
return seq_num1;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
@@ -59,19 +59,6 @@ enum VCMNaluCompleteness {
|
||||
kNaluIncomplete, // Packet is not beginning or end of NALU
|
||||
kNaluEnd, // Packet is the end of a NALU
|
||||
};
|
||||
|
||||
// Returns the latest of the two timestamps, compensating for wrap arounds.
|
||||
// This function assumes that the two timestamps are close in time.
|
||||
uint32_t LatestTimestamp(uint32_t timestamp1,
|
||||
uint32_t timestamp2,
|
||||
bool* has_wrapped);
|
||||
|
||||
// Returns the latest of the two sequence numbers, compensating for wrap
|
||||
// arounds. This function assumes that the two sequence numbers are close in
|
||||
// time.
|
||||
int32_t LatestSequenceNumber(int32_t seq_num1,
|
||||
int32_t seq_num2,
|
||||
bool* has_wrapped);
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_MODULES_VIDEO_CODING_JITTER_BUFFER_COMMON_H_
|
||||
|
||||
@@ -44,8 +44,9 @@ int VCMSessionInfo::LowSequenceNumber() const {
|
||||
int VCMSessionInfo::HighSequenceNumber() const {
|
||||
if (packets_.empty())
|
||||
return empty_seq_num_high_;
|
||||
return LatestSequenceNumber(packets_.back().seqNum, empty_seq_num_high_,
|
||||
NULL);
|
||||
if (empty_seq_num_high_ == -1)
|
||||
return packets_.back().seqNum;
|
||||
return LatestSequenceNumber(packets_.back().seqNum, empty_seq_num_high_);
|
||||
}
|
||||
|
||||
int VCMSessionInfo::PictureId() const {
|
||||
@@ -388,8 +389,7 @@ int VCMSessionInfo::InsertPacket(const VCMPacket& packet,
|
||||
// order and insert it. Loop over the list in reverse order.
|
||||
ReversePacketIterator rit = packets_.rbegin();
|
||||
for (; rit != packets_.rend(); ++rit)
|
||||
if (LatestSequenceNumber((*rit).seqNum, packet.seqNum, NULL) ==
|
||||
packet.seqNum)
|
||||
if (LatestSequenceNumber(packet.seqNum, (*rit).seqNum) == packet.seqNum)
|
||||
break;
|
||||
|
||||
// Check for duplicate packets.
|
||||
@@ -412,11 +412,12 @@ void VCMSessionInfo::InformOfEmptyPacket(uint16_t seq_num) {
|
||||
// follow the data packets, therefore, we should only keep track of the high
|
||||
// and low sequence numbers and may assume that the packets in between are
|
||||
// empty packets belonging to the same frame (timestamp).
|
||||
empty_seq_num_high_ = LatestSequenceNumber(seq_num, empty_seq_num_high_,
|
||||
NULL);
|
||||
if (empty_seq_num_low_ == -1 ||
|
||||
LatestSequenceNumber(seq_num, empty_seq_num_low_, NULL) ==
|
||||
empty_seq_num_low_)
|
||||
if (empty_seq_num_high_ == -1)
|
||||
empty_seq_num_high_ = seq_num;
|
||||
else
|
||||
empty_seq_num_high_ = LatestSequenceNumber(seq_num, empty_seq_num_high_);
|
||||
if (empty_seq_num_low_ == -1 || IsNewerSequenceNumber(empty_seq_num_low_,
|
||||
seq_num))
|
||||
empty_seq_num_low_ = seq_num;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@
|
||||
'generic_encoder.cc',
|
||||
'inter_frame_delay.cc',
|
||||
'jitter_buffer.cc',
|
||||
'jitter_buffer_common.cc',
|
||||
'jitter_estimator.cc',
|
||||
'media_opt_util.cc',
|
||||
'media_optimization.cc',
|
||||
|
||||
Reference in New Issue
Block a user