mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 18:24:08 +02:00
added window PacketStreamStats to AudioStreamStats
This commit is contained in:
parent
b4c9e51011
commit
25f4f63a1e
8 changed files with 97 additions and 21 deletions
|
@ -641,9 +641,6 @@ void AudioMixer::run() {
|
||||||
++framesSinceCutoffEvent;
|
++framesSinceCutoffEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const quint64 TOO_LONG_SINCE_LAST_SEND_AUDIO_STREAM_STATS = 1 * USECS_PER_SECOND;
|
|
||||||
|
|
||||||
bool sendAudioStreamStats = false;
|
bool sendAudioStreamStats = false;
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
if (now - _lastSendAudioStreamStatsTime > TOO_LONG_SINCE_LAST_SEND_AUDIO_STREAM_STATS) {
|
if (now - _lastSendAudioStreamStatsTime > TOO_LONG_SINCE_LAST_SEND_AUDIO_STREAM_STATS) {
|
||||||
|
|
|
@ -21,6 +21,8 @@ class AvatarAudioRingBuffer;
|
||||||
|
|
||||||
const int SAMPLE_PHASE_DELAY_AT_90 = 20;
|
const int SAMPLE_PHASE_DELAY_AT_90 = 20;
|
||||||
|
|
||||||
|
const quint64 TOO_LONG_SINCE_LAST_SEND_AUDIO_STREAM_STATS = 1 * USECS_PER_SECOND;
|
||||||
|
|
||||||
/// Handles assignments of type AudioMixer - mixing streams of audio and re-distributing to various clients.
|
/// Handles assignments of type AudioMixer - mixing streams of audio and re-distributing to various clients.
|
||||||
class AudioMixer : public ThreadedAssignment {
|
class AudioMixer : public ThreadedAssignment {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -20,10 +20,13 @@
|
||||||
#include "AudioMixerClientData.h"
|
#include "AudioMixerClientData.h"
|
||||||
#include "MovingMinMaxAvg.h"
|
#include "MovingMinMaxAvg.h"
|
||||||
|
|
||||||
|
const int INCOMING_SEQ_STATS_HISTORY_LENGTH = INCOMING_SEQ_STATS_HISTORY_LENGTH_SECONDS /
|
||||||
|
(TOO_LONG_SINCE_LAST_SEND_AUDIO_STREAM_STATS / USECS_PER_SECOND);
|
||||||
|
|
||||||
AudioMixerClientData::AudioMixerClientData() :
|
AudioMixerClientData::AudioMixerClientData() :
|
||||||
_ringBuffers(),
|
_ringBuffers(),
|
||||||
_outgoingMixedAudioSequenceNumber(0),
|
_outgoingMixedAudioSequenceNumber(0),
|
||||||
_incomingAvatarAudioSequenceNumberStats()
|
_incomingAvatarAudioSequenceNumberStats(INCOMING_SEQ_STATS_HISTORY_LENGTH)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -89,6 +92,9 @@ int AudioMixerClientData::parseData(const QByteArray& packet) {
|
||||||
// grab the stream identifier for this injected audio
|
// grab the stream identifier for this injected audio
|
||||||
QUuid streamIdentifier = QUuid::fromRfc4122(packet.mid(numBytesForPacketHeader(packet) + sizeof(quint16), NUM_BYTES_RFC4122_UUID));
|
QUuid streamIdentifier = QUuid::fromRfc4122(packet.mid(numBytesForPacketHeader(packet) + sizeof(quint16), NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
|
if (!_incomingInjectedAudioSequenceNumberStatsMap.contains(streamIdentifier)) {
|
||||||
|
_incomingInjectedAudioSequenceNumberStatsMap.insert(streamIdentifier, SequenceNumberStats(INCOMING_SEQ_STATS_HISTORY_LENGTH));
|
||||||
|
}
|
||||||
_incomingInjectedAudioSequenceNumberStatsMap[streamIdentifier].sequenceNumberReceived(sequence);
|
_incomingInjectedAudioSequenceNumberStatsMap[streamIdentifier].sequenceNumberReceived(sequence);
|
||||||
|
|
||||||
InjectedAudioRingBuffer* matchingInjectedRingBuffer = NULL;
|
InjectedAudioRingBuffer* matchingInjectedRingBuffer = NULL;
|
||||||
|
@ -175,9 +181,12 @@ AudioStreamStats AudioMixerClientData::getAudioStreamStatsOfStream(const Positio
|
||||||
streamStats._streamType = ringBuffer->getType();
|
streamStats._streamType = ringBuffer->getType();
|
||||||
if (streamStats._streamType == PositionalAudioRingBuffer::Injector) {
|
if (streamStats._streamType == PositionalAudioRingBuffer::Injector) {
|
||||||
streamStats._streamIdentifier = ((InjectedAudioRingBuffer*)ringBuffer)->getStreamIdentifier();
|
streamStats._streamIdentifier = ((InjectedAudioRingBuffer*)ringBuffer)->getStreamIdentifier();
|
||||||
streamStats._packetStreamStats = _incomingInjectedAudioSequenceNumberStatsMap[streamStats._streamIdentifier].getStats();
|
const SequenceNumberStats& sequenceNumberStats = _incomingInjectedAudioSequenceNumberStatsMap[streamStats._streamIdentifier];
|
||||||
|
streamStats._packetStreamStats = sequenceNumberStats.getStats();
|
||||||
|
streamStats._packetStreamWindowStats = sequenceNumberStats.getStatsForHistoryWindow();
|
||||||
} else {
|
} else {
|
||||||
streamStats._packetStreamStats = _incomingAvatarAudioSequenceNumberStats.getStats();
|
streamStats._packetStreamStats = _incomingAvatarAudioSequenceNumberStats.getStats();
|
||||||
|
streamStats._packetStreamWindowStats = _incomingAvatarAudioSequenceNumberStats.getStatsForHistoryWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
const MovingMinMaxAvg<quint64>& timeGapStats = ringBuffer->getInterframeTimeGapStatsForStatsPacket();
|
const MovingMinMaxAvg<quint64>& timeGapStats = ringBuffer->getInterframeTimeGapStatsForStatsPacket();
|
||||||
|
@ -199,7 +208,17 @@ AudioStreamStats AudioMixerClientData::getAudioStreamStatsOfStream(const Positio
|
||||||
return streamStats;
|
return streamStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioMixerClientData::sendAudioStreamStatsPackets(const SharedNodePointer& destinationNode) const {
|
void AudioMixerClientData::sendAudioStreamStatsPackets(const SharedNodePointer& destinationNode) {
|
||||||
|
|
||||||
|
// have all the seq number stats of each audio stream push their current stats into their history,
|
||||||
|
// which moves that history window 1 second forward (since that's how long since the last stats were pushed into history)
|
||||||
|
_incomingAvatarAudioSequenceNumberStats.pushStatsToHistory();
|
||||||
|
QHash<QUuid, SequenceNumberStats>::Iterator i = _incomingInjectedAudioSequenceNumberStatsMap.begin();
|
||||||
|
QHash<QUuid, SequenceNumberStats>::Iterator end = _incomingInjectedAudioSequenceNumberStatsMap.end();
|
||||||
|
while (i != end) {
|
||||||
|
i.value().pushStatsToHistory();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
char packet[MAX_PACKET_SIZE];
|
char packet[MAX_PACKET_SIZE];
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
@ -251,6 +270,23 @@ void AudioMixerClientData::sendAudioStreamStatsPackets(const SharedNodePointer&
|
||||||
|
|
||||||
QString AudioMixerClientData::getAudioStreamStatsString() const {
|
QString AudioMixerClientData::getAudioStreamStatsString() const {
|
||||||
QString result;
|
QString result;
|
||||||
|
AudioStreamStats streamStats = _downstreamAudioStreamStats;
|
||||||
|
result += "downstream.desired:" + QString::number(streamStats._ringBufferDesiredJitterBufferFrames)
|
||||||
|
+ " current: ?"
|
||||||
|
+ " available:" + QString::number(streamStats._ringBufferFramesAvailable)
|
||||||
|
+ " starves:" + QString::number(streamStats._ringBufferStarveCount)
|
||||||
|
+ " not mixed:" + QString::number(streamStats._ringBufferConsecutiveNotMixedCount)
|
||||||
|
+ " overflows:" + QString::number(streamStats._ringBufferOverflowCount)
|
||||||
|
+ " silents dropped: ?"
|
||||||
|
+ " lost %:" + QString::number(streamStats._packetStreamStats.getLostRate(), 'g', 2)
|
||||||
|
+ " lost % 30s:" + QString::number(streamStats._packetStreamWindowStats.getLostRate(), 'g', 2)
|
||||||
|
+ " min gap:" + QString::number(streamStats._timeGapMin)
|
||||||
|
+ " max gap:" + QString::number(streamStats._timeGapMax)
|
||||||
|
+ " avg gap:" + QString::number(streamStats._timeGapAverage, 'g', 2)
|
||||||
|
+ " min 30s gap:" + QString::number(streamStats._timeGapWindowMin)
|
||||||
|
+ " max 30s gap:" + QString::number(streamStats._timeGapWindowMax)
|
||||||
|
+ " avg 30s gap:" + QString::number(streamStats._timeGapWindowAverage, 'g', 2);
|
||||||
|
|
||||||
AvatarAudioRingBuffer* avatarRingBuffer = getAvatarAudioRingBuffer();
|
AvatarAudioRingBuffer* avatarRingBuffer = getAvatarAudioRingBuffer();
|
||||||
if (avatarRingBuffer) {
|
if (avatarRingBuffer) {
|
||||||
AudioStreamStats streamStats = getAudioStreamStatsOfStream(avatarRingBuffer);
|
AudioStreamStats streamStats = getAudioStreamStatsOfStream(avatarRingBuffer);
|
||||||
|
@ -261,9 +297,8 @@ QString AudioMixerClientData::getAudioStreamStatsString() const {
|
||||||
+ " not mixed:" + QString::number(streamStats._ringBufferConsecutiveNotMixedCount)
|
+ " not mixed:" + QString::number(streamStats._ringBufferConsecutiveNotMixedCount)
|
||||||
+ " overflows:" + QString::number(streamStats._ringBufferOverflowCount)
|
+ " overflows:" + QString::number(streamStats._ringBufferOverflowCount)
|
||||||
+ " silents dropped:" + QString::number(streamStats._ringBufferSilentFramesDropped)
|
+ " silents dropped:" + QString::number(streamStats._ringBufferSilentFramesDropped)
|
||||||
+ " early:" + QString::number(streamStats._packetStreamStats._numEarly)
|
+ " lost %:" + QString::number(streamStats._packetStreamStats.getLostRate(), 'g', 2)
|
||||||
+ " late:" + QString::number(streamStats._packetStreamStats._numLate)
|
+ " lost % 30s:" + QString::number(streamStats._packetStreamWindowStats.getLostRate(), 'g', 2)
|
||||||
+ " lost:" + QString::number(streamStats._packetStreamStats._numLost)
|
|
||||||
+ " min gap:" + QString::number(streamStats._timeGapMin)
|
+ " min gap:" + QString::number(streamStats._timeGapMin)
|
||||||
+ " max gap:" + QString::number(streamStats._timeGapMax)
|
+ " max gap:" + QString::number(streamStats._timeGapMax)
|
||||||
+ " avg gap:" + QString::number(streamStats._timeGapAverage, 'g', 2)
|
+ " avg gap:" + QString::number(streamStats._timeGapAverage, 'g', 2)
|
||||||
|
@ -277,16 +312,15 @@ QString AudioMixerClientData::getAudioStreamStatsString() const {
|
||||||
for (int i = 0; i < _ringBuffers.size(); i++) {
|
for (int i = 0; i < _ringBuffers.size(); i++) {
|
||||||
if (_ringBuffers[i]->getType() == PositionalAudioRingBuffer::Injector) {
|
if (_ringBuffers[i]->getType() == PositionalAudioRingBuffer::Injector) {
|
||||||
AudioStreamStats streamStats = getAudioStreamStatsOfStream(_ringBuffers[i]);
|
AudioStreamStats streamStats = getAudioStreamStatsOfStream(_ringBuffers[i]);
|
||||||
result += "mic.desired:" + QString::number(streamStats._ringBufferDesiredJitterBufferFrames)
|
result += "inj.desired:" + QString::number(streamStats._ringBufferDesiredJitterBufferFrames)
|
||||||
+ " current:" + QString::number(streamStats._ringBufferCurrentJitterBufferFrames)
|
+ " current:" + QString::number(streamStats._ringBufferCurrentJitterBufferFrames)
|
||||||
+ " available:" + QString::number(streamStats._ringBufferFramesAvailable)
|
+ " available:" + QString::number(streamStats._ringBufferFramesAvailable)
|
||||||
+ " starves:" + QString::number(streamStats._ringBufferStarveCount)
|
+ " starves:" + QString::number(streamStats._ringBufferStarveCount)
|
||||||
+ " not mixed:" + QString::number(streamStats._ringBufferConsecutiveNotMixedCount)
|
+ " not mixed:" + QString::number(streamStats._ringBufferConsecutiveNotMixedCount)
|
||||||
+ " overflows:" + QString::number(streamStats._ringBufferOverflowCount)
|
+ " overflows:" + QString::number(streamStats._ringBufferOverflowCount)
|
||||||
+ " silents dropped:" + QString::number(streamStats._ringBufferSilentFramesDropped)
|
+ " silents dropped:" + QString::number(streamStats._ringBufferSilentFramesDropped)
|
||||||
+ " early:" + QString::number(streamStats._packetStreamStats._numEarly)
|
+ " lost %:" + QString::number(streamStats._packetStreamStats.getLostRate(), 'g', 2)
|
||||||
+ " late:" + QString::number(streamStats._packetStreamStats._numLate)
|
+ " lost % 30s:" + QString::number(streamStats._packetStreamWindowStats.getLostRate(), 'g', 2)
|
||||||
+ " lost:" + QString::number(streamStats._packetStreamStats._numLost)
|
|
||||||
+ " min gap:" + QString::number(streamStats._timeGapMin)
|
+ " min gap:" + QString::number(streamStats._timeGapMin)
|
||||||
+ " max gap:" + QString::number(streamStats._timeGapMax)
|
+ " max gap:" + QString::number(streamStats._timeGapMax)
|
||||||
+ " avg gap:" + QString::number(streamStats._timeGapAverage, 'g', 2)
|
+ " avg gap:" + QString::number(streamStats._timeGapAverage, 'g', 2)
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
#include "AudioStreamStats.h"
|
#include "AudioStreamStats.h"
|
||||||
#include "SequenceNumberStats.h"
|
#include "SequenceNumberStats.h"
|
||||||
|
|
||||||
|
|
||||||
|
const int INCOMING_SEQ_STATS_HISTORY_LENGTH_SECONDS = 30;
|
||||||
|
|
||||||
class AudioMixerClientData : public NodeData {
|
class AudioMixerClientData : public NodeData {
|
||||||
public:
|
public:
|
||||||
AudioMixerClientData();
|
AudioMixerClientData();
|
||||||
|
@ -35,7 +38,7 @@ public:
|
||||||
AudioStreamStats getAudioStreamStatsOfStream(const PositionalAudioRingBuffer* ringBuffer) const;
|
AudioStreamStats getAudioStreamStatsOfStream(const PositionalAudioRingBuffer* ringBuffer) const;
|
||||||
QString getAudioStreamStatsString() const;
|
QString getAudioStreamStatsString() const;
|
||||||
|
|
||||||
void sendAudioStreamStatsPackets(const SharedNodePointer& destinationNode) const;
|
void sendAudioStreamStatsPackets(const SharedNodePointer& destinationNode);
|
||||||
|
|
||||||
void incrementOutgoingMixedAudioSequenceNumber() { _outgoingMixedAudioSequenceNumber++; }
|
void incrementOutgoingMixedAudioSequenceNumber() { _outgoingMixedAudioSequenceNumber++; }
|
||||||
quint16 getOutgoingSequenceNumber() const { return _outgoingMixedAudioSequenceNumber; }
|
quint16 getOutgoingSequenceNumber() const { return _outgoingMixedAudioSequenceNumber; }
|
||||||
|
|
|
@ -33,7 +33,8 @@ public:
|
||||||
_ringBufferConsecutiveNotMixedCount(0),
|
_ringBufferConsecutiveNotMixedCount(0),
|
||||||
_ringBufferOverflowCount(0),
|
_ringBufferOverflowCount(0),
|
||||||
_ringBufferSilentFramesDropped(0),
|
_ringBufferSilentFramesDropped(0),
|
||||||
_packetStreamStats()
|
_packetStreamStats(),
|
||||||
|
_packetStreamWindowStats()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PositionalAudioRingBuffer::Type _streamType;
|
PositionalAudioRingBuffer::Type _streamType;
|
||||||
|
@ -55,6 +56,7 @@ public:
|
||||||
quint32 _ringBufferSilentFramesDropped;
|
quint32 _ringBufferSilentFramesDropped;
|
||||||
|
|
||||||
PacketStreamStats _packetStreamStats;
|
PacketStreamStats _packetStreamStats;
|
||||||
|
PacketStreamStats _packetStreamWindowStats;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AudioStreamStats_h
|
#endif // hifi_AudioStreamStats_h
|
||||||
|
|
|
@ -13,17 +13,19 @@
|
||||||
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
SequenceNumberStats::SequenceNumberStats()
|
SequenceNumberStats::SequenceNumberStats(int statsHistoryLength)
|
||||||
: _lastReceived(std::numeric_limits<quint16>::max()),
|
: _lastReceived(std::numeric_limits<quint16>::max()),
|
||||||
_missingSet(),
|
_missingSet(),
|
||||||
_stats(),
|
_stats(),
|
||||||
_lastSenderUUID()
|
_lastSenderUUID(),
|
||||||
|
_statsHistory(statsHistoryLength)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequenceNumberStats::reset() {
|
void SequenceNumberStats::reset() {
|
||||||
_missingSet.clear();
|
_missingSet.clear();
|
||||||
_stats = PacketStreamStats();
|
_stats = PacketStreamStats();
|
||||||
|
_statsHistory.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int UINT16_RANGE = std::numeric_limits<uint16_t>::max() + 1;
|
static const int UINT16_RANGE = std::numeric_limits<uint16_t>::max() + 1;
|
||||||
|
@ -168,3 +170,26 @@ void SequenceNumberStats::pruneMissingSet(const bool wantExtraDebugging) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PacketStreamStats SequenceNumberStats::getStatsForHistoryWindow() const {
|
||||||
|
|
||||||
|
const PacketStreamStats* newestStats = _statsHistory.getNewestEntry();
|
||||||
|
const PacketStreamStats* oldestStats = _statsHistory.get(_statsHistory.getNumEntries() - 1);
|
||||||
|
|
||||||
|
// this catches cases where history is length 1 or 0 (both are NULL in case of 0)
|
||||||
|
if (newestStats == oldestStats) {
|
||||||
|
return PacketStreamStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate difference between newest stats and oldest stats to get window stats
|
||||||
|
PacketStreamStats windowStats;
|
||||||
|
windowStats._numReceived = newestStats->_numReceived - oldestStats->_numReceived;
|
||||||
|
windowStats._numUnreasonable = newestStats->_numUnreasonable - oldestStats->_numUnreasonable;
|
||||||
|
windowStats._numEarly = newestStats->_numEarly - oldestStats->_numEarly;
|
||||||
|
windowStats._numLate = newestStats->_numLate - oldestStats->_numLate;
|
||||||
|
windowStats._numLost = newestStats->_numLost - oldestStats->_numLost;
|
||||||
|
windowStats._numRecovered = newestStats->_numRecovered - oldestStats->_numRecovered;
|
||||||
|
windowStats._numDuplicate = newestStats->_numDuplicate - oldestStats->_numDuplicate;
|
||||||
|
|
||||||
|
return windowStats;
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define hifi_SequenceNumberStats_h
|
#define hifi_SequenceNumberStats_h
|
||||||
|
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
#include "RingBufferHistory.h"
|
||||||
#include <quuid.h>
|
#include <quuid.h>
|
||||||
|
|
||||||
const int MAX_REASONABLE_SEQUENCE_GAP = 1000;
|
const int MAX_REASONABLE_SEQUENCE_GAP = 1000;
|
||||||
|
@ -28,6 +29,14 @@ public:
|
||||||
_numRecovered(0),
|
_numRecovered(0),
|
||||||
_numDuplicate(0)
|
_numDuplicate(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
float getUnreasonableRate() const { return (float)_numUnreasonable / _numReceived; }
|
||||||
|
float getNumEaryRate() const { return (float)_numEarly / _numReceived; }
|
||||||
|
float getLateRate() const { return (float)_numLate / _numReceived; }
|
||||||
|
float getLostRate() const { return (float)_numLost / _numReceived; }
|
||||||
|
float getRecoveredRate() const { return (float)_numRecovered / _numReceived; }
|
||||||
|
float getDuplicateRate() const { return (float)_numDuplicate / _numReceived; }
|
||||||
|
|
||||||
quint32 _numReceived;
|
quint32 _numReceived;
|
||||||
quint32 _numUnreasonable;
|
quint32 _numUnreasonable;
|
||||||
quint32 _numEarly;
|
quint32 _numEarly;
|
||||||
|
@ -39,11 +48,12 @@ public:
|
||||||
|
|
||||||
class SequenceNumberStats {
|
class SequenceNumberStats {
|
||||||
public:
|
public:
|
||||||
SequenceNumberStats();
|
SequenceNumberStats(int statsHistoryLength = 0);
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void sequenceNumberReceived(quint16 incoming, QUuid senderUUID = QUuid(), const bool wantExtraDebugging = false);
|
void sequenceNumberReceived(quint16 incoming, QUuid senderUUID = QUuid(), const bool wantExtraDebugging = false);
|
||||||
void pruneMissingSet(const bool wantExtraDebugging = false);
|
void pruneMissingSet(const bool wantExtraDebugging = false);
|
||||||
|
void pushStatsToHistory() { _statsHistory.insert(_stats); }
|
||||||
|
|
||||||
quint32 getNumReceived() const { return _stats._numReceived; }
|
quint32 getNumReceived() const { return _stats._numReceived; }
|
||||||
quint32 getNumUnreasonable() const { return _stats._numUnreasonable; }
|
quint32 getNumUnreasonable() const { return _stats._numUnreasonable; }
|
||||||
|
@ -54,6 +64,7 @@ public:
|
||||||
quint32 getNumRecovered() const { return _stats._numRecovered; }
|
quint32 getNumRecovered() const { return _stats._numRecovered; }
|
||||||
quint32 getNumDuplicate() const { return _stats._numDuplicate; }
|
quint32 getNumDuplicate() const { return _stats._numDuplicate; }
|
||||||
const PacketStreamStats& getStats() const { return _stats; }
|
const PacketStreamStats& getStats() const { return _stats; }
|
||||||
|
PacketStreamStats getStatsForHistoryWindow() const;
|
||||||
const QSet<quint16>& getMissingSet() const { return _missingSet; }
|
const QSet<quint16>& getMissingSet() const { return _missingSet; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -63,6 +74,8 @@ private:
|
||||||
PacketStreamStats _stats;
|
PacketStreamStats _stats;
|
||||||
|
|
||||||
QUuid _lastSenderUUID;
|
QUuid _lastSenderUUID;
|
||||||
|
|
||||||
|
RingBufferHistory<PacketStreamStats> _statsHistory;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_SequenceNumberStats_h
|
#endif // hifi_SequenceNumberStats_h
|
||||||
|
|
|
@ -64,11 +64,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
const T* getNewestEntry() const {
|
const T* getNewestEntry() const {
|
||||||
return &_buffer[_newestEntryAtIndex];
|
return _numEntries == 0 ? NULL : &_buffer[_newestEntryAtIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
T* getNewestEntry() {
|
T* getNewestEntry() {
|
||||||
return &_buffer[_newestEntryAtIndex];
|
return _numEntries == 0 ? NULL : &_buffer[_newestEntryAtIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
int getCapacity() const { return _capacity; }
|
int getCapacity() const { return _capacity; }
|
||||||
|
|
Loading…
Reference in a new issue