-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Problem
When using the camera app on mobile devices with libcamera (e.g., postmarketOS on OnePlus 6T), captured images are rotated incorrectly. The camera sensors are physically mounted at non-zero rotation angles, but the app does not compensate for this.
Observed Behavior
- Front camera images are rotated 90° clockwise from expected orientation
- Back camera images are rotated 270° clockwise from expected orientation
- The preview may also appear rotated
Expected Behavior
Images should be automatically rotated to the correct orientation based on the sensor's physical mounting position.
Root Cause
Mobile device camera sensors are often physically mounted at 90° or 270° angles. libcamera exposes this information via PipeWire properties, but the app currently does not read or apply this rotation.
Technical Details
Device Information
- Device: OnePlus 6T (oneplus-fajita)
- OS: postmarketOS edge
- Kernel: 6.16.7-sdm845
- Architecture: aarch64
Camera Configuration
Front Camera (imx371)
id 59, type PipeWire:Interface:Node
api.libcamera.location = "front"
api.libcamera.path = "/base/soc@0/cci@ac4a000/i2c-bus@0/camera@10"
api.libcamera.rotation = "90"
device.api = "libcamera"
device.description = "imx371"
device.product.name = "imx371"
media.class = "Video/Source"
media.role = "Camera"
node.description = "Built-in Front Camera"
node.nick = "imx371"
object.path = "libcamera:/base/soc@0/cci@ac4a000/i2c-bus@0/camera@10"
object.serial = "59"
Back Camera (imx376)
id 61, type PipeWire:Interface:Node
api.libcamera.location = "back"
api.libcamera.path = "/base/soc@0/cci@ac4a000/i2c-bus@1/camera@10"
api.libcamera.rotation = "270"
device.api = "libcamera"
device.description = "imx376"
device.product.name = "imx376"
media.class = "Video/Source"
media.role = "Camera"
node.description = "Built-in Back Camera"
node.nick = "imx376"
object.path = "libcamera:/base/soc@0/cci@ac4a000/i2c-bus@1/camera@10"
object.serial = "61"
Device Tree Rotation Values
The rotation is defined in the device tree:
/proc/device-tree/soc@0/cci@ac4a000/i2c-bus@0/camera@10/rotation = 0x5a (90°)
/proc/device-tree/soc@0/cci@ac4a000/i2c-bus@1/camera@10/rotation = 0x010e (270°)
Current Code Gap
The app does not currently read or handle rotation properties.
Proposed Solution
1. Read rotation from PipeWire properties during camera enumeration
When enumerating cameras via pw-cli or PipeWire APIs, parse the api.libcamera.rotation property and store it in the CameraInfo struct.
pub struct CameraInfo { pub name: String, pub path: String, pub rotation: u32, // 0, 90, 180, or 270 degrees pub location: Option<String>, // "front", "back", or None // ... }
2. Apply rotation to captured images
When saving photos, rotate the image buffer according to the sensor rotation before encoding to JPEG.
Options:
- Use GStreamer's
videoflipelement in the capture pipeline - Rotate the image data before JPEG encoding
- Set EXIF orientation tag (less preferred as not all viewers respect it)
3. Apply rotation to preview (optional)
The preview could also be rotated, though this may have performance implications. Alternatively, the preview could remain unrotated if the compositor handles device orientation.
4. Handle front camera mirroring
Front cameras typically need horizontal mirroring in addition to rotation for a natural "mirror" selfie experience.
Implementation Locations
Key files that would need modification:
src/backends/camera/pipewire/enumeration.rs- Parse rotation from pw-cli outputsrc/backends/camera/mod.rs- Add rotation field to CameraInfosrc/media/capture/- Apply rotation when saving imagessrc/backends/camera/pipewire/pipeline.rs- Optionally add videoflip to pipeline
Testing
Tested on:
- OnePlus 6T running postmarketOS edge
- Front camera (imx371): 90° rotation
- Back camera (imx376): 270° rotation
References
Related Issues
This issue was discovered while testing the app on postmarketOS. See also the fallback format fix for libcamera raw formats that was needed to get the camera working initially.