Skip to content

Commit

Permalink
Add option to create rolling video recordings
Browse files Browse the repository at this point in the history
  • Loading branch information
zarik5 committed Aug 25, 2023
1 parent 72fb6e4 commit 828976d
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 10 deletions.
2 changes: 1 addition & 1 deletion alvr/server/cpp/alvr_server/NalParsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void sendHeaders(int codec, unsigned char *&buf, int &len, int nalNum) {
return;
}

InitializeDecoder((const unsigned char *)buf, headersLen, codec);
SetVideoConfigNals((const unsigned char *)buf, headersLen, codec);

// move the cursor forward excluding config NALs
buf = cursor;
Expand Down
2 changes: 1 addition & 1 deletion alvr/server/cpp/alvr_server/alvr_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ void (*LogInfo)(const char *stringPtr);
void (*LogDebug)(const char *stringPtr);
void (*LogPeriodically)(const char *tag, const char *stringPtr);
void (*DriverReadyIdle)(bool setDefaultChaprone);
void (*InitializeDecoder)(const unsigned char *configBuffer, int len, int codec);
void (*SetVideoConfigNals)(const unsigned char *configBuffer, int len, int codec);
void (*VideoSend)(unsigned long long targetTimestampNs, unsigned char *buf, int len, bool isIdr);
void (*HapticsSend)(unsigned long long path, float duration_s, float frequency, float amplitude);
void (*ShutdownRuntime)();
Expand Down
2 changes: 1 addition & 1 deletion alvr/server/cpp/alvr_server/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ extern "C" void (*LogInfo)(const char *stringPtr);
extern "C" void (*LogDebug)(const char *stringPtr);
extern "C" void (*LogPeriodically)(const char *tag, const char *stringPtr);
extern "C" void (*DriverReadyIdle)(bool setDefaultChaprone);
extern "C" void (*InitializeDecoder)(const unsigned char *configBuffer, int len, int codec);
extern "C" void (*SetVideoConfigNals)(const unsigned char *configBuffer, int len, int codec);
extern "C" void (*VideoSend)(unsigned long long targetTimestampNs,
unsigned char *buf,
int len,
Expand Down
22 changes: 20 additions & 2 deletions alvr/server/src/connection.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
bitrate::BitrateManager,
buttons::BUTTON_PATH_FROM_ID,
create_recording_file,
face_tracking::FaceTrackingSink,
haptics,
sockets::WelcomeSocket,
Expand Down Expand Up @@ -42,7 +43,7 @@ use std::{
Arc,
},
thread,
time::Duration,
time::{Duration, Instant},
};

const RETRY_CONNECT_MIN_INTERVAL: Duration = Duration::from_secs(1);
Expand Down Expand Up @@ -1036,7 +1037,7 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
}
}

if settings.capture.save_video_stream {
if settings.capture.startup_video_recording {
crate::create_recording_file();
}

Expand Down Expand Up @@ -1101,6 +1102,7 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
pub extern "C" fn send_video(timestamp_ns: u64, buffer_ptr: *mut u8, len: i32, is_idr: bool) {
// start in the corrupts state, the client didn't receive the initial IDR yet.
static STREAM_CORRUPTED: AtomicBool = AtomicBool::new(true);
static LAST_IDR_INSTANT: Lazy<Mutex<Instant>> = Lazy::new(|| Mutex::new(Instant::now()));

if let Some(sender) = &*VIDEO_CHANNEL_SENDER.lock() {
let buffer_size = len as usize;
Expand All @@ -1109,6 +1111,22 @@ pub extern "C" fn send_video(timestamp_ns: u64, buffer_ptr: *mut u8, len: i32, i
STREAM_CORRUPTED.store(false, Ordering::SeqCst);
}

if let Switch::Enabled(config) = &SERVER_DATA_MANAGER
.read()
.settings()
.capture
.rolling_video_files
{
if Instant::now() > *LAST_IDR_INSTANT.lock() + Duration::from_secs(config.duration_s) {
unsafe { crate::RequestIDR() };

if is_idr {
create_recording_file();
*LAST_IDR_INSTANT.lock() = Instant::now();
}
}
}

let timestamp = Duration::from_nanos(timestamp_ns);

let mut payload = vec![0; buffer_size];
Expand Down
8 changes: 5 additions & 3 deletions alvr/server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ pub fn create_recording_file() {
"h265"
};

let path = FILESYSTEM_LAYOUT.log_dir.join(format!("recording.{ext}"));
let path = FILESYSTEM_LAYOUT
.log_dir
.join(format!("recording.{}.{ext}", chrono::Local::now().format("%F.%H-%M-%S")));

match File::create(path) {
Ok(mut file) => {
Expand Down Expand Up @@ -326,7 +328,7 @@ pub unsafe extern "C" fn HmdDriverFactory(
}
}

extern "C" fn initialize_decoder(buffer_ptr: *const u8, len: i32, codec: i32) {
extern "C" fn set_video_config_nals(buffer_ptr: *const u8, len: i32, codec: i32) {
let codec = if codec == 0 {
CodecType::H264
} else {
Expand Down Expand Up @@ -435,7 +437,7 @@ pub unsafe extern "C" fn HmdDriverFactory(
LogDebug = Some(log_debug);
LogPeriodically = Some(log_periodically);
DriverReadyIdle = Some(driver_ready_idle);
InitializeDecoder = Some(initialize_decoder);
SetVideoConfigNals = Some(set_video_config_nals);
VideoSend = Some(connection::send_video);
HapticsSend = Some(connection::send_haptics);
ShutdownRuntime = Some(shutdown_driver);
Expand Down
18 changes: 16 additions & 2 deletions alvr/session/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -869,9 +869,19 @@ No action: All driver registration actions should be performed manually, ALVR in
pub open_close_steamvr_with_dashboard: bool,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
pub struct RollingVideoFilesConfig {
#[schema(strings(display_name = "Duration"))]
#[schema(suffix = "s")]
pub duration_s: u64,
}

#[derive(SettingsSchema, Serialize, Deserialize, Clone)]
pub struct CaptureConfig {
pub save_video_stream: bool,
#[schema(strings(display_name = "Start video recording at client connection"))]
pub startup_video_recording: bool,

pub rolling_video_files: Switch<RollingVideoFilesConfig>,

#[schema(flag = "steamvr-restart")]
pub capture_frame_dir: String,
Expand Down Expand Up @@ -1266,7 +1276,11 @@ pub fn session_settings_default() -> SettingsDefault {
open_close_steamvr_with_dashboard: false,
},
capture: CaptureConfigDefault {
save_video_stream: false,
startup_video_recording: false,
rolling_video_files: SwitchDefault {
enabled: false,
content: RollingVideoFilesConfigDefault { duration_s: 5 },
},
capture_frame_dir: if !cfg!(target_os = "linux") {
"/tmp".into()
} else {
Expand Down

0 comments on commit 828976d

Please sign in to comment.