use super::chunk::AudioChunk;
use crate::core::scheduler::ffmpeg_scheduler::{FfmpegScheduler, Running};
use crate::error::Error;
use crossbeam_channel::Receiver;
pub struct SampleIter {
rx: Option<Receiver<AudioChunk>>,
scheduler: Option<FfmpegScheduler<Running>>,
terminated: bool,
}
impl SampleIter {
pub(crate) fn new(rx: Receiver<AudioChunk>, scheduler: FfmpegScheduler<Running>) -> Self {
Self {
rx: Some(rx),
scheduler: Some(scheduler),
terminated: false,
}
}
fn finish(&mut self) -> Option<Result<AudioChunk, Error>> {
self.terminated = true;
self.rx = None;
match self.scheduler.take() {
Some(scheduler) => match scheduler.wait() {
Ok(()) => None,
Err(e) => Some(Err(e)),
},
None => None,
}
}
}
impl Iterator for SampleIter {
type Item = Result<AudioChunk, Error>;
fn next(&mut self) -> Option<Self::Item> {
if self.terminated {
return None;
}
let recv = match self.rx.as_ref() {
Some(rx) => rx.recv(),
None => return self.finish(),
};
match recv {
Ok(chunk) => Some(Ok(chunk)),
Err(_) => self.finish(),
}
}
}
impl std::iter::FusedIterator for SampleIter {}
impl Drop for SampleIter {
fn drop(&mut self) {
self.rx = None;
if let Some(scheduler) = self.scheduler.take() {
scheduler.abort();
}
}
}