feat: add test_image module, xorg viewer sink, and feature flag build system
Feature flags (FEATURES= make variable):
glfw — GLFW + OpenGL viewer (libglfw3, libglew)
vulkan — future Vulkan renderer
turbojpeg — MJPEG decode/encode (libturbojpeg)
xorg — XRandR geometry + screen grab (libx11, libxrandr)
vaapi — VA-API hardware codec (libva)
Each flag injects -DHAVE_<FEATURE> and the relevant pkg-config flags.
Headless build: make (no FEATURES set).
test_image module (src/modules/test_image/):
Generates test frames in YUV420, YUV422, and BGRA.
Patterns: SMPTE 75% colour bars, greyscale ramp, white/black grid.
BT.601 limited-range RGB→YCbCr in write_pixel().
test_image_cli (dev/cli/):
Generates a frame and writes it as a PPM file for visual verification.
Usage: test_image_cli [--pattern bars|ramp|grid]
[--width N] [--height N]
[--format yuv420|yuv422|bgra]
--out FILE.ppm
xorg module (src/modules/xorg/):
xorg.c — full GLFW+OpenGL implementation (compiled with FEATURES=glfw)
xorg_stub.c — no-op stub (compiled otherwise; xorg_available() returns false)
Renderer: full-screen quad via gl_VertexID, three GL_R8 textures for YUV,
BT.601 matrix in fragment shader, GL_BGRA texture for packed frames.
MJPEG path: tjDecompressToYUVPlanes → planar YUV → upload (requires turbojpeg).
push_yuv420/push_bgra/push_mjpeg all usable independently.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
35
include/test_image.h
Normal file
35
include/test_image.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum Test_Pattern {
|
||||
TEST_PATTERN_BARS, /* SMPTE 75% colour bars */
|
||||
TEST_PATTERN_RAMP, /* greyscale ramp, left to right */
|
||||
TEST_PATTERN_GRID, /* white grid lines on black */
|
||||
} Test_Pattern;
|
||||
|
||||
typedef enum Test_Fmt {
|
||||
TEST_FMT_YUV420, /* planar YUV 4:2:0 */
|
||||
TEST_FMT_YUV422, /* planar YUV 4:2:2 */
|
||||
TEST_FMT_BGRA, /* packed BGRA 8:8:8:8 */
|
||||
} Test_Fmt;
|
||||
|
||||
typedef struct Test_Frame {
|
||||
uint8_t *plane[3]; /* Y/Cb/Cr; only plane[0] used for BGRA */
|
||||
int stride[3]; /* bytes per row for each plane */
|
||||
int width;
|
||||
int height;
|
||||
Test_Fmt fmt;
|
||||
} Test_Frame;
|
||||
|
||||
/*
|
||||
* Allocate a Test_Frame with correctly-sized plane buffers.
|
||||
* Width and height must be >= 2 and even.
|
||||
* Returns NULL on allocation failure.
|
||||
*/
|
||||
Test_Frame *test_image_alloc(int width, int height, Test_Fmt fmt);
|
||||
|
||||
/* Fill all planes of f with the given pattern. */
|
||||
void test_image_generate(Test_Frame *f, Test_Pattern pat);
|
||||
|
||||
void test_image_free(Test_Frame *f);
|
||||
42
include/xorg.h
Normal file
42
include/xorg.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct Xorg_Viewer Xorg_Viewer;
|
||||
|
||||
/* Returns false when compiled without HAVE_GLFW. */
|
||||
bool xorg_available(void);
|
||||
|
||||
/*
|
||||
* Open a viewer window at screen position (x, y) with the given size.
|
||||
* Returns NULL if xorg is unavailable or if window/context creation fails.
|
||||
*/
|
||||
Xorg_Viewer *xorg_viewer_open(int x, int y, int width, int height,
|
||||
const char *title);
|
||||
|
||||
/* Push a YUV 4:2:0 planar frame for immediate display. */
|
||||
bool xorg_viewer_push_yuv420(Xorg_Viewer *v,
|
||||
const uint8_t *y, const uint8_t *cb, const uint8_t *cr,
|
||||
int width, int height);
|
||||
|
||||
/* Push a packed BGRA frame for immediate display. */
|
||||
bool xorg_viewer_push_bgra(Xorg_Viewer *v,
|
||||
const uint8_t *data, int width, int height);
|
||||
|
||||
/*
|
||||
* Push a MJPEG frame. Decoded via libjpeg-turbo to planar YUV before upload.
|
||||
* Returns false if compiled without HAVE_TURBOJPEG.
|
||||
*/
|
||||
bool xorg_viewer_push_mjpeg(Xorg_Viewer *v,
|
||||
const uint8_t *data, size_t size);
|
||||
|
||||
/*
|
||||
* Process pending window events.
|
||||
* Returns false when the user has closed the window.
|
||||
* Must be called from the thread that created the viewer.
|
||||
*/
|
||||
bool xorg_viewer_poll(Xorg_Viewer *v);
|
||||
|
||||
void xorg_viewer_close(Xorg_Viewer *v);
|
||||
Reference in New Issue
Block a user