Skip to content

Commit

Permalink
Merge pull request #487 from cobryan05/flashFix
Browse files Browse the repository at this point in the history
Improve camera flash
  • Loading branch information
feelfreelinux authored Jun 1, 2024
2 parents 6e433b4 + 1e3b94d commit 3b2bcd2
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 14 deletions.
56 changes: 44 additions & 12 deletions app/app/src/main/java/com/octo4a/camera/CameraService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import kotlin.coroutines.suspendCoroutine
class CameraService : LifecycleService(), MJpegFrameProvider {
private var latestFrame: ByteArray = ByteArray(0)
private var listenerCount = 0
private var flashRefCnt: Int = 0

private val cameraSettings: MainPreferences by inject()
private val logger: LoggerRepository by inject()
Expand Down Expand Up @@ -108,10 +109,16 @@ class CameraService : LifecycleService(), MJpegFrameProvider {
if (!cameraInitialized) {
it.resume(ByteArray(0))
} else {
if (cameraSettings.flashWhenObserved) {
addFlashObserver()
}
imageCapture.takePicture(
captureExecutor,
object : ImageCapture.OnImageCapturedCallback() {
override fun onCaptureSuccess(image: ImageProxy) {
if (cameraSettings.flashWhenObserved) {
removeFlashObserver()
}
val buffer = image.planes[0].buffer
val bytes = ByteArray(buffer.capacity()).also { array -> buffer.get(array) }
val matrix = Matrix().apply { postRotate(rotation.toFloat()) }
Expand All @@ -135,6 +142,9 @@ class CameraService : LifecycleService(), MJpegFrameProvider {
}

override fun onError(exception: ImageCaptureException) {
if (cameraSettings.flashWhenObserved) {
removeFlashObserver()
}
super.onError(exception)
logger.log(this) { "Single capture error: $exception" }
it.resume(ByteArray(0))
Expand All @@ -148,11 +158,8 @@ class CameraService : LifecycleService(), MJpegFrameProvider {
listenerCount++
}
logger.log(this) { "Camera server register listener" }

val turnFlashOn = cameraSettings.flashWhenObserved

if (listenerCount > 0 && turnFlashOn && cameraInitialized) {
currentCamera?.cameraControl?.enableTorch(true)
if (cameraSettings.flashWhenObserved) {
addFlashObserver()
}
}

Expand All @@ -161,16 +168,35 @@ class CameraService : LifecycleService(), MJpegFrameProvider {
listenerCount--
}
logger.log(this) { "Camera server unregister listener" }

if (listenerCount < 1 && cameraInitialized) {
currentCamera?.cameraControl?.enableTorch(false)
if (cameraSettings.flashWhenObserved) {
removeFlashObserver()
}
}

private val mjpegServer by lazy { MJpegServer(5001, this) }

private val callbackExecutorPool = Executors.newCachedThreadPool()

private fun addFlashObserver() {
synchronized(flashRefCnt) {
flashRefCnt++
if (cameraInitialized) {
currentCamera?.cameraControl?.enableTorch(true)
}
}
}

private fun removeFlashObserver() {
synchronized(flashRefCnt) {
if(flashRefCnt > 0) {
flashRefCnt--
}
if(cameraInitialized && flashRefCnt == 0) {
currentCamera?.cameraControl?.enableTorch(false)
}
}
}

override fun onBind(intent: Intent): IBinder {
super.onBind(intent)
return binder
Expand All @@ -184,9 +210,15 @@ class CameraService : LifecycleService(), MJpegFrameProvider {
octoprintHandler.isCameraServerRunning = false
}

fun stopPreview() {
// Doesn't actually unbind the camera
if(cameraSettings.flashWhenObserved) {
removeFlashObserver()
}
}

fun getPreview(): Preview {
cameraInitialized = false
val turnFlashOn = cameraSettings.flashWhenObserved

cameraProcessProvider?.unbindAll()
val camera = cameraProcessProvider?.bindToLifecycle(
Expand All @@ -197,10 +229,10 @@ class CameraService : LifecycleService(), MJpegFrameProvider {
cameraPreview
)

if (turnFlashOn) {
camera?.cameraControl?.enableTorch(true)
}
cameraInitialized = true
if(cameraSettings.flashWhenObserved) {
addFlashObserver()
}
return cameraPreview
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,14 @@ class ServerFragment : Fragment() {
.setTitle(R.string.camera_preview)
.setView(R.layout.dialog_camera_preview)
.setPositiveButton(R.string.action_ok) {dialog, _ -> dialog.dismiss() }
.setOnDismissListener {
if (boundToCameraService) {
cameraService.stopPreview()
}
}
.show()

dialog.findViewById<PreviewView>(R.id.previewView)?.apply {


if (boundToCameraService) {
cameraService.getPreview().setSurfaceProvider(surfaceProvider)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
private val selectedCameraResolution by lazy { findPreference<ListPreference>("selectedResolution") }
private val sshPasswordPref by lazy { findPreference<EditTextPreference>("changeSSHPassword") }
private val fpsLimit by lazy { findPreference<ListPreference>("fpsLimit") }
private val flashWhenObserved by lazy { findPreference<SwitchPreferenceCompat>("flashWhenObserved") }
private val installPluginExtras by lazy { findPreference<Preference>("installPluginExtras") }
private val imageRotation by lazy { findPreference<ListPreference>("imageRotation") }
private val disableAF by lazy { findPreference<SwitchPreferenceCompat>("disableAF") }
Expand Down Expand Up @@ -183,6 +184,12 @@ class SettingsFragment : PreferenceFragmentCompat() {
true
}

flashWhenObserved?.setOnPreferenceChangeListener { _, value ->
stopCameraServer()
startCameraServer()
true
}

enableCameraPref?.setOnPreferenceChangeListener { _, newValue ->
if (cameras.isEmpty()) {
enableCameraPref.isChecked = false
Expand Down

0 comments on commit 3b2bcd2

Please sign in to comment.