SuriDevs Logo
CameraX Feature Groups: Finally Know If HDR + 60 FPS Will Actually Work

CameraX Feature Groups: Finally Know If HDR + 60 FPS Will Actually Work

By Sagar Maiyad  Oct 17, 2025

Camera apps have always had this annoying problem: you want to offer HDR recording at 60 FPS with stabilization, but you can't know which devices support that combination until you try it. And "trying it" often means crashing.

CameraX 1.5's Feature Group API fixes this. You can finally check if a feature combination works before attempting to use it.

Old phone camera Pixel 10 Pro camera

The Problem This Solves

Previously, you'd enable features individually without knowing if they'd work together:

// Old approach - hope this works on the user's device
videoCapture.apply {
    setHdr(true)
    setTargetFrameRate(Range(60, 60))
    setStabilization(true)
}
// Might work, might crash, might silently fail

Some devices support HDR. Some support 60 FPS. Some support both together, some don't. The only way to find out was trial and error - or maintaining a giant device compatibility list.

How Feature Groups Work

CameraX 1.5 introduces a way to query and request feature combinations:

Check if a combination is supported:

val features = setOf(
    GroupableFeature.HDR_HLG10,
    GroupableFeature.FPS_60,
    GroupableFeature.PREVIEW_STABILIZATION
)

if (cameraInfo.isFeatureGroupSupported(features)) {
    // Safe to enable all three
} else {
    // Need to fall back
}

Request features with automatic fallback:

cameraProvider.bindToLifecycle(
    lifecycleOwner,
    cameraSelector,
    preview,
    videoCapture,
    SessionConfig.defaultSessionConfig(
        preferredFeatureGroup = listOf(
            GroupableFeature.HDR_HLG10,
            GroupableFeature.FPS_60,
            GroupableFeature.PREVIEW_STABILIZATION
        )
    )
)

With preferredFeatureGroup, CameraX tries your full list first, then progressively drops features until it finds a supported combination. On a Pixel 10 Pro, you might get all three. On an older phone, you might get just HDR. Either way, you don't crash.

FPS settings demo

Available Features

Right now, the API covers:

  • HDR_HLG10 - HDR video in HLG10 format
  • FPS_60 - 60 FPS recording
  • PREVIEW_STABILIZATION - Real-time stabilization
  • IMAGE_ULTRA_HDR - Ultra HDR image capture

More features will likely be added in future releases.

Building a Reactive UI

The real power is in building UIs that adapt to device capabilities. Here's a practical example:

fun updateFeatureToggles(cameraInfo: CameraInfo) {
    // Check each feature individually
    hdrToggle.isEnabled = cameraInfo.isFeatureGroupSupported(
        setOf(GroupableFeature.HDR_HLG10)
    )

    fps60Toggle.isEnabled = cameraInfo.isFeatureGroupSupported(
        setOf(GroupableFeature.FPS_60)
    )

    stabilizationToggle.isEnabled = cameraInfo.isFeatureGroupSupported(
        setOf(GroupableFeature.PREVIEW_STABILIZATION)
    )
}

fun onFeatureToggled() {
    val requested = mutableSetOf<GroupableFeature>()

    if (hdrToggle.isChecked) requested.add(GroupableFeature.HDR_HLG10)
    if (fps60Toggle.isChecked) requested.add(GroupableFeature.FPS_60)
    if (stabilizationToggle.isChecked) requested.add(GroupableFeature.PREVIEW_STABILIZATION)

    // Check if this exact combination works
    if (cameraInfo.isFeatureGroupSupported(requested)) {
        recordButton.isEnabled = true
        warningText.visibility = View.GONE
    } else {
        recordButton.isEnabled = false
        warningText.text = "This combination isn't supported on your device"
        warningText.visibility = View.VISIBLE
    }
}

Users see which features their device supports, and the UI prevents them from selecting incompatible combinations. Much better than letting them tap record and watching the app crash.

Required vs Preferred Features

Two approaches for requesting features:

requiredFeatureGroup - All features must be supported. If not, throws an exception. Use when you absolutely need specific capabilities and want to handle the failure explicitly.

preferredFeatureGroup - CameraX picks the best supported subset. Use when you want the best available quality with automatic fallback.

For most apps, preferredFeatureGroup is the better choice. You get premium features on capable devices without writing fallback logic.

Getting Started

Feature Groups are in CameraX 1.5 (experimental) and will be stable in 1.6. To use it:

dependencies {
    implementation("androidx.camera:camera-camera2:1.5.0-alpha01")
    implementation("androidx.camera:camera-lifecycle:1.5.0-alpha01")
    implementation("androidx.camera:camera-video:1.5.0-alpha01")
}

The API is marked experimental but unlikely to change significantly. It's production-ready for apps that can tolerate potential minor API adjustments.

Why This Matters

Before Feature Groups, building a camera app that worked well across devices required either:

  • Testing on dozens of devices manually
  • Maintaining compatibility lists
  • Letting users discover crashes themselves
  • Disabling advanced features entirely

Now you can query capabilities programmatically and build adaptive UIs. Users on flagship phones get flagship features. Users on budget phones get what their hardware supports. Nobody gets crashes.

If you're building camera functionality, this API is worth the upgrade to CameraX 1.5.

Android CameraX Camera API

Author

Sagar Maiyad
Written By
Sagar Maiyad

Sagar Maiyad - Android developer specializing in Kotlin, Jetpack Compose, and modern Android architecture. Sharing practical tutorials and real-world development insights.

View All Posts →

Latest Post

Latest Tags