freepassport-c/src/frame_queue.c
2026-03-27 21:45:40 -04:00

112 lines
2.5 KiB
C

#include "frame_queue.h"
#include <stdlib.h>
#include <string.h>
void frame_data_free(FrameData *frame) {
if (!frame) {
return;
}
free(frame->pixels);
memset(frame, 0, sizeof(*frame));
}
int frame_queue_init(FrameQueue *queue) {
if (!queue) {
return -1;
}
memset(queue, 0, sizeof(*queue));
queue->mutex = SDL_CreateMutex();
queue->cond = SDL_CreateCond();
return (queue->mutex && queue->cond) ? 0 : -1;
}
void frame_queue_clear(FrameQueue *queue) {
if (!queue || !queue->mutex) {
return;
}
SDL_LockMutex(queue->mutex);
while (queue->count > 0) {
frame_data_free(&queue->frames[queue->head]);
queue->head = (queue->head + 1) % FRAME_QUEUE_CAPACITY;
queue->count -= 1;
}
queue->head = 0;
SDL_UnlockMutex(queue->mutex);
}
void frame_queue_destroy(FrameQueue *queue) {
if (!queue) {
return;
}
frame_queue_clear(queue);
if (queue->cond) {
SDL_DestroyCond(queue->cond);
}
if (queue->mutex) {
SDL_DestroyMutex(queue->mutex);
}
memset(queue, 0, sizeof(*queue));
}
int frame_queue_push(FrameQueue *queue, FrameData *frame) {
int tail;
if (!queue || !frame || !queue->mutex) {
return -1;
}
SDL_LockMutex(queue->mutex);
if (queue->count == FRAME_QUEUE_CAPACITY) {
frame_data_free(&queue->frames[queue->head]);
queue->head = (queue->head + 1) % FRAME_QUEUE_CAPACITY;
queue->count -= 1;
}
tail = (queue->head + queue->count) % FRAME_QUEUE_CAPACITY;
queue->frames[tail] = *frame;
memset(frame, 0, sizeof(*frame));
queue->count += 1;
SDL_CondSignal(queue->cond);
SDL_UnlockMutex(queue->mutex);
return 0;
}
int frame_queue_pop_latest(FrameQueue *queue, FrameData *out) {
int latest_index;
if (!queue || !out || !queue->mutex) {
return 0;
}
SDL_LockMutex(queue->mutex);
if (queue->count == 0) {
SDL_UnlockMutex(queue->mutex);
return 0;
}
latest_index = (queue->head + queue->count - 1) % FRAME_QUEUE_CAPACITY;
*out = queue->frames[latest_index];
memset(&queue->frames[latest_index], 0, sizeof(queue->frames[latest_index]));
while (queue->count > 0) {
if (queue->head == latest_index) {
queue->head = 0;
queue->count = 0;
break;
}
frame_data_free(&queue->frames[queue->head]);
queue->head = (queue->head + 1) % FRAME_QUEUE_CAPACITY;
queue->count -= 1;
}
SDL_UnlockMutex(queue->mutex);
return 1;
}