Skip to content

Commit

Permalink
Try PreviewView
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Aug 1, 2023
1 parent 9099967 commit 96a7cfd
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
35 changes: 29 additions & 6 deletions android/src/main/java/com/mrousavy/camera/CameraView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ import kotlin.math.min
class CameraView(context: Context) : FrameLayout(context) {
companion object {
const val TAG = "CameraView"
const val TAG_PERF = "CameraView.performance"

private val propsThatRequireSessionReconfiguration = arrayListOf("cameraId", "format", "fps", "hdr", "lowLightBoost", "photo", "video", "enableFrameProcessor")
private val arrayListOfZoom = arrayListOf("zoom")
Expand Down Expand Up @@ -101,6 +100,10 @@ class CameraView(context: Context) : FrameLayout(context) {
private var isMounted = false
private val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager

// session
private var cameraSession: CameraCaptureSession? = null
private val previewView = SurfaceView(context)

public var frameProcessor: FrameProcessor? = null

private val inputRotation: Int
Expand Down Expand Up @@ -128,6 +131,23 @@ class CameraView(context: Context) : FrameLayout(context) {
private var maxZoom: Float = 1f

init {
this.installHierarchyFitter()
previewView.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
previewView.holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
Log.i(TAG, "PreviewView Surface created!")
if (cameraId != null) configureSession()
}

override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
Log.i(TAG, "PreviewView Surface resized!")
}

override fun surfaceDestroyed(holder: SurfaceHolder) {
Log.i(TAG, "PreviewView Surface destroyed!")
}
})
addView(previewView)
}

override fun onConfigurationChanged(newConfig: Configuration?) {
Expand Down Expand Up @@ -163,7 +183,7 @@ class CameraView(context: Context) : FrameLayout(context) {
// TODO: updateLifecycleState()
}
if (shouldReconfigureSession) {
configureSession()
// configureSession()
}
if (shouldReconfigureZoom) {
val zoomClamped = max(min(zoom, maxZoom), minZoom)
Expand All @@ -185,7 +205,6 @@ class CameraView(context: Context) : FrameLayout(context) {
* Configures the camera capture session. This should only be called when the camera device changes.
*/
private fun configureSession() {
val startTime = System.currentTimeMillis()
Log.i(TAG, "Configuring session...")
if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
throw CameraPermissionError()
Expand Down Expand Up @@ -222,6 +241,7 @@ class CameraView(context: Context) : FrameLayout(context) {
val characteristics = cameraManager.getCameraCharacteristics(camera.id)
val isMirrored = characteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT

// Setting up Video / Frame Processor
imageReader.setOnImageAvailableListener({ reader ->
Log.d(TAG, "New Image available!")
val image = reader.acquireNextImage()
Expand All @@ -233,12 +253,15 @@ class CameraView(context: Context) : FrameLayout(context) {
}, CameraQueues.videoQueue.handler)

val frameProcessorOutput = SurfaceOutput(imageReader.surface, isMirrored)
val outputs = listOf(frameProcessorOutput)
val session = camera.createCaptureSession(SessionType.REGULAR, outputs, CameraQueues.cameraQueue)
val previewOutput = SurfaceOutput(previewView.holder.surface, isMirrored)
val outputs = listOf(frameProcessorOutput, previewOutput)
cameraSession = camera.createCaptureSession(SessionType.REGULAR, outputs, CameraQueues.cameraQueue)

// Start Video / Frame Processor
val captureRequest = camera.createCaptureRequest(CameraDevice.TEMPLATE_MANUAL)
captureRequest.addTarget(imageReader.surface)
session.setRepeatingRequest(captureRequest.build(), null, null)
captureRequest.addTarget(previewView.holder.surface)
cameraSession!!.setRepeatingRequest(captureRequest.build(), null, null)

Log.i(TAG, "Successfully configured Camera Session!")
invokeOnInitialized()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ class CameraViewModule(reactContext: ReactApplicationContext): ReactContextBaseJ

val devices = Arguments.createArray()
manager.cameraIdList.forEach { cameraId ->
val device = CameraDevice(manager, cameraId)
val device = CameraDeviceDetails(manager, cameraId)
devices.pushMap(device.toMap())
}
promise.resolve(devices)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import com.mrousavy.camera.parsers.parseVideoStabilizationMode
import kotlin.math.PI
import kotlin.math.atan

class CameraDeviceDetails(private val cameraManager: CameraManager, private val cameraDevice: CameraDevice) {
private val characteristics = cameraManager.getCameraCharacteristics(cameraDevice.id)
class CameraDeviceDetails(private val cameraManager: CameraManager, private val cameraId: String) {
private val characteristics = cameraManager.getCameraCharacteristics(cameraId)
private val hardwareLevel = characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) ?: CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY
private val capabilities = characteristics.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES) ?: IntArray(0)
private val extensions = getSupportedExtensions()
Expand All @@ -35,7 +35,7 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, private val
private val focalLengths = characteristics.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS) ?: FloatArray(0)
private val sensorSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE)!!
private val name = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) characteristics.get(CameraCharacteristics.INFO_VERSION)
else null) ?: "${parseLensFacing(lensFacing)} (${cameraDevice.id})"
else null) ?: "${parseLensFacing(lensFacing)} (${cameraId})"

// "formats" (all possible configurations for this device)
private val zoomRange = (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) characteristics.get(CameraCharacteristics.CONTROL_ZOOM_RATIO_RANGE)
Expand All @@ -56,7 +56,7 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, private val
// get extensions (HDR, Night Mode, ..)
private fun getSupportedExtensions(): List<Int> {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val extensions = cameraManager.getCameraExtensionCharacteristics(cameraDevice.id)
val extensions = cameraManager.getCameraExtensionCharacteristics(cameraId)
extensions.supportedExtensions
} else {
emptyList()
Expand Down Expand Up @@ -193,7 +193,7 @@ class CameraDeviceDetails(private val cameraManager: CameraManager, private val
// convert to React Native JS object (map)
fun toMap(): ReadableMap {
val map = Arguments.createMap()
map.putString("id", cameraDevice.id)
map.putString("id", cameraId)
map.putArray("devices", getDeviceTypes())
map.putString("position", parseLensFacing(lensFacing))
map.putString("name", name)
Expand Down

0 comments on commit 96a7cfd

Please sign in to comment.