#ifndef FRAME_QUEUE_H
#define FRAME_QUEUE_H

#include <stdint.h>
#include <SDL2/SDL.h>

#define FRAME_QUEUE_CAPACITY 6
#define TARGET_WIDTH 640
#define TARGET_HEIGHT 360
#define VIDEO_BUFFER_POOL_SIZE 16

typedef struct FrameData {
    unsigned char *buffer;
    struct VideoBufferPool *pool;
    unsigned char *plane_y;
    unsigned char *plane_u;
    unsigned char *plane_v;
    int width;
    int height;
    int pitch_y;
    int pitch_u;
    int pitch_v;
    double pts_seconds;
} FrameData;

typedef struct FrameQueue {
    FrameData frames[FRAME_QUEUE_CAPACITY];
    int head;
    int count;
    SDL_mutex *mutex;
    SDL_cond *cond;
} FrameQueue;

typedef struct VideoBufferPool {
    unsigned char *buffers[VIDEO_BUFFER_POOL_SIZE];
    int buffer_size;
    int available[VIDEO_BUFFER_POOL_SIZE];
    SDL_mutex *mutex;
} VideoBufferPool;

int frame_queue_init(FrameQueue *queue);
void frame_queue_destroy(FrameQueue *queue);
void frame_queue_clear(FrameQueue *queue);
int frame_queue_push(FrameQueue *queue, FrameData *frame);
int frame_queue_pop_latest(FrameQueue *queue, FrameData *out);
int frame_queue_peek_first(FrameQueue *queue, FrameData *out);
int frame_queue_pop_first(FrameQueue *queue, FrameData *out);
void frame_data_free(FrameData *frame);
int frame_queue_is_full(FrameQueue *queue);

int video_buffer_pool_init(VideoBufferPool *pool);
void video_buffer_pool_destroy(VideoBufferPool *pool);
unsigned char *video_buffer_pool_acquire(VideoBufferPool *pool);
void video_buffer_pool_release(VideoBufferPool *pool, unsigned char *buffer);

#endif
