Skip to content

Commit

Permalink
Handle cases when 30 fps is unavailable
Browse files Browse the repository at this point in the history
(and prevent crash when video mode is directly turned on)
  • Loading branch information
MHShetty committed Jun 28, 2024
1 parent d071126 commit c41cd08
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 16 deletions.
54 changes: 47 additions & 7 deletions app/src/main/java/app/grapheneos/camera/CamConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.annotation.StringRes
import androidx.camera.camera2.interop.Camera2Interop
import androidx.camera.core.AspectRatio
import androidx.camera.core.Camera
import androidx.camera.core.CameraInfo
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageCapture
Expand Down Expand Up @@ -223,6 +224,10 @@ class CamConfig(private val mActivity: MainActivity) {

var lastCapturedItem: CapturedItem? = null

private var frontCameraInfo : CameraInfo? = null

private var rearCameraInfo : CameraInfo? = null

init {
if (mActivity !is SecureActivity) {
CapturedItems.init(mActivity, this)
Expand Down Expand Up @@ -355,7 +360,7 @@ class CamConfig(private val mActivity: MainActivity) {
modePref.getString(videoFrameRateKey, "")!!
)
} else {
SettingValues.Default.VIDEO_FRAME_RATE
defaultVideoFrameRate
}
}
set(value) {
Expand All @@ -377,6 +382,15 @@ class CamConfig(private val mActivity: MainActivity) {
return "${SettingValues.Key.VIDEO_FRAME_RATE}_$pf"
}

val defaultVideoFrameRate : Range<Int>
get() {
val availableFrameRates = getAvailableVideoFrameRates()
if (availableFrameRates.isEmpty() ||
availableFrameRates.contains(SettingValues.Default.VIDEO_FRAME_RATE))
return SettingValues.Default.VIDEO_FRAME_RATE
return availableFrameRates[0]
}

var flashMode: Int
get() = if (imageCapture != null) imageCapture!!.flashMode else
SettingValues.Default.FLASH_MODE
Expand Down Expand Up @@ -928,6 +942,18 @@ class CamConfig(private val mActivity: MainActivity) {
startCamera(true)
}

fun getCurrentCameraInfo() : CameraInfo {
return if (lensFacing == CameraSelector.LENS_FACING_BACK) rearCameraInfo!!
else frontCameraInfo!!
}

fun getAvailableVideoFrameRates(): List<Range<Int>> {
val resSet = getCurrentCameraInfo().supportedFrameRateRanges
// Individual fps -> Ranged fps (sorted by lower value of range and then upper for each lower value)
val resList = resSet.sortedWith(compareBy<Range<Int>> { it.lower != it.upper }.thenBy { it.lower }.thenBy { it.upper })
return resList
}

fun toggleCameraSelector() {

// Manually switch to the opposite lens facing
Expand Down Expand Up @@ -971,6 +997,12 @@ class CamConfig(private val mActivity: MainActivity) {
return
}

// Select a single camera for front/rear facing
for (cameraInfo in cameraProvider!!.availableCameraInfos) {
if (cameraInfo.lensFacing == CameraSelector.LENS_FACING_FRONT) frontCameraInfo = cameraInfo
else if (cameraInfo.lensFacing == CameraSelector.LENS_FACING_BACK) rearCameraInfo = cameraInfo
}

// Manually switch to the other lens facing (if the default lens facing isn't
// supported for the current device)
if (!isLensFacingSupported(lensFacing)) {
Expand All @@ -997,11 +1029,11 @@ class CamConfig(private val mActivity: MainActivity) {
}

private fun isLensFacingSupported(lensFacing : Int) : Boolean {
val tCameraSelector = CameraSelector.Builder()
.requireLensFacing(lensFacing)
.build()

return cameraProvider?.hasCamera(tCameraSelector) ?: false
return when(lensFacing) {
CameraSelector.LENS_FACING_FRONT -> frontCameraInfo != null
CameraSelector.LENS_FACING_BACK -> rearCameraInfo != null
else -> false
}
}

// Start the camera with latest hard configuration
Expand All @@ -1026,7 +1058,15 @@ class CamConfig(private val mActivity: MainActivity) {
if (mActivity.isDestroyed || mActivity.isFinishing) return

cameraSelector = CameraSelector.Builder()
.requireLensFacing(lensFacing)
.addCameraFilter {
return@addCameraFilter listOf(
if (lensFacing == CameraSelector.LENS_FACING_BACK) {
rearCameraInfo
} else {
frontCameraInfo
}
)
}
.build()

val builder = ImageCapture.Builder()
Expand Down
12 changes: 3 additions & 9 deletions app/src/main/java/app/grapheneos/camera/ui/SettingsDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -649,12 +649,6 @@ class SettingsDialog(val mActivity: MainActivity) :
return Recorder.getVideoCapabilities(cameraInfo).getSupportedQualities(DynamicRange.SDR)
}

private fun getAvailableVideoFrameRates(): List<Range<Int>> {
val resSet = camConfig.camera?.cameraInfo?.supportedFrameRateRanges ?: Collections.emptySet()
// Individual fps -> Ranged fps (sorted by lower value of range and then upper for each lower value)
val resList = resSet.sortedWith(compareBy<Range<Int>> { it.lower != it.upper }.thenBy { it.lower }.thenBy { it.upper })
return resList
}

private fun getAvailableQualityTitles(): List<String> {
val titles = arrayListOf<String>()
Expand All @@ -666,10 +660,10 @@ class SettingsDialog(val mActivity: MainActivity) :
return titles
}

private fun getAvailableFRTitles(): List<String> {
private fun getAvailableFrameRateTitles(): List<String> {
val titles = arrayListOf<String>()

getAvailableVideoFrameRates().forEach {
camConfig.getAvailableVideoFrameRates().forEach {
titles.add(getTitleForFrameRateRange(it))
}

Expand Down Expand Up @@ -727,7 +721,7 @@ class SettingsDialog(val mActivity: MainActivity) :
fun reloadVideoSettings() {

val qualityTitles = getAvailableQualityTitles()
val frameRateTitles = getAvailableFRTitles()
val frameRateTitles = getAvailableFrameRateTitles()

videoQualityAdapter = ArrayAdapter<String>(
mActivity,
Expand Down

0 comments on commit c41cd08

Please sign in to comment.