actually write a video!!!!!

This commit is contained in:
Vivian Lim 2021-04-22 00:16:09 -07:00
parent d3a88573d7
commit 88d1ab0b0e
1 changed files with 67 additions and 27 deletions

View File

@ -29,7 +29,7 @@ struct MyEmulator {
audio_filter: filter::Graph, audio_filter: filter::Graph,
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,
} }
fn video_filter( fn video_filter(
@ -125,27 +125,16 @@ impl MyEmulator {
let vcodec = ffmpeg::encoder::find(detected_vcodec).unwrap().video().unwrap(); let vcodec = ffmpeg::encoder::find(detected_vcodec).unwrap().video().unwrap();
let acodec = ffmpeg::encoder::find(detected_acodec).unwrap().audio().unwrap(); let acodec = ffmpeg::encoder::find(detected_acodec).unwrap().audio().unwrap();
let mut audio_encoder = octx.add_stream(acodec).unwrap().codec().encoder().audio().unwrap();
//let mut video_encoder = octx.add_stream(vcodec).unwrap().codec().encoder().video().unwrap();
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();
/*
let mut audio_output = octx.add_stream(acodec).unwrap();
let mut audio_encoder = audio_output.codec().encoder().audio().unwrap();
*/
video_encoder.set_bit_rate(64000); video_encoder.set_bit_rate(64000);
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());
audio_encoder.set_bit_rate(64000);
audio_encoder.set_rate(44100);
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);
video_encoder.set_time_base(Rational::new(1, fps_int)); video_encoder.set_time_base(Rational::new(1, fps_int));
video_output.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_frame_rate(av_info.timing.fps.into());
if av_info.geometry.base_height == 0 && av_info.geometry.base_width == 0 { if av_info.geometry.base_height == 0 && av_info.geometry.base_width == 0 {
av_info.geometry.base_width = 320; av_info.geometry.base_width = 320;
av_info.geometry.base_height = 224; av_info.geometry.base_height = 224;
@ -158,18 +147,42 @@ impl MyEmulator {
video_encoder.set_height(av_info.geometry.base_height); video_encoder.set_height(av_info.geometry.base_height);
//video_encoder.set_aspect_ratio(av_info.geometry.aspect_ratio as f64); //video_encoder.set_aspect_ratio(av_info.geometry.aspect_ratio as f64);
audio_encoder.set_rate(44100);
let pix_fmt = PixelFormat::ARGB1555; // temporary until env call is made let pix_fmt = PixelFormat::ARGB1555; // temporary until env call is made
let video_filter = video_filter(&video_encoder, &av_info, pix_fmt).unwrap(); let video_filter = video_filter(&video_encoder, &av_info, pix_fmt).unwrap();
let audio_filter = audio_filter(&audio_encoder, av_info.timing.sample_rate).unwrap();
let video_encoder = video_encoder.open_as(vcodec).unwrap(); let video_encoder = video_encoder.open_as(vcodec).unwrap();
video_output.set_parameters(&video_encoder); video_output.set_parameters(&video_encoder);
let mut audio_output = octx.add_stream(acodec).unwrap();
let mut audio_encoder = audio_output.codec().encoder().audio().unwrap();
//let mut video_encoder = octx.add_stream(vcodec).unwrap().codec().encoder().video().unwrap();
/*
let mut audio_output = octx.add_stream(acodec).unwrap();
let mut audio_encoder = audio_output.codec().encoder().audio().unwrap();
*/
/*
retroarch inits
static bool ffmpeg_init_config(struct ff_config_param *params,
if (!ffmpeg_init_muxer_pre(handle))
if (!ffmpeg_init_video(handle))
av_frame_alloc
*/
audio_encoder.set_bit_rate(64000);
audio_encoder.set_rate(44100);
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);
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(); 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();
let emu = MyEmulator { let emu = MyEmulator {
retro, retro,
sys_info, sys_info,
@ -183,7 +196,7 @@ impl MyEmulator {
audio_filter, audio_filter,
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, // AAA octx,
}; };
let mut pin_emu = Box::pin(emu); let mut pin_emu = Box::pin(emu);
@ -207,17 +220,28 @@ impl MyEmulator {
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.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(); 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() { 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 { 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");
} }
vframe.set_pts(Some(frame));
let encode_result = self.video_encoder.send_frame(&filtered_vframe).unwrap(); let encode_result = self.video_encoder.send_frame(&filtered_vframe).unwrap();
eprintln!("encoded: {:?}", encode_result); //eprintln!("encoded: {:?}", encode_result);
/*if encode_result { /*if encode_result {
out.set_stream(0); out.set_stream(0);
out.write_interleaved(octx).unwrap(); out.write_interleaved(octx).unwrap();
@ -225,9 +249,19 @@ impl MyEmulator {
*/ */
let mut encoded_packet = ffmpeg::Packet::empty(); let mut encoded_packet = ffmpeg::Packet::empty();
while self.video_encoder.receive_packet(&mut encoded_packet).is_ok() { while let Ok(..) = self.video_encoder.receive_packet(&mut encoded_packet) {
//eprintln!("Attempting write: {:?}", encoded_packet); //eprintln!("Attempting write: {:?}", encoded_packet);
encoded_packet.set_stream(0); // use stream index... //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.rescale_ts(Rational(1, 1), self.time_base);
//encoded_packet.write_interleaved(&mut self.octx).unwrap(); // AAA //encoded_packet.write_interleaved(&mut self.octx).unwrap(); // AAA
} }
@ -270,11 +304,9 @@ impl retro::wrapper::Handler for MyEmulator {
let pitch = pitch as usize; let pitch = pitch as usize;
let vplane = vframe.data_mut(0); let vplane = vframe.data_mut(0);
/* sus
if data.len() == vplane.len() && pitch == stride { if data.len() == vplane.len() && pitch == stride {
vplane.copy_from_slice(&data); vplane.copy_from_slice(&data);
} else { } else {
*/
for y in 0..(height as usize) { for y in 0..(height as usize) {
let ffbegin = y * stride; let ffbegin = y * stride;
let lrbegin = y * pitch; let lrbegin = y * pitch;
@ -283,7 +315,9 @@ impl retro::wrapper::Handler for MyEmulator {
&data[lrbegin..(lrbegin + min)] &data[lrbegin..(lrbegin + min)]
); );
} }
//} }
//vframe.set_pts(Some(69));
self.video_frames.push_back(vframe); self.video_frames.push_back(vframe);
} }
@ -382,15 +416,21 @@ fn main() -> Fallible<()> {
ffmpeg::init().unwrap(); ffmpeg::init().unwrap();
let mut octx = format::output(&opt.video)?; let mut octx = format::output(&opt.video)?;
unsafe {
(*octx.as_mut_ptr()).debug = 1;
eprintln!("oformat: {:?}", &((*octx.as_mut_ptr()).oformat));
eprintln!("flags: {:?}", (*(*octx.as_mut_ptr()).oformat).flags);
}
//octx.write_header().unwrap();
let mut emu = MyEmulator::new(opt.core, &opt.system, &opt.video, octx); let mut emu = MyEmulator::new(opt.core, &opt.system, &opt.video, octx);
emu.load_game(opt.rom); emu.load_game(opt.rom);
emu.frame_properties_locked = true; emu.frame_properties_locked = true;
//octx.write_header().unwrap();
//for frame in 0..60*10 { //for frame in 0..60*10 {
for frame in 0..120 { for frame in 0..9200 {
eprintln!("🖼️ frame: {}", frame); eprintln!("🖼️ frame: {}", frame);
emu.run(frame); emu.run(frame);