Skip to content

Commit

Permalink
Fix use resolution in portrait and avoid cameraxsource crash
Browse files Browse the repository at this point in the history
  • Loading branch information
pedroSG94 committed Dec 2, 2024
1 parent 6932436 commit aaf2244
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ package com.pedro.encoder.input.sources.video

import android.content.Context
import android.graphics.SurfaceTexture
import android.hardware.Camera
import android.os.Build
import android.util.Range
import android.util.Size
Expand Down Expand Up @@ -70,19 +69,14 @@ class Camera1Source(context: Context): VideoSource() {
if (width % 2 != 0 || height % 2 != 0) {
throw IllegalArgumentException("width and height values must be divisible by 2")
}
val shouldRotate = width > height
val shouldRotate = width < height
val w = if (shouldRotate) height else width
val h = if (shouldRotate) width else height
val size = Size(w, h)
val resolutions = if (facing == CameraHelper.Facing.BACK) {
camera.previewSizeBack
} else camera.previewSizeFront
return mapCamera1Resolutions(resolutions, shouldRotate).find { it.width == size.width && it.height == size.height } != null
}

@Suppress("DEPRECATION")
private fun mapCamera1Resolutions(resolutions: List<Camera.Size>, shouldRotate: Boolean) = resolutions.map {
if (shouldRotate) Size(it.height, it.width) else Size(it.width, it.height)
return resolutions.map { Size(it.width, it.height) }.find { it.width == size.width && it.height == size.height } != null
}

fun switchCamera() {
Expand All @@ -107,7 +101,7 @@ class Camera1Source(context: Context): VideoSource() {
} else {
camera.previewSizeBack
}
return mapCamera1Resolutions(resolutions, false)
return resolutions.map { Size(it.width, it.height) }
}

fun setExposure(level: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,17 +140,27 @@ public void setCameraSelect(int cameraFacing) {
public void start(CameraHelper.Facing cameraFacing, int width, int height, int fps) {
int facing = cameraFacing == CameraHelper.Facing.BACK ? Camera.CameraInfo.CAMERA_FACING_BACK
: Camera.CameraInfo.CAMERA_FACING_FRONT;
this.width = width;
this.height = height;
if (width < height) {
this.width = height;
this.height = width;
} else {
this.width = width;
this.height = height;
}
this.fps = fps;
cameraSelect =
facing == Camera.CameraInfo.CAMERA_FACING_BACK ? selectCameraBack() : selectCameraFront();
start();
}

public void start(int facing, int width, int height, int fps) {
this.width = width;
this.height = height;
if (width < height) {
this.width = height;
this.height = width;
} else {
this.width = width;
this.height = height;
}
this.fps = fps;
cameraSelect = facing;
selectCamera(facing);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,16 @@ import androidx.annotation.RequiresApi
object Camera2ResolutionCalculator {

fun getOptimalResolution(actualResolution: Size, resolutionsSupported: Array<Size>): Size {
return if (resolutionsSupported.find { it == actualResolution } != null) actualResolution
val resolution = if (actualResolution.width < actualResolution.height) Size(actualResolution.height, actualResolution.width) else actualResolution
return if (resolutionsSupported.find { it == resolution } != null) resolution
else {
val actualAspectRatio = actualResolution.width.toFloat() / actualResolution.height.toFloat()
val actualAspectRatio = resolution.width.toFloat() / resolution.height.toFloat()
val validResolutions = resolutionsSupported.filter { it.width.toFloat() / it.height.toFloat() == actualAspectRatio }
if (validResolutions.isNotEmpty()) {
val resolutions = validResolutions.toMutableList()
resolutions.add(actualResolution)
resolutions.add(resolution)
val resolutionsSorted = resolutions.sortedByDescending { it.height }
val index = resolutionsSorted.indexOf(actualResolution)
val index = resolutionsSorted.indexOf(resolution)
if (index > 0) {
return resolutionsSorted[index - 1]
} else return resolutionsSorted[index + 1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.pedro.encoder.input.sources.video.Camera2Source
import com.pedro.encoder.input.sources.video.VideoSource
import com.pedro.encoder.input.video.Camera2ResolutionCalculator.getOptimalResolution
import com.pedro.encoder.input.video.CameraHelper
import java.util.concurrent.ExecutionException
import java.util.concurrent.Executors

Expand All @@ -51,14 +54,16 @@ class CameraXSource(
private var surface: Surface? = null

override fun create(width: Int, height: Int, fps: Int, rotation: Int): Boolean {
val facing = if (facing == CameraSelector.LENS_FACING_BACK) CameraHelper.Facing.BACK else CameraHelper.Facing.FRONT
val optimalResolution = getOptimalResolution(Size(width, height), getCameraResolutions(facing).toTypedArray())
preview = Preview.Builder()
.setTargetFrameRate(Range(fps, fps))
.setResolutionSelector(
ResolutionSelector.Builder()
.setResolutionStrategy(
ResolutionStrategy(
Size(width, height),
ResolutionStrategy.FALLBACK_RULE_NONE
optimalResolution,
ResolutionStrategy.FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER
)
).build()
).build()
Expand All @@ -67,12 +72,15 @@ class CameraXSource(
}

override fun start(surfaceTexture: SurfaceTexture) {
val facing = if (facing == CameraSelector.LENS_FACING_BACK) CameraHelper.Facing.BACK else CameraHelper.Facing.FRONT
val optimalResolution = getOptimalResolution(Size(width, height), getCameraResolutions(facing).toTypedArray())
surfaceTexture.setDefaultBufferSize(optimalResolution.width, optimalResolution.height)
this.surfaceTexture = surfaceTexture
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
cameraProviderFuture.addListener({
try {
val cameraSelector = CameraSelector.Builder()
.requireLensFacing(facing)
.requireLensFacing(this.facing)
.build()

preview.setSurfaceProvider {
Expand Down Expand Up @@ -115,5 +123,10 @@ class CameraXSource(
}
}

fun getCameraResolutions(facing: CameraHelper.Facing): List<Size> {
val camera2 = Camera2Source(context)
return camera2.getCameraResolutions(facing)
}

override val lifecycle: Lifecycle = lifecycleRegistry
}

0 comments on commit aaf2244

Please sign in to comment.