CameraActivity: only bind 2 use cases at most + some other fixes
This commit is contained in:
parent
c521c7f998
commit
ab48f9219b
@ -76,7 +76,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation "androidx.concurrent:concurrent-futures:1.1.0"
|
implementation "androidx.concurrent:concurrent-futures:1.1.0"
|
||||||
|
|
||||||
def camerax_version = "1.1.0-beta02"
|
def camerax_version = "1.1.0-beta03"
|
||||||
implementation "androidx.camera:camera-camera2:$camerax_version"
|
implementation "androidx.camera:camera-camera2:$camerax_version"
|
||||||
implementation "androidx.camera:camera-lifecycle:$camerax_version"
|
implementation "androidx.camera:camera-lifecycle:$camerax_version"
|
||||||
implementation "androidx.camera:camera-view:$camerax_version"
|
implementation "androidx.camera:camera-view:$camerax_version"
|
||||||
|
@ -78,6 +78,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
private var camera: Camera? = null
|
private var camera: Camera? = null
|
||||||
private var resolutions: List<Size>? = null
|
private var resolutions: List<Size>? = null
|
||||||
private var currentResolutionIndex: Int = 0
|
private var currentResolutionIndex: Int = 0
|
||||||
|
private var currentResolution: Size? = null
|
||||||
private var captureMode = ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY
|
private var captureMode = ImageCapture.CAPTURE_MODE_MAXIMIZE_QUALITY
|
||||||
private var isBackCamera = true
|
private var isBackCamera = true
|
||||||
private var isInVideoMode = false
|
private var isInVideoMode = false
|
||||||
@ -139,7 +140,11 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
if (newCaptureMode != captureMode) {
|
if (newCaptureMode != captureMode) {
|
||||||
captureMode = newCaptureMode
|
captureMode = newCaptureMode
|
||||||
binding.imageCaptureMode.setImageResource(resId)
|
binding.imageCaptureMode.setImageResource(resId)
|
||||||
setupCamera()
|
if (!isInVideoMode) {
|
||||||
|
cameraProvider.unbind(imageCapture)
|
||||||
|
refreshImageCapture()
|
||||||
|
cameraProvider.bindToLifecycle(this, cameraSelector, imageCapture)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
@ -151,9 +156,10 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
CustomAlertDialogBuilder(this, themeValue)
|
CustomAlertDialogBuilder(this, themeValue)
|
||||||
.setTitle(R.string.choose_resolution)
|
.setTitle(R.string.choose_resolution)
|
||||||
.setSingleChoiceItems(it.map { size -> size.toString() }.toTypedArray(), currentResolutionIndex) { dialog, which ->
|
.setSingleChoiceItems(it.map { size -> size.toString() }.toTypedArray(), currentResolutionIndex) { dialog, which ->
|
||||||
setupCamera(resolutions!![which])
|
currentResolution = resolutions!![which]
|
||||||
dialog.dismiss()
|
|
||||||
currentResolutionIndex = which
|
currentResolutionIndex = which
|
||||||
|
setupCamera()
|
||||||
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
.setNegativeButton(R.string.cancel, null)
|
.setNegativeButton(R.string.cancel, null)
|
||||||
.show()
|
.show()
|
||||||
@ -204,6 +210,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
}
|
}
|
||||||
binding.imageModeSwitch.setOnClickListener {
|
binding.imageModeSwitch.setOnClickListener {
|
||||||
isInVideoMode = !isInVideoMode
|
isInVideoMode = !isInVideoMode
|
||||||
|
setupCamera()
|
||||||
binding.imageFlash.setImageResource(if (isInVideoMode) {
|
binding.imageFlash.setImageResource(if (isInVideoMode) {
|
||||||
binding.recordVideoButton.visibility = View.VISIBLE
|
binding.recordVideoButton.visibility = View.VISIBLE
|
||||||
binding.takePhotoButton.visibility = View.GONE
|
binding.takePhotoButton.visibility = View.GONE
|
||||||
@ -239,6 +246,7 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
resolutions = null
|
||||||
setupCamera()
|
setupCamera()
|
||||||
}
|
}
|
||||||
binding.takePhotoButton.onClick = ::onClickTakePhoto
|
binding.takePhotoButton.onClick = ::onClickTakePhoto
|
||||||
@ -301,52 +309,67 @@ class CameraActivity : BaseActivity(), SensorOrientationListener.Listener {
|
|||||||
|
|
||||||
private fun adaptPreviewSize(resolution: Size) {
|
private fun adaptPreviewSize(resolution: Size) {
|
||||||
val screenWidth = resources.displayMetrics.widthPixels
|
val screenWidth = resources.displayMetrics.widthPixels
|
||||||
binding.cameraPreview.layoutParams = if (screenWidth < resolution.width) {
|
val screenHeight = resources.displayMetrics.heightPixels
|
||||||
RelativeLayout.LayoutParams(
|
|
||||||
screenWidth,
|
var height = (resolution.height * (screenWidth.toFloat() / resolution.width)).toInt()
|
||||||
(resolution.height * (screenWidth.toFloat() / resolution.width)).toInt()
|
var width = screenWidth
|
||||||
)
|
if (height > screenHeight) {
|
||||||
} else {
|
width = (width * (screenHeight.toFloat() / height)).toInt()
|
||||||
RelativeLayout.LayoutParams(resolution.width, resolution.height)
|
height = screenHeight
|
||||||
|
}
|
||||||
|
binding.cameraPreview.layoutParams = RelativeLayout.LayoutParams(width, height).apply {
|
||||||
|
addRule(RelativeLayout.CENTER_IN_PARENT)
|
||||||
}
|
}
|
||||||
(binding.cameraPreview.layoutParams as RelativeLayout.LayoutParams).addRule(RelativeLayout.CENTER_IN_PARENT)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("RestrictedApi")
|
private fun refreshImageCapture() {
|
||||||
private fun setupCamera(resolution: Size? = null){
|
|
||||||
if (permissionsGranted && ::extensionsManager.isInitialized && ::cameraProvider.isInitialized) {
|
|
||||||
imageCapture = ImageCapture.Builder()
|
imageCapture = ImageCapture.Builder()
|
||||||
.setCaptureMode(captureMode)
|
.setCaptureMode(captureMode)
|
||||||
.setFlashMode(imageCapture?.flashMode ?: ImageCapture.FLASH_MODE_AUTO)
|
.setFlashMode(imageCapture?.flashMode ?: ImageCapture.FLASH_MODE_AUTO)
|
||||||
.apply {
|
.apply {
|
||||||
resolution?.let {
|
currentResolution?.let {
|
||||||
setTargetResolution(it)
|
setTargetResolution(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun refreshVideoCapture() {
|
||||||
videoCapture = VideoCapture.Builder().apply {
|
videoCapture = VideoCapture.Builder().apply {
|
||||||
resolution?.let {
|
currentResolution?.let {
|
||||||
setTargetResolution(it)
|
setTargetResolution(it)
|
||||||
}
|
}
|
||||||
}.build()
|
}.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("RestrictedApi")
|
||||||
|
private fun setupCamera() {
|
||||||
|
if (permissionsGranted && ::extensionsManager.isInitialized && ::cameraProvider.isInitialized) {
|
||||||
cameraSelector = if (isBackCamera){ CameraSelector.DEFAULT_BACK_CAMERA } else { CameraSelector.DEFAULT_FRONT_CAMERA }
|
cameraSelector = if (isBackCamera){ CameraSelector.DEFAULT_BACK_CAMERA } else { CameraSelector.DEFAULT_FRONT_CAMERA }
|
||||||
if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.HDR)) {
|
if (extensionsManager.isExtensionAvailable(cameraSelector, ExtensionMode.AUTO)) {
|
||||||
cameraSelector = extensionsManager.getExtensionEnabledCameraSelector(cameraSelector, ExtensionMode.HDR)
|
cameraSelector = extensionsManager.getExtensionEnabledCameraSelector(cameraSelector, ExtensionMode.AUTO)
|
||||||
}
|
}
|
||||||
|
|
||||||
cameraProvider.unbindAll()
|
cameraProvider.unbindAll()
|
||||||
camera = cameraProvider.bindToLifecycle(this, cameraSelector, cameraPreview, imageCapture, videoCapture)
|
|
||||||
|
|
||||||
adaptPreviewSize(resolution ?: imageCapture!!.attachedSurfaceResolution!!.swap())
|
val currentUseCase = (if (isInVideoMode) {
|
||||||
|
refreshVideoCapture()
|
||||||
|
camera = cameraProvider.bindToLifecycle(this, cameraSelector, cameraPreview, videoCapture)
|
||||||
|
videoCapture
|
||||||
|
} else {
|
||||||
|
refreshImageCapture()
|
||||||
|
camera = cameraProvider.bindToLifecycle(this, cameraSelector, cameraPreview, imageCapture)
|
||||||
|
imageCapture
|
||||||
|
})!!
|
||||||
|
|
||||||
|
adaptPreviewSize(currentResolution ?: currentUseCase.attachedSurfaceResolution!!.swap())
|
||||||
|
|
||||||
if (resolutions == null) {
|
if (resolutions == null) {
|
||||||
val info = Camera2CameraInfo.from(camera!!.cameraInfo)
|
val info = Camera2CameraInfo.from(camera!!.cameraInfo)
|
||||||
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
|
||||||
val characteristics = cameraManager.getCameraCharacteristics(info.cameraId)
|
val characteristics = cameraManager.getCameraCharacteristics(info.cameraId)
|
||||||
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)?.let { streamConfigurationMap ->
|
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)?.let { streamConfigurationMap ->
|
||||||
resolutions = streamConfigurationMap.getOutputSizes(imageCapture!!.imageFormat).map { it.swap() }
|
resolutions = streamConfigurationMap.getOutputSizes(currentUseCase.imageFormat).map { it.swap() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ import static androidx.camera.core.internal.ThreadConfig.OPTION_BACKGROUND_EXECU
|
|||||||
import static androidx.camera.core.internal.UseCaseEventConfig.OPTION_USE_CASE_EVENT_CALLBACK;
|
import static androidx.camera.core.internal.UseCaseEventConfig.OPTION_USE_CASE_EVENT_CALLBACK;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioRecord;
|
import android.media.AudioRecord;
|
||||||
import android.media.CamcorderProfile;
|
import android.media.CamcorderProfile;
|
||||||
@ -76,6 +75,7 @@ import androidx.annotation.VisibleForTesting;
|
|||||||
import androidx.camera.core.AspectRatio;
|
import androidx.camera.core.AspectRatio;
|
||||||
import androidx.camera.core.CameraSelector;
|
import androidx.camera.core.CameraSelector;
|
||||||
import androidx.camera.core.CameraXThreads;
|
import androidx.camera.core.CameraXThreads;
|
||||||
|
import androidx.camera.core.ImageCapture;
|
||||||
import androidx.camera.core.Logger;
|
import androidx.camera.core.Logger;
|
||||||
import androidx.camera.core.UseCase;
|
import androidx.camera.core.UseCase;
|
||||||
import androidx.camera.core.impl.CameraInternal;
|
import androidx.camera.core.impl.CameraInternal;
|
||||||
@ -121,7 +121,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
|
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
|
||||||
@SuppressLint("RestrictedApi")
|
|
||||||
public final class VideoCapture extends UseCase {
|
public final class VideoCapture extends UseCase {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -280,7 +279,9 @@ public final class VideoCapture extends UseCase {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public UseCaseConfig<?> getDefaultConfig(boolean applyDefaultConfig,
|
public UseCaseConfig<?> getDefaultConfig(boolean applyDefaultConfig,
|
||||||
@NonNull UseCaseConfigFactory factory) {
|
@NonNull UseCaseConfigFactory factory) {
|
||||||
Config captureConfig = factory.getConfig(UseCaseConfigFactory.CaptureType.VIDEO_CAPTURE);
|
Config captureConfig = factory.getConfig(
|
||||||
|
UseCaseConfigFactory.CaptureType.VIDEO_CAPTURE,
|
||||||
|
ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY);
|
||||||
|
|
||||||
if (applyDefaultConfig) {
|
if (applyDefaultConfig) {
|
||||||
captureConfig = Config.mergeConfigs(captureConfig, DEFAULT_CONFIG.getConfig());
|
captureConfig = Config.mergeConfigs(captureConfig, DEFAULT_CONFIG.getConfig());
|
||||||
|
Loading…
Reference in New Issue
Block a user