use crate::{define::CESStreamInfo, sys::*, util::SlicePack};
use cyberex::{void::*, xself::*};
use std::{ffi::c_uchar, marker::PhantomPinned, pin::Pin};
use anyhow::{bail, Result};
unsafe extern "C" fn comCb(data: *const c_uchar, len: ::std::os::raw::c_int, user: *mut ::std::os::raw::c_void) {
let p = opacue_to_mut::<PsMuxer>(user.cast());
p.psBuf.push(SlicePack {
ptr: HyVoidConst::from_ptr(data.cast()),
size: len as usize,
});
}
pub struct PsMuxer {
ctx: HyVoid<()>,
psBuf: Vec<SlicePack>,
_pin: PhantomPinned,
}
impl PsMuxer {
pub fn new() -> Pin<Box<Self>> {
let mut pin_obj = Box::pin(Self {
ctx: HyVoid::from_ptr(unsafe { psMCreate() }),
psBuf: Vec::new(),
_pin: PhantomPinned,
});
let this = unsafe { self_mut_from_pinbox(&mut pin_obj) };
unsafe {
psMInit(this.ctx.as_ptr(), Some(comCb), HyVoid::from_ref(this).as_ptr());
}
pin_obj
}
pub fn write<'a>(self: &'a mut Pin<Box<Self>>, data: &[u8], info: &CESStreamInfo) -> Result<Vec<&'a [u8]>> {
let this = unsafe { self_mut_from_pinbox(self) };
let ok = unsafe { psMInputData(this.ctx.as_ptr(), data.as_ptr(), data.len() as _, info as *const _) };
if ok == 0 {
bail!("psM input data fail, continue")
}
let mut v = Vec::new();
for pack in &this.psBuf {
v.push(unsafe { std::slice::from_raw_parts(pack.ptr.as_ptr().cast(), pack.size) });
}
this.psBuf.clear();
Ok(v)
}
}
impl Drop for PsMuxer {
fn drop(&mut self) {
unsafe {
psMDestroy(self.ctx.as_ptr());
}
}
}