Skip to content

Commit

Permalink
fix: Fix 10-bit HDR in combination with HDR Extension
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Mar 18, 2024
1 parent 1682bb2 commit 19a7b0c
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,6 @@ data class CameraConfiguration(
// Audio Session
var audio: Output<Audio> = Output.Disabled.create()
) {
val enableHdr: Boolean
get() {
val photoConfig = photo as? Output.Enabled<Photo>
val videoConfig = video as? Output.Enabled<Video>
return photoConfig?.config?.enableHdr == true || videoConfig?.config?.enableHdr == true
}

// Output<T> types, those need to be comparable
data class CodeScanner(val codeTypes: List<CodeType>)
data class Photo(val enableHdr: Boolean, val photoQualityBalance: QualityBalance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ class CameraDeviceDetails(private val cameraInfo: CameraInfo, extensionsManager:
map.putInt("minISO", isoRange.lower)
map.putInt("maxISO", isoRange.upper)
map.putDouble("fieldOfView", maxFieldOfView)
map.putBoolean("supportsVideoHdr", supports10BitHdr || supportsHdrExtension)
map.putBoolean("supportsVideoHdr", supports10BitHdr)
map.putBoolean("supportsPhotoHdr", supportsHdrExtension)
map.putBoolean("supportsDepthCapture", supportsDepthCapture)
map.putString("autoFocusSystem", autoFocusSystem.unionValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,18 @@ class InvalidVideoHdrError :
"invalid-video-hdr",
"The given format does not support videoHdr! Select a format where `format.supportsVideoHdr` is true."
)
class PhotoHdrAndVideoHdrNotSupportedSimultaneously :
CameraError(
"format",
"photo-hdr-and-video-hdr-not-suppoted-simultaneously",
"Photo HDR and Video HDR are not supported simultaneously! Disable either `videoHdr` or `photoHdr`."
)
class LowLightBoostNotSupportedWithVideoHdr :
CameraError(
"format",
"low-light-boost-not-supported-with-video-hdr",
"The low light boost extension does not work when video HDR is enabled! Disable either `lowLightBoost` or `videoHdr`."
)

class VideoNotEnabledError :
CameraError("capture", "video-not-enabled", "Video capture is disabled! Pass `video={true}` to enable video recordings.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,25 +349,37 @@ class CameraSession(private val context: Context, private val callback: Callback
Log.i(TAG, "Binding Camera #${configuration.cameraId}...")
checkCameraPermission()

// Outputs
val useCases = listOfNotNull(previewOutput, photoOutput, videoOutput, codeScannerOutput)
if (useCases.isEmpty()) {
throw NoOutputsError()
}

// Input
val cameraId = configuration.cameraId ?: throw NoCameraDeviceError()
var cameraSelector = CameraSelector.Builder().byId(cameraId).build()

// Wrap input with a vendor extension if needed (see https://developer.android.com/media/camera/camera-extensions)
val isStreamingHDR = useCases.any { it.currentConfig.dynamicRange != DynamicRange.SDR }
val needsImageAnalysis = codeScannerOutput != null
if (configuration.enableHdr) {
// TODO: Fix Extensions are only supported for use with standard dynamic range.
val photoOptions = configuration.photo as? CameraConfiguration.Output.Enabled<CameraConfiguration.Photo>
if (photoOptions != null && photoOptions.config.enableHdr) {
if (isStreamingHDR) {
// extensions don't work if a camera stream is running at 10-bit HDR.
throw PhotoHdrAndVideoHdrNotSupportedSimultaneously()
}
// Load HDR Vendor extension (HDR only applies to image capture)
cameraSelector = cameraSelector.withExtension(context, provider, needsImageAnalysis, ExtensionMode.HDR, "HDR")
}
if (configuration.enableLowLightBoost) {
if (isStreamingHDR) {
// extensions don't work if a camera stream is running at 10-bit HDR.
throw LowLightBoostNotSupportedWithVideoHdr()
}
// Load night mode Vendor extension (only applies to image capture)
cameraSelector = cameraSelector.withExtension(context, provider, needsImageAnalysis, ExtensionMode.NIGHT, "NIGHT")
}

// Outputs
val useCases = listOfNotNull(previewOutput, photoOutput, videoOutput, codeScannerOutput)
if (useCases.isEmpty()) {
throw NoOutputsError()
}

// Frame Processor is a CameraEffect (Surface middleman)
val frameProcessorEffect = frameProcessorEffect
if (frameProcessorEffect != null) {
Expand Down
2 changes: 1 addition & 1 deletion package/example/src/CameraPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export function CameraPage({ navigation }: Props): React.ReactElement {
onStopped={() => 'Camera stopped!'}
format={format}
fps={fps}
photoHdr={format?.supportsPhotoHdr && enableHdr}
// photoHdr={format?.supportsPhotoHdr && enableHdr}
videoHdr={format?.supportsVideoHdr && enableHdr}
photoQualityBalance="quality"
lowLightBoost={device.supportsLowLightBoost && enableNightMode}
Expand Down
2 changes: 2 additions & 0 deletions package/src/CameraError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export type DeviceError =
export type FormatError =
| 'format/invalid-fps'
| 'format/invalid-video-hdr'
| 'format/photo-hdr-and-video-hdr-not-suppoted-simultaneously'
| 'format/low-light-boost-not-supported-with-video-hdr'
| 'format/invalid-video-stabilization-mode'
| 'format/incompatible-pixel-format-with-hdr-setting'
| 'format/invalid-format'
Expand Down

0 comments on commit 19a7b0c

Please sign in to comment.