diff --git a/build/cross/Dockerfile.aarch64 b/build/cross/Dockerfile.aarch64 index c4459fbe..0724aeac 100644 --- a/build/cross/Dockerfile.aarch64 +++ b/build/cross/Dockerfile.aarch64 @@ -3,6 +3,10 @@ FROM debian:12 +# Set Rustup mirrors (Aliyun) +ENV RUSTUP_UPDATE_ROOT=https://mirrors.aliyun.com/rustup/rustup \ + RUSTUP_DIST_SERVER=https://mirrors.aliyun.com/rustup + # Install Rust toolchain RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ @@ -24,24 +28,25 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ git \ libclang-dev \ llvm \ + protobuf-compiler \ + mold \ + meson \ + ninja-build \ + wget \ gcc-aarch64-linux-gnu \ g++-aarch64-linux-gnu \ libc6-dev-arm64-cross \ && rm -rf /var/lib/apt/lists/* -# Install ARM64 development libraries +# Install ARM64 development libraries (without system ffmpeg) RUN apt-get update && apt-get install -y --no-install-recommends \ + libssl-dev:arm64 \ libasound2-dev:arm64 \ libv4l-dev:arm64 \ libudev-dev:arm64 \ zlib1g-dev:arm64 \ libjpeg62-turbo-dev:arm64 \ libyuv-dev:arm64 \ - libavcodec-dev:arm64 \ - libavformat-dev:arm64 \ - libavutil-dev:arm64 \ - libswscale-dev:arm64 \ - libswresample-dev:arm64 \ libx264-dev:arm64 \ libx265-dev:arm64 \ libvpx-dev:arm64 \ @@ -54,13 +59,106 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libxdmcp-dev:arm64 \ && rm -rf /var/lib/apt/lists/* +# Download and build FFmpeg with RKMPP support +RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \ + && wget -q https://files.mofeng.run/src/image/other/ffmpeg.tar.gz \ + && tar -xzf ffmpeg.tar.gz \ + && cd ffmpeg \ + # Build RKMPP + && mkdir -p rkmpp/build && cd rkmpp/build \ + && cmake .. \ + -DCMAKE_SYSTEM_NAME=Linux \ + -DCMAKE_SYSTEM_PROCESSOR=aarch64 \ + -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \ + -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \ + -DCMAKE_INSTALL_PREFIX=/usr/aarch64-linux-gnu \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=ON \ + -DBUILD_TEST=OFF \ + && make -j$(nproc) \ + && make install \ + && cd ../.. \ + # Build RKRGA - create cross file for meson + && echo '[binaries]' > /tmp/aarch64-cross.txt \ + && echo "c = 'aarch64-linux-gnu-gcc'" >> /tmp/aarch64-cross.txt \ + && echo "cpp = 'aarch64-linux-gnu-g++'" >> /tmp/aarch64-cross.txt \ + && echo "ar = 'aarch64-linux-gnu-ar'" >> /tmp/aarch64-cross.txt \ + && echo "strip = 'aarch64-linux-gnu-strip'" >> /tmp/aarch64-cross.txt \ + && echo "pkgconfig = 'pkg-config'" >> /tmp/aarch64-cross.txt \ + && echo '[host_machine]' >> /tmp/aarch64-cross.txt \ + && echo "system = 'linux'" >> /tmp/aarch64-cross.txt \ + && echo "cpu_family = 'aarch64'" >> /tmp/aarch64-cross.txt \ + && echo "cpu = 'aarch64'" >> /tmp/aarch64-cross.txt \ + && echo "endian = 'little'" >> /tmp/aarch64-cross.txt \ + && cd rkrga \ + && meson setup build --prefix=/usr/aarch64-linux-gnu --libdir=lib \ + --cross-file=/tmp/aarch64-cross.txt \ + --buildtype=release \ + -Dcpp_args=-fpermissive \ + -Dlibdrm=false \ + -Dlibrga_demo=false \ + && ninja -C build \ + && ninja -C build install \ + && cd .. \ + # Create pkg-config wrapper for cross-compilation + && echo '#!/bin/sh' > /tmp/aarch64-pkg-config \ + && echo 'export PKG_CONFIG_LIBDIR=/usr/aarch64-linux-gnu/lib/pkgconfig:/usr/lib/aarch64-linux-gnu/pkgconfig' >> /tmp/aarch64-pkg-config \ + && echo 'export PKG_CONFIG_PATH=""' >> /tmp/aarch64-pkg-config \ + && echo 'export PKG_CONFIG_SYSROOT_DIR=""' >> /tmp/aarch64-pkg-config \ + && echo 'exec pkg-config "$@"' >> /tmp/aarch64-pkg-config \ + && chmod +x /tmp/aarch64-pkg-config \ + # Build FFmpeg with RKMPP + && cd ffmpeg-rockchip \ + && ./configure \ + --prefix=/usr/aarch64-linux-gnu \ + --cross-prefix=aarch64-linux-gnu- \ + --arch=aarch64 \ + --target-os=linux \ + --enable-cross-compile \ + --pkg-config=/tmp/aarch64-pkg-config \ + --enable-gpl \ + --enable-version3 \ + --enable-shared \ + --disable-static \ + --enable-libdrm \ + --enable-rkmpp \ + --enable-rkrga \ + --enable-libv4l2 \ + --enable-libx264 \ + --enable-libx265 \ + --enable-libvpx \ + --enable-vaapi \ + --enable-v4l2-m2m \ + --disable-programs \ + --disable-doc \ + --disable-htmlpages \ + --disable-manpages \ + --disable-podpages \ + --disable-txtpages \ + --disable-network \ + --disable-protocols \ + --disable-debug \ + --disable-decoder=mjpeg \ + --disable-decoder=mjpegb \ + && make -j$(nproc) \ + && make install \ + && cd / \ + && rm -rf /tmp/ffmpeg-build /tmp/aarch64-cross.txt /tmp/aarch64-pkg-config + # Add Rust target RUN rustup target add aarch64-unknown-linux-gnu +# Create symlink for mold to work with cross-compiler +RUN ln -s /usr/bin/mold /usr/bin/aarch64-linux-gnu-ld.mold + # Configure environment for cross-compilation +# Use PKG_CONFIG_LIBDIR to completely replace default search paths +# This ensures we use our custom-built FFmpeg instead of system FFmpeg ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \ CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc \ CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++ \ AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar \ - PKG_CONFIG_PATH=/usr/lib/aarch64-linux-gnu/pkgconfig \ - PKG_CONFIG_ALLOW_CROSS=1 + PKG_CONFIG_LIBDIR=/usr/aarch64-linux-gnu/lib/pkgconfig:/usr/lib/aarch64-linux-gnu/pkgconfig \ + PKG_CONFIG_PATH="" \ + PKG_CONFIG_ALLOW_CROSS=1 \ + RUSTFLAGS="-C linker=aarch64-linux-gnu-gcc -C link-arg=-fuse-ld=mold" diff --git a/build/cross/Dockerfile.armv7 b/build/cross/Dockerfile.armv7 index db539905..b86c824f 100644 --- a/build/cross/Dockerfile.armv7 +++ b/build/cross/Dockerfile.armv7 @@ -3,6 +3,10 @@ FROM debian:12 +# Set Rustup mirrors (Aliyun) +ENV RUSTUP_UPDATE_ROOT=https://mirrors.aliyun.com/rustup/rustup \ + RUSTUP_DIST_SERVER=https://mirrors.aliyun.com/rustup + # Install Rust toolchain RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ @@ -24,24 +28,25 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ git \ libclang-dev \ llvm \ + protobuf-compiler \ + mold \ + meson \ + ninja-build \ + wget \ gcc-arm-linux-gnueabihf \ g++-arm-linux-gnueabihf \ libc6-dev-armhf-cross \ && rm -rf /var/lib/apt/lists/* -# Install ARMv7 development libraries +# Install ARMv7 development libraries (without system ffmpeg) RUN apt-get update && apt-get install -y --no-install-recommends \ + libssl-dev:armhf \ libasound2-dev:armhf \ libv4l-dev:armhf \ libudev-dev:armhf \ zlib1g-dev:armhf \ libjpeg62-turbo-dev:armhf \ libyuv-dev:armhf \ - libavcodec-dev:armhf \ - libavformat-dev:armhf \ - libavutil-dev:armhf \ - libswscale-dev:armhf \ - libswresample-dev:armhf \ libx264-dev:armhf \ libx265-dev:armhf \ libvpx-dev:armhf \ @@ -54,13 +59,106 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libxdmcp-dev:armhf \ && rm -rf /var/lib/apt/lists/* +# Download and build FFmpeg with RKMPP support +RUN mkdir -p /tmp/ffmpeg-build && cd /tmp/ffmpeg-build \ + && wget -q https://files.mofeng.run/src/image/other/ffmpeg.tar.gz \ + && tar -xzf ffmpeg.tar.gz \ + && cd ffmpeg \ + # Build RKMPP + && mkdir -p rkmpp/build && cd rkmpp/build \ + && cmake .. \ + -DCMAKE_SYSTEM_NAME=Linux \ + -DCMAKE_SYSTEM_PROCESSOR=arm \ + -DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \ + -DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \ + -DCMAKE_INSTALL_PREFIX=/usr/arm-linux-gnueabihf \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=ON \ + -DBUILD_TEST=OFF \ + && make -j$(nproc) \ + && make install \ + && cd ../.. \ + # Build RKRGA - create cross file for meson + && echo '[binaries]' > /tmp/armhf-cross.txt \ + && echo "c = 'arm-linux-gnueabihf-gcc'" >> /tmp/armhf-cross.txt \ + && echo "cpp = 'arm-linux-gnueabihf-g++'" >> /tmp/armhf-cross.txt \ + && echo "ar = 'arm-linux-gnueabihf-ar'" >> /tmp/armhf-cross.txt \ + && echo "strip = 'arm-linux-gnueabihf-strip'" >> /tmp/armhf-cross.txt \ + && echo "pkgconfig = 'pkg-config'" >> /tmp/armhf-cross.txt \ + && echo '[host_machine]' >> /tmp/armhf-cross.txt \ + && echo "system = 'linux'" >> /tmp/armhf-cross.txt \ + && echo "cpu_family = 'arm'" >> /tmp/armhf-cross.txt \ + && echo "cpu = 'armv7'" >> /tmp/armhf-cross.txt \ + && echo "endian = 'little'" >> /tmp/armhf-cross.txt \ + && cd rkrga \ + && meson setup build --prefix=/usr/arm-linux-gnueabihf --libdir=lib \ + --cross-file=/tmp/armhf-cross.txt \ + --buildtype=release \ + -Dcpp_args=-fpermissive \ + -Dlibdrm=false \ + -Dlibrga_demo=false \ + && ninja -C build \ + && ninja -C build install \ + && cd .. \ + # Create pkg-config wrapper for cross-compilation + && echo '#!/bin/sh' > /tmp/armhf-pkg-config \ + && echo 'export PKG_CONFIG_LIBDIR=/usr/arm-linux-gnueabihf/lib/pkgconfig:/usr/lib/arm-linux-gnueabihf/pkgconfig' >> /tmp/armhf-pkg-config \ + && echo 'export PKG_CONFIG_PATH=""' >> /tmp/armhf-pkg-config \ + && echo 'export PKG_CONFIG_SYSROOT_DIR=""' >> /tmp/armhf-pkg-config \ + && echo 'exec pkg-config "$@"' >> /tmp/armhf-pkg-config \ + && chmod +x /tmp/armhf-pkg-config \ + # Build FFmpeg with RKMPP + && cd ffmpeg-rockchip \ + && ./configure \ + --prefix=/usr/arm-linux-gnueabihf \ + --cross-prefix=arm-linux-gnueabihf- \ + --arch=arm \ + --target-os=linux \ + --enable-cross-compile \ + --pkg-config=/tmp/armhf-pkg-config \ + --enable-gpl \ + --enable-version3 \ + --enable-shared \ + --disable-static \ + --enable-libdrm \ + --enable-rkmpp \ + --enable-rkrga \ + --enable-libv4l2 \ + --enable-libx264 \ + --enable-libx265 \ + --enable-libvpx \ + --enable-vaapi \ + --enable-v4l2-m2m \ + --disable-programs \ + --disable-doc \ + --disable-htmlpages \ + --disable-manpages \ + --disable-podpages \ + --disable-txtpages \ + --disable-network \ + --disable-protocols \ + --disable-debug \ + --disable-decoder=mjpeg \ + --disable-decoder=mjpegb \ + && make -j$(nproc) \ + && make install \ + && cd / \ + && rm -rf /tmp/ffmpeg-build /tmp/armhf-cross.txt /tmp/armhf-pkg-config + # Add Rust target RUN rustup target add armv7-unknown-linux-gnueabihf +# Create symlink for mold to work with cross-compiler +RUN ln -s /usr/bin/mold /usr/bin/arm-linux-gnueabihf-ld.mold + # Configure environment for cross-compilation +# Use PKG_CONFIG_LIBDIR to completely replace default search paths +# This ensures we use our custom-built FFmpeg instead of system FFmpeg ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \ CC_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \ CXX_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \ AR_armv7_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \ - PKG_CONFIG_PATH=/usr/lib/arm-linux-gnueabihf/pkgconfig \ - PKG_CONFIG_ALLOW_CROSS=1 + PKG_CONFIG_LIBDIR=/usr/arm-linux-gnueabihf/lib/pkgconfig:/usr/lib/arm-linux-gnueabihf/pkgconfig \ + PKG_CONFIG_PATH="" \ + PKG_CONFIG_ALLOW_CROSS=1 \ + RUSTFLAGS="-C linker=arm-linux-gnueabihf-gcc -C link-arg=-fuse-ld=mold" diff --git a/build/cross/Dockerfile.x86_64 b/build/cross/Dockerfile.x86_64 index c4435f24..a3adb247 100644 --- a/build/cross/Dockerfile.x86_64 +++ b/build/cross/Dockerfile.x86_64 @@ -3,6 +3,10 @@ FROM debian:12 +# Set Rustup mirrors (Aliyun) +ENV RUSTUP_UPDATE_ROOT=https://mirrors.aliyun.com/rustup/rustup \ + RUSTUP_DIST_SERVER=https://mirrors.aliyun.com/rustup + # Install Rust toolchain RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ @@ -22,6 +26,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ git \ libclang-dev \ llvm \ + protobuf-compiler \ + libssl-dev \ + mold \ # Core system libraries libasound2-dev \ libv4l-dev \ @@ -55,3 +62,6 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ # Add Rust target RUN rustup target add x86_64-unknown-linux-gnu + +# Configure mold as the linker +ENV RUSTFLAGS="-C link-arg=-fuse-ld=mold" diff --git a/libs/hwcodec/cpp/common/util.cpp b/libs/hwcodec/cpp/common/util.cpp index b0aa17d7..a65d5a7f 100644 --- a/libs/hwcodec/cpp/common/util.cpp +++ b/libs/hwcodec/cpp/common/util.cpp @@ -136,6 +136,26 @@ bool set_lantency_free(void *priv_data, const std::string &name) { return false; } } + // RKMPP (Rockchip MPP) hardware encoder - minimize buffer latency + if (name.find("rkmpp") != std::string::npos) { + // Set async_depth to 1 for minimal buffering (0 = synchronous, higher = more buffering) + if ((ret = av_opt_set(priv_data, "async_depth", "1", 0)) < 0) { + LOG_WARN(std::string("rkmpp set async_depth failed, ret = ") + av_err2str(ret)); + // Not fatal - older FFmpeg versions may not support this option + } + } + // V4L2 M2M hardware encoder - minimize buffer latency + if (name.find("v4l2m2m") != std::string::npos) { + // Minimize number of output buffers for lower latency + if ((ret = av_opt_set_int(priv_data, "num_output_buffers", 2, 0)) < 0) { + LOG_WARN(std::string("v4l2m2m set num_output_buffers failed, ret = ") + av_err2str(ret)); + // Not fatal + } + if ((ret = av_opt_set_int(priv_data, "num_capture_buffers", 2, 0)) < 0) { + LOG_WARN(std::string("v4l2m2m set num_capture_buffers failed, ret = ") + av_err2str(ret)); + // Not fatal + } + } if (name.find("videotoolbox") != std::string::npos) { if ((ret = av_opt_set_int(priv_data, "realtime", 1, 0)) < 0) { LOG_ERROR(std::string("videotoolbox set realtime failed, ret = ") + av_err2str(ret)); diff --git a/src/audio/capture.rs b/src/audio/capture.rs index 0dc94fd0..b8c67ef3 100644 --- a/src/audio/capture.rs +++ b/src/audio/capture.rs @@ -140,7 +140,7 @@ impl AudioCapturer { /// Create a new audio capturer pub fn new(config: AudioConfig) -> Self { let (state_tx, state_rx) = watch::channel(CaptureState::Stopped); - let (frame_tx, _) = broadcast::channel(32); + let (frame_tx, _) = broadcast::channel(16); // Buffer size 16 for low latency Self { config, diff --git a/src/audio/streamer.rs b/src/audio/streamer.rs index dcd8d40a..3e2cd8e0 100644 --- a/src/audio/streamer.rs +++ b/src/audio/streamer.rs @@ -111,7 +111,7 @@ impl AudioStreamer { /// Create a new audio streamer with specified configuration pub fn with_config(config: AudioStreamerConfig) -> Self { let (state_tx, state_rx) = watch::channel(AudioStreamState::Stopped); - let (opus_tx, _) = broadcast::channel(64); + let (opus_tx, _) = broadcast::channel(16); // Buffer size 16 for low latency Self { config: RwLock::new(config), diff --git a/src/hid/ch9329.rs b/src/hid/ch9329.rs index caa38da3..63e8a68c 100644 --- a/src/hid/ch9329.rs +++ b/src/hid/ch9329.rs @@ -449,29 +449,6 @@ impl Ch9329Backend { self.port.lock().is_some() } - /// Convert I/O error to HidError with appropriate error code - #[allow(dead_code)] - fn io_error_to_hid_error(e: std::io::Error, operation: &str) -> AppError { - let error_code = match e.kind() { - std::io::ErrorKind::NotFound => "port_not_found", - std::io::ErrorKind::PermissionDenied => "permission_denied", - std::io::ErrorKind::TimedOut => "timeout", - std::io::ErrorKind::BrokenPipe => "broken_pipe", - _ => match e.raw_os_error() { - Some(6) => "enxio", // ENXIO - no such device - Some(19) => "enodev", // ENODEV - no such device - Some(5) => "eio", // EIO - I/O error - _ => "serial_error", - }, - }; - - AppError::HidError { - backend: "ch9329".to_string(), - reason: format!("{}: {}", operation, e), - error_code: error_code.to_string(), - } - } - /// Convert serialport error to HidError fn serial_error_to_hid_error(e: serialport::Error, operation: &str) -> AppError { let error_code = match e.kind() { diff --git a/src/hid/otg.rs b/src/hid/otg.rs index dcecb052..b9dbb37b 100644 --- a/src/hid/otg.rs +++ b/src/hid/otg.rs @@ -284,31 +284,6 @@ impl OtgBackend { Ok(()) } - /// Close a device (used when ESHUTDOWN is received) - #[allow(dead_code)] - fn close_device(&self, device_type: DeviceType) { - let dev_mutex = match device_type { - DeviceType::Keyboard => &self.keyboard_dev, - DeviceType::MouseRelative => &self.mouse_rel_dev, - DeviceType::MouseAbsolute => &self.mouse_abs_dev, - }; - - let mut dev = dev_mutex.lock(); - if dev.is_some() { - debug!("Closing {:?} device handle for recovery", device_type); - *dev = None; - } - } - - /// Close all device handles (for recovery) - #[allow(dead_code)] - fn close_all_devices(&self) { - self.close_device(DeviceType::Keyboard); - self.close_device(DeviceType::MouseRelative); - self.close_device(DeviceType::MouseAbsolute); - self.online.store(false, Ordering::Relaxed); - } - /// Open a HID device file with read/write access fn open_device(path: &PathBuf) -> Result { OpenOptions::new() @@ -527,7 +502,6 @@ impl OtgBackend { Ok(_) => { self.online.store(true, Ordering::Relaxed); self.reset_error_count(); - trace!("Sent absolute mouse report: {:02X?}", data); Ok(()) } Err(e) => { diff --git a/src/hid/websocket.rs b/src/hid/websocket.rs index a4add1c2..a0804009 100644 --- a/src/hid/websocket.rs +++ b/src/hid/websocket.rs @@ -28,8 +28,6 @@ use crate::utils::LogThrottler; const RESP_OK: u8 = 0x00; const RESP_ERR_HID_UNAVAILABLE: u8 = 0x01; const RESP_ERR_INVALID_MESSAGE: u8 = 0x02; -#[allow(dead_code)] -const RESP_ERR_SEND_FAILED: u8 = 0x03; /// WebSocket HID upgrade handler pub async fn ws_hid_handler(ws: WebSocketUpgrade, State(state): State>) -> Response { diff --git a/src/rustdesk/connection.rs b/src/rustdesk/connection.rs index 68ddc6d3..c7cd5a05 100644 --- a/src/rustdesk/connection.rs +++ b/src/rustdesk/connection.rs @@ -723,16 +723,6 @@ impl Connection { } } - /// Create public key message (for legacy compatibility) - fn create_public_key_message(&self) -> hbb::Message { - hbb::Message { - union: Some(message::Union::PublicKey(hbb::PublicKey { - asymmetric_value: self.keypair.public_key_bytes().to_vec(), - symmetric_value: vec![], - })), - } - } - /// Handle peer's public key and negotiate session encryption /// After successful negotiation, send Hash message for password authentication async fn handle_peer_public_key( diff --git a/src/rustdesk/mod.rs b/src/rustdesk/mod.rs index cfb56343..1971c6a9 100644 --- a/src/rustdesk/mod.rs +++ b/src/rustdesk/mod.rs @@ -383,12 +383,6 @@ impl RustDeskService { self.start().await } - /// Get a shutdown receiver for graceful shutdown handling - #[allow(dead_code)] - pub fn shutdown_rx(&self) -> broadcast::Receiver<()> { - self.shutdown_tx.subscribe() - } - /// Save keypair and UUID to config /// Returns the updated config if changes were made pub fn save_credentials(&self) -> Option { diff --git a/src/rustdesk/rendezvous.rs b/src/rustdesk/rendezvous.rs index 4d7427fe..63d17b9c 100644 --- a/src/rustdesk/rendezvous.rs +++ b/src/rustdesk/rendezvous.rs @@ -31,10 +31,6 @@ const MIN_REG_TIMEOUT_MS: u64 = 3_000; /// Maximum registration timeout const MAX_REG_TIMEOUT_MS: u64 = 30_000; -/// Connection timeout -#[allow(dead_code)] -const CONNECT_TIMEOUT_MS: u64 = 18_000; - /// Timer interval for checking registration status const TIMER_INTERVAL_MS: u64 = 300; @@ -682,7 +678,6 @@ impl AddrMangle { } /// Decode bytes to SocketAddr using RustDesk's mangle algorithm - #[allow(dead_code)] pub fn decode(bytes: &[u8]) -> Option { use std::convert::TryInto; use std::net::{Ipv4Addr, Ipv6Addr, SocketAddrV4}; diff --git a/src/stream/mjpeg.rs b/src/stream/mjpeg.rs index f98aef55..e5f5d3b1 100644 --- a/src/stream/mjpeg.rs +++ b/src/stream/mjpeg.rs @@ -167,7 +167,7 @@ impl MjpegStreamHandler { /// Create handler with custom drop limit pub fn with_drop_limit(max_drop: u64) -> Self { - let (frame_notify, _) = broadcast::channel(4); // Reduced from 16 for lower latency + let (frame_notify, _) = broadcast::channel(16); // Buffer size 16 for low latency Self { current_frame: ArcSwap::from_pointee(None), frame_notify, diff --git a/src/video/capture.rs b/src/video/capture.rs index f8fa2294..b56bb374 100644 --- a/src/video/capture.rs +++ b/src/video/capture.rs @@ -143,7 +143,7 @@ impl VideoCapturer { /// Create a new video capturer pub fn new(config: CaptureConfig) -> Self { let (state_tx, state_rx) = watch::channel(CaptureState::Stopped); - let (frame_tx, _) = broadcast::channel(4); // Reduced from 64 for lower latency + let (frame_tx, _) = broadcast::channel(16); // Buffer size 16 for low latency Self { config, diff --git a/src/video/shared_video_pipeline.rs b/src/video/shared_video_pipeline.rs index 5b253597..edaf3b79 100644 --- a/src/video/shared_video_pipeline.rs +++ b/src/video/shared_video_pipeline.rs @@ -314,7 +314,7 @@ impl SharedVideoPipeline { config.input_format ); - let (frame_tx, _) = broadcast::channel(8); // Reduced from 64 for lower latency + let (frame_tx, _) = broadcast::channel(16); // Reduced from 64 for lower latency let (running_tx, running_rx) = watch::channel(false); let nv12_size = (config.resolution.width * config.resolution.height * 3 / 2) as usize; let yuv420p_size = nv12_size; // Same size as NV12 diff --git a/src/video/streamer.rs b/src/video/streamer.rs index 861421fb..92b60fa9 100644 --- a/src/video/streamer.rs +++ b/src/video/streamer.rs @@ -452,9 +452,7 @@ impl Streamer { Ok(frame) => { mjpeg_handler.update_frame(frame); } - Err(tokio::sync::broadcast::error::RecvError::Lagged(n)) => { - trace!("Frame distribution lagged by {} frames", n); - } + Err(tokio::sync::broadcast::error::RecvError::Lagged(_)) => {} Err(tokio::sync::broadcast::error::RecvError::Closed) => { debug!("Frame channel closed"); break; @@ -544,9 +542,7 @@ impl Streamer { } } } - Err(tokio::sync::broadcast::error::RecvError::Lagged(n)) => { - trace!("Frame distribution lagged by {} frames", n); - } + Err(tokio::sync::broadcast::error::RecvError::Lagged(_)) => {} Err(tokio::sync::broadcast::error::RecvError::Closed) => { debug!("Frame channel closed"); break; diff --git a/src/web/audio_ws.rs b/src/web/audio_ws.rs index 85bf0aac..d9884fda 100644 --- a/src/web/audio_ws.rs +++ b/src/web/audio_ws.rs @@ -180,42 +180,6 @@ fn encode_audio_packet(frame: &OpusFrame, stream_start: Instant) -> Vec { buf } -/// Decode audio packet from binary format (for testing/debugging) -#[allow(dead_code)] -pub fn decode_audio_packet(data: &[u8]) -> Option { - if data.len() < 15 { - return None; - } - - if data[0] != AUDIO_PACKET_TYPE { - return None; - } - - let timestamp = u32::from_le_bytes([data[1], data[2], data[3], data[4]]); - let duration_ms = u16::from_le_bytes([data[5], data[6]]); - let sequence = u32::from_le_bytes([data[7], data[8], data[9], data[10]]); - let data_length = u32::from_le_bytes([data[11], data[12], data[13], data[14]]); - - Some(AudioPacketHeader { - packet_type: data[0], - timestamp, - duration_ms, - sequence, - data_length, - }) -} - -/// Audio packet header (for decoding/testing) -#[derive(Debug, Clone)] -#[allow(dead_code)] -pub struct AudioPacketHeader { - pub packet_type: u8, - pub timestamp: u32, - pub duration_ms: u16, - pub sequence: u32, - pub data_length: u32, -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/web/static_files.rs b/src/web/static_files.rs index 9bd967a8..26ba82c3 100644 --- a/src/web/static_files.rs +++ b/src/web/static_files.rs @@ -4,9 +4,10 @@ use axum::{ routing::get, Router, }; +#[cfg(debug_assertions)] use std::path::PathBuf; +#[cfg(debug_assertions)] use std::sync::OnceLock; -use tracing; // Only embed assets in release mode #[cfg(not(debug_assertions))] @@ -22,6 +23,7 @@ pub struct StaticAssets; /// Get the base directory for static files /// In debug mode: relative to executable directory /// In release mode: not used (embedded assets) +#[cfg(debug_assertions)] fn get_static_base_dir() -> PathBuf { static BASE_DIR: OnceLock = OnceLock::new(); BASE_DIR.get_or_init(|| { diff --git a/src/webrtc/peer.rs b/src/webrtc/peer.rs index 162a9d5e..a88ff05e 100644 --- a/src/webrtc/peer.rs +++ b/src/webrtc/peer.rs @@ -383,7 +383,7 @@ pub struct PeerConnectionManager { impl PeerConnectionManager { /// Create a new peer connection manager pub fn new(config: WebRtcConfig) -> Self { - let (frame_tx, _) = broadcast::channel(16); + let (frame_tx, _) = broadcast::channel(16); // Buffer size 16 for low latency Self { config, @@ -395,7 +395,7 @@ impl PeerConnectionManager { /// Create a new peer connection manager with HID controller pub fn with_hid(config: WebRtcConfig, hid: Arc) -> Self { - let (frame_tx, _) = broadcast::channel(16); + let (frame_tx, _) = broadcast::channel(16); // Buffer size 16 for low latency Self { config, diff --git a/src/webrtc/unified_video_track.rs b/src/webrtc/unified_video_track.rs index dad8638a..1367b5f7 100644 --- a/src/webrtc/unified_video_track.rs +++ b/src/webrtc/unified_video_track.rs @@ -339,7 +339,6 @@ impl UnifiedVideoTrack { _ => {} } - trace!("H264 NAL: type={} size={}", nal_type, nal.data.len()); nals.push(nal.data.freeze()); } diff --git a/src/webrtc/universal_session.rs b/src/webrtc/universal_session.rs index 29f793d3..8c5732b9 100644 --- a/src/webrtc/universal_session.rs +++ b/src/webrtc/universal_session.rs @@ -573,7 +573,7 @@ impl UniversalSession { } } Err(broadcast::error::RecvError::Lagged(n)) => { - warn!("Session {} lagged by {} frames", session_id, n); + debug!("Session {} lagged by {} frames", session_id, n); } Err(broadcast::error::RecvError::Closed) => { info!("Video frame channel closed for session {}", session_id); diff --git a/src/webrtc/video_track.rs b/src/webrtc/video_track.rs index 8142838e..510ba2e3 100644 --- a/src/webrtc/video_track.rs +++ b/src/webrtc/video_track.rs @@ -376,7 +376,6 @@ impl UniversalVideoTrack { _ => {} } - trace!("H264 NAL: type={} size={}", nal_type, nal.data.len()); nals.push(nal.data.freeze()); }