Skip to content

Commit bc0438d

Browse files
committed
Handle cases when 30 fps is unavailable
(and prevent crash when video mode is directly turned on)
1 parent d071126 commit bc0438d

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

app/src/main/java/app/grapheneos/camera/CamConfig.kt

+52-7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.annotation.StringRes
2222
import androidx.camera.camera2.interop.Camera2Interop
2323
import androidx.camera.core.AspectRatio
2424
import androidx.camera.core.Camera
25+
import androidx.camera.core.CameraInfo
2526
import androidx.camera.core.CameraSelector
2627
import androidx.camera.core.ImageAnalysis
2728
import androidx.camera.core.ImageCapture
@@ -223,6 +224,10 @@ class CamConfig(private val mActivity: MainActivity) {
223224

224225
var lastCapturedItem: CapturedItem? = null
225226

227+
private var frontCameraInfo : CameraInfo? = null
228+
229+
private var rearCameraInfo : CameraInfo? = null
230+
226231
init {
227232
if (mActivity !is SecureActivity) {
228233
CapturedItems.init(mActivity, this)
@@ -355,7 +360,7 @@ class CamConfig(private val mActivity: MainActivity) {
355360
modePref.getString(videoFrameRateKey, "")!!
356361
)
357362
} else {
358-
SettingValues.Default.VIDEO_FRAME_RATE
363+
defaultVideoFrameRate
359364
}
360365
}
361366
set(value) {
@@ -377,6 +382,14 @@ class CamConfig(private val mActivity: MainActivity) {
377382
return "${SettingValues.Key.VIDEO_FRAME_RATE}_$pf"
378383
}
379384

385+
val defaultVideoFrameRate : Range<Int>
386+
get() {
387+
val availableFrameRates = getAvailableVideoFrameRates()
388+
if (availableFrameRates.contains(SettingValues.Default.VIDEO_FRAME_RATE))
389+
return SettingValues.Default.VIDEO_FRAME_RATE
390+
return availableFrameRates[0]
391+
}
392+
380393
var flashMode: Int
381394
get() = if (imageCapture != null) imageCapture!!.flashMode else
382395
SettingValues.Default.FLASH_MODE
@@ -928,6 +941,24 @@ class CamConfig(private val mActivity: MainActivity) {
928941
startCamera(true)
929942
}
930943

944+
fun getCurrentCameraInfo() : CameraInfo {
945+
return if (lensFacing == CameraSelector.LENS_FACING_BACK) rearCameraInfo!!
946+
else frontCameraInfo!!
947+
}
948+
949+
fun getAvailableVideoFrameRates(): List<Range<Int>> {
950+
val resSet = getCurrentCameraInfo().supportedFrameRateRanges
951+
952+
// Individual fps -> Ranged fps (sorted by lower value of range and then upper for each lower value)
953+
val resList = resSet.sortedWith(compareBy<Range<Int>> { it.lower != it.upper }.thenBy { it.lower }.thenBy { it.upper })
954+
955+
// If the supportedFrameRateRange list is somehow empty due to device/library implementation
956+
// go with the most likely default rate
957+
if (resList.isEmpty()) return listOf(SettingValues.Default.VIDEO_FRAME_RATE)
958+
959+
return resList
960+
}
961+
931962
fun toggleCameraSelector() {
932963

933964
// Manually switch to the opposite lens facing
@@ -971,6 +1002,12 @@ class CamConfig(private val mActivity: MainActivity) {
9711002
return
9721003
}
9731004

1005+
// Select a single camera for front/rear facing
1006+
for (cameraInfo in cameraProvider!!.availableCameraInfos) {
1007+
if (cameraInfo.lensFacing == CameraSelector.LENS_FACING_FRONT) frontCameraInfo = cameraInfo
1008+
else if (cameraInfo.lensFacing == CameraSelector.LENS_FACING_BACK) rearCameraInfo = cameraInfo
1009+
}
1010+
9741011
// Manually switch to the other lens facing (if the default lens facing isn't
9751012
// supported for the current device)
9761013
if (!isLensFacingSupported(lensFacing)) {
@@ -997,11 +1034,11 @@ class CamConfig(private val mActivity: MainActivity) {
9971034
}
9981035

9991036
private fun isLensFacingSupported(lensFacing : Int) : Boolean {
1000-
val tCameraSelector = CameraSelector.Builder()
1001-
.requireLensFacing(lensFacing)
1002-
.build()
1003-
1004-
return cameraProvider?.hasCamera(tCameraSelector) ?: false
1037+
return when(lensFacing) {
1038+
CameraSelector.LENS_FACING_FRONT -> frontCameraInfo != null
1039+
CameraSelector.LENS_FACING_BACK -> rearCameraInfo != null
1040+
else -> false
1041+
}
10051042
}
10061043

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

10281065
cameraSelector = CameraSelector.Builder()
1029-
.requireLensFacing(lensFacing)
1066+
.addCameraFilter {
1067+
return@addCameraFilter listOf(
1068+
if (lensFacing == CameraSelector.LENS_FACING_BACK) {
1069+
rearCameraInfo
1070+
} else {
1071+
frontCameraInfo
1072+
}
1073+
)
1074+
}
10301075
.build()
10311076

10321077
val builder = ImageCapture.Builder()

app/src/main/java/app/grapheneos/camera/ui/SettingsDialog.kt

+3-9
Original file line numberDiff line numberDiff line change
@@ -649,12 +649,6 @@ class SettingsDialog(val mActivity: MainActivity) :
649649
return Recorder.getVideoCapabilities(cameraInfo).getSupportedQualities(DynamicRange.SDR)
650650
}
651651

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

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

669-
private fun getAvailableFRTitles(): List<String> {
663+
private fun getAvailableFrameRateTitles(): List<String> {
670664
val titles = arrayListOf<String>()
671665

672-
getAvailableVideoFrameRates().forEach {
666+
camConfig.getAvailableVideoFrameRates().forEach {
673667
titles.add(getTitleForFrameRateRange(it))
674668
}
675669

@@ -727,7 +721,7 @@ class SettingsDialog(val mActivity: MainActivity) :
727721
fun reloadVideoSettings() {
728722

729723
val qualityTitles = getAvailableQualityTitles()
730-
val frameRateTitles = getAvailableFRTitles()
724+
val frameRateTitles = getAvailableFrameRateTitles()
731725

732726
videoQualityAdapter = ArrayAdapter<String>(
733727
mActivity,

0 commit comments

Comments
 (0)