use nihav_registry::register::*;
use nihav_allstuff::*;
+#[cfg(feature="hwaccel")]
+use hwdec_vaapi::*;
+
mod audiodec;
use audiodec::*;
mod videodec;
($log: expr; $blk: block) => {};
}
+enum ScaleSize {
+ Auto,
+ Times(f32),
+ Fixed(usize, usize)
+}
+
+impl FromStr for ScaleSize {
+ type Err = ();
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ if matches!(s, "" | "auto") {
+ Ok(ScaleSize::Auto)
+ } else if s.ends_with('x') || s.ends_with('X') {
+ let factor = s[..s.len() - 1].parse::<f32>().map_err(|_| ())?;
+ if factor > 0.0 {
+ Ok(ScaleSize::Times(factor))
+ } else {
+ Err(())
+ }
+ } else if s.contains('x') | s.contains('X') {
+ let mut dims = if s.contains('x') { s.split('x') } else { s.split('X') };
+ let w = dims.next().unwrap();
+ let h = dims.next().unwrap();
+ let width = w.parse::<usize>().map_err(|_| ())?;
+ let height = h.parse::<usize>().map_err(|_| ())?;
+ if width > 0 && height > 0 {
+ Ok(ScaleSize::Fixed(width, height))
+ } else {
+ Err(())
+ }
+ } else {
+ Err(())
+ }
+ }
+}
+
pub enum PktSendEvent {
Packet(NAPacket),
GetFrames,
Audio(Box<dyn NADecoder + Send>),
Video(Box<dyn NADecoder + Send>, Box<dyn FrameReorderer + Send>),
VideoMT(Box<dyn NADecoderMT + Send>, MTFrameReorderer),
+ #[cfg(feature="hwaccel")]
+ VideoHW(Box<dyn HWDecoder + Send>),
}
pub struct DecoderStuff {
has_audio: bool,
video_str: u32,
audio_str: u32,
+ sc_size: ScaleSize,
vthreads: usize,
use_mt: bool,
+ #[cfg(feature="hwaccel")]
+ use_hwaccel: bool,
paused: bool,
mute: bool,
has_audio: false,
video_str: 0,
audio_str: 0,
+ sc_size: ScaleSize::Auto,
vthreads: 3,
use_mt: true,
+ #[cfg(feature="hwaccel")]
+ use_hwaccel: true,
paused: false,
mute: false,
return Ok(true);
},
Keycode::Return | Keycode::KpEnter => return Ok(true),
+ Keycode::R => { self.seek(0, true, dmx, disp_queue)?; },
Keycode::Right => { self.seek(10, true, dmx, disp_queue)?; },
Keycode::Left => { self.seek(10, false, dmx, disp_queue)?; },
Keycode::Up => { self.seek(60, true, dmx, disp_queue)?; },
let str_id = s.get_id();
if info.is_video() {
if video_dec.is_none() && self.play_video {
+ #[cfg(feature="hwaccel")]
+ if info.get_name() == "h264" && self.use_hwaccel {
+ let mut dec = new_h264_hwdec();
+ let dsupp = Box::new(NADecoderSupport::new());
+ let props = info.get_properties().get_video_info().unwrap();
+ if props.get_width() != 0 {
+ width = props.get_width();
+ height = props.get_height();
+ }
+ if dec.init(info.clone()).is_err() {
+ println!("failed to initialise hwaccel video decoder");
+ } else {
+ video_dec = Some(DecoderStuff{ dsupp, dec: DecoderType::VideoHW(dec) });
+ self.video_str = str_id;
+ let (tbn, tbd) = s.get_timebase();
+ tb_num = tbn;
+ tb_den = tbd;
+ self.has_video = true;
+ println!(" using hardware-accelerated decoding");
+ continue;
+ }
+ }
if let Some(decfunc) = decfunc_mt {
let mut dec = (decfunc)();
let mut dsupp = Box::new(NADecoderSupport::new());
return window;
}
- while (width <= 384) && (height <= 288) {
- width <<= 1;
- height <<= 1;
- }
+ match self.sc_size {
+ ScaleSize::Auto => {
+ while (width <= 384) && (height <= 288) {
+ width <<= 1;
+ height <<= 1;
+ }
+ },
+ ScaleSize::Times(factor) => {
+ let nw = ((width as f32) * factor).ceil() as usize;
+ let nh = ((height as f32) * factor).ceil() as usize;
+ if nw > 0 && nh > 0 {
+ width = nw;
+ height = nh;
+ }
+ },
+ ScaleSize::Fixed(w, h) => {
+ width = w;
+ height = h;
+ },
+ };
// prepare playback structure
let mut new_vcontrol = VideoControl::new(video_dec, width, height, tb_num, tb_den);
"-nomt" => {
player.use_mt = false;
},
+ #[cfg(feature="hwaccel")]
+ "-hwaccel" => {
+ player.use_hwaccel = true;
+ },
+ #[cfg(feature="hwaccel")]
+ "-nohwaccel" => {
+ player.use_hwaccel = false;
+ },
"-threads" => {
if let Some(arg) = aiter.next() {
if let Ok(val) = arg.parse::<usize>() {
}
}
},
+ "-scale" => {
+ if let Some(arg) = aiter.next() {
+ if let Ok(ssize) = arg.parse::<ScaleSize>() {
+ player.sc_size = ssize;
+ } else {
+ println!("invalid scale size");
+ }
+ }
+ },
_ => {
window = player.play(window, arg, seek_time);
if player.end { break; }