#pragma once #include #include "error.h" typedef struct Ingest_Handle Ingest_Handle; /* * Called from the capture thread for each dequeued frame. * data points into the mmap'd buffer — valid only for the duration of the call. * Do not free data; copy if you need to retain it beyond the callback. */ typedef void (*Ingest_Frame_Fn)( const uint8_t *data, uint32_t len, int width, int height, uint32_t pixfmt, void *userdata); /* * Called from the capture thread when a fatal error terminates the capture loop. * After this callback returns, the thread exits and the handle is in a stopped * state (equivalent to after ingest_stop). msg is a static string. */ typedef void (*Ingest_Error_Fn)(const char *msg, void *userdata); struct Ingest_Config { const char *device; /* e.g. "/dev/video0" */ uint32_t pixfmt; /* V4L2_PIX_FMT_MJPEG etc.; 0 = auto (best MJPEG) */ int width; /* 0 = auto */ int height; /* 0 = auto */ Ingest_Frame_Fn on_frame; Ingest_Error_Fn on_error; /* may be NULL */ void *userdata; }; /* * Open the V4L2 device, negotiate format, allocate MMAP buffers. * Does NOT start streaming. on_frame must not be NULL. */ struct App_Error ingest_open(const struct Ingest_Config *cfg, Ingest_Handle **out); /* * Enable streaming and start the capture thread. * Must be called on a handle in the OPEN (not streaming) state. */ struct App_Error ingest_start(Ingest_Handle *h); /* * Signal the capture thread to stop and block until it exits. * Disables streaming. The handle returns to the OPEN state and can be * restarted with ingest_start or released with ingest_close. */ struct App_Error ingest_stop(Ingest_Handle *h); /* * Release MMAP buffers and close the device fd. * Must be called only when the handle is not streaming (before ingest_start * or after ingest_stop). */ void ingest_close(Ingest_Handle *h); /* Query the negotiated format — valid after a successful ingest_open. */ int ingest_width(const Ingest_Handle *h); int ingest_height(const Ingest_Handle *h); uint32_t ingest_pixfmt(const Ingest_Handle *h); int ingest_fps_n(const Ingest_Handle *h); int ingest_fps_d(const Ingest_Handle *h);