video with slightly more correct time scale

This commit is contained in:
Vivian Lim 2021-04-23 20:02:07 -07:00
parent 88d1ab0b0e
commit eac635dc71
1 changed files with 41 additions and 48 deletions

View File

@ -30,6 +30,7 @@ struct MyEmulator {
sys_path: Option<PathBuf>,
frame_properties_locked: bool,
octx: ffmpeg::format::context::Output,
frame: u64,
}
fn video_filter(
@ -176,13 +177,14 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
audio_encoder.set_channels(2);
audio_encoder.set_channel_layout(ChannelLayout::STEREO);
audio_encoder.set_rate(44100);
let audio_filter = audio_filter(&audio_encoder, av_info.timing.sample_rate).unwrap();
let mut audio_encoder = audio_encoder.open_as(acodec).unwrap();
audio_encoder.set_rate(av_info.timing.sample_rate.round() as i32);
//audio_output.set_parameters(&audio_encoder);
octx.write_header().unwrap();
audio_output.set_parameters(&audio_encoder);
octx.write_header().unwrap();
let emu = MyEmulator {
retro,
sys_info,
@ -197,6 +199,7 @@ octx.write_header().unwrap();
sys_path: sys_path.as_ref().map(|x| x.as_ref().to_path_buf()),
frame_properties_locked: false,
octx,
frame: 0
};
let mut pin_emu = Box::pin(emu);
@ -207,9 +210,32 @@ octx.write_header().unwrap();
}
pub fn run(&mut self, frame: i64) {
self.frame += 1;
self.retro.run();
let mut vframe = self.video_frames.pop_front().unwrap();
self.video_filter.get("in").unwrap().source().add(&vframe).unwrap();
let mut filtered_vframe = frame::Video::empty();
while self.video_filter.get("out").unwrap().sink().frame(&mut filtered_vframe).is_ok() {
if self.video_filter.get("in").unwrap().source().failed_requests() > 0 {
println!("🎥 failed to put filter input frame");
}
filtered_vframe.set_pts(Some(frame));
self.video_encoder.send_frame(&filtered_vframe).unwrap();
let mut encoded_packet = ffmpeg::Packet::empty();
while let Ok(..) = self.video_encoder.receive_packet(&mut encoded_packet) {
if encoded_packet.size() > 0 {
encoded_packet.set_stream(0); // use stream index...
//encoded_packet.rescale_ts(Rational(1, 1), Rational(1, 60));
encoded_packet.write(&mut self.octx).unwrap(); // AAA
}
//encoded_packet.write_interleaved(&mut self.octx).unwrap(); // AAA
}
}
let mut aframe = frame::Audio::new(
format::Sample::I16(format::sample::Type::Packed),
self.audio_buf.len(),
@ -220,57 +246,24 @@ octx.write_header().unwrap();
aplane.copy_from_slice(self.audio_buf.as_ref());
self.audio_buf.clear();
//vframe.set_pts(Some(frame));
unsafe
{
//(*vframe.as_mut_ptr()).pts = frame;
//(*vframe.as_mut_ptr()).pkt_dts = frame;
}
let mut out = ffmpeg::Packet::empty();
self.video_filter.get("in").unwrap().source().add(&vframe).unwrap();
self.audio_filter.get("in").unwrap().source().add(&aframe).unwrap();
let mut filtered_vframe = frame::Video::empty();
// ffmpeg_push_video_thread takes ffmpeg_t handle which is a retroarch struct holding ffmpeg context
// video_frame_record_scale
// grabs frame from input (record_video_data struct) and copies it to ffmpeg_t handle .video.conv_frame.data[0]
// conv_frame is an AVFrame. where's that from
while self.video_filter.get("out").unwrap().sink().frame(&mut filtered_vframe).is_ok() {
if self.video_filter.get("in").unwrap().source().failed_requests() > 0 {
let mut filtered_aframe = frame::Audio::empty();
while let Ok(..) = self.audio_filter.get("out").unwrap().sink().frame(&mut filtered_aframe) {
if self.audio_filter.get("in").unwrap().source().failed_requests() > 0 {
println!("🎥 failed to put filter input frame");
}
let encode_result = self.video_encoder.send_frame(&filtered_vframe).unwrap();
//eprintln!("encoded: {:?}", encode_result);
/*if encode_result {
out.set_stream(0);
out.write_interleaved(octx).unwrap();
}
*/
self.audio_encoder.send_frame(&aframe).unwrap();
let mut encoded_packet = ffmpeg::Packet::empty();
while let Ok(..) = self.video_encoder.receive_packet(&mut encoded_packet) {
//eprintln!("Attempting write: {:?}", encoded_packet);
//encoded_packet.set_stream(0); // use stream index...
unsafe {
(*self.octx.as_mut_ptr()).debug = 1;
eprintln!("oformat: {:?}", &((*self.octx.as_mut_ptr()).oformat));
eprintln!("flags: {:?}", (*(*self.octx.as_mut_ptr()).oformat).flags);
}
if encoded_packet.size() > 0 {
encoded_packet.write(&mut self.octx).unwrap(); // AAA
}
//encoded_packet.rescale_ts(Rational(1, 1), self.time_base);
//encoded_packet.write_interleaved(&mut self.octx).unwrap(); // AAA
while let Ok(..) = self.audio_encoder.receive_packet(&mut encoded_packet) {
if encoded_packet.size() > 0 {
encoded_packet.set_stream(1);
//encoded_packet.rescale_ts(Rational(1, 1), Rational(1, 60));
encoded_packet.write(&mut self.octx).unwrap(); // AAA
}
}
//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();
}
}
@ -317,7 +310,7 @@ impl retro::wrapper::Handler for MyEmulator {
}
}
//vframe.set_pts(Some(69));
//vframe.set_pts(Some(self.frame as i64));
self.video_frames.push_back(vframe);
}
@ -430,7 +423,7 @@ fn main() -> Fallible<()> {
emu.frame_properties_locked = true;
//for frame in 0..60*10 {
for frame in 0..9200 {
for frame in 0..600 {
eprintln!("🖼️ frame: {}", frame);
emu.run(frame);