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::ffi::{PixelFormat, GameGeometry, SystemAvInfo, SystemInfo};
|
||||||
use ferretro::retro::wrapper::{LibretroWrapper, Handler};
|
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;
|
use ffmpeg::util::rational::Rational;
|
||||||
|
|
||||||
struct MyEmulator {
|
struct MyEmulator {
|
||||||
|
@ -77,7 +77,7 @@ fn video_filter(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn audio_filter(
|
fn audio_filter(
|
||||||
audio_encoder: &ffmpeg::encoder::audio::Audio,
|
audio_encoder: &ffmpeg::codec::encoder::Audio,
|
||||||
sample_rate: f64,
|
sample_rate: f64,
|
||||||
) -> Result<filter::Graph, ffmpeg::Error> {
|
) -> Result<filter::Graph, ffmpeg::Error> {
|
||||||
let mut afilter = filter::Graph::new();
|
let mut afilter = filter::Graph::new();
|
||||||
|
@ -99,6 +99,21 @@ fn audio_filter(
|
||||||
.input("out", 0)?
|
.input("out", 0)?
|
||||||
.parse("anull")?;
|
.parse("anull")?;
|
||||||
afilter.validate()?;
|
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)
|
Ok(afilter)
|
||||||
}
|
}
|
||||||
|
@ -129,7 +144,7 @@ impl MyEmulator {
|
||||||
let mut video_output = octx.add_stream(vcodec).unwrap();
|
let mut video_output = octx.add_stream(vcodec).unwrap();
|
||||||
let mut video_encoder = video_output.codec().encoder().video().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_format(video_encoder.codec().unwrap().video().unwrap().formats().unwrap().nth(0).unwrap());
|
||||||
|
|
||||||
video_encoder.set_time_base(Rational::new(1, fps_int));
|
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_format(audio_encoder.codec().unwrap().audio().unwrap().formats().unwrap().nth(0).unwrap());
|
||||||
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_time_base(Rational::new(1, fps_int));
|
||||||
let audio_filter = audio_filter(&audio_encoder, av_info.timing.sample_rate).unwrap();
|
audio_output.set_time_base(Rational::new(1, fps_int));
|
||||||
|
|
||||||
let mut audio_encoder = audio_encoder.open_as(acodec).unwrap();
|
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_encoder.set_rate(av_info.timing.sample_rate.round() as i32);
|
||||||
audio_output.set_parameters(&audio_encoder);
|
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();
|
self.video_filter.get("in").unwrap().source().add(&vframe).unwrap();
|
||||||
let mut filtered_vframe = frame::Video::empty();
|
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 {
|
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");
|
||||||
}
|
}
|
||||||
|
@ -229,24 +246,27 @@ static bool ffmpeg_init_config(struct ff_config_param *params,
|
||||||
if encoded_packet.size() > 0 {
|
if encoded_packet.size() > 0 {
|
||||||
encoded_packet.set_stream(0); // use stream index...
|
encoded_packet.set_stream(0); // use stream index...
|
||||||
//encoded_packet.rescale_ts(Rational(1, 1), Rational(1, 60));
|
//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
|
//encoded_packet.write_interleaved(&mut self.octx).unwrap(); // AAA
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eprintln!("Audio buffer length {}", self.audio_buf.len());
|
||||||
|
|
||||||
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(),
|
||||||
ChannelLayout::STEREO
|
ChannelLayout::STEREO
|
||||||
);
|
);
|
||||||
|
aframe.set_channels(2);
|
||||||
aframe.set_rate(32040);
|
aframe.set_rate(32040);
|
||||||
|
aframe.set_pts(Some(frame));
|
||||||
let aplane: &mut [(i16, i16)] = aframe.plane_mut(0);
|
let aplane: &mut [(i16, i16)] = aframe.plane_mut(0);
|
||||||
aplane.copy_from_slice(self.audio_buf.as_ref());
|
aplane.copy_from_slice(self.audio_buf.as_ref());
|
||||||
|
//eprintln!("src: {:?}, dest: {:?}", self.audio_buf, aplane);
|
||||||
self.audio_buf.clear();
|
self.audio_buf.clear();
|
||||||
|
|
||||||
let mut out = ffmpeg::Packet::empty();
|
|
||||||
self.audio_filter.get("in").unwrap().source().add(&aframe).unwrap();
|
self.audio_filter.get("in").unwrap().source().add(&aframe).unwrap();
|
||||||
|
|
||||||
let mut filtered_aframe = frame::Audio::empty();
|
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");
|
println!("🎥 failed to put filter input frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filtered_aframe.set_pts(Some(frame));
|
||||||
self.audio_encoder.send_frame(&aframe).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.audio_encoder.receive_packet(&mut encoded_packet) {
|
while let Ok(..) = self.audio_encoder.receive_packet(&mut encoded_packet) {
|
||||||
if encoded_packet.size() > 0 {
|
if encoded_packet.size() > 0 {
|
||||||
encoded_packet.set_stream(1);
|
encoded_packet.set_stream(1);
|
||||||
//encoded_packet.rescale_ts(Rational(1, 1), Rational(1, 60));
|
//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)
|
.load_game(Some(path), data, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn end(&mut self) {
|
||||||
|
self.octx.write_trailer().unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl retro::wrapper::Handler for MyEmulator {
|
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());
|
self.video_encoder.set_frame_rate(system_av_info.timing.fps.into());
|
||||||
/*
|
|
||||||
if system_av_info.timing.sample_rate.round() as i32 > 0 {
|
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.audio_encoder.set_rate(system_av_info.timing.sample_rate.round() as i32);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
self.av_info.timing = system_av_info.timing;
|
self.av_info.timing = system_av_info.timing;
|
||||||
self.set_geometry(system_av_info.geometry);
|
self.set_geometry(system_av_info.geometry);
|
||||||
true
|
true
|
||||||
|
@ -431,6 +454,7 @@ fn main() -> Fallible<()> {
|
||||||
let mut packet = Packet::empty();
|
let mut packet = Packet::empty();
|
||||||
eprintln!("flushed: {:?}", emu.video_encoder.flush(&mut packet).unwrap());
|
eprintln!("flushed: {:?}", emu.video_encoder.flush(&mut packet).unwrap());
|
||||||
|
|
||||||
|
emu.end();
|
||||||
//octx.write_trailer().unwrap();
|
//octx.write_trailer().unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue