SL100_FactoryTestTool/FactoryTestTool/SourceCode/Media/VideoDecoder/RingBuffer.cpp

52 lines
1.7 KiB
C++

// RingBuffer.cpp
#include "RingBuffer.h"
RingBuffer::RingBuffer(size_t size) :
buffer(size), head(0), tail(0), capacity(size), isFull(false) {}
bool RingBuffer::push(const uint8_t* data, size_t size) {
std::unique_lock<std::mutex> lock(mtx);
size_t bytesToWrite = size;
while (bytesToWrite > 0) {
size_t spaceAvailable = (tail >= head) ? capacity - (tail - head) : head - tail;
if (isFull) {
notFull.wait(lock, [this]() { return !isFull; });
}
size_t bytesToWriteNow = std::min(bytesToWrite, spaceAvailable);
std::memcpy(&buffer[tail], data, bytesToWriteNow);
tail = (tail + bytesToWriteNow) % capacity;
if (tail == head) {
isFull = true;
}
data += bytesToWriteNow;
bytesToWrite -= bytesToWriteNow;
notEmpty.notify_one();
}
return true;
}
bool RingBuffer::pop(uint8_t* outBuffer, size_t& size) {
std::unique_lock<std::mutex> lock(mtx);
notEmpty.wait(lock, [this]() { return head != tail || isFull; });
size_t bytesAvailable = (tail >= head) ? tail - head : capacity - (head - tail);
size_t bytesToRead = std::min(size, bytesAvailable);
std::memcpy(outBuffer, &buffer[head], bytesToRead);
head = (head + bytesToRead) % capacity;
if (head == tail) {
isFull = false;
}
size = bytesToRead;
notFull.notify_one();
return bytesAvailable > 0;
}
bool RingBuffer::empty() const {
std::unique_lock<std::mutex> lock(mtx);
return !isFull && head == tail;
}
bool RingBuffer::full() const {
std::unique_lock<std::mutex> lock(mtx);
return isFull;
}