Add display sink: START_DISPLAY/STOP_DISPLAY, multi-window xorg, random port
Protocol: - Add PROTO_CMD_START_DISPLAY (0x000A) and PROTO_CMD_STOP_DISPLAY (0x000B) with write/read functions; Proto_Start_Display carries stream_id, window position/size, scale and anchor; PROTO_DISPLAY_SCALE_*/ANCHOR_* constants Node display sink: - Display_Slot struct with wanted_state/current_state (DISP_CLOSED/DISP_OPEN); handlers set wanted state, display_loop_tick on main thread reconciles - Up to MAX_DISPLAYS (4) simultaneous viewer windows - on_frame routes incoming VIDEO_FRAME messages to matching display slot; transport thread deposits payload, main thread consumes without holding lock during JPEG decode/upload - Main thread runs GL event loop when xorg is available; headless fallback joins reconciler timer thread as before Xorg multi-window: - Ref-count glfwInit/glfwTerminate via glfw_acquire/glfw_release so closing one viewer does not terminate GLFW for remaining windows - Add glfwMakeContextCurrent before GL calls in push_yuv420, push_bgra, push_mjpeg and poll so each viewer uses its own GL context correctly Transport random port: - Bind port 0 lets the OS assign a free port; getsockname reads it back into server->bound_port after bind - Add transport_server_get_port() accessor - Default tcp_port changed from 8000 to 0 (random); node prints actual port after server start so it is always visible in output - Add --port PORT CLI override (before config-file argument) controller_cli: - Add start-display and stop-display commands Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -302,6 +302,39 @@ static void cmd_stop_ingest(struct Transport_Conn *conn,
|
||||
proto_write_stop_ingest(conn, next_req_id(req), stream_id));
|
||||
}
|
||||
|
||||
static void cmd_start_display(struct Transport_Conn *conn,
|
||||
struct Ctrl_State *cs, uint16_t *req,
|
||||
int ntok, char *tokens[])
|
||||
{
|
||||
/* Required: stream_id
|
||||
* Optional: win_x win_y win_w win_h */
|
||||
if (ntok < 2) {
|
||||
printf("usage: start-display <stream_id> [win_x] [win_y] [win_w] [win_h]\n");
|
||||
return;
|
||||
}
|
||||
uint16_t stream_id = (uint16_t)atoi(tokens[1]);
|
||||
int16_t win_x = ntok > 2 ? (int16_t)atoi(tokens[2]) : 0;
|
||||
int16_t win_y = ntok > 3 ? (int16_t)atoi(tokens[3]) : 0;
|
||||
uint16_t win_w = ntok > 4 ? (uint16_t)atoi(tokens[4]) : 0;
|
||||
uint16_t win_h = ntok > 5 ? (uint16_t)atoi(tokens[5]) : 0;
|
||||
printf("start-display: stream=%u pos=%d,%d size=%ux%u\n",
|
||||
stream_id, win_x, win_y, win_w, win_h);
|
||||
SEND_AND_WAIT(cs, PROTO_CMD_START_DISPLAY,
|
||||
proto_write_start_display(conn, next_req_id(req),
|
||||
stream_id, win_x, win_y, win_w, win_h,
|
||||
PROTO_DISPLAY_SCALE_FIT, PROTO_DISPLAY_ANCHOR_CENTER));
|
||||
}
|
||||
|
||||
static void cmd_stop_display(struct Transport_Conn *conn,
|
||||
struct Ctrl_State *cs, uint16_t *req,
|
||||
const char *sid_str)
|
||||
{
|
||||
uint16_t stream_id = (uint16_t)atoi(sid_str);
|
||||
printf("stop-display: stream=%u\n", stream_id);
|
||||
SEND_AND_WAIT(cs, PROTO_CMD_STOP_DISPLAY,
|
||||
proto_write_stop_display(conn, next_req_id(req), stream_id));
|
||||
}
|
||||
|
||||
static void cmd_help(void)
|
||||
{
|
||||
printf("commands:\n"
|
||||
@@ -312,6 +345,8 @@ static void cmd_help(void)
|
||||
" start-ingest <stream_id> <device> <dest_host> <dest_port>"
|
||||
" [format] [width] [height] [fps_n] [fps_d]\n"
|
||||
" stop-ingest <stream_id>\n"
|
||||
" start-display <stream_id> [win_x] [win_y] [win_w] [win_h]\n"
|
||||
" stop-display <stream_id>\n"
|
||||
" help\n"
|
||||
" quit / exit\n");
|
||||
}
|
||||
@@ -412,6 +447,11 @@ int main(int argc, char **argv)
|
||||
} else if (strcmp(cmd, "stop-ingest") == 0) {
|
||||
if (ntok < 2) { printf("usage: stop-ingest <stream_id>\n"); }
|
||||
else { cmd_stop_ingest(conn, &cs, &req_id, tokens[1]); }
|
||||
} else if (strcmp(cmd, "start-display") == 0) {
|
||||
cmd_start_display(conn, &cs, &req_id, ntok, tokens);
|
||||
} else if (strcmp(cmd, "stop-display") == 0) {
|
||||
if (ntok < 2) { printf("usage: stop-display <stream_id>\n"); }
|
||||
else { cmd_stop_display(conn, &cs, &req_id, tokens[1]); }
|
||||
} else {
|
||||
printf("unknown command: %s (type 'help' for commands)\n", cmd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user