synced a/v on some players at least. ideally i'd like to write the header with the right time bases set.
This commit is contained in:
parent
57530da214
commit
ea771c8dd7
|
@ -82,7 +82,7 @@ fn audio_filter(
|
|||
) -> Result<filter::Graph, ffmpeg::Error> {
|
||||
let mut afilter = filter::Graph::new();
|
||||
let sample_rate = if sample_rate == 0.0 { 32040.0 } else { sample_rate };
|
||||
let args = format!("sample_rate={}:sample_fmt=s16:channel_layout=stereo", sample_rate);
|
||||
let args = format!("sample_rate={}:sample_fmt=s16:channel_layout=stereo:time_base=1/60", sample_rate);
|
||||
eprintln!("🔊 filter args: {}", args);
|
||||
afilter.add(&filter::find("abuffer").unwrap(), "in", &args)?;
|
||||
//aresample?
|
||||
|
@ -145,14 +145,16 @@ let wavname = Path::new("out.wav");
|
|||
let acodec = ffmpeg::encoder::find(detected_acodec).unwrap().audio().unwrap();
|
||||
|
||||
let mut video_output = octx.add_stream(vcodec).unwrap();
|
||||
video_output.set_time_base(Rational::new(1, 60));
|
||||
let mut video_encoder = video_output.codec().encoder().video().unwrap();
|
||||
|
||||
video_encoder.set_bit_rate(2560000);
|
||||
video_encoder.set_format(video_encoder.codec().unwrap().video().unwrap().formats().unwrap().nth(0).unwrap());
|
||||
|
||||
video_encoder.set_time_base(Rational::new(1, fps_int));
|
||||
video_output.set_time_base(Rational::new(1, fps_int));
|
||||
video_encoder.set_frame_rate(av_info.timing.fps.into());
|
||||
video_encoder.set_time_base(Rational::new(1, 60));
|
||||
video_encoder.set_frame_rate(Some(Rational::new(60, 1)));
|
||||
|
||||
//video_encoder.set_frame_rate(av_info.timing.fps.into());
|
||||
|
||||
if av_info.geometry.base_height == 0 && av_info.geometry.base_width == 0 {
|
||||
av_info.geometry.base_width = 320;
|
||||
|
@ -197,8 +199,8 @@ 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_format(audio_encoder.codec().unwrap().audio().unwrap().formats().unwrap().nth(0).unwrap());
|
||||
audio_encoder.set_time_base(Rational::new(1, fps_int));
|
||||
audio_output.set_time_base(Rational::new(1, fps_int));
|
||||
audio_encoder.set_time_base(Rational::new(1, 60));
|
||||
audio_output.set_time_base(Rational::new(1, 60));
|
||||
|
||||
let mut audio_encoder = audio_encoder.open_as(acodec).unwrap();
|
||||
//audio_output.set_parameters(&audio_encoder);
|
||||
|
@ -250,8 +252,18 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
|||
Ok(..) => {
|
||||
//if encoded_packet.size() > 0 {
|
||||
encoded_packet.set_stream(stream_index);
|
||||
eprintln!("Writing packet, pts {:?} dts {:?} size {}", encoded_packet.pts(), encoded_packet.dts(), encoded_packet.size());
|
||||
match encoded_packet.write(&mut self.octx) {
|
||||
eprintln!("📦 Writing packet, pts {:?} dts {:?} size {}", encoded_packet.pts(), encoded_packet.dts(), encoded_packet.size());
|
||||
if let EncoderToWriteFrom::Video = encoder{
|
||||
//encoded_packet.rescale_ts(Rational(1, 60), Rational(1, 44100)); // slow, ~30fps
|
||||
encoded_packet.rescale_ts(Rational(1, 60), Rational(1, 15360));
|
||||
}
|
||||
if let EncoderToWriteFrom::Audio = encoder{
|
||||
//encoded_packet.rescale_ts(Rational(1, 60), Rational(1, 44100)); // slow, ~30fps
|
||||
encoded_packet.rescale_ts(Rational(1, 60), Rational(1, 44100));
|
||||
}
|
||||
eprintln!("📦 rescaled , pts {:?} dts {:?} size {}", encoded_packet.pts(), encoded_packet.dts(), encoded_packet.size());
|
||||
|
||||
match encoded_packet.write_interleaved(&mut self.octx) {
|
||||
Ok(..) => eprintln!("Write OK"),
|
||||
Err(e) => eprintln!("Error writing: {}", e),
|
||||
}
|
||||
|
@ -274,17 +286,19 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
|||
self.retro.run();
|
||||
|
||||
let mut vframe = self.video_frames.pop_front().unwrap();
|
||||
vframe.set_pts(Some(frame));
|
||||
eprintln!("🎞 queue frame pts {:?}", vframe.pts());
|
||||
self.video_filter.get("in").unwrap().source().add(&vframe).unwrap();
|
||||
let mut filtered_vframe = frame::Video::empty();
|
||||
|
||||
loop {
|
||||
match self.video_filter.get("out").unwrap().sink().frame(&mut filtered_vframe) {
|
||||
Ok(..) => {
|
||||
eprintln!("Got filtered video frame");
|
||||
eprintln!("🎥 Got filtered video frame {}x{} pts {:?}", filtered_vframe.width(), filtered_vframe.height(), filtered_vframe.pts());
|
||||
if self.video_filter.get("in").unwrap().source().failed_requests() > 0 {
|
||||
println!("🎥 failed to put filter input frame");
|
||||
}
|
||||
filtered_vframe.set_pts(Some(frame));
|
||||
//filtered_vframe.set_pts(Some(frame));
|
||||
self.video_encoder.send_frame(&filtered_vframe).unwrap();
|
||||
|
||||
self.receive_and_write_packets(EncoderToWriteFrom::Video);
|
||||
|
@ -312,20 +326,21 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
|||
|
||||
eprintln!("frame audio: {:?}", aframe);
|
||||
|
||||
//aframe.set_pts(Some(frame));
|
||||
eprintln!("🎞 queue frame pts {:?}", aframe.pts());
|
||||
self.audio_filter.get("in").unwrap().source().add(&aframe).unwrap();
|
||||
|
||||
let mut filtered_aframe = frame::Audio::empty();
|
||||
loop {
|
||||
match self.audio_filter.get("out").unwrap().sink().frame(&mut filtered_aframe) {
|
||||
Ok(..) => {
|
||||
eprintln!("Got filtered audio frame {:?}", filtered_aframe);
|
||||
eprintln!("🔊 Got filtered audio frame {:?} pts {:?}", filtered_aframe, filtered_aframe.pts());
|
||||
if self.audio_filter.get("in").unwrap().source().failed_requests() > 0 {
|
||||
println!("🎥 failed to put filter input frame");
|
||||
}
|
||||
//let faplane: &[f32] = filtered_aframe.plane(0);
|
||||
//filtered_aframe.set_pts(Some(frame));
|
||||
filtered_aframe.set_pts(Some(frame));
|
||||
|
||||
//filtered_aframe.set_pts(Some(frame));
|
||||
self.audio_encoder.send_frame(&filtered_aframe).unwrap();
|
||||
self.receive_and_write_packets(EncoderToWriteFrom::Audio);
|
||||
},
|
||||
|
@ -429,7 +444,9 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
return true;
|
||||
}
|
||||
|
||||
self.video_encoder.set_frame_rate(system_av_info.timing.fps.into());
|
||||
//self.video_encoder.set_frame_rate(system_av_info.timing.fps.into());
|
||||
//self.video_encoder.set_time_base(Rational::new(1, 60));
|
||||
//self.video_encoder.set_frame_rate(Some(Rational::new(1, 60)));
|
||||
if system_av_info.timing.sample_rate.round() as i32 > 0 {
|
||||
self.audio_encoder.set_rate(system_av_info.timing.sample_rate.round() as i32);
|
||||
}
|
||||
|
@ -499,7 +516,7 @@ fn main() -> Fallible<()> {
|
|||
emu.frame_properties_locked = true;
|
||||
|
||||
//for frame in 0..60*10 {
|
||||
for frame in 0..1300 {
|
||||
for frame in 0..800 {
|
||||
eprintln!("🖼️ frame: {}", frame);
|
||||
emu.run(frame);
|
||||
|
||||
|
|
Loading…
Reference in New Issue