shuffle some stuff around
This commit is contained in:
parent
eac635dc71
commit
d660a9cc94
|
@ -13,7 +13,7 @@ use ferretro::retro;
|
|||
use ferretro::retro::ffi::{PixelFormat, GameGeometry, SystemAvInfo, SystemInfo};
|
||||
use ferretro::retro::wrapper::{LibretroWrapper, Handler};
|
||||
|
||||
use ffmpeg::{ChannelLayout, Packet, filter, format, frame, media};
|
||||
use ffmpeg::{ChannelLayout, Packet, codec, filter, format, frame, media};
|
||||
use ffmpeg::util::rational::Rational;
|
||||
|
||||
struct MyEmulator {
|
||||
|
@ -77,7 +77,7 @@ fn video_filter(
|
|||
}
|
||||
|
||||
fn audio_filter(
|
||||
audio_encoder: &ffmpeg::encoder::audio::Audio,
|
||||
audio_encoder: &ffmpeg::codec::encoder::Audio,
|
||||
sample_rate: f64,
|
||||
) -> Result<filter::Graph, ffmpeg::Error> {
|
||||
let mut afilter = filter::Graph::new();
|
||||
|
@ -99,6 +99,21 @@ fn audio_filter(
|
|||
.input("out", 0)?
|
||||
.parse("anull")?;
|
||||
afilter.validate()?;
|
||||
// human-readable filter graph
|
||||
eprintln!("{}", afilter.dump());
|
||||
|
||||
if let Some(codec) = audio_encoder.codec() {
|
||||
if !codec
|
||||
.capabilities()
|
||||
.contains(ffmpeg::codec::capabilities::Capabilities::VARIABLE_FRAME_SIZE)
|
||||
{
|
||||
afilter
|
||||
.get("out")
|
||||
.unwrap()
|
||||
.sink()
|
||||
.set_frame_size(audio_encoder.frame_size());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(afilter)
|
||||
}
|
||||
|
@ -129,7 +144,7 @@ impl MyEmulator {
|
|||
let mut video_output = octx.add_stream(vcodec).unwrap();
|
||||
let mut video_encoder = video_output.codec().encoder().video().unwrap();
|
||||
|
||||
video_encoder.set_bit_rate(64000);
|
||||
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));
|
||||
|
@ -176,10 +191,12 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
|||
audio_encoder.set_format(audio_encoder.codec().unwrap().audio().unwrap().formats().unwrap().nth(0).unwrap());
|
||||
audio_encoder.set_channels(2);
|
||||
audio_encoder.set_channel_layout(ChannelLayout::STEREO);
|
||||
|
||||
let audio_filter = audio_filter(&audio_encoder, av_info.timing.sample_rate).unwrap();
|
||||
audio_encoder.set_time_base(Rational::new(1, fps_int));
|
||||
audio_output.set_time_base(Rational::new(1, fps_int));
|
||||
|
||||
let mut audio_encoder = audio_encoder.open_as(acodec).unwrap();
|
||||
let audio_filter = audio_filter(&audio_encoder, av_info.timing.sample_rate).unwrap();
|
||||
|
||||
audio_encoder.set_rate(av_info.timing.sample_rate.round() as i32);
|
||||
audio_output.set_parameters(&audio_encoder);
|
||||
|
||||
|
@ -217,7 +234,7 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
|||
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() {
|
||||
while let Ok(..) = self.video_filter.get("out").unwrap().sink().frame(&mut filtered_vframe) {
|
||||
if self.video_filter.get("in").unwrap().source().failed_requests() > 0 {
|
||||
println!("🎥 failed to put filter input frame");
|
||||
}
|
||||
|
@ -229,24 +246,27 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
|||
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
|
||||
}
|
||||
//encoded_packet.write_interleaved(&mut self.octx).unwrap(); // AAA
|
||||
}
|
||||
}
|
||||
|
||||
eprintln!("Audio buffer length {}", self.audio_buf.len());
|
||||
|
||||
let mut aframe = frame::Audio::new(
|
||||
format::Sample::I16(format::sample::Type::Packed),
|
||||
self.audio_buf.len(),
|
||||
ChannelLayout::STEREO
|
||||
);
|
||||
aframe.set_channels(2);
|
||||
aframe.set_rate(32040);
|
||||
aframe.set_pts(Some(frame));
|
||||
let aplane: &mut [(i16, i16)] = aframe.plane_mut(0);
|
||||
aplane.copy_from_slice(self.audio_buf.as_ref());
|
||||
//eprintln!("src: {:?}, dest: {:?}", self.audio_buf, aplane);
|
||||
self.audio_buf.clear();
|
||||
|
||||
let mut out = ffmpeg::Packet::empty();
|
||||
self.audio_filter.get("in").unwrap().source().add(&aframe).unwrap();
|
||||
|
||||
let mut filtered_aframe = frame::Audio::empty();
|
||||
|
@ -255,13 +275,14 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
|||
println!("🎥 failed to put filter input frame");
|
||||
}
|
||||
|
||||
filtered_aframe.set_pts(Some(frame));
|
||||
self.audio_encoder.send_frame(&aframe).unwrap();
|
||||
let mut encoded_packet = ffmpeg::Packet::empty();
|
||||
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
|
||||
encoded_packet.write_interleaved(&mut self.octx).unwrap(); // AAA
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,6 +304,10 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
|||
.load_game(Some(path), data, None)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn end(&mut self) {
|
||||
self.octx.write_trailer().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl retro::wrapper::Handler for MyEmulator {
|
||||
|
@ -352,11 +377,9 @@ impl retro::wrapper::Handler for MyEmulator {
|
|||
}
|
||||
|
||||
self.video_encoder.set_frame_rate(system_av_info.timing.fps.into());
|
||||
/*
|
||||
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);
|
||||
}
|
||||
*/
|
||||
self.av_info.timing = system_av_info.timing;
|
||||
self.set_geometry(system_av_info.geometry);
|
||||
true
|
||||
|
@ -431,6 +454,7 @@ fn main() -> Fallible<()> {
|
|||
let mut packet = Packet::empty();
|
||||
eprintln!("flushed: {:?}", emu.video_encoder.flush(&mut packet).unwrap());
|
||||
|
||||
emu.end();
|
||||
//octx.write_trailer().unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue