Skip to content

Privacy Shutter: harden transitions and clean up flows - #78

Open
deep0294 wants to merge 1 commit into
intel:mainfrom
deep0294:privacy-shutter-fix
Open

deep0294 wants to merge 1 commit into
intel:mainfrom
deep0294:privacy-shutter-fix

Conversation

@deep0294

@deep0294 deep0294 commented Oct 8, 2026 •

Copy link
Copy Markdown

Technical Summary & Overview

This change comprehensively hardens the Intel Linux Camera HAL (libcamhal) privacy shutter subsystem on IPU7/IPU8 platforms (#JSWBALINUX-181). It resolves critical race conditions, threading deadlocks, state-machine synchronization failures, buffer ownership leaks, DMA memory corruption, and visual artifacts (freezes, tearing, ghosting) during rapid physical privacy shutter open/close toggles and cold launch with the shutter closed.


Key Features & Architectural Enhancements

1. Robust State Machine & Asynchronous Lifecycle Synchronization (CameraDevice)

  • Non-Cancellable Background Teardown: Replaced class IsysTeardownThread : public Thread with std::thread mIsysTeardownThread. joinIsysTeardown() guarantees that sub-unit stops and hardware node destruction complete unconditionally without being aborted mid-execution during rapid shutter bouncing.
  • Immediate Dummy Stream Interruption: In switchToNormal(), mBackupProducer->stop() and listener unregistration execute first, halting dummy frame generation immediately to prevent stale dummy frame backlog from flooding client applications.
  • Cold Launch in Privacy Mode: Checks initial privacy cover state at CameraDevice::start(); if closed, starts directly into backup streaming without initializing live ISYS/PSYS silicon, saving platform power and eliminating un-shuttering crashes.
  • Reconfiguration Fallback: Automatically restores the backup dummy stream if live CaptureUnit::reconfigure() fails, preventing pipeline freezes.
  • Safe dqbuf() Lifecycle: Synchronizes dqbuf() state inspection under mDeviceLock after waitFrame() to prevent deadlocks with stop().

2. DMA Lifecycle & Hardware Buffer Re-entrancy Protection (CaptureUnit, DeviceBase, CsiMetaDevice)

  • Self-Guarding Reconfiguration: CaptureUnit::reconfigure() verifies if the unit is in CAPTURE_START and executes stop() and destroyDevices() before configuring new parameters, avoiding INVALID_OPERATION (-38) state violations.
  • Duplicate Enqueue Guard: DeviceBase::addPendingBuffer() checks against both mPendingBuffers and mBuffersInDevice before queuing to the kernel V4L2 video ring, eliminating kernel VIDIOC_QBUF -EINVAL duplicate enqueues.
  • Thread-Safe Consumer Access: Guarded BufferConsumer list operations with mConsumerLock across buffer queues.
  • CSI Metadata Device Reset: Added explicit state reset and de-initialization routines during stream transitions to prevent stale descriptor reuse.

3. PSYS Pipeline Lifecycle & TNR State Cleansing (PSysDevice, CBStage, PipeLine, PipeManager)

  • Device Handle & Buffer Re-Registration: Re-maps all terminal, payload, metadata, and node2self buffers onto the reopened PSYS device fd upon un-shuttering.
  • TNR Ghosting Elimination: Added explicit memset zeroing of intermediate pipeline and node2self frame buffers in CBStage::allocateFrameBuffers() to prevent Temporal Noise Reduction (TNR) filters from blending stale pre-shutter frames with fresh sensor data.
  • Sub-Pipeline Polling Lifecycle: Added suspendPolling() / resumePolling() in PSysDevice and lifecycle stops in PipeLine and PipeManager to avoid servicing dangling tasks during transitions.

4. Deterministic Buffer Handoff & Monotonic Sequencing (CameraStream, RequestThread, ProcessingUnit, FileSource)

  • Atomic Buffer Producer Redirection: CameraStream::redirectBufferProducer() transfers active in-flight buffers between producers with sequence epoch reset (setSettingSequence(-1)), and removes buffers from mBufferInProcessing prior to listener dispatch to prevent re-entrancy races.
  • Monotonic Frame Delivery: Enforced monotonic ubuffer->sequence delivery in CameraStream::onBufferAvailable() across transitions from dummy to live streaming, avoiding sequence drops ($N \to 0$) and downstream GStreamer clock skew.
  • Carried-Over Sequence Allocation: RequestThread::reserveEffectSeqRange() reserves the exact sequence range consumed by carried-over buffers so initial 3A effectSeq assignments align with incoming live sensor frames without queue collision.
  • Dummy Stream Setting Synchronization: FileSource::produce() synchronizes setSettingSequence() with mSequence, ensuring monotonic timestamps and sequencing across all dummy frames.
  • 3A Result Invalidation: Added AiqResultStorage::resetAiqResults() to invalidate cached 3A results and prevent stale exposure/gain application across stream restarts.

5. Platform & Sensor Configuration (PlatformData, CameraSensorsParser)

  • Configurable Shutter Polarity: Added privacyShutterActiveLow JSON parser and schema support in PlatformData to accurately model hardware GPIO lid switches and electrical buttons across different OEM designs.

Usage & Verification

Test Command (GStreamer)

gst-launch-1.0 icamerasrc buffer-count=7 printfps=true ! video/x-raw,format=NV12,width=1920,height=1080 ! videoconvert ! ximagesink

Verification Results

  1. Cold Launch with Shutter Closed: Smoothly starts in backup mode with dummy video streaming at 30 fps without live ISYS power consumption.
  2. Dynamic Shutter Toggling: Seamless transition from backup mode to live sensor capture and back without application stalls, frozen frames, or visual flicker.
  3. Buffer Pool Integrity: Fixed buffer count of 7 maintained throughout with zero buffer leaks and zero duplicate frames.

Tracked-On: #JSWBALINUX-181
Signed-off-by: Amarnath Kumar, Deepak deepak.amarnath.kumar@intel.com

@deep0294
deep0294 force-pushed the privacy-shutter-fix branch 15 times, most recently from c632bab to 82491df Compare October 13, 2026 08:28
Strengthen privacy shutter switchover robustness and resolve
edge cases across threading, buffer ownership, and lifecycle.

Tracked-On: #JSWBALINUX-181
Change-Id: I9665191d8a13bb5d8258a371fb74bc02ce516f69
Signed-off-by: Amarnath Kumar, Deepak <deepak.amarnath.kumar@intel.com>
@deep0294
deep0294 force-pushed the privacy-shutter-fix branch from 82491df to 85561c7 Compare October 13, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant