actually write a video!!!!!
This commit is contained in:
		
							parent
							
								
									d3a88573d7
								
							
						
					
					
						commit
						88d1ab0b0e
					
				
					 1 changed files with 67 additions and 27 deletions
				
			
		| 
						 | 
				
			
			@ -29,7 +29,7 @@ struct MyEmulator {
 | 
			
		|||
    audio_filter: filter::Graph,
 | 
			
		||||
    sys_path: Option<PathBuf>,
 | 
			
		||||
    frame_properties_locked: bool,
 | 
			
		||||
    //octx: ffmpeg::format::context::Output,
 | 
			
		||||
    octx: ffmpeg::format::context::Output,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn video_filter(
 | 
			
		||||
| 
						 | 
				
			
			@ -125,27 +125,16 @@ impl MyEmulator {
 | 
			
		|||
        let vcodec = ffmpeg::encoder::find(detected_vcodec).unwrap().video().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_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_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_output.set_time_base(Rational::new(1, fps_int));
 | 
			
		||||
        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;
 | 
			
		||||
            av_info.geometry.base_height = 224;
 | 
			
		||||
| 
						 | 
				
			
			@ -158,18 +147,42 @@ impl MyEmulator {
 | 
			
		|||
        video_encoder.set_height(av_info.geometry.base_height);
 | 
			
		||||
        //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 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();
 | 
			
		||||
        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();
 | 
			
		||||
        audio_encoder.set_rate(av_info.timing.sample_rate.round() as i32);
 | 
			
		||||
        //audio_output.set_parameters(&audio_encoder);
 | 
			
		||||
 | 
			
		||||
octx.write_header().unwrap();
 | 
			
		||||
        let emu = MyEmulator {
 | 
			
		||||
            retro,
 | 
			
		||||
            sys_info,
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +196,7 @@ impl MyEmulator {
 | 
			
		|||
            audio_filter,
 | 
			
		||||
            sys_path: sys_path.as_ref().map(|x| x.as_ref().to_path_buf()),
 | 
			
		||||
            frame_properties_locked: false,
 | 
			
		||||
            //octx, // AAA
 | 
			
		||||
            octx,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let mut pin_emu = Box::pin(emu);
 | 
			
		||||
| 
						 | 
				
			
			@ -207,17 +220,28 @@ impl MyEmulator {
 | 
			
		|||
        aplane.copy_from_slice(self.audio_buf.as_ref());
 | 
			
		||||
        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();
 | 
			
		||||
        self.video_filter.get("in").unwrap().source().add(&vframe).unwrap();
 | 
			
		||||
        self.audio_filter.get("in").unwrap().source().add(&aframe).unwrap();
 | 
			
		||||
        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() {
 | 
			
		||||
            if self.video_filter.get("in").unwrap().source().failed_requests() > 0 {
 | 
			
		||||
                println!("🎥 failed to put filter input frame");
 | 
			
		||||
            }
 | 
			
		||||
            vframe.set_pts(Some(frame));
 | 
			
		||||
            let encode_result = self.video_encoder.send_frame(&filtered_vframe).unwrap();
 | 
			
		||||
            eprintln!("encoded: {:?}", encode_result);
 | 
			
		||||
            //eprintln!("encoded: {:?}", encode_result);
 | 
			
		||||
            /*if encode_result {
 | 
			
		||||
                out.set_stream(0);
 | 
			
		||||
                out.write_interleaved(octx).unwrap();
 | 
			
		||||
| 
						 | 
				
			
			@ -225,9 +249,19 @@ impl MyEmulator {
 | 
			
		|||
            */
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
                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.write_interleaved(&mut self.octx).unwrap(); // AAA
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -270,11 +304,9 @@ impl retro::wrapper::Handler for MyEmulator {
 | 
			
		|||
        let pitch = pitch as usize;
 | 
			
		||||
 | 
			
		||||
        let vplane = vframe.data_mut(0);
 | 
			
		||||
        /* sus
 | 
			
		||||
        if data.len() == vplane.len() && pitch == stride {
 | 
			
		||||
            vplane.copy_from_slice(&data);
 | 
			
		||||
        } else {
 | 
			
		||||
            */
 | 
			
		||||
            for y in 0..(height as usize) {
 | 
			
		||||
                let ffbegin = y * stride;
 | 
			
		||||
                let lrbegin = y * pitch;
 | 
			
		||||
| 
						 | 
				
			
			@ -283,7 +315,9 @@ impl retro::wrapper::Handler for MyEmulator {
 | 
			
		|||
                    &data[lrbegin..(lrbegin + min)]
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        //}
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //vframe.set_pts(Some(69));
 | 
			
		||||
 | 
			
		||||
        self.video_frames.push_back(vframe);
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -382,15 +416,21 @@ fn main() -> Fallible<()> {
 | 
			
		|||
    ffmpeg::init().unwrap();
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    emu.load_game(opt.rom);
 | 
			
		||||
 | 
			
		||||
    emu.frame_properties_locked = true;
 | 
			
		||||
    //octx.write_header().unwrap();
 | 
			
		||||
 | 
			
		||||
    //for frame in 0..60*10 {
 | 
			
		||||
    for frame in 0..120 {
 | 
			
		||||
    for frame in 0..9200 {
 | 
			
		||||
        eprintln!("🖼️ frame: {}", frame);
 | 
			
		||||
        emu.run(frame);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue