Skip to main content

Frame Service: HDMI Frame Capture Service

frame_service is a long-running C++ service that exclusively owns /dev/video0, continuously reads frames from the detected RK628D or TC358743 HDMI capture path, and provides the latest frames, screenshots, and health status externally through a Unix domain socket.

Why Frame Service is Needed

Allowing multiple processes to directly open /dev/video0 can lead to resource conflicts and unstable states. frame_service centralizes video device management:

  • Completes HDMI sync / EDID / DV timings / VI initialization at startup;
  • Copies frames to a ring buffer at a fixed FPS;
  • Provides frames to consumers (Agent, CLI, HTTP examples, etc.) through a socket;
  • Supports restarting the capture manager on errors.

Default Parameters

ParameterDefault ValueDescription
Socket (development direct run)/tmp/frame_service.sockDefault value in frame_service_main.cpp
Socket (firmware service)/run/frame_service/frame_service.sockDefault value in init configuration
EDIDBridge-awareRK628D keeps its driver-provided 1080p60 EDID; TC358743 loads /oem/usr/share/aiden/edid/hdmi_1080p30_cta.hex
Ring size3kDefaultFrameServiceRingSize
FPS (binary default)3.0Used when frame_service is run directly without --fps
FPS (firmware service default)30S52frame_service passes --fps 30 from /etc/aiden_frame_service.conf
Screenshot max edge960Related to Go screenshot tool default compression strategy

Startup

Development mode:

./build/bin/frame_service --socket /tmp/frame_service.sock

This direct invocation uses the binary default of 3 FPS unless --fps is provided.

Firmware service:

/etc/init.d/S52frame_service start

The firmware service overrides the binary default and samples at 30 FPS by default. Change FRAME_SERVICE_FPS in /etc/aiden_frame_service.conf to tune the deployed service.

Parameters

frame_service [--socket PATH] [--device PATH] [--width N] [--height N]
[--pixel-format FMT] [--subdev PATH] [--edid PATH]
[--ring-size N] [--fps N] [--no-hdmi-sync]
[--force-trigger|--no-force-trigger]
[--require-exact-resolution|--allow-resolution-mismatch]
ParameterDescription
--socket PATHUDS socket path
--device PATHV4L2 capture device, defaults to /dev/video0
--width N / --height NRequired HDMI resolution, defaults to 1920x1080
--pixel-format FMTnv12, nv16, uyvy, yuyv, defaults to uyvy
--subdev PATHHDMI bridge subdev; the binary defaults to /dev/v4l-subdev2
--edid PATHCustom EDID hex. The firmware init script automatically selects the 1080p30 CTA EDID for TC358743 and leaves RK628D on its 1080p60 driver EDID; an explicit path overrides this policy
--force-trigger / --no-force-triggerEnable or disable one-shot startup EDID/HPD renegotiation. The init script defaults to bridge-aware auto: disabled for RK628D and enabled for TC358743. Before starting capture on TC358743, the init script also holds HPD low for 2 seconds and allows 5 seconds for the HDMI source to settle on 1080p30
--ring-size NRing buffer capacity
--fps NSampling FPS; 0 means as fast as possible
--no-hdmi-syncSkip HDMI sync helper flow
--require-exact-resolution / --allow-resolution-mismatchRequire or relax matching --width/--height; exact matching is enabled by default

Environment variables can also be used:

export FRAME_SERVICE_SOCKET=/tmp/frame_service.sock

The firmware init script leaves FRAME_SERVICE_SUBDEV empty by default and discovers a subdevice whose sysfs name contains rk628-csi or tc358743. Set an explicit path in /etc/aiden_frame_service.conf only when automatic discovery is not suitable.

CLI

frame_service_cli [--socket PATH] <health|latest-frame|screenshot|list-frames|restart> [--out PATH]

Examples:

./build/bin/frame_service_cli --socket /tmp/frame_service.sock health
./build/bin/frame_service_cli --socket /tmp/frame_service.sock screenshot --out /tmp/screenshot.bmp
./build/bin/frame_service_cli --socket /tmp/frame_service.sock latest-frame --out /tmp/frame.raw
./build/bin/frame_service_cli --socket /tmp/frame_service.sock list-frames
./build/bin/frame_service_cli --socket /tmp/frame_service.sock restart

Relationship with Agent

The Go Agent's screenshot tool accesses frame_service through FrameServiceClient. Configuration:

[hid]
frame_socket = "/run/frame_service/frame_service.sock"

Screenshot interpretation requires the model/provider to support image input. Text-only models can call screenshot but cannot understand pixel content.

Conflicts with Direct Camera Examples

frame_service exclusively owns /dev/video0 while running. To run example_camera_capture:

/etc/init.d/S52frame_service stop
./build/bin/example_camera_capture
/etc/init.d/S52frame_service start