chore(workspace): tighten quality gates (#2230)

This commit is contained in:
Hampus
2026-08-31 04:43:20 +02:00
committed by GitHub
parent e6e4c6f7b5
commit 5c2dca1c51
123 changed files with 4925 additions and 5640 deletions
+2 -2
View File
@@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "autotools"
@@ -7,61 +7,61 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CRATE_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
require_pkg_config() {
if ! command -v pkg-config >/dev/null 2>&1; then
echo "error: pkg-config is required but was not found in PATH." >&2
echo " Install via: brew install pkg-config (macOS)" >&2
echo " apt-get install pkg-config (Debian/Ubuntu)" >&2
exit 1
fi
if ! command -v pkg-config >/dev/null 2>&1; then
echo "error: pkg-config is required but was not found in PATH." >&2
echo " Install via: brew install pkg-config (macOS)" >&2
echo " apt-get install pkg-config (Debian/Ubuntu)" >&2
exit 1
fi
}
assert_webrtc_pkgconfig() {
if ! pkg-config --exists webrtc-audio-processing-2; then
echo "error: pkg-config cannot locate webrtc-audio-processing-2." >&2
echo " See fluxer_desktop/native/audio-apm/README.md for install steps." >&2
exit 1
fi
if ! pkg-config --exists webrtc-audio-processing-2; then
echo "error: pkg-config cannot locate webrtc-audio-processing-2." >&2
echo " See fluxer_desktop/native/audio-apm/README.md for install steps." >&2
exit 1
fi
}
assert_absl_pkgconfig() {
if ! pkg-config --exists absl_base; then
echo "error: pkg-config cannot locate absl_base." >&2
echo " Install via: brew install abseil (macOS)" >&2
echo " apt-get install libabsl-dev (Debian/Ubuntu)" >&2
exit 1
fi
if ! pkg-config --exists absl_base; then
echo "error: pkg-config cannot locate absl_base." >&2
echo " Install via: brew install abseil (macOS)" >&2
echo " apt-get install libabsl-dev (Debian/Ubuntu)" >&2
exit 1
fi
}
inject_absl_include_path() {
local absl_includes
absl_includes="$(pkg-config --cflags-only-I absl_base)"
if [[ -z "${absl_includes}" ]]; then
echo "error: pkg-config returned no include path for absl_base." >&2
exit 1
fi
local absl_includes
absl_includes="$(pkg-config --cflags-only-I absl_base)"
if [[ -z "${absl_includes}" ]]; then
echo "error: pkg-config returned no include path for absl_base." >&2
exit 1
fi
local prev_cxxflags="${CXXFLAGS-}"
local prev_bindgen="${BINDGEN_EXTRA_CLANG_ARGS-}"
local prev_cxxflags="${CXXFLAGS-}"
local prev_bindgen="${BINDGEN_EXTRA_CLANG_ARGS-}"
export CXXFLAGS="${absl_includes} ${prev_cxxflags}"
export BINDGEN_EXTRA_CLANG_ARGS="${absl_includes} ${prev_bindgen}"
export CXXFLAGS="${absl_includes} ${prev_cxxflags}"
export BINDGEN_EXTRA_CLANG_ARGS="${absl_includes} ${prev_bindgen}"
}
main() {
cd "${CRATE_DIR}"
cd "${CRATE_DIR}"
local cargo_subcmd="build"
if [[ $# -gt 0 && "$1" != -* && "$1" != "--" ]]; then
cargo_subcmd="$1"
shift
fi
local cargo_subcmd="build"
if [[ $# -gt 0 && "$1" != -* && "$1" != "--" ]]; then
cargo_subcmd="$1"
shift
fi
require_pkg_config
assert_webrtc_pkgconfig
assert_absl_pkgconfig
inject_absl_include_path
require_pkg_config
assert_webrtc_pkgconfig
assert_absl_pkgconfig
inject_absl_include_path
exec cargo "${cargo_subcmd}" --features real-apm "$@"
exec cargo "${cargo_subcmd}" --features real-apm "$@"
}
main "$@"
+2 -2
View File
@@ -165,9 +165,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
dependencies = [
"crossbeam-utils",
]
+2 -2
View File
@@ -165,9 +165,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
dependencies = [
"crossbeam-utils",
]
+107
View File
@@ -0,0 +1,107 @@
[graph]
all-features = true
no-default-features = false
[output]
feature-depth = 1
[advisories]
version = 2
yanked = "deny"
unmaintained = "all"
ignore = []
[licenses]
version = 2
confidence-threshold = 0.93
unused-allowed-license = "allow"
allow = [
"MIT",
"MIT-0",
"Apache-2.0",
"Apache-2.0 WITH LLVM-exception",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"MPL-2.0",
"NCSA",
"Unicode-3.0",
"Zlib",
"CC0-1.0",
"AGPL-3.0-or-later",
"BSL-1.0",
"CDLA-Permissive-2.0",
]
exceptions = []
[licenses.private]
ignore = true
registries = []
[[licenses.clarify]]
crate = "ring"
expression = "ISC AND MIT AND OpenSSL"
license-files = [
{ path = "LICENSE", hash = 0xbd0eed23 },
]
[[licenses.clarify]]
crate = "[email protected]"
expression = "BSD-3-Clause"
license-files = [
{ path = "COPYING", hash = 0x3d3ea952 },
]
[[licenses.clarify]]
crate = "[email protected]"
expression = "BSD-3-Clause"
license-files = [
{ path = "COPYING", hash = 0x7e861f0d },
]
[[licenses.clarify]]
crate = "[email protected]"
expression = "BSD-3-Clause"
license-files = [
{ path = "COPYING", hash = 0x7e861f0d },
]
[bans]
multiple-versions = "warn"
wildcards = "deny"
allow-wildcard-paths = true
highlight = "all"
workspace-default-features = "allow"
external-default-features = "allow"
deny = [
{ crate = "fuse", reason = "libfuse2-based Rust wrapper; use a maintained FUSE3-native crate only if Fluxer ever needs FUSE directly" },
{ crate = "fuse-sys", reason = "libfuse2 FFI crate; Fluxer AppImages must not reintroduce libfuse2 through native Rust dependencies" },
]
skip = [
{ crate = "[email protected]", reason = "hunspell bindgen requires the legacy bitflags API" },
{ crate = "[email protected]", reason = "transitive dependencies require the prior hash table API" },
{ crate = "[email protected]", reason = "transitive dependencies require the older hash table API" },
{ crate = "[email protected]", reason = "transitive dependencies require the prior hash table API" },
{ crate = "[email protected]", reason = "udev requires the prior Hermit ABI" },
{ crate = "[email protected]", reason = "bindgen and criterion require the prior iterator API" },
{ crate = "[email protected]", reason = "bindgen requires the prior dynamic loading API" },
{ crate = "[email protected]", reason = "evdev requires the prior Unix API" },
{ crate = "[email protected]", reason = "bindgen requires the prior parser API" },
{ crate = "[email protected]", reason = "hunspell bindgen requires the legacy hash API" },
{ crate = "[email protected]", reason = "bindgen requires the prior shell parsing API" },
{ crate = "[email protected]", reason = "hunspell bindgen requires the legacy macro API" },
{ crate = "[email protected]", reason = "napi derive requires the prior macro API" },
{ crate = "[email protected]", reason = "udev requires the legacy Windows API" },
{ crate = "[email protected]", reason = "hunspell build tooling requires the prior Windows API" },
{ crate = "[email protected]", reason = "the WASI preview 3 compatibility layer requires the prior binding API" },
]
skip-tree = []
[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []
[sources.allow-org]
github = []
+2 -2
View File
@@ -211,9 +211,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
dependencies = [
"crossbeam-utils",
]
@@ -52,12 +52,11 @@ impl EncoderFrameRate {
let denominator = u64::from(self.denominator);
assert!(numerator > 0, "fps numerator positive");
assert!(denominator > 0, "fps denominator positive");
((1_000_000u64 * denominator) + numerator - 1) / numerator
(1_000_000u64 * denominator).div_ceil(numerator)
}
pub fn gop_pic_size(self) -> u16 {
let rounded = (u64::from(self.numerator) + u64::from(self.denominator) - 1)
/ u64::from(self.denominator);
let rounded = u64::from(self.numerator).div_ceil(u64::from(self.denominator));
let bounded = rounded.clamp(1, u64::from(ENCODER_FRAME_RATE_MAX));
bounded as u16
}
+2 -2
View File
@@ -245,9 +245,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
dependencies = [
"crossbeam-utils",
]
@@ -228,12 +228,11 @@ fn retain_screen_audio_sink_handle(
"DirectAudioCapture.setScreenAudioSink received an empty native external sink handle",
));
}
let handle = unsafe {
NativeScreenFrameSinkHandle::retain_from_raw(data.cast::<NativeScreenFrameSinkHandle>())
}
.ok_or_else(|| {
generic_error("DirectAudioCapture.setScreenAudioSink received an invalid handle")
})?;
let handle = unsafe { data.cast::<NativeScreenFrameSinkHandle>().as_ref() }
.and_then(NativeScreenFrameSinkHandle::retain_ref)
.ok_or_else(|| {
generic_error("DirectAudioCapture.setScreenAudioSink received an invalid handle")
})?;
Ok(Arc::new(handle))
}
@@ -740,8 +740,8 @@ mod tests {
.expect("apm");
let frame_len = DIRECT_CAPTURE_APM_FRAME_SAMPLES;
let mut samples = vec![0.0_f32; frame_len];
for n in 0..frame_len {
samples[n] = ((n as f32) / (frame_len as f32) - 0.5) * 0.5;
for (n, sample) in samples.iter_mut().enumerate() {
*sample = ((n as f32) / (frame_len as f32) - 0.5) * 0.5;
}
let original = samples.clone();
let _ = apm.process_in_place(&mut samples).expect("process");
+2 -2
View File
@@ -4,9 +4,9 @@ version = 4
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "async-broadcast"
+2 -2
View File
@@ -4,9 +4,9 @@ version = 4
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "async-broadcast"
+4 -4
View File
@@ -44,9 +44,9 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "arrayvec"
@@ -1479,9 +1479,9 @@ checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "spin"
version = "0.10.0"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
checksum = "023a211cb3138dbc438680b32560ad89f699977624c9f8dbb95a47d5b4c07dd3"
dependencies = [
"lock_api",
]
@@ -952,12 +952,13 @@ fn retain_native_frame_sink_handle(
));
}
let handle = unsafe {
NativeScreenFrameSinkHandle::retain_from_raw(data.cast::<NativeScreenFrameSinkHandle>())
}
.ok_or_else(|| {
invalid_arg("ScreenCapture.setFrameSinkHandle received an invalid native frame sink handle")
})?;
let handle = unsafe { data.cast::<NativeScreenFrameSinkHandle>().as_ref() }
.and_then(NativeScreenFrameSinkHandle::retain_ref)
.ok_or_else(|| {
invalid_arg(
"ScreenCapture.setFrameSinkHandle received an invalid native frame sink handle",
)
})?;
Ok(Arc::new(handle))
}
@@ -967,7 +968,7 @@ fn enqueue_native_bus_video_frame(
frame: &VideoFrame,
) -> EnqueueOutcome {
if let Some(dmabuf) = frame.dmabuf.as_ref() {
if sink.handle().enqueue_dmabuf.is_none() {
if !sink.supports_dmabuf() {
return EnqueueOutcome::Rejected;
}
let plane_count = dmabuf.plane_count as usize;
@@ -975,18 +976,13 @@ fn enqueue_native_bus_video_frame(
return EnqueueOutcome::Rejected;
}
let mut duped_fds: Vec<i32> = Vec::with_capacity(plane_count);
let mut duped_fds: Vec<OwnedFd> = Vec::with_capacity(plane_count);
for raw in dmabuf.fds.iter().take(plane_count) {
let duped = unsafe { libc::dup(*raw) };
if duped < 0 {
for fd in duped_fds {
unsafe {
libc::close(fd);
}
}
return EnqueueOutcome::Rejected;
}
duped_fds.push(duped);
duped_fds.push(unsafe { OwnedFd::from_raw_fd(duped) });
}
let desc = BusDmabufDesc {
@@ -1001,7 +997,7 @@ fn enqueue_native_bus_video_frame(
timestamp_us: frame.timestamp_us,
};
return unsafe { sink.enqueue_dmabuf_take_fds(desc, &duped_fds) };
return sink.enqueue_dmabuf_take_fds(desc, duped_fds);
}
sink.enqueue_nv12_copy(
@@ -138,15 +138,14 @@ fn retain_screen_audio_sink_handle(
"ProcessLoopback.setScreenAudioSink received an empty native external sink handle",
));
}
let handle = unsafe {
NativeScreenFrameSinkHandle::retain_from_raw(data.cast::<NativeScreenFrameSinkHandle>())
}
.ok_or_else(|| {
napi::Error::new(
Status::InvalidArg,
"ProcessLoopback.setScreenAudioSink received an invalid native sink handle",
)
})?;
let handle = unsafe { data.cast::<NativeScreenFrameSinkHandle>().as_ref() }
.and_then(NativeScreenFrameSinkHandle::retain_ref)
.ok_or_else(|| {
napi::Error::new(
Status::InvalidArg,
"ProcessLoopback.setScreenAudioSink received an invalid native sink handle",
)
})?;
Ok(Arc::new(handle))
}
@@ -960,15 +960,14 @@ fn retain_native_frame_sink_handle(
));
}
let handle = unsafe {
NativeScreenFrameSinkHandle::retain_from_raw(data.cast::<NativeScreenFrameSinkHandle>())
}
.ok_or_else(|| {
napi::Error::new(
Status::InvalidArg,
"ScreenCapture.setFrameSinkHandle received an invalid native frame sink handle",
)
})?;
let handle = unsafe { data.cast::<NativeScreenFrameSinkHandle>().as_ref() }
.and_then(NativeScreenFrameSinkHandle::retain_ref)
.ok_or_else(|| {
napi::Error::new(
Status::InvalidArg,
"ScreenCapture.setFrameSinkHandle received an invalid native frame sink handle",
)
})?;
Ok(Arc::new(handle))
}
@@ -980,7 +979,7 @@ fn try_enqueue_native_cv_pixel_buffer(
height: u32,
sample_buffer: &CMSampleBuffer,
) -> EnqueueOutcome {
if sink.handle().enqueue_mac_cv_pixel_buffer.is_none() {
if !sink.supports_mac_cv_pixel_buffer() {
return EnqueueOutcome::Rejected;
}
let retained =
+2 -2
View File
@@ -4,9 +4,9 @@ version = 4
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "bitflags"
+2 -2
View File
@@ -165,9 +165,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
dependencies = [
"crossbeam-utils",
]
+4 -4
View File
@@ -34,9 +34,9 @@ checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "autocfg"
@@ -216,9 +216,9 @@ dependencies = [
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
version = "0.9.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f"
dependencies = [
"crossbeam-utils",
]
@@ -30,12 +30,6 @@ pub struct NSErrorBlock {
pub user_invoke: NsErrorUserInvoke,
}
pub unsafe extern "C" fn ns_error_trampoline(block: *mut NSErrorBlock, err: *mut c_void) {
if let Some(block) = unsafe { block.as_mut() } {
unsafe { (block.user_invoke)(block.ctx, err) };
}
}
pub type ContentErrorUserInvoke =
unsafe extern "C" fn(ctx: *mut c_void, content: *mut c_void, err: *mut c_void);
pub type ContentErrorInvoke =
@@ -52,16 +46,6 @@ pub struct ContentErrorBlock {
pub user_invoke: ContentErrorUserInvoke,
}
pub unsafe extern "C" fn content_error_trampoline(
block: *mut ContentErrorBlock,
content: *mut c_void,
err: *mut c_void,
) {
if let Some(block) = unsafe { block.as_mut() } {
unsafe { (block.user_invoke)(block.ctx, content, err) };
}
}
pub const NS_ERROR_BLOCK_DESCRIPTOR: BlockDescriptorSig = BlockDescriptorSig {
reserved: 0,
size: std::mem::size_of::<NSErrorBlock>() as u64,
@@ -78,6 +62,22 @@ pub const CONTENT_ERROR_BLOCK_DESCRIPTOR: BlockDescriptorSig = BlockDescriptorSi
mod tests {
use super::*;
unsafe extern "C" fn ns_error_trampoline(block: *mut NSErrorBlock, err: *mut c_void) {
if let Some(block) = unsafe { block.as_mut() } {
unsafe { (block.user_invoke)(block.ctx, err) };
}
}
unsafe extern "C" fn content_error_trampoline(
block: *mut ContentErrorBlock,
content: *mut c_void,
err: *mut c_void,
) {
if let Some(block) = unsafe { block.as_mut() } {
unsafe { (block.user_invoke)(block.ctx, content, err) };
}
}
#[repr(C)]
struct RoundTripCtx {
seen_err: *mut c_void,
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
use criterion::{Criterion, black_box, criterion_group, criterion_main};
use std::hint::black_box;
use criterion::{Criterion, criterion_group, criterion_main};
use fluxer_screen_frame_bus::{CpuStagingBackend, StagingSurfacePair};
const BENCH_WIDTH: usize = 1920;
@@ -13,7 +13,7 @@ use std::sync::OnceLock;
use crate::frame_pool::PooledFrame;
#[cfg(target_os = "linux")]
use std::os::fd::OwnedFd;
use std::os::fd::{IntoRawFd, OwnedFd};
#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -325,30 +325,30 @@ pub type NativeScreenFrameSinkEnqueueScreenAudioFn = unsafe extern "C" fn(
#[repr(C)]
#[derive(Clone, Copy)]
pub struct NativeScreenFrameSinkHandle {
pub magic: u32,
pub version: u32,
pub context: *const c_void,
pub retain: NativeScreenFrameSinkRetainFn,
pub release: NativeScreenFrameSinkReleaseFn,
pub enqueue_nv12: Option<NativeScreenFrameSinkEnqueueNv12Fn>,
pub enqueue_bgra: Option<NativeScreenFrameSinkEnqueueBgraFn>,
pub enqueue_mac_cv_pixel_buffer: Option<NativeScreenFrameSinkEnqueueMacCvPixelBufferFn>,
pub enqueue_dmabuf: Option<NativeScreenFrameSinkEnqueueDmabufFn>,
pub enqueue_shared_texture: Option<NativeScreenFrameSinkEnqueueSharedTextureFn>,
pub enqueue_screen_audio: Option<NativeScreenFrameSinkEnqueueScreenAudioFn>,
magic: u32,
version: u32,
context: *const c_void,
retain: NativeScreenFrameSinkRetainFn,
release: NativeScreenFrameSinkReleaseFn,
enqueue_nv12: Option<NativeScreenFrameSinkEnqueueNv12Fn>,
enqueue_bgra: Option<NativeScreenFrameSinkEnqueueBgraFn>,
enqueue_mac_cv_pixel_buffer: Option<NativeScreenFrameSinkEnqueueMacCvPixelBufferFn>,
enqueue_dmabuf: Option<NativeScreenFrameSinkEnqueueDmabufFn>,
enqueue_shared_texture: Option<NativeScreenFrameSinkEnqueueSharedTextureFn>,
enqueue_screen_audio: Option<NativeScreenFrameSinkEnqueueScreenAudioFn>,
}
unsafe impl Send for NativeScreenFrameSinkHandle {}
unsafe impl Sync for NativeScreenFrameSinkHandle {}
impl NativeScreenFrameSinkHandle {
pub fn is_valid(&self) -> bool {
fn is_valid(&self) -> bool {
self.magic == NATIVE_SCREEN_FRAME_SINK_HANDLE_MAGIC
&& self.version == NATIVE_SCREEN_FRAME_SINK_HANDLE_VERSION
&& !self.context.is_null()
}
pub unsafe fn retain_ref(&self) -> Option<NativeScreenFrameSinkHandleRef> {
pub fn retain_ref(&self) -> Option<NativeScreenFrameSinkHandleRef> {
if !self.is_valid() {
return None;
}
@@ -356,13 +356,6 @@ impl NativeScreenFrameSinkHandle {
Some(NativeScreenFrameSinkHandleRef { handle: *self })
}
pub unsafe fn retain_from_raw(raw: *const Self) -> Option<NativeScreenFrameSinkHandleRef> {
if raw.is_null() {
return None;
}
unsafe { (*raw).retain_ref() }
}
pub fn native_outcome(outcome: EnqueueOutcome) -> u32 {
match outcome {
EnqueueOutcome::Accepted => NATIVE_SCREEN_FRAME_SINK_ACCEPTED,
@@ -388,10 +381,6 @@ unsafe impl Send for NativeScreenFrameSinkHandleRef {}
unsafe impl Sync for NativeScreenFrameSinkHandleRef {}
impl NativeScreenFrameSinkHandleRef {
pub fn handle(&self) -> &NativeScreenFrameSinkHandle {
&self.handle
}
pub fn enqueue_nv12_copy(
&self,
data: &[u8],
@@ -442,6 +431,11 @@ impl NativeScreenFrameSinkHandleRef {
})
}
#[cfg(target_os = "macos")]
pub fn supports_mac_cv_pixel_buffer(&self) -> bool {
self.handle.enqueue_mac_cv_pixel_buffer.is_some()
}
#[cfg(target_os = "macos")]
pub unsafe fn enqueue_mac_cv_pixel_buffer(
&self,
@@ -467,12 +461,25 @@ impl NativeScreenFrameSinkHandleRef {
}
#[cfg(target_os = "linux")]
pub unsafe fn enqueue_dmabuf_take_fds(&self, desc: DmabufDesc, fds: &[i32]) -> EnqueueOutcome {
pub fn supports_dmabuf(&self) -> bool {
self.handle.enqueue_dmabuf.is_some()
}
#[cfg(target_os = "linux")]
pub fn enqueue_dmabuf_take_fds(&self, desc: DmabufDesc, fds: Vec<OwnedFd>) -> EnqueueOutcome {
let Some(enqueue) = self.handle.enqueue_dmabuf else {
return EnqueueOutcome::Rejected;
};
let fd_count = fds.len();
if fd_count == 0 || fd_count > 4 || usize::from(desc.plane_count) != fd_count {
return EnqueueOutcome::Rejected;
}
let mut raw_fds = [-1; 4];
for (raw_fd, fd) in raw_fds.iter_mut().zip(fds) {
*raw_fd = fd.into_raw_fd();
}
NativeScreenFrameSinkHandle::outcome_from_native(unsafe {
enqueue(self.handle.context, desc, fds.as_ptr(), fds.len())
enqueue(self.handle.context, desc, raw_fds.as_ptr(), fd_count)
})
}
+2 -2
View File
@@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "bindgen"
+2 -2
View File
@@ -13,9 +13,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "bindgen"
@@ -792,10 +792,10 @@ fn retain_native_frame_sink_handle(
}
let handle = unsafe {
fluxer_screen_frame_bus::NativeScreenFrameSinkHandle::retain_from_raw(
data.cast::<fluxer_screen_frame_bus::NativeScreenFrameSinkHandle>(),
)
data.cast::<fluxer_screen_frame_bus::NativeScreenFrameSinkHandle>()
.as_ref()
}
.and_then(fluxer_screen_frame_bus::NativeScreenFrameSinkHandle::retain_ref)
.ok_or_else(|| {
napi::Error::new(
Status::InvalidArg,
@@ -37,15 +37,14 @@ fn retain_screen_audio_sink_handle(
"ProcessLoopback.setScreenAudioSink received an empty native external sink handle",
));
}
let handle = unsafe {
NativeScreenFrameSinkHandle::retain_from_raw(data.cast::<NativeScreenFrameSinkHandle>())
}
.ok_or_else(|| {
Error::new(
Status::InvalidArg,
"ProcessLoopback.setScreenAudioSink received an invalid native sink handle",
)
})?;
let handle = unsafe { data.cast::<NativeScreenFrameSinkHandle>().as_ref() }
.and_then(NativeScreenFrameSinkHandle::retain_ref)
.ok_or_else(|| {
Error::new(
Status::InvalidArg,
"ProcessLoopback.setScreenAudioSink received an invalid native sink handle",
)
})?;
Ok(Arc::new(handle))
}
@@ -341,7 +340,7 @@ impl Callbacks {
FrameSamples::Owned(owned) => owned.as_slice(),
};
let channels = u32::from(audio_contract::TARGET_CHANNELS);
if channels == 0 || samples.is_empty() || samples.len() % (channels as usize) != 0 {
if channels == 0 || samples.is_empty() || !samples.len().is_multiple_of(channels as usize) {
return true;
}
let frames = samples.len() as u32 / channels;
+2 -1
View File
@@ -26,7 +26,8 @@
"@types/node": "24.10.9",
"@typescript/native-preview": "7.0.0-dev.20260130.1",
"electron": "42.10.0",
"electron-builder": "26.9.0",
"electron-builder": "26.15.3",
"electron-builder-squirrel-windows": "26.15.3",
"esbuild": "0.27.2",
"typescript": "5.9.3"
},