Don't panic if the emulator doesn't have frames ready to render, use angrylion with parallel-n64
This commit is contained in:
		
							parent
							
								
									ee9678af68
								
							
						
					
					
						commit
						7c03aac388
					
				
					 1 changed files with 84 additions and 60 deletions
				
			
		|  | @ -13,6 +13,8 @@ use ferretro::retro; | |||
| use ferretro::retro::ffi::{PixelFormat, GameGeometry, SystemAvInfo, SystemInfo}; | ||||
| use ferretro::retro::wrapper::{LibretroWrapper, Handler}; | ||||
| 
 | ||||
| use ferretro::retro::wrapped_types::{Variable2}; | ||||
| 
 | ||||
| use ffmpeg::{ChannelLayout, Packet, codec, filter, format, frame, media}; | ||||
| use ffmpeg::util::rational::Rational; | ||||
| 
 | ||||
|  | @ -278,71 +280,77 @@ static bool ffmpeg_init_config(struct ff_config_param *params, | |||
|         self.frame += 1; | ||||
|         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(); | ||||
|         match self.video_frames.pop_front() { | ||||
|             Some(mut vframe) => { | ||||
|                 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 {}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"); | ||||
|                 loop { | ||||
|                     match self.video_filter.get("out").unwrap().sink().frame(&mut filtered_vframe) { | ||||
|                         Ok(..) => { | ||||
|                             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));
 | ||||
|                             self.video_encoder.send_frame(&filtered_vframe).unwrap(); | ||||
| 
 | ||||
|                             self.receive_and_write_packets(EncoderToWriteFrom::Video); | ||||
|                         }, | ||||
|                         Err(e) => { | ||||
|                             eprintln!("Error getting filtered video frame: {:?}", e); | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     //filtered_vframe.set_pts(Some(frame));
 | ||||
|                     self.video_encoder.send_frame(&filtered_vframe).unwrap(); | ||||
| 
 | ||||
|                     self.receive_and_write_packets(EncoderToWriteFrom::Video); | ||||
|                 }, | ||||
|                 Err(e) => { | ||||
|                     eprintln!("Error getting filtered video frame: {:?}", e); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|                 
 | ||||
|                 // Assumption: if there is a video frame, there is an audio frame.
 | ||||
|                 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(44100); | ||||
|                 let aplane: &mut [(i16, i16)] = aframe.plane_mut(0); | ||||
|                 eprintln!("Audio buffer length {} -> {}", self.audio_buf.len(), aplane.len()); | ||||
|                 aplane.copy_from_slice(self.audio_buf.as_ref()); | ||||
|                 //eprintln!("src: {:?}, dest: {:?}", self.audio_buf, aplane);
 | ||||
|                 self.audio_buf.clear(); | ||||
| 
 | ||||
|                 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 {:?} 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)); | ||||
| 
 | ||||
|                             self.audio_encoder.send_frame(&filtered_aframe).unwrap(); | ||||
|                             self.receive_and_write_packets(EncoderToWriteFrom::Audio); | ||||
|                         }, | ||||
|                         Err(e) => { | ||||
|                             eprintln!("Error getting filtered audio frame: {:?}", e); | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             None => println!("Video not ready during frame {}", self.frame) | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         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(44100); | ||||
|         let aplane: &mut [(i16, i16)] = aframe.plane_mut(0); | ||||
|         eprintln!("Audio buffer length {} -> {}", self.audio_buf.len(), aplane.len()); | ||||
|         aplane.copy_from_slice(self.audio_buf.as_ref()); | ||||
|         //eprintln!("src: {:?}, dest: {:?}", self.audio_buf, aplane);
 | ||||
|         self.audio_buf.clear(); | ||||
| 
 | ||||
|         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 {:?} 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)); | ||||
| 
 | ||||
|                     self.audio_encoder.send_frame(&filtered_aframe).unwrap(); | ||||
|                     self.receive_and_write_packets(EncoderToWriteFrom::Audio); | ||||
|                 }, | ||||
|                 Err(e) => { | ||||
|                     eprintln!("Error getting filtered audio frame: {:?}", e); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|  | @ -468,9 +476,25 @@ impl retro::wrapper::Handler for MyEmulator { | |||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     fn get_variable(&mut self, key: &str) -> Option<String> { | ||||
|         match key { | ||||
|             "beetle_saturn_analog_stick_deadzone" => Some("15%".to_string()), | ||||
|             "parallel-n64-gfxplugin" => Some("angrylion".to_string()), | ||||
|             "parallel-n64-astick-deadzone" => Some("15%".to_string()), | ||||
|             _ => None, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn set_variables(&mut self, variables: Vec<Variable2>) -> bool { | ||||
|         for v in variables { | ||||
|             eprintln!("{:?}", v); | ||||
|         } | ||||
|         true | ||||
|     } | ||||
| 
 | ||||
|     fn log_print(&mut self, level: retro::ffi::LogLevel, msg: &str) { | ||||
|         eprint!("🕹️ [{:?}] {}", level, msg); | ||||
| } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(StructOpt)] | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue