From f2e80a04b68220bdd4712e4b73146dad76c10648 Mon Sep 17 00:00:00 2001 From: "Joseph C. Osborn" Date: Wed, 5 Nov 2025 11:20:54 -0800 Subject: [PATCH] fix some clippy warnings --- genvideo/src/main.rs | 96 +++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/genvideo/src/main.rs b/genvideo/src/main.rs index 808bc02..f41e5d0 100644 --- a/genvideo/src/main.rs +++ b/genvideo/src/main.rs @@ -5,13 +5,45 @@ use ffmpeg_next::{ use retro_rs::Emulator; use ringbuf::traits::{Consumer, Observer, RingBuffer}; use rply_codec::{Frame, decode}; -use std::path::Path; +use std::{error::Error, path::Path}; + +#[derive(Debug, Clone, Copy)] +struct ToI32Err(); + +impl std::fmt::Display for ToI32Err { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "Float conversion out of integer bounds or applied to nan" + ) + } +} +impl Error for ToI32Err {} + +trait ToI32 { + fn to_i32(self) -> Result; +} + +impl ToI32 for f64 { + fn to_i32(mut self) -> Result { + self = self.trunc(); + if self.is_infinite() + || self.is_nan() + || (self < f64::from(i32::MIN)) + || (f64::from(i32::MAX) < self) + { + return Err(ToI32Err()); + } + Ok(unsafe { self.to_int_unchecked() }) + } +} fn copy_audio(samples: &[i16], frame: &mut FFAFrame) { + const BOUND: f32 = i16::MAX as f32; for (i, pair) in samples.chunks_exact(2).enumerate() { let [l, r] = pair else { unreachable!() }; - frame.plane_mut(0)[i] = *l as f32 / i16::MAX as f32; - frame.plane_mut(1)[i] = *r as f32 / i16::MAX as f32; + frame.plane_mut(0)[i] = f32::from(*l) / BOUND; + frame.plane_mut(1)[i] = f32::from(*r) / BOUND; } } fn copy_video( @@ -51,7 +83,8 @@ fn main() { let (w, h) = emu.framebuffer_size(); let mut output = ffmpeg_next::format::output(&outfile).unwrap(); - let emu_time_base = ffmpeg_next::util::rational::Rational::new(1, emu.get_video_fps() as i32); + let emu_time_base = + ffmpeg_next::util::rational::Rational::new(1, emu.get_video_fps().to_i32().unwrap()); let out_video_codec = ffmpeg_next::encoder::find(ffmpeg_next::codec::Id::H264).unwrap(); let mut out_video_ctx = ffmpeg_next::codec::context::Context::new_with_codec(out_video_codec); // out_video_ctx.set_time_base(emu_time_base); @@ -64,7 +97,7 @@ fn main() { (*vps).codec_type = ffmpeg_next::ffi::AVMediaType::AVMEDIA_TYPE_VIDEO; }; out_video_ctx.set_parameters(video_params).unwrap(); - let mut out_video = output.add_stream_with(&out_video_ctx).unwrap(); + let _out_video = output.add_stream_with(&out_video_ctx).unwrap(); let mut encoded_video = ffmpeg_next::Packet::empty(); // out_video.set_time_base(emu_time_base); let mut out_video_enc = out_video_ctx.encoder().video().unwrap(); @@ -81,8 +114,10 @@ fn main() { let aps = audio_params.as_mut_ptr(); (*aps).codec_id = out_audio_codec.id().into(); (*aps).codec_type = ffmpeg_next::ffi::AVMediaType::AVMEDIA_TYPE_AUDIO; - (*aps).frame_size = (emu.get_audio_sample_rate() / emu.get_video_fps().floor()) as i32; - (*aps).sample_rate = emu.get_audio_sample_rate() as i32; + (*aps).frame_size = (emu.get_audio_sample_rate() / emu.get_video_fps().floor()) + .to_i32() + .unwrap(); + (*aps).sample_rate = emu.get_audio_sample_rate().to_i32().unwrap(); (*aps).channels = 2; }; out_audio_ctx.set_parameters(audio_params).unwrap(); @@ -90,15 +125,16 @@ fn main() { // 1, // emu.get_audio_sample_rate() as i32, // )); - let mut out_audio = output.add_stream_with(&out_audio_ctx).unwrap(); + let _out_audio = output.add_stream_with(&out_audio_ctx).unwrap(); let mut encoded_audio = ffmpeg_next::Packet::empty(); // out_audio.set_time_base(ffmpeg_next::util::rational::Rational::new( // 1, // emu.get_audio_sample_rate() as i32, // )); - let audio_time_base = - ffmpeg_next::util::rational::Rational::new(1, emu.get_audio_sample_rate() as i32); - // dbg!(audio_time_base); + let audio_time_base = ffmpeg_next::util::rational::Rational::new( + 1, + emu.get_audio_sample_rate().to_i32().unwrap(), + ); let mut out_audio_enc = out_audio_ctx.encoder().audio().unwrap(); out_audio_enc.set_channels(2); out_audio_enc.set_format(ffmpeg_next::format::Sample::F32( @@ -106,7 +142,7 @@ fn main() { )); out_audio_enc.set_channel_layout(ffmpeg_next::ChannelLayout::STEREO); out_audio_enc.set_time_base(audio_time_base); - out_audio_enc.set_rate(emu.get_audio_sample_rate() as i32); + out_audio_enc.set_rate(emu.get_audio_sample_rate().to_i32().unwrap()); let mut out_audio_enc = out_audio_enc.open().unwrap(); let mut out_vframe = FFVFrame::new( out_video_enc.format(), @@ -123,13 +159,6 @@ fn main() { out_audio_enc.frame_size() as usize, out_audio_enc.channel_layout(), ); - // dbg!( - // out_audio_enc.channels(), - // out_audio_enc.channel_layout(), - // out_audio_enc.format() - // ); - // dbg!(out_aframe.samples()); - // dbg!(out_aframe.data(0).len(), out_aframe.data(1).len()); output.write_header().unwrap(); assert!(emu.load(&rply.initial_state)); let video_stream_time_base = output.stream(0).unwrap().time_base(); @@ -157,7 +186,6 @@ fn main() { emu.run(buttons); emu.copy_framebuffer_rgb888(&mut fb).unwrap(); if !frame.checkpoint_bytes.is_empty() { - // println!("Load CP at {frame_num}"); assert!(emu.load(&frame.checkpoint_bytes)); } // output one frame of video/audio, set_pts @@ -165,13 +193,6 @@ fn main() { copy_video(&fb, &mut converter, &mut out_rgbframe, &mut out_vframe); let frame_num = i64::try_from(rply.frame_number).unwrap(); let frame_pts = frame_num.rescale(emu_time_base, out_video_enc.time_base()); - // let mut rgb = image::RgbImage::new(w as u32, h as u32); - // rgb.clone_from_slice(&fb); - // rgb.save(format!("test/{frame_num}.png")).unwrap(); - println!( - "Send video frame at {frame_pts}; as audio frame {}", - frame_pts.rescale(emu_time_base, audio_stream_time_base) - ); out_vframe.set_pts(Some(frame_pts)); out_video_enc.send_frame(&out_vframe).unwrap(); // copy audio to out_aframe, set_pts @@ -179,31 +200,17 @@ fn main() { #[allow(unused_must_use)] emu.peek_audio_sample(|samples| { audio_buf.push_slice_overwrite(samples); - println!( - "read {} samples, current len {}", - samples.len(), - audio_buf.occupied_len() - ); while audio_buf.occupied_len() >= out_aframe.samples() * 2 { assert_eq!( audio_buf.pop_slice(&mut frame_audio_buf), frame_audio_buf.len() ); - println!( - "copy {} samples at {audio_frame}", - frame_audio_buf.len() / 2 - ); copy_audio(&frame_audio_buf, &mut out_aframe); out_aframe.set_pts(Some(audio_frame)); - audio_frame += out_aframe.samples() as i64; + audio_frame += i64::try_from(out_aframe.samples()).unwrap(); out_audio_enc.send_frame(&out_aframe).unwrap(); } }); - // println!( - // "vtime {} atime {}", - // out_vframe.pts().unwrap() as f64 / 60.0, - // out_aframe.pts().unwrap() as f64 / 48000.0 - // ); while out_video_enc.receive_packet(&mut encoded_video).is_ok() { encoded_video.set_stream(0); encoded_video.rescale_ts(out_video_enc.time_base(), video_stream_time_base); @@ -218,12 +225,11 @@ fn main() { break; } } - dbg!(audio_frame as f32 / 48000.0); while audio_buf.occupied_len() >= out_aframe.samples() { let len = audio_buf.pop_slice(&mut frame_audio_buf); frame_audio_buf[len..].fill(0); out_aframe.set_pts(Some(audio_frame)); - audio_frame += (len / 2) as i64; + audio_frame += i64::try_from(len / 2).unwrap(); copy_audio(&frame_audio_buf, &mut out_aframe); out_audio_enc.send_frame(&out_aframe).unwrap(); } @@ -242,8 +248,6 @@ fn main() { encoded_audio.write_interleaved(&mut output).unwrap(); } output.write_trailer().unwrap(); - dbg!(output.stream(0).unwrap().time_base()); - dbg!(audio_frame as f32 / 48000.0); } fn frame_to_buttons(frame: &Frame) -> [retro_rs::Buttons; 2] {