commit a5ed05e41501dc1c1bb3f8c3d04cf80d95b8341c parent e144c932808ec9e1ca638d6ce717d55c6fc265cd Author: rhunk <101876869+rhunk@users.noreply.github.com> Date: Mon, 28 Aug 2023 22:51:40 +0200 feat: custom camera frame rate Diffstat:
4 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/core/src/main/assets/lang/en_US.json b/core/src/main/assets/lang/en_US.json @@ -289,9 +289,9 @@ "name": "Override Picture Resolution", "description": "Overrides the picture resolution" }, - "force_highest_frame_rate": { - "name": "Force Highest Frame Rate", - "description": "Forces the highest possible frame rate" + "custom_frame_rate": { + "name": "Custom Frame Rate", + "description": "Overrides the camera frame rate" }, "force_camera_source_encoding": { "name": "Force Camera Source Encoding", diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/Camera.kt b/core/src/main/kotlin/me/rhunk/snapenhance/core/config/impl/Camera.kt @@ -12,6 +12,8 @@ class Camera : ConfigContainer() { { addFlags(ConfigFlag.NO_TRANSLATE) } val overridePictureResolution = unique("override_picture_resolution", *CameraTweaks.resolutions.toTypedArray()) { addFlags(ConfigFlag.NO_TRANSLATE) } - val forceHighestFrameRate = boolean("force_highest_frame_rate") { addNotices(FeatureNotice.MAY_BREAK_INTERNAL_BEHAVIOR) } + val customFrameRate = unique("custom_frame_rate", + "5", "10", "20", "25", "30", "48", "60", "90", "120" + ) { addNotices(FeatureNotice.MAY_BREAK_INTERNAL_BEHAVIOR); addFlags(ConfigFlag.NO_TRANSLATE) } val forceCameraSourceEncoding = boolean("force_camera_source_encoding") } diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ConfigurationOverride.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/ConfigurationOverride.kt @@ -17,7 +17,6 @@ class ConfigurationOverride : Feature("Configuration Override", loadParams = Fea overrideProperty("STREAK_EXPIRATION_INFO", { context.config.userInterface.streakExpirationInfo.get() }, true) - overrideProperty("FORCE_CAMERA_HIGHEST_FPS", { context.config.camera.forceHighestFrameRate.get() }, true) overrideProperty("MEDIA_RECORDER_MAX_QUALITY_LEVEL", { context.config.camera.forceCameraSourceEncoding.get() }, true) overrideProperty("REDUCE_MY_PROFILE_UI_COMPLEXITY", { context.config.userInterface.mapFriendNameTags.get() }, true) overrideProperty("ENABLE_LONG_SNAP_SENDING", { context.config.global.disableSnapSplitting.get() }, true) diff --git a/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/CameraTweaks.kt b/core/src/main/kotlin/me/rhunk/snapenhance/features/impl/tweaks/CameraTweaks.kt @@ -4,13 +4,17 @@ import android.Manifest import android.annotation.SuppressLint import android.content.ContextWrapper import android.content.pm.PackageManager +import android.hardware.camera2.CameraCharacteristics +import android.hardware.camera2.CameraCharacteristics.Key import android.hardware.camera2.CameraManager +import android.util.Range import me.rhunk.snapenhance.data.wrapper.impl.ScSize import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.FeatureLoadParams import me.rhunk.snapenhance.hook.HookStage import me.rhunk.snapenhance.hook.hook import me.rhunk.snapenhance.hook.hookConstructor +import me.rhunk.snapenhance.util.ktx.setObjectField class CameraTweaks : Feature("Camera Tweaks", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) { companion object { @@ -39,6 +43,21 @@ class CameraTweaks : Feature("Camera Tweaks", loadParams = FeatureLoadParams.ACT val previewResolutionConfig = context.config.camera.overridePreviewResolution.getNullable()?.let { parseResolution(it) } val captureResolutionConfig = context.config.camera.overridePictureResolution.getNullable()?.let { parseResolution(it) } + context.config.camera.customFrameRate.getNullable()?.also { value -> + val customFrameRate = value.toInt() + CameraCharacteristics::class.java.hook("get", HookStage.AFTER) { param -> + val key = param.arg<Key<*>>(0) + if (key == CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES) { + val fpsRanges = param.getResult() as? Array<*> ?: return@hook + fpsRanges.forEach { + val range = it as? Range<*> ?: return@forEach + range.setObjectField("mUpper", customFrameRate) + range.setObjectField("mLower", customFrameRate) + } + } + } + } + context.mappings.getMappedClass("ScCameraSettings").hookConstructor(HookStage.BEFORE) { param -> val previewResolution = ScSize(param.argNullable(2)) val captureResolution = ScSize(param.argNullable(3))