diff --git a/decoder/src/lib.rs b/decoder/src/lib.rs index c2a29b9..1e86c72 100644 --- a/decoder/src/lib.rs +++ b/decoder/src/lib.rs @@ -1,34 +1,48 @@ -use std::{mem::transmute, net::{self, SocketAddr}}; +use std::{mem::transmute, net::{self, SocketAddr}, slice, sync::{Mutex, OnceLock}}; -#[repr(C)] -pub struct ServerAddress { - ip_octet_1: u8, - ip_octet_2: u8, - ip_octet_3: u8, - ip_octet_4: u8, - port: u16, -} - -impl Into for ServerAddress { - fn into(self) -> SocketAddr { - SocketAddr::from(([self.ip_octet_1, self.ip_octet_2, self.ip_octet_3, self.ip_octet_4], self.port)) - } -} - -#[no_mangle] -pub extern fn connect(server: ServerAddress) -> u64 { - let _connection = net::TcpStream::connect(Into::::into(server)); - - 0 -} +use openh264::decoder::Decoder; #[no_mangle] pub extern fn add(a: u64, b: u64) -> u64 { a + b } +static DECODER: OnceLock> = OnceLock::new(); + #[no_mangle] -pub extern fn blit_red(arr: &mut u32) -> u64 { +/// reset h264 decoder +/// +/// call before opening new stream +pub extern fn reset_decoder() -> u64 { + // calls constructor twice in the reset case, not big deal + if let Err(_) = DECODER.set(Mutex::new(Decoder::new().unwrap())) { + *DECODER.get().unwrap().lock().unwrap() = Decoder::new().unwrap(); + } + + 0 +} + +#[no_mangle] +/// decode h264 packet of given length +/// +/// returns 1 if the packet contained a new frame, otherwise 0 +pub extern fn decode_h264(image: &mut u32, packet: &u8, length: u32) -> u64 { + let decoder = DECODER.get_or_init(|| Mutex::new(Decoder::new().unwrap())); + let mut decoder = decoder.lock().unwrap(); + + let packet = unsafe {slice::from_raw_parts(packet, length as usize)}; + let image: &mut [u8; 4*320*240] = unsafe{transmute(image)}; + + if let Ok(Some(frame)) = decoder.decode(packet) { + frame.write_rgba8(image); + return 1; + } + + 0 +} + +#[no_mangle] +pub extern fn blit_pattern(arr: &mut u32) -> u64 { let arr: &mut [u32; 320*240] = unsafe{transmute(arr)}; let arr: &mut [[u32; 320];240] = unsafe{transmute(arr)}; for x in 0..320 {