feat: custom camera frame rate

This commit is contained in:
rhunk
2023-08-28 22:51:40 +02:00
parent e144c93280
commit a5ed05e415
4 changed files with 25 additions and 5 deletions

View File

@ -289,9 +289,9 @@
"name": "Override Picture Resolution", "name": "Override Picture Resolution",
"description": "Overrides the picture resolution" "description": "Overrides the picture resolution"
}, },
"force_highest_frame_rate": { "custom_frame_rate": {
"name": "Force Highest Frame Rate", "name": "Custom Frame Rate",
"description": "Forces the highest possible frame rate" "description": "Overrides the camera frame rate"
}, },
"force_camera_source_encoding": { "force_camera_source_encoding": {
"name": "Force Camera Source Encoding", "name": "Force Camera Source Encoding",

View File

@ -12,6 +12,8 @@ class Camera : ConfigContainer() {
{ addFlags(ConfigFlag.NO_TRANSLATE) } { addFlags(ConfigFlag.NO_TRANSLATE) }
val overridePictureResolution = unique("override_picture_resolution", *CameraTweaks.resolutions.toTypedArray()) val overridePictureResolution = unique("override_picture_resolution", *CameraTweaks.resolutions.toTypedArray())
{ addFlags(ConfigFlag.NO_TRANSLATE) } { 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") val forceCameraSourceEncoding = boolean("force_camera_source_encoding")
} }

View File

@ -17,7 +17,6 @@ class ConfigurationOverride : Feature("Configuration Override", loadParams = Fea
overrideProperty("STREAK_EXPIRATION_INFO", { context.config.userInterface.streakExpirationInfo.get() }, true) 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("MEDIA_RECORDER_MAX_QUALITY_LEVEL", { context.config.camera.forceCameraSourceEncoding.get() }, true)
overrideProperty("REDUCE_MY_PROFILE_UI_COMPLEXITY", { context.config.userInterface.mapFriendNameTags.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) overrideProperty("ENABLE_LONG_SNAP_SENDING", { context.config.global.disableSnapSplitting.get() }, true)

View File

@ -4,13 +4,17 @@ import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ContextWrapper import android.content.ContextWrapper
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraCharacteristics.Key
import android.hardware.camera2.CameraManager import android.hardware.camera2.CameraManager
import android.util.Range
import me.rhunk.snapenhance.data.wrapper.impl.ScSize import me.rhunk.snapenhance.data.wrapper.impl.ScSize
import me.rhunk.snapenhance.features.Feature import me.rhunk.snapenhance.features.Feature
import me.rhunk.snapenhance.features.FeatureLoadParams import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.hook.HookStage import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.hook import me.rhunk.snapenhance.hook.hook
import me.rhunk.snapenhance.hook.hookConstructor import me.rhunk.snapenhance.hook.hookConstructor
import me.rhunk.snapenhance.util.ktx.setObjectField
class CameraTweaks : Feature("Camera Tweaks", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) { class CameraTweaks : Feature("Camera Tweaks", loadParams = FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
companion object { 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 previewResolutionConfig = context.config.camera.overridePreviewResolution.getNullable()?.let { parseResolution(it) }
val captureResolutionConfig = context.config.camera.overridePictureResolution.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 -> context.mappings.getMappedClass("ScCameraSettings").hookConstructor(HookStage.BEFORE) { param ->
val previewResolution = ScSize(param.argNullable(2)) val previewResolution = ScSize(param.argNullable(2))
val captureResolution = ScSize(param.argNullable(3)) val captureResolution = ScSize(param.argNullable(3))