fix some clippy warnings

This commit is contained in:
2025-11-05 11:20:54 -08:00
parent b7875f23cd
commit f2e80a04b6
+50 -46
View File
@@ -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<i32, ToI32Err>;
}
impl ToI32 for f64 {
fn to_i32(mut self) -> Result<i32, ToI32Err> {
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] {