112 lines
2.5 KiB
C
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;
|
|
}
|