properly handle sequence numbers to not skip when supressing duplicate packets

This commit is contained in:
ZappoMan 2013-11-27 15:33:48 -08:00
parent 7f9d0849bd
commit 040ad1853e
5 changed files with 37 additions and 23 deletions

View file

@ -48,6 +48,7 @@ void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char*
return; // bail since piggyback data doesn't match our versioning
}
} else {
// Note... stats packets don't have sequence numbers, so we don't want to send those to trackIncomingVoxelPacket()
return; // bail since no piggyback data
}
} // fall through to piggyback message

View file

@ -36,8 +36,7 @@ VoxelNodeData::VoxelNodeData(Node* owningNode) :
_lastVoxelPacketLength = 0;
_duplicatePacketCount = 0;
_sequenceNumber = 0;
resetVoxelPacket();
resetVoxelPacket(true); // don't bump sequence
}
void VoxelNodeData::initializeVoxelSendThread(VoxelServer* voxelServer) {
@ -48,8 +47,11 @@ void VoxelNodeData::initializeVoxelSendThread(VoxelServer* voxelServer) {
}
bool VoxelNodeData::packetIsDuplicate() const {
// since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp
// of the entire packet, we need to compare only the packet content...
if (_lastVoxelPacketLength == getPacketLength()) {
return memcmp(_lastVoxelPacket, _voxelPacket, getPacketLength()) == 0;
return memcmp(_lastVoxelPacket + VOXEL_PACKET_HEADER_SIZE,
_voxelPacket+VOXEL_PACKET_HEADER_SIZE , getPacketLength() - VOXEL_PACKET_HEADER_SIZE) == 0;
}
return false;
}
@ -88,7 +90,7 @@ bool VoxelNodeData::shouldSuppressDuplicatePacket() {
return shouldSuppress;
}
void VoxelNodeData::resetVoxelPacket() {
void VoxelNodeData::resetVoxelPacket(bool lastWasSurpressed) {
// Whenever we call this, we will keep a copy of the last packet, so we can determine if the last packet has
// changed since we last reset it. Since we know that no two packets can ever be identical without being the same
// scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing
@ -124,7 +126,9 @@ void VoxelNodeData::resetVoxelPacket() {
*sequenceAt = _sequenceNumber;
_voxelPacketAt += sizeof(VOXEL_PACKET_SEQUENCE);
_voxelPacketAvailableBytes -= sizeof(VOXEL_PACKET_SEQUENCE);
_sequenceNumber++;
if (!(lastWasSurpressed || _lastVoxelPacketLength == VOXEL_PACKET_HEADER_SIZE)) {
_sequenceNumber++;
}
// pack in timestamp
VOXEL_PACKET_SENT_TIME now = usecTimestampNow();
@ -144,12 +148,12 @@ void VoxelNodeData::writeToPacket(const unsigned char* buffer, int bytes) {
_voxelPacketAt += sizeof(VOXEL_PACKET_INTERNAL_SECTION_SIZE);
_voxelPacketAvailableBytes -= sizeof(VOXEL_PACKET_INTERNAL_SECTION_SIZE);
}
memcpy(_voxelPacketAt, buffer, bytes);
_voxelPacketAvailableBytes -= bytes;
_voxelPacketAt += bytes;
_voxelPacketWaiting = true;
assert(_voxelPacketAvailableBytes >= 0);
if (bytes <= _voxelPacketAvailableBytes) {
memcpy(_voxelPacketAt, buffer, bytes);
_voxelPacketAvailableBytes -= bytes;
_voxelPacketAt += bytes;
_voxelPacketWaiting = true;
}
}
VoxelNodeData::~VoxelNodeData() {

View file

@ -27,7 +27,7 @@ public:
VoxelNodeData(Node* owningNode);
virtual ~VoxelNodeData();
void resetVoxelPacket(); // resets voxel packet to after "V" header
void resetVoxelPacket(bool lastWasSurpressed = false); // resets voxel packet to after "V" header
void writeToPacket(const unsigned char* buffer, int bytes); // writes to end of packet

View file

@ -105,9 +105,17 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
// obscure the packet and not send it. This allows the callers and upper level logic to not need to know about
// this rate control savings.
if (nodeData->shouldSuppressDuplicatePacket()) {
nodeData->resetVoxelPacket(); // we still need to reset it though!
nodeData->resetVoxelPacket(true); // we still need to reset it though!
return packetsSent; // without sending...
}
const unsigned char* messageData = nodeData->getPacket();
int numBytesPacketHeader = numBytesForPacketHeader(messageData);
const unsigned char* dataAt = messageData + numBytesPacketHeader;
dataAt += sizeof(VOXEL_PACKET_FLAGS);
VOXEL_PACKET_SEQUENCE sequence = (*(VOXEL_PACKET_SEQUENCE*)dataAt);
dataAt += sizeof(VOXEL_PACKET_SEQUENCE);
// If we've got a stats message ready to send, then see if we can piggyback them together
if (nodeData->stats.isReadyToSend()) {
@ -127,12 +135,12 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
int thisWastedBytes = 0;
_totalWastedBytes += thisWastedBytes;
_totalBytes += nodeData->getPacketLength();
_totalPackets++;
_totalPackets++;
if (debug) {
qDebug("Adding stats to packet at %llu [%llu]: size:%d [%llu] wasted bytes:%d [%llu]\n",
qDebug("Adding stats to packet at %llu [%llu]: sequence: %d size:%d [%llu] wasted bytes:%d [%llu]\n",
now,
_totalPackets,
nodeData->getPacketLength(), _totalBytes,
sequence, nodeData->getPacketLength(), _totalBytes,
thisWastedBytes, _totalWastedBytes);
}
@ -147,13 +155,13 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
// there was nothing else to send.
int thisWastedBytes = 0;
_totalWastedBytes += thisWastedBytes;
_totalBytes += nodeData->getPacketLength();
_totalBytes += statsMessageLength;
_totalPackets++;
if (debug) {
qDebug("Sending separate stats packet at %llu [%llu]: size:%d [%llu] wasted bytes:%d [%llu]\n",
now,
_totalPackets,
nodeData->getPacketLength(), _totalBytes,
statsMessageLength, _totalBytes,
thisWastedBytes, _totalWastedBytes);
}
@ -171,10 +179,10 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
_totalBytes += nodeData->getPacketLength();
_totalPackets++;
if (debug) {
qDebug("Sending packet at %llu [%llu]: size:%d [%llu] wasted bytes:%d [%llu]\n",
qDebug("Sending packet at %llu [%llu]: sequence: %d size:%d [%llu] wasted bytes:%d [%llu]\n",
now,
_totalPackets,
nodeData->getPacketLength(), _totalBytes,
sequence, nodeData->getPacketLength(), _totalBytes,
thisWastedBytes, _totalWastedBytes);
}
}
@ -192,10 +200,10 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
_totalBytes += nodeData->getPacketLength();
_totalPackets++;
if (debug) {
qDebug("Sending packet at %llu [%llu]: size:%d [%llu] wasted bytes:%d [%llu]\n",
qDebug("Sending packet at %llu [%llu]: sequence:%d size:%d [%llu] wasted bytes:%d [%llu]\n",
now,
_totalPackets,
nodeData->getPacketLength(), _totalBytes,
sequence, nodeData->getPacketLength(), _totalBytes,
thisWastedBytes, _totalWastedBytes);
}
}

View file

@ -832,7 +832,8 @@ void VoxelSceneStats::trackIncomingVoxelPacket(unsigned char* messageData, ssize
}
// detect likely lost packets
if (sequence > (_incomingLastSequence+1)) {
VOXEL_PACKET_SEQUENCE expected = _incomingLastSequence+1;
if (sequence > expected) {
_incomingLikelyLost++;
}