video with slightly more correct time scale
This commit is contained in:
parent
88d1ab0b0e
commit
eac635dc71
|
@ -30,6 +30,7 @@ struct MyEmulator {
|
||||||
sys_path: Option<PathBuf>,
|
sys_path: Option<PathBuf>,
|
||||||
frame_properties_locked: bool,
|
frame_properties_locked: bool,
|
||||||
octx: ffmpeg::format::context::Output,
|
octx: ffmpeg::format::context::Output,
|
||||||
|
frame: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn video_filter(
|
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_channels(2);
|
||||||
audio_encoder.set_channel_layout(ChannelLayout::STEREO);
|
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 audio_filter = audio_filter(&audio_encoder, av_info.timing.sample_rate).unwrap();
|
||||||
|
|
||||||
let mut audio_encoder = audio_encoder.open_as(acodec).unwrap();
|
let mut audio_encoder = audio_encoder.open_as(acodec).unwrap();
|
||||||
audio_encoder.set_rate(av_info.timing.sample_rate.round() as i32);
|
audio_encoder.set_rate(av_info.timing.sample_rate.round() as i32);
|
||||||
//audio_output.set_parameters(&audio_encoder);
|
audio_output.set_parameters(&audio_encoder);
|
||||||
octx.write_header().unwrap();
|
|
||||||
|
octx.write_header().unwrap();
|
||||||
|
|
||||||
let emu = MyEmulator {
|
let emu = MyEmulator {
|
||||||
retro,
|
retro,
|
||||||
sys_info,
|
sys_info,
|
||||||
|
@ -197,6 +199,7 @@ octx.write_header().unwrap();
|
||||||
sys_path: sys_path.as_ref().map(|x| x.as_ref().to_path_buf()),
|
sys_path: sys_path.as_ref().map(|x| x.as_ref().to_path_buf()),
|
||||||
frame_properties_locked: false,
|
frame_properties_locked: false,
|
||||||
octx,
|
octx,
|
||||||
|
frame: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut pin_emu = Box::pin(emu);
|
let mut pin_emu = Box::pin(emu);
|
||||||
|
@ -207,9 +210,32 @@ octx.write_header().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(&mut self, frame: i64) {
|
pub fn run(&mut self, frame: i64) {
|
||||||
|
self.frame += 1;
|
||||||
self.retro.run();
|
self.retro.run();
|
||||||
|
|
||||||
let mut vframe = self.video_frames.pop_front().unwrap();
|
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(
|
let mut aframe = frame::Audio::new(
|
||||||
format::Sample::I16(format::sample::Type::Packed),
|
format::Sample::I16(format::sample::Type::Packed),
|
||||||
self.audio_buf.len(),
|
self.audio_buf.len(),
|
||||||
|
@ -220,57 +246,24 @@ octx.write_header().unwrap();
|
||||||
aplane.copy_from_slice(self.audio_buf.as_ref());
|
aplane.copy_from_slice(self.audio_buf.as_ref());
|
||||||
self.audio_buf.clear();
|
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();
|
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();
|
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
|
let mut filtered_aframe = frame::Audio::empty();
|
||||||
// video_frame_record_scale
|
while let Ok(..) = self.audio_filter.get("out").unwrap().sink().frame(&mut filtered_aframe) {
|
||||||
// grabs frame from input (record_video_data struct) and copies it to ffmpeg_t handle .video.conv_frame.data[0]
|
if self.audio_filter.get("in").unwrap().source().failed_requests() > 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 {
|
|
||||||
println!("🎥 failed to put filter input frame");
|
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();
|
let mut encoded_packet = ffmpeg::Packet::empty();
|
||||||
while let Ok(..) = self.video_encoder.receive_packet(&mut encoded_packet) {
|
while let Ok(..) = self.audio_encoder.receive_packet(&mut encoded_packet) {
|
||||||
//eprintln!("Attempting write: {:?}", encoded_packet);
|
if encoded_packet.size() > 0 {
|
||||||
//encoded_packet.set_stream(0); // use stream index...
|
encoded_packet.set_stream(1);
|
||||||
|
//encoded_packet.rescale_ts(Rational(1, 1), Rational(1, 60));
|
||||||
unsafe {
|
encoded_packet.write(&mut self.octx).unwrap(); // AAA
|
||||||
(*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
|
|
||||||
}
|
}
|
||||||
//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);
|
self.video_frames.push_back(vframe);
|
||||||
}
|
}
|
||||||
|
@ -430,7 +423,7 @@ fn main() -> Fallible<()> {
|
||||||
emu.frame_properties_locked = true;
|
emu.frame_properties_locked = true;
|
||||||
|
|
||||||
//for frame in 0..60*10 {
|
//for frame in 0..60*10 {
|
||||||
for frame in 0..9200 {
|
for frame in 0..600 {
|
||||||
eprintln!("🖼️ frame: {}", frame);
|
eprintln!("🖼️ frame: {}", frame);
|
||||||
emu.run(frame);
|
emu.run(frame);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue