Skip to content

Commit 9d8f705

Browse files
committed
fix: Spawn network connection in background-task (to gain responsive main-window)
1 parent c347e1f commit 9d8f705

2 files changed

Lines changed: 72 additions & 59 deletions

File tree

client_sdl3/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ gamestreaming_webrtc = { path = "../gamestreaming_webrtc" }
1111
tokio = { version = "1", features = ["full"] }
1212
sdl3-sys = "0.5.4"
1313
ffmpeg-next = { version = "7.1.0" }
14+
bytes = "1.10.1"

client_sdl3/src/main.rs

Lines changed: 71 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::Result;
1+
use anyhow::{Result, anyhow};
22
use ffmpeg_next::{codec, filter, format, frame, media};
33
use webrtc::rtp::codecs::h264::H264Packet;
44
use webrtc::rtp::packetizer::Depacketizer;
@@ -11,6 +11,7 @@ use std::io::Write;
1111
use std::mem::zeroed;
1212
use std::ffi::CStr;
1313
use std::fs::File;
14+
use bytes::Bytes;
1415
use std::sync::Arc;
1516
use std::collections::HashMap;
1617
use tokio::sync::{Mutex, Notify};
@@ -151,53 +152,11 @@ async fn create_peer_connection() -> Result<RTCPeerConnection, webrtc::Error> {
151152
api.new_peer_connection(config).await
152153
}
153154

154-
#[tokio::main]
155-
async fn main() -> Result<(), Box<dyn std::error::Error>> {
156-
// XCloud part
157-
let mut window = unsafe { zeroed() };
158-
let mut renderer = unsafe { zeroed() };
159-
let mut texture = unsafe { zeroed() };
160-
161-
unsafe {
162-
if SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == false {
163-
println!("SDL_Init Error: {:?}", CStr::from_ptr(SDL_GetError()));
164-
return Err("SDL Init failed".into());
165-
}
166-
167-
// Create a window
168-
window = SDL_CreateWindow(
169-
c"SDL3 Video Playback".as_ptr(),
170-
1920,
171-
1080,
172-
SDL_WindowFlags::default()
173-
);
174-
175-
if window.is_null() {
176-
println!("SDL_CreateWindow Error: {:?}", CStr::from_ptr(SDL_GetError()));
177-
SDL_Quit();
178-
return Err("SDL_CreateWindow Error".into());
179-
}
180-
181-
renderer = SDL_CreateRenderer(window, ptr::null());
182-
183-
if renderer.is_null() {
184-
println!("SDL_CreateRenderer Error: {:?}", CStr::from_ptr(SDL_GetError()));
185-
SDL_Quit();
186-
return Err("SDL_CreateRenderer Error".into());
187-
}
188-
189-
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, 1920, 1080);
190-
if texture.is_null() {
191-
println!("SDL_CreateTexture Error: {:?}", CStr::from_ptr(SDL_GetError()));
192-
SDL_Quit();
193-
return Err("SDL_CreateTexture Error".into());
194-
}
195-
}
196-
197-
198-
let ts = authenticate(TOKENS_FILEPATH).await?;
155+
async fn start_remote_connection(audio_tx: tokio::sync::mpsc::Sender<Bytes>, video_tx: tokio::sync::mpsc::Sender<Bytes>) -> Result<()> {
156+
let ts = authenticate(TOKENS_FILEPATH)
157+
.await
158+
.map_err(|e|anyhow!("Authentication failed"))?;
199159

200-
/*
201160
let xcloud = GamestreamingClient::new(
202161
Platform::Home,
203162
&ts.gssv_token.token,
@@ -211,11 +170,12 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
211170
xcloud.start_stream_xhome(&c.server_id).await?
212171
},
213172
Err(err) => {
214-
return Err("No consoles received from API".into());
173+
return Err(anyhow!("No consoles received from API"));
215174
}
216175
};
217-
*/
218176

177+
178+
/*
219179
let xcloud = GamestreamingClient::new(
220180
Platform::Cloud,
221181
&ts.gssv_token.token,
@@ -234,6 +194,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
234194
return Err("No titles received from API".into());
235195
}
236196
};
197+
*/
237198

238199
// WebRTC part
239200

@@ -389,9 +350,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
389350
));
390351
*/
391352

392-
let (mut video_tx, mut video_rx) = tokio::sync::mpsc::channel(10);
393-
let (mut audio_tx, mut audio_rx) = tokio::sync::mpsc::channel(10);
394-
395353
let notify_tx = Arc::new(Notify::new());
396354
let notify_rx = notify_tx.clone();
397355

@@ -466,7 +424,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
466424
}
467425
None => {
468426
peer_connection.close().await?;
469-
return Err("Failed to get successful SDP answer".into());
427+
return Err(anyhow!("Failed to get successful SDP answer"));
470428
}
471429
}
472430

@@ -489,6 +447,10 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
489447
let ice_response = xcloud.exchange_ice(&session, candidates_ready).await?;
490448
println!("ICE Response {:?}", ice_response);
491449

450+
if ice_response.exchange_response.is_empty() {
451+
return Err(anyhow!("No candidates in ICE response"));
452+
}
453+
492454
println!("Adding remote ICE candidates");
493455
for candidate in ice_response.exchange_response {
494456
println!("Adding remote ICE candidate={:?}", candidate);
@@ -505,6 +467,61 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
505467
peer_connection.add_ice_candidate(c).await?;
506468
}
507469

470+
Ok(())
471+
}
472+
473+
#[tokio::main]
474+
async fn main() -> Result<()> {
475+
// XCloud part
476+
let mut window = unsafe { zeroed() };
477+
let mut renderer = unsafe { zeroed() };
478+
let mut texture = unsafe { zeroed() };
479+
480+
unsafe {
481+
if SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) == false {
482+
println!("SDL_Init Error: {:?}", CStr::from_ptr(SDL_GetError()));
483+
return Err(anyhow!("SDL Init failed"));
484+
}
485+
486+
// Create a window
487+
window = SDL_CreateWindow(
488+
c"SDL3 Video Playback".as_ptr(),
489+
1920,
490+
1080,
491+
SDL_WindowFlags::default()
492+
);
493+
494+
if window.is_null() {
495+
println!("SDL_CreateWindow Error: {:?}", CStr::from_ptr(SDL_GetError()));
496+
SDL_Quit();
497+
return Err(anyhow!("SDL_CreateWindow Error"));
498+
}
499+
500+
renderer = SDL_CreateRenderer(window, ptr::null());
501+
502+
if renderer.is_null() {
503+
println!("SDL_CreateRenderer Error: {:?}", CStr::from_ptr(SDL_GetError()));
504+
SDL_Quit();
505+
return Err(anyhow!("SDL_CreateRenderer Error"));
506+
}
507+
508+
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, 1920, 1080);
509+
if texture.is_null() {
510+
println!("SDL_CreateTexture Error: {:?}", CStr::from_ptr(SDL_GetError()));
511+
SDL_Quit();
512+
return Err(anyhow!("SDL_CreateTexture Error"));
513+
}
514+
}
515+
516+
let (mut video_tx, mut video_rx) = tokio::sync::mpsc::channel(10);
517+
let (mut audio_tx, mut audio_rx) = tokio::sync::mpsc::channel(10);
518+
519+
println!("Spawning remote connection...");
520+
let handle = tokio::spawn(start_remote_connection(audio_tx, video_tx));
521+
522+
523+
// Create a channel to signal the main loop to exit
524+
let (exit_tx, mut exit_rx) = tokio::sync::mpsc::channel::<()>(1);
508525
println!("Press ctrl-c to stop");
509526

510527
ffmpeg_next::init()?;
@@ -516,9 +533,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
516533
.unwrap();
517534

518535
unsafe {
519-
// Create a channel to signal the main loop to exit
520-
let (exit_tx, mut exit_rx) = tokio::sync::mpsc::channel::<()>(1);
521-
522536
// Clear the screen
523537
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
524538
SDL_RenderClear(renderer);
@@ -535,7 +549,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
535549
let _ = exit_tx.send(()).await;
536550
},
537551
_ => {
538-
println!("Unhandled evt: {:?}", evt.r#type);
552+
// println!("Unhandled evt: {:?}", evt.r#type);
539553
}
540554
}
541555

@@ -581,11 +595,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
581595
}
582596
}
583597

584-
/*
585598
SDL_DestroyRenderer(renderer);
586599
SDL_DestroyWindow(window);
587600
SDL_Quit();
588-
*/
589601
}
590602

591603
Ok(())

0 commit comments

Comments
 (0)