videoplayer: add hardware-accelerated H.264 video decoding support
[nihav-player.git] / videoplayer / src / main.rs
index cd35eb5e8d2e6d8cb9aff0d314c2041e34abaf1e..cabb925fb5e0ecd1dbcd6d7ecfcf8a7cc72b8d58 100644 (file)
@@ -27,6 +27,9 @@ use nihav_core::demuxers::*;
 use nihav_registry::register::*;
 use nihav_allstuff::*;
 
+#[cfg(feature="hwaccel")]
+use hwdec_vaapi::*;
+
 mod audiodec;
 use audiodec::*;
 mod videodec;
@@ -140,6 +143,8 @@ pub enum DecoderType {
     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 {
@@ -342,6 +347,8 @@ struct Player {
 
     vthreads:       usize,
     use_mt:         bool,
+    #[cfg(feature="hwaccel")]
+    use_hwaccel:    bool,
 
     paused:         bool,
     mute:           bool,
@@ -380,6 +387,8 @@ impl Player {
 
             vthreads:       3,
             use_mt:         true,
+            #[cfg(feature="hwaccel")]
+            use_hwaccel:    true,
 
             paused:         false,
             mute:           false,
@@ -660,6 +669,28 @@ impl Player {
             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());
@@ -971,6 +1002,14 @@ fn main() {
             "-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>() {