use std::{marker::PhantomPinned, pin::Pin, ptr::copy_nonoverlapping};
use cyberex::{void::*, xself::*};
use crate::{
define::{CESStreamInfo, EsPkg},
sys::*,
};
extern "C" fn DataCallBack(
data: *const ::std::os::raw::c_uchar,
len: ::std::os::raw::c_int,
info: *const ESStreamInfo,
user: *mut ::std::os::raw::c_void,
) {
let pkgs = opacue_to_mut::<Vec<EsPkg>>(user.cast());
pkgs.push(EsPkg {
payload: {
let payload = vec![0u8; len as _];
unsafe {
copy_nonoverlapping(data, payload.as_ptr() as _, len as _);
}
payload
},
info: unsafe { std::ptr::read(info) },
});
}
pub struct Dmuxer {
ptr: HyVoid<()>,
_pin: PhantomPinned,
}
impl Dmuxer {
pub fn new() -> Pin<Box<Self>> {
Box::pin(Self {
ptr: unsafe { HyVoid::from_ptr(ffDmCreate()) },
_pin: PhantomPinned,
})
}
pub fn write(self: &mut Pin<Box<Self>>, data: &[u8], info: &CESStreamInfo) -> Vec<EsPkg> {
let this = unsafe { self_mut_from_pinbox(self) };
let mut pkgs = Box::<std::vec::Vec<EsPkg>>::default();
unsafe {
ffDmStreamInput(
this.ptr.as_ptr(),
data.as_ptr(),
data.len() as i32,
info as *const _,
0 as _, mut_to_opacue(pkgs.as_mut()),
Some(DataCallBack),
None,
);
}
*pkgs
}
}
impl Drop for Dmuxer {
fn drop(&mut self) {
unsafe { ffDmDestroy(self.ptr.as_ptr()) }
}
}