code wiki / (root) / nx_video_session.nx

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 }