use std::path::PathBuf;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread::JoinHandle;
use std::time::Duration;
use crate::audio::AudioTrackHandle;
use crate::playback::SwsRgbaConverter;
use crate::playback::decode_buffer::DecodeBuffer;
use super::audio_resampling::spawn_audio_track_thread;
pub(super) struct ClipState {
pub(super) source: PathBuf,
pub(super) decode_buf: DecodeBuffer,
pub(super) timeline_start: Duration,
pub(super) timeline_end: Duration,
pub(super) in_point: Duration,
pub(super) out_point: Option<Duration>,
pub(super) transition_dur: Duration,
pub(super) audio_track: Option<AudioTrackHandle>,
pub(super) speed: f64,
pub(super) opacity: f32,
}
pub(super) struct TransitionState {
pub(super) next_idx: usize,
pub(super) start: Duration,
pub(super) duration: Duration,
}
pub(super) struct OverlayLayer {
pub(super) clips: Vec<ClipState>,
pub(super) active: usize,
pub(super) sws: SwsRgbaConverter,
pub(super) rgba: Vec<u8>,
}
#[derive(Clone, Copy)]
pub(super) struct AudioFadeConfig {
pub(super) fade_in: Duration,
pub(super) fade_out: Duration,
pub(super) clip_dur: Duration,
pub(super) in_point: Duration,
pub(super) speed: f64,
}
impl AudioFadeConfig {
pub(super) const NONE: Self = Self {
fade_in: Duration::ZERO,
fade_out: Duration::ZERO,
clip_dur: Duration::ZERO,
in_point: Duration::ZERO,
speed: 1.0,
};
}
pub(super) struct AudioOnlyTrack {
pub(super) source: PathBuf,
pub(super) timeline_start: Duration,
pub(super) timeline_end: Duration,
pub(super) in_point: Duration,
pub(super) fade_in: Duration,
pub(super) fade_out: Duration,
pub(super) clip_dur: Duration,
pub(super) handle: AudioTrackHandle,
pub(super) cancel: Option<Arc<AtomicBool>>,
pub(super) thread: Option<JoinHandle<()>>,
}
impl AudioOnlyTrack {
pub(super) fn start_at(&mut self, from_pts: Duration) {
if let Some(c) = self.cancel.take() {
c.store(true, Ordering::Release);
}
drop(self.thread.take());
self.handle.clear();
let cancel = Arc::new(AtomicBool::new(false));
let t = spawn_audio_track_thread(
self.source.clone(),
from_pts,
self.handle.clone(),
Arc::clone(&cancel),
AudioFadeConfig {
fade_in: self.fade_in,
fade_out: self.fade_out,
clip_dur: self.clip_dur,
in_point: self.in_point,
speed: 1.0,
},
);
self.cancel = Some(cancel);
self.thread = Some(t);
}
pub(super) fn stop(&mut self) {
if let Some(c) = self.cancel.take() {
c.store(true, Ordering::Release);
}
drop(self.thread.take());
}
}
impl Drop for AudioOnlyTrack {
fn drop(&mut self) {
self.stop();
}
}