diff --git a/justfile b/justfile index c817c3c..8880a47 100644 --- a/justfile +++ b/justfile @@ -49,7 +49,7 @@ check-json: (check '--message-format=json') dev *args: cargo fmt cargo build --profile release-with-debug - RUST_BACKTRACE=1 RUST_LOG=cosmic_player=info target/release-with-debug/cosmic-player {{args}} + RUST_BACKTRACE=1 RUST_LOG=cosmic_player=debug target/release-with-debug/cosmic-player {{args}} # Profile memory usage with heaptrack heaptrack: diff --git a/src/main.rs b/src/main.rs index d3e7078..d326da5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ use cosmic::{ }; use std::{ any::TypeId, - collections::HashMap, + collections::{HashMap, VecDeque}, env, path::PathBuf, process, @@ -67,7 +67,7 @@ fn main() -> Result<(), Box> { } }; - let (player_tx, video_frame_lock) = player::run(path); + let (player_tx, video_frames_lock) = player::run(path); let mut settings = Settings::default(); settings = settings.theme(config.app_theme.theme()); @@ -85,7 +85,7 @@ fn main() -> Result<(), Box> { config_handler, config, player_tx, - video_frame_lock, + video_frames_lock, }; cosmic::app::run::(settings, flags)?; @@ -114,7 +114,7 @@ pub struct Flags { config_handler: Option, config: Config, player_tx: mpsc::Sender, - video_frame_lock: Arc>>, + video_frames_lock: Arc>>, } /// Messages that are used specifically by our [`App`]. @@ -299,8 +299,8 @@ impl Application for App { let start = Instant::now(); match { - let mut video_frame_opt = self.flags.video_frame_lock.lock().unwrap(); - video_frame_opt.take() + let mut video_frames = self.flags.video_frames_lock.lock().unwrap(); + video_frames.pop_front() } { Some(video_frame) => { let pts = video_frame.0.pts(); diff --git a/src/player.rs b/src/player.rs index 7151270..f97205e 100644 --- a/src/player.rs +++ b/src/player.rs @@ -6,7 +6,7 @@ use cpal::{ FromSample, SizedSample, }; use ffmpeg::{ - codec::discard, + codec, ffi, format::{input, Pixel}, media::Type, software::{resampling, scaling}, @@ -21,7 +21,7 @@ use std::{ collections::VecDeque, error::Error, path::{Path, PathBuf}, - slice, + ptr, slice, sync::{mpsc, Arc, Mutex}, thread, time::{Duration, Instant}, @@ -124,7 +124,7 @@ where fn ffmpeg_thread>( path: P, player_rx: mpsc::Receiver, - video_frame_lock: Arc>>, + video_frames_lock: Arc>>, ) -> Result<(), Box> { let audio_queue_lock = Arc::new(Mutex::new(VecDeque::new())); let (audio_config, cpal_stream) = cpal(audio_queue_lock.clone()); @@ -137,17 +137,41 @@ fn ffmpeg_thread>( .ok_or(ffmpeg::Error::StreamNotFound)?; let video_stream_index = video_stream.index(); - let video_context_decoder = - ffmpeg::codec::context::Context::from_parameters(video_stream.parameters())?; - let mut video_decoder = video_context_decoder.decoder().video()?; + let mut video_decoder = { + let mut video_decoder_context = + codec::context::Context::from_parameters(video_stream.parameters())?; + + //TODO: safe wrappers + let mut hw_device_ctx = ptr::null_mut(); + unsafe { + //TODO: support other types + let hw_device_kind = ffi::AVHWDeviceType::AV_HWDEVICE_TYPE_VAAPI; + if ffi::av_hwdevice_ctx_create( + &mut hw_device_ctx, + hw_device_kind, + ptr::null(), + ptr::null_mut(), + 0, + ) < 0 + { + //TODO: support other hardware devices and fall back to software + panic!("failed to get hardware context"); + } + + (&mut *video_decoder_context.as_mut_ptr()).hw_device_ctx = + ffi::av_buffer_ref(hw_device_ctx); + } + + video_decoder_context.decoder().video()? + }; let video_format = video_decoder.format(); let video_width = video_decoder.width(); let video_height = video_decoder.height(); - let (raw_frame_tx, raw_frame_rx) = mpsc::channel::