From 35d0d63a755ace4c79769aeb04f94469f8b47709 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Fri, 20 Oct 2023 18:40:20 +0200 Subject: [PATCH] videoplayer: add hardware-accelerated H.264 video decoding support --- videoplayer/Cargo.toml | 6 ++++-- videoplayer/src/main.rs | 39 +++++++++++++++++++++++++++++++++++++ videoplayer/src/videodec.rs | 32 ++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/videoplayer/Cargo.toml b/videoplayer/Cargo.toml index f145029..8cdc4a2 100644 --- a/videoplayer/Cargo.toml +++ b/videoplayer/Cargo.toml @@ -8,9 +8,11 @@ edition = "2018" nihav_core = { path="../../nihav-core" } nihav_registry = { path="../../nihav-registry" } nihav_allstuff = { path="../../nihav-allstuff" } +hwdec_vaapi = { path="../hwdec-vaapi", optional = true } sdl2 = "^0.33" [features] -default = [] -debug = [] \ No newline at end of file +default = ["hwaccel"] +debug = [] +hwaccel = ["hwdec_vaapi"] \ No newline at end of file diff --git a/videoplayer/src/main.rs b/videoplayer/src/main.rs index cd35eb5..cabb925 100644 --- a/videoplayer/src/main.rs +++ b/videoplayer/src/main.rs @@ -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), Video(Box, Box), VideoMT(Box, MTFrameReorderer), + #[cfg(feature="hwaccel")] + VideoHW(Box), } 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::() { diff --git a/videoplayer/src/videodec.rs b/videoplayer/src/videodec.rs index 7ebf177..295cfc7 100644 --- a/videoplayer/src/videodec.rs +++ b/videoplayer/src/videodec.rs @@ -137,6 +137,16 @@ impl VideoDecoder { return self.convert_buf(bt, ts); } }, + #[cfg(feature="hwaccel")] + DecoderType::VideoHW(ref mut vdec) => { + let _ = vdec.queue_pkt(pkt); + while let Some(frm) = vdec.get_frame() { + let bt = frm.get_buffer(); + if let NABufferType::None = bt { continue; } + let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0)); + return self.convert_buf(bt, ts); + } + }, _ => panic!("not a video decoder!"), }; None @@ -188,6 +198,15 @@ impl VideoDecoder { return self.convert_buf(bt, ts); } }, + #[cfg(feature="hwaccel")] + DecoderType::VideoHW(ref mut vdec) => { + while let Some(frm) = vdec.get_frame() { + let bt = frm.get_buffer(); + if let NABufferType::None = bt { continue; } + let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0)); + return self.convert_buf(bt, ts); + } + }, _ => {}, }; None @@ -210,6 +229,15 @@ impl VideoDecoder { return self.convert_buf(bt, ts); } }, + #[cfg(feature="hwaccel")] + DecoderType::VideoHW(ref mut dec) => { + while let Some(frm) = dec.get_last_frames() { + let bt = frm.get_buffer(); + if let NABufferType::None = bt { continue; } + let ts = frm.get_dts().unwrap_or_else(|| frm.get_pts().unwrap_or(0)); + return self.convert_buf(bt, ts); + } + }, _ => {}, }; None @@ -224,6 +252,10 @@ impl VideoDecoder { dec.flush(); reord.flush(); }, + #[cfg(feature="hwaccel")] + DecoderType::VideoHW(ref mut dec) => { + dec.flush(); + }, _ => {}, }; } -- 2.30.2