From 4d04b06d41edbf77ade88832d72ea62779c3cf7a Mon Sep 17 00:00:00 2001 From: 28allday Date: Sat, 28 Mar 2026 18:15:22 +0000 Subject: [PATCH] Initial commit: FaceTime HD camera driver and OBS performance scripts Co-Authored-By: Claude Opus 4.6 (1M context) --- facetimehd-installer.sh | 451 ++++++++++++++++++++++++++++++++++++++ obs-performance-script.sh | 105 +++++++++ 2 files changed, 556 insertions(+) create mode 100755 facetimehd-installer.sh create mode 100755 obs-performance-script.sh diff --git a/facetimehd-installer.sh b/facetimehd-installer.sh new file mode 100755 index 0000000..b936c8d --- /dev/null +++ b/facetimehd-installer.sh @@ -0,0 +1,451 @@ +#!/bin/bash + +# FaceTime HD Camera Installation Script for Linux Kernel 6.8+ +# Compatible with MacBook Air A1466 EMC 3178 and similar models +# Author: System Script +# Version: 1.0 +# Last Updated: 2025 + +set -e + +# Color codes for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Script name for logging +SCRIPT_NAME=$(basename "$0") +LOG_FILE="/tmp/facetimehd-install-$(date +%Y%m%d-%H%M%S).log" + +# Function to print colored output +print_status() { + echo -e "${BLUE}[${SCRIPT_NAME}]${NC} $1" | tee -a "$LOG_FILE" +} + +print_success() { + echo -e "${GREEN}[✓]${NC} $1" | tee -a "$LOG_FILE" +} + +print_error() { + echo -e "${RED}[✗]${NC} $1" | tee -a "$LOG_FILE" +} + +print_warning() { + echo -e "${YELLOW}[!]${NC} $1" | tee -a "$LOG_FILE" +} + +# Function to check if running as root +check_root() { + if [[ $EUID -eq 0 ]]; then + print_error "This script should not be run as root!" + print_status "Please run without sudo: ./$SCRIPT_NAME" + exit 1 + fi +} + +# Function to detect distribution +detect_distro() { + if [ -f /etc/os-release ]; then + . /etc/os-release + OS=$NAME + VER=$VERSION_ID + else + print_error "Cannot detect distribution" + exit 1 + fi +} + +# Function to check kernel version +check_kernel() { + KERNEL_VERSION=$(uname -r) + KERNEL_MAJOR=$(echo $KERNEL_VERSION | cut -d. -f1) + KERNEL_MINOR=$(echo $KERNEL_VERSION | cut -d. -f2) + + print_status "Detected kernel version: $KERNEL_VERSION" + + if [[ $KERNEL_MAJOR -lt 5 ]] || ([[ $KERNEL_MAJOR -eq 5 ]] && [[ $KERNEL_MINOR -lt 7 ]]); then + print_warning "Kernel version is older than 5.7, using legacy installation method" + USE_LEGACY=true + else + USE_LEGACY=false + fi +} + +# Function to check if camera is already working +check_camera() { + if [ -e /dev/video0 ] || [ -e /dev/video1 ]; then + if lsmod | grep -q facetimehd; then + print_warning "FaceTime HD camera driver appears to be already installed" + read -p "Do you want to reinstall? (y/N): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + print_status "Exiting..." + exit 0 + fi + fi + fi +} + +# Function to check and disable Secure Boot if needed +check_secure_boot() { + if command -v mokutil &> /dev/null; then + if mokutil --sb-state 2>&1 | grep -q "SecureBoot enabled"; then + print_warning "Secure Boot is enabled. The camera driver may not load." + print_status "You have three options:" + echo " 1. Disable Secure Boot in BIOS/UEFI (recommended)" + echo " 2. Sign the kernel module (advanced)" + echo " 3. Continue anyway (module may not load)" + read -p "Choose option (1-3): " -n 1 -r + echo + case $REPLY in + 1) + print_status "Please reboot and disable Secure Boot in BIOS/UEFI settings" + print_status "Then run this script again" + exit 0 + ;; + 2) + SIGN_MODULE=true + ;; + 3) + print_warning "Continuing with Secure Boot enabled..." + ;; + esac + fi + fi +} + +# Function to install dependencies +install_dependencies() { + print_status "Installing required dependencies..." + + if [[ "$OS" == "Ubuntu" ]] || [[ "$OS" == "Linux Mint" ]] || [[ "$OS" == "Debian"* ]]; then + sudo apt update + sudo apt install -y \ + git \ + curl \ + xz-utils \ + cpio \ + make \ + gcc \ + linux-headers-$(uname -r) \ + libssl-dev \ + checkinstall \ + build-essential \ + dkms \ + v4l-utils || { + print_error "Failed to install dependencies" + exit 1 + } + elif [[ "$OS" == "Fedora" ]]; then + sudo dnf install -y \ + git \ + curl \ + xz \ + cpio \ + make \ + gcc \ + kernel-devel-$(uname -r) \ + openssl-devel \ + dkms \ + v4l-utils || { + print_error "Failed to install dependencies" + exit 1 + } + else + print_error "Unsupported distribution: $OS" + exit 1 + fi + + print_success "Dependencies installed successfully" +} + +# Function to remove old installations +cleanup_old_installation() { + print_status "Cleaning up old installations..." + + # Unload module if loaded + if lsmod | grep -q facetimehd; then + sudo modprobe -r facetimehd 2>/dev/null || true + fi + + # Remove old DKMS installations + if dkms status | grep -q facetimehd; then + sudo dkms remove facetimehd/0.6.13 --all 2>/dev/null || true + sudo dkms remove facetimehd/0.1 --all 2>/dev/null || true + fi + + # Remove old files + sudo rm -rf /usr/src/facetimehd* 2>/dev/null || true + sudo rm -f /lib/modules/*/extra/facetimehd.ko* 2>/dev/null || true + + print_success "Cleanup completed" +} + +# Function to download and install firmware +install_firmware() { + print_status "Downloading and installing camera firmware..." + + WORK_DIR=$(mktemp -d) + cd "$WORK_DIR" + + # Clone firmware repository + git clone https://github.com/patjak/facetimehd-firmware.git || { + print_error "Failed to download firmware repository" + exit 1 + } + + cd facetimehd-firmware + + # Build and install firmware + make || { + print_error "Failed to build firmware" + exit 1 + } + + sudo make install || { + print_error "Failed to install firmware" + exit 1 + } + + # Verify firmware installation + if [ ! -f /lib/firmware/facetimehd/firmware.bin ]; then + print_warning "Firmware not found in expected location, creating symlink..." + sudo mkdir -p /lib/firmware/facetimehd + if [ -f /usr/lib/firmware/facetimehd/firmware.bin ]; then + sudo ln -sf /usr/lib/firmware/facetimehd/firmware.bin /lib/firmware/facetimehd/firmware.bin + else + print_error "Firmware installation failed" + exit 1 + fi + fi + + print_success "Firmware installed successfully" + cd ~ + rm -rf "$WORK_DIR" +} + +# Function to install driver for kernel 6.8+ +install_driver() { + print_status "Downloading and installing FaceTime HD driver..." + + WORK_DIR=$(mktemp -d) + cd "$WORK_DIR" + + # For kernel 6.8+, try the updated repository first + if [[ $KERNEL_MAJOR -ge 6 ]] && [[ $KERNEL_MINOR -ge 8 ]]; then + print_status "Using updated driver for kernel 6.8+" + + # Try multiple repositories in order of compatibility + REPOS=( + "https://github.com/patjak/facetimehd.git" + "https://github.com/kekrby/facetimehd.git" + "https://github.com/bartkessels/facetimehd.git" + ) + + CLONED=false + for repo in "${REPOS[@]}"; do + print_status "Trying repository: $repo" + if git clone "$repo" facetimehd 2>/dev/null; then + CLONED=true + break + fi + done + + if [ "$CLONED" = false ]; then + print_error "Failed to download any driver repository" + exit 1 + fi + else + # For older kernels, use the standard repository + git clone https://github.com/patjak/facetimehd.git || { + print_error "Failed to download driver repository" + exit 1 + } + fi + + cd facetimehd + + # Apply patches for kernel 6.8+ if needed + if [[ $KERNEL_MAJOR -ge 6 ]]; then + print_status "Applying kernel 6.x compatibility patches..." + + # Fix for VFL_TYPE_GRABBER deprecation + if grep -q "VFL_TYPE_GRABBER" fthd_v4l2.c 2>/dev/null; then + sed -i 's/VFL_TYPE_GRABBER/VFL_TYPE_VIDEO/g' fthd_v4l2.c + fi + + # Fix for other kernel 6.x API changes + if grep -q "v4l2_device_release" fthd_v4l2.c 2>/dev/null; then + sed -i 's/v4l2_device_release/video_device_release/g' fthd_v4l2.c + fi + fi + + # Install via DKMS + print_status "Installing driver via DKMS..." + + DRIVER_VERSION="0.6.13" + sudo cp -r . "/usr/src/facetimehd-$DRIVER_VERSION" + + # Create DKMS configuration if it doesn't exist + if [ ! -f "/usr/src/facetimehd-$DRIVER_VERSION/dkms.conf" ]; then + sudo tee "/usr/src/facetimehd-$DRIVER_VERSION/dkms.conf" > /dev/null < /dev/null + + # Add facetimehd to modules + if ! grep -q "^facetimehd$" /etc/modules 2>/dev/null; then + echo 'facetimehd' | sudo tee -a /etc/modules > /dev/null + fi + + # Load the module + print_status "Loading FaceTime HD module..." + sudo modprobe -r bdc_pci 2>/dev/null || true + sudo modprobe facetimehd || { + print_error "Failed to load module" + print_status "Check dmesg for errors: sudo dmesg | tail -20" + exit 1 + } + + print_success "Module configured and loaded" +} + +# Function to verify installation +verify_installation() { + print_status "Verifying installation..." + + # Check if module is loaded + if ! lsmod | grep -q facetimehd; then + print_error "Module is not loaded" + return 1 + fi + + # Check for video device + if [ ! -e /dev/video0 ] && [ ! -e /dev/video1 ] && [ ! -e /dev/video2 ]; then + print_error "No video device found" + return 1 + fi + + # Get video device + VIDEO_DEVICE=$(ls /dev/video* 2>/dev/null | head -1) + + if [ -n "$VIDEO_DEVICE" ]; then + print_success "Camera device found at: $VIDEO_DEVICE" + + # Show camera information + print_status "Camera information:" + v4l2-ctl -d "$VIDEO_DEVICE" --info 2>/dev/null || true + fi + + return 0 +} + +# Function to test camera +test_camera() { + print_status "Would you like to test the camera now? (y/N): " + read -n 1 -r + echo + + if [[ $REPLY =~ ^[Yy]$ ]]; then + VIDEO_DEVICE=$(ls /dev/video* 2>/dev/null | head -1) + + if command -v cheese &> /dev/null; then + print_status "Starting Cheese..." + cheese & + elif command -v guvcview &> /dev/null; then + print_status "Starting guvcview..." + guvcview & + else + print_warning "No camera application found. Install cheese or guvcview to test." + print_status "You can install with: sudo apt install cheese" + fi + fi +} + +# Main installation flow +main() { + clear + echo "======================================" + echo "FaceTime HD Camera Installation Script" + echo "======================================" + echo + print_status "Log file: $LOG_FILE" + echo + + # Pre-installation checks + check_root + detect_distro + check_kernel + check_camera + check_secure_boot + + # Installation + install_dependencies + cleanup_old_installation + install_firmware + install_driver + configure_module + + # Post-installation + if verify_installation; then + print_success "Installation completed successfully!" + echo + print_status "Camera should now be working." + print_status "You can test it with applications like:" + echo " - cheese" + echo " - guvcview" + echo " - Google Chrome/Chromium" + echo " - Firefox" + echo + test_camera + else + print_error "Installation completed but verification failed" + print_status "Please check the log file: $LOG_FILE" + print_status "And kernel messages: sudo dmesg | grep -i facetime" + fi + + echo + print_status "If you encounter issues, please check:" + echo " 1. Secure Boot status (disable if enabled)" + echo " 2. Kernel messages: sudo dmesg | grep -i facetime" + echo " 3. Module status: lsmod | grep facetimehd" + echo " 4. Log file: $LOG_FILE" +} + +# Run main function +main "$@" \ No newline at end of file diff --git a/obs-performance-script.sh b/obs-performance-script.sh new file mode 100755 index 0000000..f83ac39 --- /dev/null +++ b/obs-performance-script.sh @@ -0,0 +1,105 @@ +#!/bin/bash +# OBS Performance Script for Linux Mint Cinnamon +# Fixed version for newer Cinnamon versions + +# Color codes for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +echo -e "${GREEN}OBS Performance Optimizer for Linux Mint Cinnamon${NC}" +echo "==================================================" + +# Check if OBS is installed +if ! command -v obs-studio &> /dev/null && ! command -v flatpak run com.obsproject.Studio &> /dev/null; then + echo -e "${RED}Error: OBS Studio not found!${NC}" + echo "Install with: sudo apt install obs-studio" + echo "Or: flatpak install flathub com.obsproject.Studio" + exit 1 +fi + +# Detect OBS installation type +if command -v obs-studio &> /dev/null; then + OBS_COMMAND="obs-studio" +elif flatpak list | grep -q "com.obsproject.Studio"; then + OBS_COMMAND="flatpak run com.obsproject.Studio" +else + OBS_COMMAND="obs" # fallback +fi + +# Store original settings (using correct keys for newer Cinnamon) +echo -e "${YELLOW}Saving current desktop settings...${NC}" + +# Check Cinnamon version and use appropriate settings +if gsettings list-keys org.cinnamon.desktop.wm.preferences | grep -q "compositor-manager"; then + # Newer Cinnamon + ORIGINAL_COMPOSITOR=$(gsettings get org.cinnamon.desktop.wm.preferences compositor-manager 2>/dev/null || echo "true") + COMPOSITOR_KEY="org.cinnamon.desktop.wm.preferences compositor-manager" +else + # Try muffin settings + ORIGINAL_COMPOSITOR="true" + COMPOSITOR_KEY="" +fi + +ORIGINAL_UNREDIRECT=$(gsettings get org.cinnamon.muffin unredirect-fullscreen-windows 2>/dev/null || echo "false") + +echo "Unredirect: $ORIGINAL_UNREDIRECT" + +# Apply performance settings +echo -e "\n${YELLOW}Applying performance optimizations...${NC}" + +# Disable effects using available methods +if [ -n "$COMPOSITOR_KEY" ]; then + gsettings set $COMPOSITOR_KEY false 2>/dev/null && echo -e "${GREEN}✓ Compositor disabled${NC}" +else + # Alternative: disable effects + gsettings set org.cinnamon enable-effects false 2>/dev/null && echo -e "${GREEN}✓ Desktop effects disabled${NC}" +fi + +# Set unredirect for fullscreen +gsettings set org.cinnamon.muffin unredirect-fullscreen-windows true 2>/dev/null && echo -e "${GREEN}✓ Fullscreen unredirect enabled${NC}" + +# Alternative compositor control for Cinnamon +if command -v cinnamon-settings &> /dev/null; then + # Try to disable vsync through muffin dconf settings + dconf write /org/cinnamon/muffin/sync-to-vblank false 2>/dev/null +fi + +# Set CPU governor to performance if available +if [ -f /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then + echo -e "\n${YELLOW}Setting CPU to performance mode (may require password)${NC}" + echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo -e "${GREEN}✓ CPU performance mode set${NC}" + fi +fi + +# Launch OBS with optimized environment +echo -e "\n${GREEN}Launching OBS with optimized settings...${NC}" +echo "===========================================" +echo "Using command: $OBS_COMMAND" + +# Run OBS with performance environment variables +env vblank_mode=0 \ + __GL_SYNC_TO_VBLANK=0 \ + __GL_THREADED_OPTIMIZATIONS=1 \ + PULSE_LATENCY_MSEC=30 \ + $OBS_COMMAND + +# Restore original settings after OBS closes +echo -e "\n${YELLOW}OBS closed. Restoring original settings...${NC}" + +if [ -n "$COMPOSITOR_KEY" ]; then + gsettings set $COMPOSITOR_KEY "$ORIGINAL_COMPOSITOR" 2>/dev/null +else + gsettings set org.cinnamon enable-effects true 2>/dev/null +fi + +gsettings set org.cinnamon.muffin unredirect-fullscreen-windows "$ORIGINAL_UNREDIRECT" 2>/dev/null + +# Restore vsync if it was modified +dconf write /org/cinnamon/muffin/sync-to-vblank true 2>/dev/null + +echo -e "${GREEN}✓ Desktop settings restored${NC}" +echo -e "${GREEN}Done!${NC}" \ No newline at end of file