feat: measure footage across segments and test X11 capture
Matroska output can stay buffered until a segment closes, so progress counts bytes across all segments and the stall limit scales with segment length. Unknown capture source types now fail instead of recording an empty placeholder. The rig gains an Xwayland mode for Xcomposite window capture.
This commit is contained in:
@@ -129,7 +129,9 @@ unsafe extern "C" fn log_to_stderr(
|
||||
args: VaList,
|
||||
_: *mut c_void,
|
||||
) {
|
||||
if level >= sys::LOG_DEBUG as i32 && std::env::var_os("CLIPBIN_OBS_DEBUG").is_none() {
|
||||
// LOG_* constants are u32 in the Linux bindings and i32 in the Windows ones.
|
||||
let level = i64::from(level);
|
||||
if level >= i64::from(sys::LOG_DEBUG) && std::env::var_os("CLIPBIN_OBS_DEBUG").is_none() {
|
||||
return;
|
||||
}
|
||||
let mut message = Dstr {
|
||||
@@ -141,9 +143,9 @@ unsafe extern "C" fn log_to_stderr(
|
||||
// allocates message.array with bmalloc, released with bfree.
|
||||
unsafe { dstr_vprintf(&mut message, format, args) };
|
||||
let label = match level {
|
||||
level if level <= sys::LOG_ERROR as i32 => "error",
|
||||
level if level <= sys::LOG_WARNING as i32 => "warning",
|
||||
level if level <= sys::LOG_INFO as i32 => "info",
|
||||
level if level <= i64::from(sys::LOG_ERROR) => "error",
|
||||
level if level <= i64::from(sys::LOG_WARNING) => "warning",
|
||||
level if level <= i64::from(sys::LOG_INFO) => "info",
|
||||
_ => "debug",
|
||||
};
|
||||
if let Some(text) = owned(message.array) {
|
||||
@@ -757,7 +759,7 @@ impl Pipeline {
|
||||
total_bytes: sys::obs_output_get_total_bytes(self.output),
|
||||
lagged_frames: sys::obs_get_lagged_frames() as u64,
|
||||
current_segment: None,
|
||||
current_segment_bytes: 0,
|
||||
written_bytes: 0,
|
||||
disk_available_bytes: None,
|
||||
}
|
||||
}
|
||||
@@ -824,11 +826,18 @@ impl Drop for Pipeline {
|
||||
/// # Safety
|
||||
/// Must run on the OBS thread.
|
||||
unsafe fn create_source(spec: &SourceSpec, name: &CStr) -> Result<*mut sys::obs_source_t, String> {
|
||||
let id = cstring(spec.id);
|
||||
// OBS creates a placeholder for unknown source types instead of failing.
|
||||
// SAFETY: looks up a registered type by id.
|
||||
if unsafe { sys::obs_source_get_display_name(id.as_ptr()) }.is_null() {
|
||||
return Err(format!(
|
||||
"the {} capture source is not available (its OBS plugin did not register it)",
|
||||
spec.id
|
||||
));
|
||||
}
|
||||
let settings = Data::new(&spec.settings);
|
||||
// SAFETY: arguments are valid; the caller owns the returned reference.
|
||||
let source = unsafe {
|
||||
sys::obs_source_create_private(cstring(spec.id).as_ptr(), name.as_ptr(), settings.0)
|
||||
};
|
||||
let source = unsafe { sys::obs_source_create_private(id.as_ptr(), name.as_ptr(), settings.0) };
|
||||
if source.is_null() {
|
||||
Err(format!(
|
||||
"OBS could not create the {} source (is its plugin loaded?)",
|
||||
|
||||
Reference in New Issue
Block a user