Skip to content

Commit c41cd08

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

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

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

+47-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,15 @@ 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.isEmpty() ||
389+
availableFrameRates.contains(SettingValues.Default.VIDEO_FRAME_RATE))
390+
return SettingValues.Default.VIDEO_FRAME_RATE
391+
return availableFrameRates[0]
392+
}
393+
380394
var flashMode: Int
381395
get() = if (imageCapture != null) imageCapture!!.flashMode else
382396
SettingValues.Default.FLASH_MODE
@@ -928,6 +942,18 @@ class CamConfig(private val mActivity: MainActivity) {
928942
startCamera(true)
929943
}
930944

945+
fun getCurrentCameraInfo() : CameraInfo {
946+
return if (lensFacing == CameraSelector.LENS_FACING_BACK) rearCameraInfo!!
947+
else frontCameraInfo!!
948+
}
949+
950+
fun getAvailableVideoFrameRates(): List<Range<Int>> {
951+
val resSet = getCurrentCameraInfo().supportedFrameRateRanges
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+
return resList
955+
}
956+
931957
fun toggleCameraSelector() {
932958

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

1000+
// Select a single camera for front/rear facing
1001+
for (cameraInfo in cameraProvider!!.availableCameraInfos) {
1002+
if (cameraInfo.lensFacing == CameraSelector.LENS_FACING_FRONT) frontCameraInfo = cameraInfo
1003+
else if (cameraInfo.lensFacing == CameraSelector.LENS_FACING_BACK) rearCameraInfo = cameraInfo
1004+
}
1005+
9741006
// Manually switch to the other lens facing (if the default lens facing isn't
9751007
// supported for the current device)
9761008
if (!isLensFacingSupported(lensFacing)) {
@@ -997,11 +1029,11 @@ class CamConfig(private val mActivity: MainActivity) {
9971029
}
9981030

9991031
private fun isLensFacingSupported(lensFacing : Int) : Boolean {
1000-
val tCameraSelector = CameraSelector.Builder()
1001-
.requireLensFacing(lensFacing)
1002-
.build()
1003-
1004-
return cameraProvider?.hasCamera(tCameraSelector) ?: false
1032+
return when(lensFacing) {
1033+
CameraSelector.LENS_FACING_FRONT -> frontCameraInfo != null
1034+
CameraSelector.LENS_FACING_BACK -> rearCameraInfo != null
1035+
else -> false
1036+
}
10051037
}
10061038

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

10281060
cameraSelector = CameraSelector.Builder()
1029-
.requireLensFacing(lensFacing)
1061+
.addCameraFilter {
1062+
return@addCameraFilter listOf(
1063+
if (lensFacing == CameraSelector.LENS_FACING_BACK) {
1064+
rearCameraInfo
1065+
} else {
1066+
frontCameraInfo
1067+
}
1068+
)
1069+
}
10301070
.build()
10311071

10321072
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)