From a40826dd44fdb06af81fb921ae0544c32b90cf9b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 28 Nov 2017 11:56:23 +0000 Subject: [PATCH] Update to the latest jitter buffer for compilation issues. --- JitterBuffer.cpp | 94 ++++++++++++++++++++++++++++++++---------------- JitterBuffer.h | 14 ++++---- 2 files changed, 72 insertions(+), 36 deletions(-) diff --git a/JitterBuffer.cpp b/JitterBuffer.cpp index 3a12efd..cc9cb20 100644 --- a/JitterBuffer.cpp +++ b/JitterBuffer.cpp @@ -18,27 +18,32 @@ #include "JitterBuffer.h" +#include "Log.h" + #include #include +#include -CJitterBuffer::CJitterBuffer(unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber) : +CJitterBuffer::CJitterBuffer(unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber, bool debug) : m_blockSize(blockSize), m_blockTime(blockTime), m_topSequenceNumber(topSequenceNumber), +m_debug(debug), m_blockCount(0U), m_timer(1000U, 0U, jitterTime), m_stopWatch(), m_buffer(NULL), m_headSequenceNumber(0U), m_lastData(NULL), -m_lastDataValid(false) +m_lastDataLength(0U), +m_running(false) { assert(blockSize > 0U); assert(blockTime > 0U); assert(jitterTime > 0U); assert(topSequenceNumber > 0U); - m_blockCount = jitterTime / blockTime + 1U; + m_blockCount = (jitterTime / blockTime) * 2U + 1U; m_buffer = new JitterEntry[m_blockCount]; @@ -59,20 +64,28 @@ CJitterBuffer::~CJitterBuffer() delete[] m_lastData; } -bool CJitterBuffer::addData(const unsigned char* data, unsigned int sequenceNumber) +bool CJitterBuffer::addData(const unsigned char* data, unsigned int length, unsigned int sequenceNumber) { assert(data != NULL); + assert(length > 0U); + assert(length <= m_blockSize); unsigned int headSequenceNumber = m_headSequenceNumber % m_topSequenceNumber; unsigned int tailSequenceNumber = (m_headSequenceNumber + m_blockCount) % m_topSequenceNumber; // Is the data out of sequence? if (headSequenceNumber < tailSequenceNumber) { - if (sequenceNumber < headSequenceNumber || sequenceNumber >= tailSequenceNumber) + if (sequenceNumber < headSequenceNumber || sequenceNumber >= tailSequenceNumber) { + if (m_debug) + LogDebug("JitterBuffer: rejecting frame with seqNo=%u, raw=%u, head=%u, tail=%u", sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber); return false; + } } else { - if (sequenceNumber >= tailSequenceNumber && sequenceNumber < headSequenceNumber) + if (sequenceNumber >= tailSequenceNumber && sequenceNumber < headSequenceNumber) { + if (m_debug) + LogDebug("JitterBuffer: rejecting frame with seqNo=%u, raw=%u, head=%u, tail=%u", sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber); return false; + } } unsigned int number; @@ -84,70 +97,91 @@ bool CJitterBuffer::addData(const unsigned char* data, unsigned int sequenceNumb unsigned int index = (m_headSequenceNumber + number) % m_blockCount; // Do we already have the data? - if (m_buffer[index].m_used) + if (m_buffer[index].m_length > 0U) { + if (m_debug) + LogDebug("JitterBuffer: rejecting duplicate frame with seqNo=%u, raw=%u, head=%u, tail=%u", sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber); return false; + } - ::memcpy(m_buffer[index].m_data, data, m_blockSize); - m_buffer[index].m_used = true; + LogDebug("JitterBuffer: adding frame with seqNo=%u, raw=%u, head=%u, tail=%u", sequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber); - if (!m_timer.isRunning()) + ::memcpy(m_buffer[index].m_data, data, length); + m_buffer[index].m_length = length; + + if (!m_timer.isRunning()) { + LogDebug("JitterBuffer: starting the timer"); m_timer.start(); + } return true; } -JB_STATUS CJitterBuffer::getData(unsigned char* data) +JB_STATUS CJitterBuffer::getData(unsigned char* data, unsigned int& length) { assert(data != NULL); - if (!m_timer.isRunning() || !m_timer.hasExpired()) { - m_stopWatch.start(); + if (!m_running) return JBS_NO_DATA; - } - unsigned int sequenceNumber = m_stopWatch.elapsed() / m_blockTime; + unsigned int sequenceNumber = m_stopWatch.elapsed() / m_blockTime + 3U; if (m_headSequenceNumber > sequenceNumber) return JBS_NO_DATA; unsigned int head = m_headSequenceNumber % m_blockCount; - if (m_buffer[head].m_used) { - ::memcpy(data, m_buffer[head].m_data, m_blockSize); - m_buffer[head].m_used = false; + m_headSequenceNumber++; + + if (m_buffer[head].m_length > 0U) { + LogDebug("JitterBuffer: returning data, elapsed=%ums, raw=%u, head=%u", m_stopWatch.elapsed(), m_headSequenceNumber - 1U, head); + + ::memcpy(data, m_buffer[head].m_data, m_buffer[head].m_length); + length = m_buffer[head].m_length; // Save this data in case no more data is available next time - ::memcpy(m_lastData, m_buffer[head].m_data, m_blockSize); - m_lastDataValid = true; + ::memcpy(m_lastData, m_buffer[head].m_data, m_buffer[head].m_length); + m_lastDataLength = m_buffer[head].m_length; - m_headSequenceNumber++; + m_buffer[head].m_length = 0U; return JBS_DATA; } - // Return the last data frame or null data if none exists - if (m_lastDataValid) - ::memcpy(data, m_lastData, m_blockSize); - else - ::memset(data, 0x00U, m_blockSize); + if (m_debug) + LogDebug("JitterBuffer: no data available, elapsed=%ums, raw=%u, head=%u", m_stopWatch.elapsed(), m_headSequenceNumber - 1U, head); - m_headSequenceNumber++; + // Return the last data frame if we have it + if (m_lastDataLength > 0U) { + LogDebug("JitterBuffer: returning the last received frame"); + ::memcpy(data, m_lastData, m_lastDataLength); + length = m_lastDataLength; - return JBS_MISSING; + return JBS_MISSING; + } + + return JBS_NO_DATA; } void CJitterBuffer::reset() { for (unsigned int i = 0U; i < m_blockCount; i++) - m_buffer[i].m_used = false; + m_buffer[i].m_length = 0U; m_headSequenceNumber = 0U; - m_lastDataValid = false; + m_lastDataLength = 0U; m_timer.stop(); + + m_running = false; } void CJitterBuffer::clock(unsigned int ms) { m_timer.clock(ms); + if (m_timer.isRunning() && m_timer.hasExpired()) { + if (!m_running) { + m_stopWatch.start(); + m_running = true; + } + } } diff --git a/JitterBuffer.h b/JitterBuffer.h index 74fb1d8..37471e6 100644 --- a/JitterBuffer.h +++ b/JitterBuffer.h @@ -30,12 +30,12 @@ enum JB_STATUS { class CJitterBuffer { public: - CJitterBuffer(unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber); + CJitterBuffer(unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber, bool debug); ~CJitterBuffer(); - bool addData(const unsigned char* data, unsigned int sequenceNumber); + bool addData(const unsigned char* data, unsigned int length, unsigned int sequenceNumber); - JB_STATUS getData(unsigned char* data); + JB_STATUS getData(unsigned char* data, unsigned int& length); void reset(); @@ -45,21 +45,23 @@ private: unsigned int m_blockSize; unsigned int m_blockTime; unsigned int m_topSequenceNumber; + bool m_debug; unsigned int m_blockCount; CTimer m_timer; CStopWatch m_stopWatch; - + bool m_running; + struct JitterEntry { unsigned char* m_data; - bool m_used; + unsigned int m_length; }; JitterEntry* m_buffer; unsigned int m_headSequenceNumber; unsigned char* m_lastData; - bool m_lastDataValid; + unsigned int m_lastDataLength; }; #endif