react-native-vision-camera: š Fatal signal: SIGSEGV when using `runAsync` in Frame Processor
Whatās happening?
Trying to open the app on production mode react-native run-android --variant=release
makes app crash when opening camera view.
Iām using example app, didnāt add any new library but I removed some props in CameraPage.tsx
I donāt need (capture photo button, etcā¦).
IMPORTANT:
This crash only happens if the app is fresh installed on the device or if you clean app data and open app.
If you keep reopening app after some crashes (in my case 2 crashes) thereās no crash anymore BUT runAsync
is NOT called. Everything inside frame processor is called except runAsync
.
EDIT:
Fatal signal
crash changes, they are not always the same, I tryed reinstalling the app right now and crash code error was Fatal signal 11 (SIGSEGV), code 2, fault addr 0xc87f3f60 in tid 27643 (ionCamera.video)
Some notes in my real app:
If I use any reanimated
functions the app donāt crash but nothing inside runAsync
are called.
If I try to add any svg
from react-native-svg
in my app it crash with a similar error in this issue. Doesnāt matter if is reaniamted creating a svg or if I just import and add it to screen, both ways crash with a similar error:
import Svg from 'react-native-svg'
const AnimatedSvg = Animated.createAnimatedComponent( Svg )
// or
return (
<Camera
....
/>
<Svg>
...
</Svg>
)
Reproduceable Code
import * as React from 'react'
import { useRef } from 'react'
import { StyleSheet, View, useWindowDimensions, Text } from 'react-native'
import {
useCameraDevice,
useCameraFormat,
useFrameProcessor,
runAsync,
Camera,
useCameraPermission
} from 'react-native-vision-camera'
import Reanimated, { useSharedValue } from 'react-native-reanimated'
import { useIsFocused } from '@react-navigation/core'
import { useIsForeground } from './hooks/useIsForeground'
import { examplePlugin } from './frame-processors/ExamplePlugin'
import { exampleKotlinSwiftPlugin } from './frame-processors/ExampleKotlinSwiftPlugin'
const ReanimatedCamera = Reanimated.createAnimatedComponent( Camera )
Reanimated.addWhitelistedNativeProps( {
zoom: true
} )
export function CameraPage(): React.ReactElement {
const camera = useRef<Camera>( null )
const zoom = useSharedValue( 1 )
// check if camera page is active
const isFocussed = useIsFocused()
const isForeground = useIsForeground()
const isActive = isFocussed && isForeground
// camera device settings
let device = useCameraDevice( 'front' )
const { hasPermission, requestPermission } = useCameraPermission()
React.useEffect( () => {
if ( hasPermission ) return
requestPermission()
}, [] )
const {
width: windowWidth,
height: windowHeight
} = useWindowDimensions()
const screenAspectRatio = windowHeight / windowWidth
const format = useCameraFormat( device, [
{ fps: 30 },
{ videoAspectRatio: screenAspectRatio },
{ videoResolution: 'max' },
{ photoAspectRatio: screenAspectRatio },
{ photoResolution: 'max' },
] )
const fps = Math.min( format?.maxFps ?? 30 )
const frameProcessor = useFrameProcessor( ( frame ) => {
'worklet'
console.log( 'frame processor call' )
exampleKotlinSwiftPlugin( frame )
runAsync( frame, () => {
'worklet'
console.log( ' ' )
console.log( ' ' )
console.log( 'runAsync call' )
examplePlugin( frame )
console.log( ' ' )
console.log( ' ' )
} )
}, [] )
return ( <View style={ styles.container }>
{ hasPermission && device ? (
<Reanimated.View style={ StyleSheet.absoluteFill }>
<ReanimatedCamera
style={ StyleSheet.absoluteFill }
device={ device }
isActive={ isActive }
ref={ camera }
onStarted={ () => 'Camera started!' }
onStopped={ () => 'Camera stopped!' }
format={ format }
fps={ fps }
enableZoomGesture={ false }
exposure={ 0 }
enableFpsGraph={ true }
orientation="portrait"
photo={ true }
video={ true }
frameProcessor={ frameProcessor }
zoom={ zoom.value }
/>
</Reanimated.View>
) : <Text
style={ {
backgroundColor: 'rgb(255,0,0)',
color: 'white'
} }
>
No camera device or permission
</Text> }
</View> )
}
const styles = StyleSheet.create( {
container: {
flex: 1,
backgroundColor: 'black',
}
} )
Relevant log output
23276-23292 CameraManagerGlobal Connecting to camera service
23276-23292 VendorTagDescriptor addVendorDescriptor: vendor tag id 3854507339 added
23276-23296 OpenGLRenderer HWUI GL Pipeline
23276-23276 InputTransport Input channel constructed: fd=57
23276-23276 ViewRootImpl@98a7bca[MainActivity] setView = DecorView@a7805b1[MainActivity] TM=true MM=false
23276-23276 ViewRootImpl@98a7bca[MainActivity] dispatchAttachedToWindow
23276-23292 unknown:ReactContext initializeMessageQueueThreads() is called.
23276-23276 Surface sf_framedrop debug : 0x4f4c, game : false, logging : 0
23276-23276 ViewRootImpl@98a7bca[MainActivity] Relayout returned: old=[0,0][0,0] new=[0,0][720,1280] result=0x7 surface={valid=true 3364714496} changed=true
23276-23296 OpenGLRenderer Initialized EGL, version 1.4
23276-23296 OpenGLRenderer Swap behavior 2
23276-23296 libGLESv1 STS_GLApi : DTS, ODTC are not allowed for Package : com.mrousavy.camera.example
23276-23296 mali_winsys EGLint new_window_surface(egl_winsys_display *, void *, EGLSurface, EGLConfig, egl_winsys_surface **, egl_color_buffer_format *, EGLBoolean) returns 0x3000, [720x1280]-format:1
23276-23296 OpenGLRenderer eglCreateWindowSurface = 0xc5cdd2c0
23276-23294 CameraSession configure { ... }: Updating CameraSession Configuration... Difference(deviceChanged=false, outputsChanged=false, sidePropsChanged=false, isActiveChanged=true)
23276-23294 PersistentCameraCaptureSession --> setIsActive(false)
23276-23294 PersistentCameraCaptureSession Configure() with isActive: false, ID: 1, device: android.hardware.camera2.impl.CameraDeviceImpl@d2a5131, session: android.hardware.camera2.impl.CameraCaptureSessionImpl@ca7b016
23276-23294 PersistentCameraCaptureSession Stopping repeating request...
23276-23294 PersistentCameraCaptureSession Configure() done! isActive: false, ID: 1, device: android.hardware.camera2.impl.CameraDeviceImpl@d2a5131, session: android.hardware.camera2.impl.CameraCaptureSessionImpl@ca7b016
23276-23294 CameraSession configure { ... }: Completed CameraSession Configuration! (isActive: true, isRunning: false)
23276-23276 ViewRootImpl@98a7bca[MainActivity] Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=true 3364714496} changed=false
23276-23276 SurfaceView BG show() Surface(name=Background for - SurfaceView - com.mrousavy.camera.example/com.mrousavy.camera.example.MainActivity@b221460@0) com.mrousavy.camera.core.PreviewView{b221460 V.E...... ......ID -778,0-1498,1280}
23276-23276 Surface sf_framedrop debug : 0x4f4c, game : false, logging : 0
23276-23276 SurfaceView surfaceCreated 2 #8 com.mrousavy.camera.core.PreviewView{b221460 V.E...... ......ID -778,0-1498,1280}
23276-23276 CameraSession PreviewView Surface created! Surface(name=null)/@0xe7c8b84
23276-23276 CameraSession Setting Preview Output...
23276-23276 SurfaceView surfaceChanged (720,1280) 2 #8 com.mrousavy.camera.core.PreviewView{b221460 V.E...... ......ID -778,0-1498,1280}
23276-23276 CameraSession PreviewView Surface updated! Surface(name=null)/@0xe7c8b84 720 x 1280
23276-23294 CameraSession configure { ... }: Waiting for lock...
23276-23294 CameraSession configure { ... }: Updating CameraSession Configuration... Difference(deviceChanged=false, outputsChanged=true, sidePropsChanged=true, isActiveChanged=true)
23276-23294 CameraSession Destroying previous outputs...
23276-23294 SurfaceOutput Closing 2560x1440 PHOTO ImageReader..
23276-23294 SurfaceOutput Closing 1920x1080 Video Pipeline..
23276-23294 CameraSession Creating outputs for Camera #1...
23276-23294 CameraManager getCameraCharacteristics : cameraId = 1
23276-23294 CameraSession Adding 2560x1440 Photo Output in JPEG...
23276-23294 Surface sf_framedrop debug : 0x4f4c, game : false, logging : 0
23276-23294 CameraSession Adding 1920x1080 Video Output in YUV_420_888...
23276-23294 VideoPipeline Initializing 1920 x 1080 Video Pipeline (format: YUV)
23276-23294 Surface sf_framedrop debug : 0x4f4c, game : false, logging : 0
23276-23294 VideoPipeline Using ImageReader round-trip (format: #35)
23276-23294 VideoPipeline Creating ImageReader with default usage flags...
23276-23294 Surface sf_framedrop debug : 0x4f4c, game : false, logging : 0
23276-23294 VideoPipeline Creating ImageWriter with default format...
23276-23294 Surface sf_framedrop debug : 0x4f4c, game : false, logging : 0
23276-23294 CameraSession Adding 1280x720 Preview Output...
23276-23276 ViewRootImpl@98a7bca[MainActivity] Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=true 3364714496} changed=false
23276-23276 VisionCameraProxy Finding view 3...
23276-23276 VisionCameraProxy Found view 3!
23276-23276 ViewRootImpl@98a7bca[MainActivity] Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=true 3364714496} changed=false
23276-23276 PreviewView Input Orientation changed: LANDSCAPE_LEFT -> LANDSCAPE_RIGHT
23276-23276 SurfaceHolder Resizing SurfaceHolder to 1280 x 720...
23276-23276 SurfaceView setPackageUsesOwnResolution() (Java SurfaceView) for com.mrousavy.camera.example: 1280x720 (true)
23276-23276 SurfaceView BG show() Surface(name=Background for - SurfaceView - com.mrousavy.camera.example/com.mrousavy.camera.example.MainActivity@b221460@0) com.mrousavy.camera.core.PreviewView{b221460 V.E...... ......I. -778,0-1498,1280}
23276-23276 SurfaceView surfaceChanged (1280,720) 3 #8 com.mrousavy.camera.core.PreviewView{b221460 V.E...... ......I. -778,0-1498,1280}
23276-23276 PreviewView Surface Size changed: 720x1280 -> 1280x720
23276-23276 CameraSession PreviewView Surface updated! Surface(name=null)/@0xe7c8b84 1280 x 720
23276-23276 SurfaceHolder Resized SurfaceHolder to 1280 x 720!
23276-23276 PreviewView PreviewView is 720x1232, rendering 720x1280 content (LANDSCAPE_RIGHT). Resizing to: 720x1280 (COVER)
23276-23276 ViewRootImpl@98a7bca[MainActivity] Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=true 3364714496} changed=false
23276-23294 PersistentCameraCaptureSession --> setOutputs([PHOTO (2560x1440 in JPEG), VIDEO (1920x1080 in YUV), PREVIEW (1280 x 720)])
23276-23294 CameraSession Successfully configured Session with 3 outputs for Camera #1!
23276-23294 CameraSession Updating Video Outputs...
23276-23294 VideoPipeline Removing RecordingSession Output...
23276-23294 PersistentCameraCaptureSession --> setRepeatingRequest(...)
23276-23294 PersistentCameraCaptureSession --> setIsActive(true)
23276-23294 PersistentCameraCaptureSession Configure() with isActive: true, ID: 1, device: android.hardware.camera2.impl.CameraDeviceImpl@d2a5131, session: null
23276-23294 PersistentCameraCaptureSession Creating new session...
23276-23294 CameraManager getCameraCharacteristics : cameraId = 1
23276-23294 CreateCaptureSession Camera #1: Creating Capture Session #2... (Hardware Level: 0 | Outputs: [PHOTO (2560x1440 in JPEG), VIDEO (1920x1080 in YUV), PREVIEW (1280 x 720)])
23276-23294 CreateCaptureSession Using legacy API (<28)
23276-23276 ViewRootImpl@98a7bca[MainActivity] Relayout returned: old=[0,0][720,1280] new=[0,0][720,1280] result=0x1 surface={valid=true 3364714496} changed=false
23276-23295 CreateCaptureSession Camera #1: CameraCaptureSession #1 has been closed.
23276-23295 PersistentCameraCaptureSession Session android.hardware.camera2.impl.CameraCaptureSessionImpl@ca7b016 closed!
23276-23295 CreateCaptureSession Camera #1: Successfully created CameraCaptureSession #2!
23276-23294 PersistentCameraCaptureSession Updating repeating request...
23276-23294 CameraManager getCameraCharacteristics : cameraId = 1
23276-23294 PersistentCameraCaptureSession Configure() done! isActive: true, ID: 1, device: android.hardware.camera2.impl.CameraDeviceImpl@d2a5131, session: android.hardware.camera2.impl.CameraCaptureSessionImpl@5a7c71c
23276-23294 CameraSession configure { ... }: Completed CameraSession Configuration! (isActive: true, isRunning: true)
23276-23294 CameraView invokeOnStarted()
23276-23295 VideoPipeline ImageReader::onImageAvailable!
23276-23297 ReactNativeJS frame processor call
23276-23295 ExampleKotlinPlugin 1920 x 1080 Image with format #35. Logging 5 parameters:
23276-23295 ExampleKotlinPlugin -> 42.0 (java.lang.Double)
23276-23295 ExampleKotlinPlugin -> true (java.lang.Boolean)
23276-23295 ExampleKotlinPlugin -> {test=0.0, second=test} (java.util.HashMap)
23276-23295 ExampleKotlinPlugin -> hello! (java.lang.String)
23276-23295 ExampleKotlinPlugin -> [another test, 5.0] (java.util.ArrayList)
23276-23295 libc Fatal signal 11 (SIGSEGV), code 1, fault addr 0x18 in tid 23295 (ionCamera.video)
Camera Device
{
"hardwareLevel": "limited",
"minExposure": -20,
"neutralZoom": 1,
"minZoom": 1,
"supportsFocus": false,
"formats": [],
"supportsLowLightBoost": false,
"hasTorch": false,
"supportsRawCapture": false,
"minFocusDistance": 0,
"sensorOrientation": "landscape-right",
"maxZoom": 4,
"physicalDevices": [
"wide-angle-camera"
],
"isMultiCam": false,
"position": "front",
"id": "1",
"hasFlash": false,
"maxExposure": 20,
"name": "FRONT (1)"
}
Device
Galaxy J5 Android 8
VisionCamera Version
3.9.0
Can you reproduce this issue in the VisionCamera Example app?
Yes, I can reproduce the same issue in the Example app here
Additional information
- I am using Expo
- I have enabled Frame Processors (react-native-worklets-core)
- I have read the Troubleshooting Guide
- I agree to follow this projectās Code of Conduct
- I searched for similar issues in this repository and found none.
About this issue
- Original URL
- State: closed
- Created 4 months ago
- Comments: 19 (16 by maintainers)
@robertyulisman I had the same problem. If you are using reanimated in your project, you need to add
processNestedWorklets: true
in your babel configuration.I think this has been fixed in react-native-worklets-core 1.x.x.! š
@chrfalch it is - thatās for when you want to animate
zoom
orexposure
using Reanimated š@mrousavy I made a little progress, at least my app is not crashing anymore⦠I created a custom
runAsync
method inside my function but usinguseWorklet
anduseSharedValue
hookd from worklets core. With this change my app stop crashing and my customrunAsync
is called everytime.This is my code at this moment.
Maybe thereās a problem with
Worklets.createContext
method because this is the only method that (I think) is not used in this workaround.