writes some garbage to file each frame (using .mp4 output). i'm not sure if this is an improvement

This commit is contained in:
Vivian Lim 2021-04-19 01:06:47 -07:00
parent ba90e89cdb
commit 2408654651
3 changed files with 39 additions and 8 deletions

View File

@ -19,4 +19,4 @@ sdl2 = "^0.32"
crossbeam-channel = "^0.4"
structopt = "^0.3"
# example: ffmpeg_recorder
ffmpeg-next = "4.3.7"
ffmpeg-next = "4.3.8"

View File

@ -13,7 +13,7 @@ use ferretro::retro;
use ferretro::retro::ffi::{PixelFormat, GameGeometry, SystemAvInfo, SystemInfo};
use ferretro::retro::wrapper::{LibretroWrapper, Handler};
use ffmpeg::{format, filter, frame, media, ChannelLayout};
use ffmpeg::{ChannelLayout, Packet, filter, format, frame, media};
use ffmpeg::util::rational::Rational;
struct MyEmulator {
@ -164,7 +164,7 @@ impl MyEmulator {
pin_emu
}
pub fn run(&mut self) {
pub fn run(&mut self, octx: &mut format::context::Output, frame: i64) {
self.retro.run();
let mut vframe = self.video_frames.pop_front().unwrap();
@ -188,11 +188,30 @@ impl MyEmulator {
if self.video_filter.get("out").unwrap().source().failed_requests() > 0 {
println!("🎥 failed to get filter output frame");
}
self.video_encoder.encode(&vframe, &mut out).unwrap();
vframe.set_pts(Some(frame));
let encode_result = self.video_encoder.encode(&vframe, &mut out).unwrap();
eprintln!("encoded: {:?}", encode_result);
if encode_result {
out.set_stream(0);
out.write_interleaved(octx).unwrap();
}
/*
while self.video_encoder.receive_packet(&mut encoded).is_ok() {
panic!("actually trying to write something!!");
encoded.set_stream(0); // use stream index...
// rescale_ts??
encoded.write_interleaved(&mut octx).unwrap();
}
*/
//eprintln!("packet: {:?}", &out.data());
//self.video_encoder.flush(&mut out).unwrap();
//eprintln!("flushed packet: {:?}", &out.data());
}
while let Ok(..) = self.audio_filter.get("out").unwrap().sink().frame(&mut aframe) {
self.audio_encoder.encode(&aframe, &mut out);//.unwrap();
}
}
pub fn load_game(&self, rom: impl AsRef<Path>) {
@ -224,9 +243,11 @@ impl retro::wrapper::Handler for MyEmulator {
let pitch = pitch as usize;
let vplane = vframe.data_mut(0);
/* sus
if data.len() == vplane.len() && pitch == stride {
vplane.copy_from_slice(&data);
} else {
*/
for y in 0..(height as usize) {
let ffbegin = y * stride;
let lrbegin = y * pitch;
@ -235,7 +256,7 @@ impl retro::wrapper::Handler for MyEmulator {
&data[lrbegin..(lrbegin + min)]
);
}
}
//}
self.video_frames.push_back(vframe);
}
@ -360,10 +381,20 @@ fn main() -> Fallible<()> {
octx.write_header().unwrap();
//for frame in 0..60*10 {
for frame in 0..10 {
for frame in 0..120 {
eprintln!("🖼️ frame: {}", frame);
emu.run();
emu.run(&mut octx, frame);
let mut encoded = ffmpeg::Packet::empty();
while emu.video_encoder.receive_packet(&mut encoded).is_ok() {
panic!("actually trying to write something!!");
encoded.set_stream(0); // use stream index...
// rescale_ts??
encoded.write_interleaved(&mut octx).unwrap();
}
}
let mut packet = Packet::empty();
eprintln!("flushed: {:?}", emu.video_encoder.flush(&mut packet).unwrap());
octx.write_trailer().unwrap();
Ok(())

View File

@ -158,7 +158,7 @@ impl MyEmulator {
// similar hack to the sample rate, make sure we don't divide by zero.
let mut spf = 1.0 / self.av_info.timing.fps;
if spf.is_nan() {
if spf.is_nan() || spf.is_infinite() {
spf = 1.0 / 60.0;
}
Duration::from_secs_f64(spf)