From db1a9fa09b40c36ef0e751323db066880211b2df Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 10:14:41 -0700 Subject: [PATCH 1/5] Fix for streaming error. --- libraries/metavoxels/src/MetavoxelClientManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index e69794917f..f16b6c2396 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -143,6 +143,9 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { _reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX); _reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream()); _reliableDeltaLOD = getLastAcknowledgedSendRecord()->getLOD(); + PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); + _remoteDataLOD = receiveRecord->getLOD(); + _remoteData = receiveRecord->getData(); } } else { Endpoint::handleMessage(message, in); From 02cf1f006e14a4f2fde6db2e85ea159934778d8f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 13:41:42 -0700 Subject: [PATCH 2/5] Change tests to reflect transmission changes and fixed issue with reprocessing already-handled reliable delta. --- .../src/metavoxels/MetavoxelServer.cpp | 9 ++++--- .../src/metavoxels/MetavoxelServer.h | 1 + .../metavoxels/src/MetavoxelClientManager.cpp | 8 ++++-- .../metavoxels/src/MetavoxelClientManager.h | 1 + libraries/metavoxels/src/MetavoxelMessages.h | 4 +++ tests/metavoxels/src/MetavoxelTests.cpp | 27 +++++++++++++------ tests/metavoxels/src/MetavoxelTests.h | 3 +++ 7 files changed, 40 insertions(+), 13 deletions(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index c601478f70..b0cf93fb3a 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -93,7 +93,8 @@ void MetavoxelServer::sendDeltas() { MetavoxelSession::MetavoxelSession(const SharedNodePointer& node, MetavoxelServer* server) : Endpoint(node, new PacketRecord(), NULL), _server(server), - _reliableDeltaChannel(NULL) { + _reliableDeltaChannel(NULL), + _reliableDeltaID(0) { connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleMessage(const QVariant&))); connect(&_sequencer, SIGNAL(sendAcknowledged(int)), SLOT(checkReliableDeltaReceived())); @@ -109,7 +110,8 @@ void MetavoxelSession::update() { // if we're sending a reliable delta, wait until it's acknowledged if (_reliableDeltaChannel) { Bitstream& out = _sequencer.startPacket(); - out << QVariant::fromValue(MetavoxelDeltaPendingMessage()); + MetavoxelDeltaPendingMessage msg = { _reliableDeltaID }; + out << QVariant::fromValue(msg); _sequencer.endPacket(); return; } @@ -134,7 +136,8 @@ void MetavoxelSession::update() { // go back to the beginning with the current packet and note that there's a delta pending _sequencer.getOutputStream().getUnderlying().device()->seek(start); - out << QVariant::fromValue(MetavoxelDeltaPendingMessage()); + MetavoxelDeltaPendingMessage msg = { ++_reliableDeltaID }; + out << QVariant::fromValue(msg); _sequencer.endPacket(); } else { diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index f2769f26f2..0e8db55587 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -83,6 +83,7 @@ private: MetavoxelData _reliableDeltaData; MetavoxelLOD _reliableDeltaLOD; Bitstream::WriteMappings _reliableDeltaWriteMappings; + int _reliableDeltaID; }; #endif // hifi_MetavoxelServer_h diff --git a/libraries/metavoxels/src/MetavoxelClientManager.cpp b/libraries/metavoxels/src/MetavoxelClientManager.cpp index f16b6c2396..f3ea1ae8c5 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.cpp +++ b/libraries/metavoxels/src/MetavoxelClientManager.cpp @@ -87,7 +87,8 @@ void MetavoxelClientManager::updateClient(MetavoxelClient* client) { MetavoxelClient::MetavoxelClient(const SharedNodePointer& node, MetavoxelClientManager* manager) : Endpoint(node, new PacketRecord(), new PacketRecord()), _manager(manager), - _reliableDeltaChannel(NULL) { + _reliableDeltaChannel(NULL), + _reliableDeltaID(0) { connect(_sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX), SIGNAL(receivedMessage(const QVariant&, Bitstream&)), SLOT(handleMessage(const QVariant&, Bitstream&))); @@ -139,7 +140,10 @@ void MetavoxelClient::handleMessage(const QVariant& message, Bitstream& in) { } } } else if (userType == MetavoxelDeltaPendingMessage::Type) { - if (!_reliableDeltaChannel) { + // check the id to make sure this is not a delta we've already processed + int id = message.value().id; + if (id > _reliableDeltaID) { + _reliableDeltaID = id; _reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX); _reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream()); _reliableDeltaLOD = getLastAcknowledgedSendRecord()->getLOD(); diff --git a/libraries/metavoxels/src/MetavoxelClientManager.h b/libraries/metavoxels/src/MetavoxelClientManager.h index 1f37b15c18..ad6c86c8fc 100644 --- a/libraries/metavoxels/src/MetavoxelClientManager.h +++ b/libraries/metavoxels/src/MetavoxelClientManager.h @@ -74,6 +74,7 @@ private: ReliableChannel* _reliableDeltaChannel; MetavoxelLOD _reliableDeltaLOD; + int _reliableDeltaID; }; #endif // hifi_MetavoxelClientManager_h diff --git a/libraries/metavoxels/src/MetavoxelMessages.h b/libraries/metavoxels/src/MetavoxelMessages.h index b822f1c561..91d73c08a9 100644 --- a/libraries/metavoxels/src/MetavoxelMessages.h +++ b/libraries/metavoxels/src/MetavoxelMessages.h @@ -64,6 +64,10 @@ DECLARE_STREAMABLE_METATYPE(MetavoxelDeltaMessage) /// A message indicating that metavoxel delta information is being sent on a reliable channel. class MetavoxelDeltaPendingMessage { STREAMABLE + +public: + + STREAM int id; }; DECLARE_STREAMABLE_METATYPE(MetavoxelDeltaPendingMessage) diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index 4132270620..49808fe080 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -647,7 +647,8 @@ TestEndpoint::TestEndpoint(Mode mode) : _mode(mode), _highPriorityMessagesToSend(0.0f), _reliableMessagesToSend(0.0f), - _reliableDeltaChannel(NULL) { + _reliableDeltaChannel(NULL), + _reliableDeltaID(0) { connect(&_sequencer, SIGNAL(receivedHighPriorityMessage(const QVariant&)), SLOT(handleHighPriorityMessage(const QVariant&))); @@ -908,7 +909,8 @@ bool TestEndpoint::simulate(int iterationNumber) { // if we're sending a reliable delta, wait until it's acknowledged if (_reliableDeltaChannel) { Bitstream& out = _sequencer.startPacket(); - out << QVariant::fromValue(MetavoxelDeltaPendingMessage()); + MetavoxelDeltaPendingMessage msg = { _reliableDeltaID }; + out << QVariant::fromValue(msg); _sequencer.endPacket(); return false; } @@ -932,7 +934,8 @@ bool TestEndpoint::simulate(int iterationNumber) { _reliableDeltaLOD = _lod; _sequencer.getOutputStream().getUnderlying().device()->seek(start); - out << QVariant::fromValue(MetavoxelDeltaPendingMessage()); + MetavoxelDeltaPendingMessage msg = { ++_reliableDeltaID }; + out << QVariant::fromValue(msg); _sequencer.endPacket(); } else { @@ -1081,15 +1084,22 @@ void TestEndpoint::handleMessage(const QVariant& message, Bitstream& in) { } else if (userType == MetavoxelDeltaMessage::Type) { PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); - _data.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, - _dataLOD = getLastAcknowledgedSendRecord()->getLOD()); + _remoteData.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, + _remoteDataLOD = getLastAcknowledgedSendRecord()->getLOD()); + in.reset(); + _data = _remoteData; compareMetavoxelData(); } else if (userType == MetavoxelDeltaPendingMessage::Type) { - if (!_reliableDeltaChannel) { + int id = message.value().id; + if (id > _reliableDeltaID) { + _reliableDeltaID = id; _reliableDeltaChannel = _sequencer.getReliableInputChannel(RELIABLE_DELTA_CHANNEL_INDEX); _reliableDeltaChannel->getBitstream().copyPersistentMappings(_sequencer.getInputStream()); _reliableDeltaLOD = getLastAcknowledgedSendRecord()->getLOD(); + PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); + _remoteDataLOD = receiveRecord->getLOD(); + _remoteData = receiveRecord->getData(); } } else if (userType == QMetaType::QVariantList) { foreach (const QVariant& element, message.toList()) { @@ -1107,7 +1117,7 @@ PacketRecord* TestEndpoint::maybeCreateSendRecord() const { } PacketRecord* TestEndpoint::maybeCreateReceiveRecord() const { - return new TestReceiveRecord(_dataLOD, (_mode == METAVOXEL_SERVER_MODE) ? MetavoxelData() : _data, _remoteState); + return new TestReceiveRecord(_remoteDataLOD, _remoteData, _remoteState); } void TestEndpoint::handleHighPriorityMessage(const QVariant& message) { @@ -1127,9 +1137,10 @@ void TestEndpoint::handleHighPriorityMessage(const QVariant& message) { void TestEndpoint::handleReliableMessage(const QVariant& message, Bitstream& in) { if (message.userType() == MetavoxelDeltaMessage::Type) { PacketRecord* receiveRecord = getLastAcknowledgedReceiveRecord(); - _data.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, _dataLOD = _reliableDeltaLOD); + _remoteData.readDelta(receiveRecord->getData(), receiveRecord->getLOD(), in, _remoteDataLOD = _reliableDeltaLOD); _sequencer.getInputStream().persistReadMappings(in.getAndResetReadMappings()); in.clearPersistentMappings(); + _data = _remoteData; compareMetavoxelData(); _reliableDeltaChannel = NULL; return; diff --git a/tests/metavoxels/src/MetavoxelTests.h b/tests/metavoxels/src/MetavoxelTests.h index 5d719ccfdf..ce357fbb90 100644 --- a/tests/metavoxels/src/MetavoxelTests.h +++ b/tests/metavoxels/src/MetavoxelTests.h @@ -79,6 +79,8 @@ private: MetavoxelData _data; MetavoxelLOD _dataLOD; + MetavoxelData _remoteData; + MetavoxelLOD _remoteDataLOD; MetavoxelLOD _lod; SharedObjectPointer _sphere; @@ -104,6 +106,7 @@ private: MetavoxelData _reliableDeltaData; MetavoxelLOD _reliableDeltaLOD; Bitstream::WriteMappings _reliableDeltaWriteMappings; + int _reliableDeltaID; }; /// A simple shared object. From 56361718369be6d464cbfd8bba02083675a4c67e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 14:41:16 -0700 Subject: [PATCH 3/5] Timing fix. --- assignment-client/src/metavoxels/MetavoxelServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index b0cf93fb3a..63776de7fa 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -87,7 +87,7 @@ void MetavoxelServer::sendDeltas() { int elapsed = now - _lastSend; _lastSend = now; - _sendTimer.start(qMax(0, 2 * SEND_INTERVAL - elapsed)); + _sendTimer.start(qMax(0, 2 * SEND_INTERVAL - qMax(elapsed, SEND_INTERVAL))); } MetavoxelSession::MetavoxelSession(const SharedNodePointer& node, MetavoxelServer* server) : From b6570dc4ee83971e4cd8b480cf7eafaa5854a609 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 15:10:05 -0700 Subject: [PATCH 4/5] Use congestion control on server. --- .../src/metavoxels/MetavoxelServer.cpp | 22 +++++++++++++++---- .../src/metavoxels/MetavoxelServer.h | 2 ++ .../metavoxels/src/DatagramSequencer.cpp | 2 +- libraries/metavoxels/src/DatagramSequencer.h | 4 ++-- tests/metavoxels/src/MetavoxelTests.cpp | 2 +- 5 files changed, 24 insertions(+), 8 deletions(-) diff --git a/assignment-client/src/metavoxels/MetavoxelServer.cpp b/assignment-client/src/metavoxels/MetavoxelServer.cpp index 63776de7fa..14765e2ddc 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.cpp +++ b/assignment-client/src/metavoxels/MetavoxelServer.cpp @@ -109,10 +109,7 @@ void MetavoxelSession::update() { } // if we're sending a reliable delta, wait until it's acknowledged if (_reliableDeltaChannel) { - Bitstream& out = _sequencer.startPacket(); - MetavoxelDeltaPendingMessage msg = { _reliableDeltaID }; - out << QVariant::fromValue(msg); - _sequencer.endPacket(); + sendPacketGroup(); return; } Bitstream& out = _sequencer.startPacket(); @@ -143,6 +140,9 @@ void MetavoxelSession::update() { } else { _sequencer.endPacket(); } + + // perhaps send additional packets to fill out the group + sendPacketGroup(1); } void MetavoxelSession::handleMessage(const QVariant& message, Bitstream& in) { @@ -179,3 +179,17 @@ void MetavoxelSession::checkReliableDeltaReceived() { _reliableDeltaData = MetavoxelData(); _reliableDeltaChannel = NULL; } + +void MetavoxelSession::sendPacketGroup(int alreadySent) { + int additionalPackets = _sequencer.notePacketGroup() - alreadySent; + for (int i = 0; i < additionalPackets; i++) { + Bitstream& out = _sequencer.startPacket(); + if (_reliableDeltaChannel) { + MetavoxelDeltaPendingMessage msg = { _reliableDeltaID }; + out << QVariant::fromValue(msg); + } else { + out << QVariant(); + } + _sequencer.endPacket(); + } +} diff --git a/assignment-client/src/metavoxels/MetavoxelServer.h b/assignment-client/src/metavoxels/MetavoxelServer.h index 0e8db55587..6df769227c 100644 --- a/assignment-client/src/metavoxels/MetavoxelServer.h +++ b/assignment-client/src/metavoxels/MetavoxelServer.h @@ -74,6 +74,8 @@ private slots: private: + void sendPacketGroup(int alreadySent = 0); + MetavoxelServer* _server; MetavoxelLOD _lod; diff --git a/libraries/metavoxels/src/DatagramSequencer.cpp b/libraries/metavoxels/src/DatagramSequencer.cpp index 2c594fc1ca..536cfc9dfb 100644 --- a/libraries/metavoxels/src/DatagramSequencer.cpp +++ b/libraries/metavoxels/src/DatagramSequencer.cpp @@ -79,7 +79,7 @@ ReliableChannel* DatagramSequencer::getReliableInputChannel(int index) { return channel; } -int DatagramSequencer::startPacketGroup(int desiredPackets) { +int DatagramSequencer::notePacketGroup(int desiredPackets) { // figure out how much data we have enqueued and increase the number of packets desired int totalAvailable = 0; foreach (ReliableChannel* channel, _reliableOutputChannels) { diff --git a/libraries/metavoxels/src/DatagramSequencer.h b/libraries/metavoxels/src/DatagramSequencer.h index b85916b561..b6dce464f7 100644 --- a/libraries/metavoxels/src/DatagramSequencer.h +++ b/libraries/metavoxels/src/DatagramSequencer.h @@ -108,10 +108,10 @@ public: /// Returns the intput channel at the specified index, creating it if necessary. ReliableChannel* getReliableInputChannel(int index = 0); - /// Starts a packet group. + /// Notes that we're sending a group of packets. /// \param desiredPackets the number of packets we'd like to write in the group /// \return the number of packets to write in the group - int startPacketGroup(int desiredPackets = 1); + int notePacketGroup(int desiredPackets = 1); /// Starts a new packet for transmission. /// \return a reference to the Bitstream to use for writing to the packet diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index 49808fe080..0a6a5de96d 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -859,7 +859,7 @@ bool TestEndpoint::simulate(int iterationNumber) { bytesReceived += datagram.size(); _remainingPipelineCapacity += datagram.size(); } - int packetCount = _sequencer.startPacketGroup(); + int packetCount = _sequencer.notePacketGroup(); groupsSent++; maxPacketsPerGroup = qMax(maxPacketsPerGroup, packetCount); for (int i = 0; i < packetCount; i++) { From 1b890a9e48ea88f27ff154db0851ee50c08d7754 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 8 Jul 2014 15:37:59 -0700 Subject: [PATCH 5/5] Use congestion control for client sends, too. --- libraries/metavoxels/src/Endpoint.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/metavoxels/src/Endpoint.cpp b/libraries/metavoxels/src/Endpoint.cpp index 666ffe52d9..420a52ef95 100644 --- a/libraries/metavoxels/src/Endpoint.cpp +++ b/libraries/metavoxels/src/Endpoint.cpp @@ -39,9 +39,12 @@ Endpoint::~Endpoint() { } void Endpoint::update() { - Bitstream& out = _sequencer.startPacket(); - writeUpdateMessage(out); - _sequencer.endPacket(); + int packetsToSend = _sequencer.notePacketGroup(); + for (int i = 0; i < packetsToSend; i++) { + Bitstream& out = _sequencer.startPacket(); + writeUpdateMessage(out); + _sequencer.endPacket(); + } } int Endpoint::parseData(const QByteArray& packet) {