nx_video_session.nx source
↩ module page · 137 lines · 5288 B
1// nx_video_session.nx -- concrete video-session subtype.
2//
3// Extends nx_media_session (embedded as FIRST field). Holds a video
4// codec, image dimensions, and capture/render backend slots (filled
5// by the consumer; null until concrete backends ship).
6//
7// Consumers:
8// nx_video_room.nx -- audio + video + chat + signaling
9// future nx_screenshare -- video session over a screen-capture backend
10
11// nx_safety_envelope:
12// intended_use: reusable video session for sovereign media stack
13// sil_target: SIL2
14// evidence: composes nx_media_session + nx_codec; bench/
15// nx_video_session_smoke.nx asserts encode -> decode
16// round-trip with REAL NishiVideo v1 codec
17// verdict: NOT_YET_EVALUATED -- pending smoke
18
19import "nx_syscalls_x86_64.nx"
20import "nx_media_session.nx"
21import "nx_codec.nx"
22
23// ---- The struct ----
24
25struct nx_video_session {
26 base: nx_media_session, // FIRST -- pointer-cast-up
27
28 width: i64, // pixels
29 height: i64, // pixels
30 framerate: i64, // fps (informational)
31 codec: *nx_codec, // points at NishiVideo v1 or v2 instance
32
33 // Backend slots; null until concrete capture/render backends ship.
34 // Future: nx_video_capture (v4l2 / avfoundation / webrtc / synth)
35 // nx_video_render (sdl / wayland / canvas / tap)
36 capture: i64,
37 render: i64,
38 simulcast: i64, // future per-layer simulcast fan-out
39}
40
41const NX_VIDEO_SESSION_BYTES: i64 = 184
42
43// ---- Vtable impls ----
44
45func nx_video_session_open_impl(ms: *nx_media_session) -> i64 {
46 let s: *nx_video_session = ms as *nx_video_session
47 if s.codec as i64 == 0 {
48 s.base.state = NX_MEDIA_STATE_ERROR
49 return -1
50 }
51 s.base.state = NX_MEDIA_STATE_ACTIVE
52 return 0
53}
54
55func nx_video_session_close_impl(ms: *nx_media_session) -> i64 {
56 let s: *nx_video_session = ms as *nx_video_session
57 s.base.state = NX_MEDIA_STATE_CLOSED
58 return 0
59}
60
61func nx_video_session_on_peer_join_impl(ms: *nx_media_session,
62 peer_id: i64, reason: i64) -> i64 {
63 return 0
64}
65
66func nx_video_session_on_peer_leave_impl(ms: *nx_media_session,
67 peer_id: i64, reason: i64) -> i64 {
68 return 0
69}
70
71func nx_video_session_on_tier_change_impl(ms: *nx_media_session,
72 new_bw_tier: i64,
73 new_hw_tier: i64) -> i64 {
74 // v1: no live codec reconfig. v2 will adjust quant_step here.
75 return 0
76}
77
78func nx_video_session_health_check_impl(ms: *nx_media_session) -> i64 {
79 let s: *nx_video_session = ms as *nx_video_session
80 if s.base.state == NX_MEDIA_STATE_ACTIVE { return NX_MEDIA_HEALTH_OK }
81 if s.base.state == NX_MEDIA_STATE_ERROR { return NX_MEDIA_HEALTH_FAILING }
82 if s.base.state == NX_MEDIA_STATE_CLOSED { return NX_MEDIA_HEALTH_DEAD }
83 return NX_MEDIA_HEALTH_UNKNOWN
84}
85
86// ---- Constructor ----
87
88func nx_video_session_new(out: *nx_video_session,
89 codec: *nx_codec,
90 width: i64, height: i64, framerate: i64,
91 room_id: i64) -> i64 {
92 let ms: *nx_media_session = out as *nx_media_session
93 nx_media_session_init(ms, NX_MEDIA_KIND_VIDEO, room_id)
94
95 out.base.open_fn = nx_video_session_open_impl
96 out.base.close_fn = nx_video_session_close_impl
97 out.base.on_peer_join_fn = nx_video_session_on_peer_join_impl
98 out.base.on_peer_leave_fn = nx_video_session_on_peer_leave_impl
99 out.base.on_tier_change_fn = nx_video_session_on_tier_change_impl
100 out.base.health_check_fn = nx_video_session_health_check_impl
101
102 out.width = width
103 out.height = height
104 out.framerate = framerate
105 out.codec = codec
106 out.capture = 0
107 out.render = 0
108 out.simulcast = 0
109 return 0
110}
111
112// ---- API ----
113
114// Encode one luma-only frame (width*height bytes) to wire bytes.
115// Returns wire byte count or NX_CODEC_ERR_*.
116func nx_video_session_encode_frame(s: *nx_video_session,
117 pixels: *u8, pixels_n: i64,
118 wire_out: *u8, wire_cap: i64) -> i64 {
119 if s.codec as i64 == 0 { return NX_CODEC_ERR_NOT_SUPPORTED }
120 return nx_codec_encode(s.codec, pixels, pixels_n, wire_out, wire_cap)
121}
122
123// Decode one wire frame to luma-only pixels.
124// Returns pixel byte count or NX_CODEC_ERR_*.
125func nx_video_session_decode_frame(s: *nx_video_session,
126 wire_in: *u8, wire_n: i64,
127 pixels_out: *u8, pixels_cap: i64) -> i64 {
128 if s.codec as i64 == 0 { return NX_CODEC_ERR_NOT_SUPPORTED }
129 return nx_codec_decode(s.codec, wire_in, wire_n, pixels_out, pixels_cap)
130}
131
132// ---- Accessors ----
133
134func nx_video_session_width(s: *nx_video_session) -> i64 { return s.width }
135func nx_video_session_height(s: *nx_video_session) -> i64 { return s.height }
136func nx_video_session_framerate(s: *nx_video_session) -> i64 { return s.framerate }
137func nx_video_session_codec(s: *nx_video_session) -> *nx_codec { return s.codec }