perf: Use existing cameraQueue instead of yet another Thread (#2459)
				
					
				
			* perf: Use existing `cameraQueue` instead of yet another Thread * fix: Use `coroutineScope` to avoid wrong use of isActive * fix: Do the same for `CameraSession` * Lint
This commit is contained in:
		@@ -23,7 +23,6 @@ import com.mrousavy.camera.types.PixelFormat
 | 
				
			|||||||
import com.mrousavy.camera.types.ResizeMode
 | 
					import com.mrousavy.camera.types.ResizeMode
 | 
				
			||||||
import com.mrousavy.camera.types.Torch
 | 
					import com.mrousavy.camera.types.Torch
 | 
				
			||||||
import com.mrousavy.camera.types.VideoStabilizationMode
 | 
					import com.mrousavy.camera.types.VideoStabilizationMode
 | 
				
			||||||
import kotlin.coroutines.CoroutineContext
 | 
					 | 
				
			||||||
import kotlinx.coroutines.CoroutineScope
 | 
					import kotlinx.coroutines.CoroutineScope
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -39,7 +38,6 @@ import kotlinx.coroutines.launch
 | 
				
			|||||||
@SuppressLint("ClickableViewAccessibility", "ViewConstructor", "MissingPermission")
 | 
					@SuppressLint("ClickableViewAccessibility", "ViewConstructor", "MissingPermission")
 | 
				
			||||||
class CameraView(context: Context) :
 | 
					class CameraView(context: Context) :
 | 
				
			||||||
  FrameLayout(context),
 | 
					  FrameLayout(context),
 | 
				
			||||||
  CoroutineScope,
 | 
					 | 
				
			||||||
  CameraSession.Callback {
 | 
					  CameraSession.Callback {
 | 
				
			||||||
  companion object {
 | 
					  companion object {
 | 
				
			||||||
    const val TAG = "CameraView"
 | 
					    const val TAG = "CameraView"
 | 
				
			||||||
@@ -98,7 +96,7 @@ class CameraView(context: Context) :
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  internal var frameProcessor: FrameProcessor? = null
 | 
					  internal var frameProcessor: FrameProcessor? = null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override val coroutineContext: CoroutineContext = CameraQueues.cameraQueue.coroutineDispatcher
 | 
					  private val coroutineScope = CoroutineScope(CameraQueues.cameraQueue.coroutineDispatcher)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  init {
 | 
					  init {
 | 
				
			||||||
    this.installHierarchyFitter()
 | 
					    this.installHierarchyFitter()
 | 
				
			||||||
@@ -131,7 +129,7 @@ class CameraView(context: Context) :
 | 
				
			|||||||
    val now = System.currentTimeMillis()
 | 
					    val now = System.currentTimeMillis()
 | 
				
			||||||
    currentConfigureCall = now
 | 
					    currentConfigureCall = now
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    launch {
 | 
					    coroutineScope.launch {
 | 
				
			||||||
      cameraSession.configure { config ->
 | 
					      cameraSession.configure { config ->
 | 
				
			||||||
        if (currentConfigureCall != now) {
 | 
					        if (currentConfigureCall != now) {
 | 
				
			||||||
          // configure waits for a lock, and if a new call to update() happens in the meantime we can drop this one.
 | 
					          // configure waits for a lock, and if a new call to update() happens in the meantime we can drop this one.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ import com.facebook.react.modules.core.PermissionAwareActivity
 | 
				
			|||||||
import com.facebook.react.modules.core.PermissionListener
 | 
					import com.facebook.react.modules.core.PermissionListener
 | 
				
			||||||
import com.facebook.react.uimanager.UIManagerHelper
 | 
					import com.facebook.react.uimanager.UIManagerHelper
 | 
				
			||||||
import com.mrousavy.camera.core.CameraError
 | 
					import com.mrousavy.camera.core.CameraError
 | 
				
			||||||
 | 
					import com.mrousavy.camera.core.CameraQueues
 | 
				
			||||||
import com.mrousavy.camera.core.ViewNotFoundError
 | 
					import com.mrousavy.camera.core.ViewNotFoundError
 | 
				
			||||||
import com.mrousavy.camera.frameprocessor.VisionCameraInstaller
 | 
					import com.mrousavy.camera.frameprocessor.VisionCameraInstaller
 | 
				
			||||||
import com.mrousavy.camera.frameprocessor.VisionCameraProxy
 | 
					import com.mrousavy.camera.frameprocessor.VisionCameraProxy
 | 
				
			||||||
@@ -39,7 +40,7 @@ class CameraViewModule(reactContext: ReactApplicationContext) : ReactContextBase
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private val coroutineScope = CoroutineScope(Dispatchers.Default) // TODO: or Dispatchers.Main?
 | 
					  private val coroutineScope = CoroutineScope(CameraQueues.cameraQueue.coroutineDispatcher)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override fun invalidate() {
 | 
					  override fun invalidate() {
 | 
				
			||||||
    super.invalidate()
 | 
					    super.invalidate()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,7 +49,6 @@ import com.mrousavy.camera.utils.ImageFormatUtils
 | 
				
			|||||||
import java.io.Closeable
 | 
					import java.io.Closeable
 | 
				
			||||||
import java.lang.IllegalStateException
 | 
					import java.lang.IllegalStateException
 | 
				
			||||||
import java.util.concurrent.CancellationException
 | 
					import java.util.concurrent.CancellationException
 | 
				
			||||||
import kotlin.coroutines.CoroutineContext
 | 
					 | 
				
			||||||
import kotlinx.coroutines.CoroutineScope
 | 
					import kotlinx.coroutines.CoroutineScope
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
import kotlinx.coroutines.runBlocking
 | 
					import kotlinx.coroutines.runBlocking
 | 
				
			||||||
@@ -58,8 +57,7 @@ import kotlinx.coroutines.sync.withLock
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class CameraSession(private val context: Context, private val cameraManager: CameraManager, private val callback: Callback) :
 | 
					class CameraSession(private val context: Context, private val cameraManager: CameraManager, private val callback: Callback) :
 | 
				
			||||||
  CameraManager.AvailabilityCallback(),
 | 
					  CameraManager.AvailabilityCallback(),
 | 
				
			||||||
  Closeable,
 | 
					  Closeable {
 | 
				
			||||||
  CoroutineScope {
 | 
					 | 
				
			||||||
  companion object {
 | 
					  companion object {
 | 
				
			||||||
    private const val TAG = "CameraSession"
 | 
					    private const val TAG = "CameraSession"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -95,8 +93,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
 | 
				
			|||||||
      field = value
 | 
					      field = value
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  override val coroutineContext: CoroutineContext
 | 
					  private val coroutineScope = CoroutineScope(CameraQueues.cameraQueue.coroutineDispatcher)
 | 
				
			||||||
    get() = CameraQueues.cameraQueue.coroutineDispatcher
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Video Outputs
 | 
					  // Video Outputs
 | 
				
			||||||
  private var recording: RecordingSession? = null
 | 
					  private var recording: RecordingSession? = null
 | 
				
			||||||
@@ -139,7 +136,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
 | 
				
			|||||||
    super.onCameraAvailable(cameraId)
 | 
					    super.onCameraAvailable(cameraId)
 | 
				
			||||||
    if (this.configuration?.cameraId == cameraId && cameraDevice == null && configuration?.isActive == true) {
 | 
					    if (this.configuration?.cameraId == cameraId && cameraDevice == null && configuration?.isActive == true) {
 | 
				
			||||||
      Log.i(TAG, "Camera #$cameraId is now available again, trying to re-open it now...")
 | 
					      Log.i(TAG, "Camera #$cameraId is now available again, trying to re-open it now...")
 | 
				
			||||||
      launch {
 | 
					      coroutineScope.launch {
 | 
				
			||||||
        configure {
 | 
					        configure {
 | 
				
			||||||
          // re-open CameraDevice if needed
 | 
					          // re-open CameraDevice if needed
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -252,7 +249,7 @@ class CameraSession(private val context: Context, private val cameraManager: Cam
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  private fun createPreviewOutput(surface: Surface) {
 | 
					  private fun createPreviewOutput(surface: Surface) {
 | 
				
			||||||
    Log.i(TAG, "Setting Preview Output...")
 | 
					    Log.i(TAG, "Setting Preview Output...")
 | 
				
			||||||
    launch {
 | 
					    coroutineScope.launch {
 | 
				
			||||||
      configure { config ->
 | 
					      configure { config ->
 | 
				
			||||||
        config.preview = CameraConfiguration.Output.Enabled.create(CameraConfiguration.Preview(surface))
 | 
					        config.preview = CameraConfiguration.Output.Enabled.create(CameraConfiguration.Preview(surface))
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user