Optimise queues and rendering

This commit is contained in:
Niellune
2025-05-20 23:16:06 +03:00
parent 7f3ea88b21
commit 64f709072f
23 changed files with 585 additions and 476 deletions
+64 -20
View File
@@ -1,5 +1,5 @@
#ifndef SRC_VIDEO_BUFFER
#define SRC_VIDEO_BUFFER
#ifndef SRC_STRUCT_VIDEO_BUFFER
#define SRC_STRUCT_VIDEO_BUFFER
extern "C"
{
@@ -7,31 +7,75 @@ extern "C"
}
#include <atomic>
#include "helper/error.h"
#include <stdexcept>
#define BUFFER_VIDEO_FRAMES 3
class VideoBuffer
{
public:
VideoBuffer();
~VideoBuffer();
Error allocate(uint16_t width, uint16_t height);
uint16_t width() const { return _width; };
uint16_t height() const { return _height; };
void reset();
bool getLatest(AVFrame **frame, uint32_t *id);
void consumeLatest();
const AVFrame *writeFrame(uint32_t id);
void commitFrame();
VideoBuffer()
{
_writing.store(0);
_reading.store(-1);
_latest.store(-1);
for (uint8_t i = 0; i < BUFFER_VIDEO_FRAMES; ++i)
{
_ids[i] = 0;
_frames[i] = av_frame_alloc();
if (!_frames[i])
{
throw std::runtime_error("Failed to allocate AVFrame");
}
}
}
~VideoBuffer()
{
for (uint8_t i = 0; i < BUFFER_VIDEO_FRAMES; ++i)
{
if (_frames[i])
{
av_frame_free(&_frames[i]);
_frames[i] = nullptr;
}
}
}
bool latest(AVFrame **frame, uint32_t *id)
{
_reading.store(_latest.load());
int index = _reading.load();
if (index < 0)
return false;
*frame = _frames[index];
*id = _ids[index];
return true;
}
void consume()
{
_reading.store(-1);
}
AVFrame *write(uint32_t id)
{
int index = _writing.load();
while (index == _reading.load() || index == _latest.load())
{
index = (index + 1) % BUFFER_VIDEO_FRAMES;
}
_writing.store(index);
_ids[index] = id;
return _frames[index];
}
void commit()
{
_latest.store(_writing.load());
}
private:
void deallocate();
uint16_t _width;
uint16_t _height;
std::atomic<int8_t> _latest;
std::atomic<int8_t> _reading;
std::atomic<int8_t> _writing;
@@ -39,4 +83,4 @@ private:
uint32_t _ids[BUFFER_VIDEO_FRAMES];
};
#endif /* SRC_VIDEO_BUFFER */
#endif /* SRC_STRUCT_VIDEO_BUFFER */