This commit is contained in:
Lily Tsuru 2024-10-11 00:33:40 -04:00
parent d54f65af8b
commit a34f833c80
3 changed files with 26 additions and 38 deletions

View file

@ -3,14 +3,12 @@ mod surface;
mod types; mod types;
mod video; mod video;
use retro_thread::{spawn_retro_thread, RetroState, RetroEvent}; use retro_thread::{spawn_retro_thread, RetroEvent};
use video::encoder_thread::EncodeThreadInput; use video::encoder_thread::EncodeThreadInput;
use video::h264_encoder::H264Encoder;
use video::{encoder_thread, ffmpeg}; use video::{encoder_thread, ffmpeg};
use std::{ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
thread,
time::Duration, time::Duration,
}; };
@ -76,7 +74,8 @@ async fn main() -> anyhow::Result<()> {
let state_clone = state.clone(); let state_clone = state.clone();
let vnc_recv_handle = tokio::spawn(async move { // retro event handler. drives the encoder thread too
tokio::spawn(async move {
let surface_clone = surface.clone(); let surface_clone = surface.clone();
let frame_clone = frame.clone(); let frame_clone = frame.clone();
@ -121,7 +120,7 @@ async fn main() -> anyhow::Result<()> {
} }
} }
state_clone let _ = state_clone
.encoder_tx .encoder_tx
.lock() .lock()
.await .await
@ -141,7 +140,7 @@ async fn main() -> anyhow::Result<()> {
)); ));
} }
state_clone let _ = state_clone
.encoder_tx .encoder_tx
.lock() .lock()
.await .await
@ -346,9 +345,9 @@ async fn handle_socket(socket: WebSocket, who: SocketAddr, state: Arc<AppState>)
break; break;
} }
let x = json["x"].as_u64().unwrap() as u32; //let x = json["x"].as_u64().unwrap() as u32;
let y = json["y"].as_u64().unwrap() as u32; //let y = json["y"].as_u64().unwrap() as u32;
let mask = json["mask"].as_u64().unwrap() as u8; //let mask = json["mask"].as_u64().unwrap() as u8;
/*let _ = recv_clone /*let _ = recv_clone
.engine_tx .engine_tx

View file

@ -17,10 +17,7 @@ use retro_frontend::{
use gpu::egl_helpers::DeviceContext; use gpu::egl_helpers::DeviceContext;
use letsplay_gpu as gpu; use letsplay_gpu as gpu;
use crate::{ use crate::{surface::Surface, types::Size};
surface::Surface,
types::{Rect, Size},
};
/// Called by OpenGL. We use this to dump errors. /// Called by OpenGL. We use this to dump errors.
extern "system" fn opengl_message_callback( extern "system" fn opengl_message_callback(
@ -110,11 +107,7 @@ impl RetroState {
fn init_display(&mut self) { fn init_display(&mut self) {
let av_info = self.get_frontend().get_av_info().expect("No AV info"); let av_info = self.get_frontend().get_av_info().expect("No AV info");
self.video_resize(av_info.geometry.base_width, av_info.geometry.base_height);
//self.window.resize(
// av_info.geometry.base_width as u16,
// av_info.geometry.base_height as u16,
//);
} }
pub fn load_core<P: AsRef<Path>>(&mut self, path: P) -> Result<()> { pub fn load_core<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
@ -157,37 +150,34 @@ impl RetroState {
/// Bleh, I don't like this is an associated fn, but whatever /// Bleh, I don't like this is an associated fn, but whatever
fn update_impl(framebuffer: Arc<Mutex<Surface>>, slice: &[u32], pitch: u32, from_opengl: bool) { fn update_impl(framebuffer: Arc<Mutex<Surface>>, slice: &[u32], pitch: u32, from_opengl: bool) {
let mut framebuffer_locked = framebuffer.lock().expect("could not lock framebuffer"); let mut framebuffer_locked = framebuffer.lock().expect("could not lock framebuffer");
let size = framebuffer_locked.size.clone(); let size = framebuffer_locked.size.clone();
let buffer = framebuffer_locked.get_buffer();
let has_disconnected_pitch = pitch != size.width as u32; let has_disconnected_pitch = pitch != size.width as u32;
// If this frame came from OpenGL we need to flip the image around // If this frame came from OpenGL we need to flip the image around
// so it is right side up (from our perspective). // so it is right side up (from our perspective).
//
// We do this in a bit of a convoluted way (but it's also zero allocation!)
if from_opengl { if from_opengl {
let mut scanlines: Vec<&[u32]> = Vec::with_capacity(size.height as usize);
// Push scanline slices in reverse order (which will actually flip them to the right orientation)
for y in (0..size.height).rev() { for y in (0..size.height).rev() {
let src_line_off = (y as u32 * pitch) as usize; let src_line_off = (y as u32 * pitch) as usize;
let src_slice = &slice[src_line_off..src_line_off + size.width as usize]; let src_slice = &slice[src_line_off..src_line_off + size.width as usize];
scanlines.push(src_slice);
}
// Draw them let reversed_y = (size.height - 1) - y;
for y in 0..size.height {
let src_line_off = (y as u32 * pitch) as usize; let src_line_off = (reversed_y as u32 * pitch) as usize;
let mut dest_line_off = src_line_off; let mut dest_line_off = src_line_off;
// copy only // copy only
if has_disconnected_pitch { if has_disconnected_pitch {
dest_line_off = (y * size.width.min(pitch)) as usize; dest_line_off = (reversed_y * pitch.min(size.width)) as usize;
} }
let dest_slice = &mut framebuffer_locked.get_buffer() let dest_slice = &mut buffer[dest_line_off..dest_line_off + size.width as usize];
[dest_line_off..dest_line_off + size.width as usize];
dest_slice.copy_from_slice(scanlines[y as usize]);
dest_slice.copy_from_slice(src_slice);
} }
} else { } else {
for y in 0..size.height { for y in 0..size.height {
@ -245,6 +235,7 @@ impl FrontendInterface for RetroState {
// Read back the framebuffer // Read back the framebuffer
let slice = { let slice = {
// lame, doesn't do bgra conversion for us
//self.gl_framebuffer.read_pixels( //self.gl_framebuffer.read_pixels(
// &mut self.readback_buffer.get_buffer()[..], // &mut self.readback_buffer.get_buffer()[..],
// dimensions.0, // dimensions.0,
@ -252,7 +243,7 @@ impl FrontendInterface for RetroState {
//); //);
unsafe { unsafe {
let scope = self.gl_framebuffer.bind(); let _bind = self.gl_framebuffer.bind();
gl::ReadPixels( gl::ReadPixels(
0, 0,
0, 0,

View file

@ -7,8 +7,6 @@ use tokio::sync::mpsc::{self, error::TryRecvError};
use super::ffmpeg; use super::ffmpeg;
use super::h264_encoder::H264Encoder; use super::h264_encoder::H264Encoder;
use super::hwframe::HwFrameContext;
pub enum EncodeThreadInput { pub enum EncodeThreadInput {
Init { size: crate::types::Size }, Init { size: crate::types::Size },
ForceKeyframe, ForceKeyframe,
@ -48,9 +46,9 @@ impl EncoderState {
Ok(()) Ok(())
} }
fn frame(&mut self) -> Arc<Mutex<Option<ffmpeg::frame::Video>>> { //fn frame(&mut self) -> Arc<Mutex<Option<ffmpeg::frame::Video>>> {
self.frame.clone() // self.frame.clone()
} //}
fn send_frame(&mut self, pts: u64, force_keyframe: bool) -> Option<ffmpeg::Packet> { fn send_frame(&mut self, pts: u64, force_keyframe: bool) -> Option<ffmpeg::Packet> {
let mut lk = self.frame.lock().expect("fuck"); let mut lk = self.frame.lock().expect("fuck");