use std::sync::Mutex;
use std::thread::ThreadId;
use bytes::Bytes;
use moq_net::Timestamp;
use super::{Backend, Codec, Config};
use crate::{Error, Frame, I420, Size, Surface};
pub(crate) const NAME: &str = "probe";
pub(crate) type Event = (&'static str, ThreadId);
static LOG: Mutex<Vec<Event>> = Mutex::new(Vec::new());
#[cfg(not(target_os = "macos"))]
static EXCLUSIVE: Mutex<()> = Mutex::new(());
#[cfg(not(target_os = "macos"))]
pub(crate) fn exclusive() -> std::sync::MutexGuard<'static, ()> {
let guard = EXCLUSIVE.lock().unwrap_or_else(|err| err.into_inner());
let _ = take();
guard
}
#[cfg(not(target_os = "macos"))]
pub(crate) fn take() -> Vec<Event> {
std::mem::take(&mut LOG.lock().unwrap())
}
fn record(what: &'static str) {
LOG.lock().unwrap().push((what, std::thread::current().id()));
}
pub(crate) const SIZE: Size = Size {
width: 320,
height: 240,
};
pub(crate) struct Probe;
impl Probe {
pub(crate) fn open(_codec: Codec, _config: &Config) -> Result<Box<dyn Backend>, Error> {
record("open");
Ok(Box::new(Self))
}
}
impl Backend for Probe {
fn decode(&mut self, _access_unit: Bytes, timestamp: Timestamp, _keyframe: bool) -> Result<Vec<Frame>, Error> {
record("decode");
let i420 = I420::new(
SIZE.width,
SIZE.height,
vec![0x80u8; I420::len(SIZE.width, SIZE.height)],
)?;
Ok(vec![Frame::new(Surface::I420(i420), timestamp)])
}
fn name(&self) -> &str {
NAME
}
}
impl Drop for Probe {
fn drop(&mut self) {
record("drop");
}
}