client-sdk-android icon indicating copy to clipboard operation
client-sdk-android copied to clipboard

Livekit 2.0 Native crash Fatal signal 11 (SIGSEGV)

Open SimovicIvan opened this issue 1 year ago • 15 comments

I am getting a Fatal signal 11 (SIGSEGV). I think it started since upgrading to 2.0 of Livekit. the issue seems to be related to NetworkMonitor. I have disabledNetworkMonitor in options.

Reproduced both on Samsung A52 and Pixel 6

Seems to happen only when I end a call, but not always reproducable

private fun buildPeerConnectionFactory(): PeerConnectionFactory {
    return PeerConnectionFactory
        .builder()
        .setVideoDecoderFactory(DefaultVideoDecoderFactory(rootEglBase.eglBaseContext))
        .setVideoEncoderFactory(
            DefaultVideoEncoderFactory(
                rootEglBase.eglBaseContext,
                true,
                true
            )
        )
        .setOptions(PeerConnectionFactory.Options().apply {
            disableNetworkMonitor = true
        })
        .createPeerConnectionFactory()
}

2024-04-18 12:28:11.189 12226-12461 libc com.bambuser.onetoone.dev A Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xffffffc2000008 in tid 12461 (ConnectivityThr), pid 12226 (er.onetoone.dev) 2024-04-18 12:28:12.061 13151-13151 DEBUG pid-13151 A Cmdline: com.bambuser.onetoone.dev 2024-04-18 12:28:12.061 13151-13151 DEBUG pid-13151 A pid: 12226, tid: 12461, name: ConnectivityThr >>> com.bambuser.onetoone.dev <<< 2024-04-18 12:28:12.062 13151-13151 DEBUG pid-13151 A #00 pc 0000000000390c44 /data/app/~~lFNIYzULyDLD2VfRjyfeiA==/com.bambuser.onetoone.dev-QgpzWBLO_PUuaPsu0lnOkw==/base.apk!libjingle_peerconnection_so.so (offset 0x1603000) (BuildId: 6ca9af36c844c199) 2024-04-18 12:28:12.062 13151-13151 DEBUG pid-13151 A #01 pc 000000000041b5c8 /data/app/~~lFNIYzULyDLD2VfRjyfeiA==/com.bambuser.onetoone.dev-QgpzWBLO_PUuaPsu0lnOkw==/base.apk!libjingle_peerconnection_so.so (offset 0x1603000) (BuildId: 6ca9af36c844c199) 2024-04-18 12:28:12.062 13151-13151 DEBUG pid-13151 A #02 pc 000000000041b4b0 /data/app/~~lFNIYzULyDLD2VfRjyfeiA==/com.bambuser.onetoone.dev-QgpzWBLO_PUuaPsu0lnOkw==/base.apk!libjingle_peerconnection_so.so (offset 0x1603000) (Java_livekit_org_webrtc_NetworkMonitor_nativeNotifyOfNetworkConnect+32) (BuildId: 6ca9af36c844c199) 2024-04-18 12:28:12.062 13151-13151 DEBUG pid-13151 A #08 pc 0000000000061cc4 [anon:dalvik-classes33.dex extracted in memory from /data/app/~~lFNIYzULyDLD2VfRjyfeiA==/com.bambuser.onetoone.dev-QgpzWBLO_PUuaPsu0lnOkw==/base.apk!classes33.dex] (livekit.org.webrtc.NetworkMonitor.notifyObserversOfNetworkConnect+0) 2024-04-18 12:28:12.062 13151-13151 DEBUG pid-13151 A #13 pc 0000000000061ab4 [anon:dalvik-classes33.dex extracted in memory from /data/app/~~lFNIYzULyDLD2VfRjyfeiA==/com.bambuser.onetoone.dev-QgpzWBLO_PUuaPsu0lnOkw==/base.apk!classes33.dex] (livekit.org.webrtc.NetworkMonitor.-$$Nest$mnotifyObserversOfNetworkConnect+0) 2024-04-18 12:28:12.063 13151-13151 DEBUG pid-13151 A #18 pc 0000000000060350 [anon:dalvik-classes33.dex extracted in memory from /data/app/~~lFNIYzULyDLD2VfRjyfeiA==/com.bambuser.onetoone.dev-QgpzWBLO_PUuaPsu0lnOkw==/base.apk!classes33.dex] (livekit.org.webrtc.NetworkMonitor$2.onNetworkConnect+0) 2024-04-18 12:28:12.063 13151-13151 DEBUG pid-13151 A #23 pc 0000000000060fb8 [anon:dalvik-classes33.dex extracted in memory from /data/app/~~lFNIYzULyDLD2VfRjyfeiA==/com.bambuser.onetoone.dev-QgpzWBLO_PUuaPsu0lnOkw==/base.apk!classes33.dex] (livekit.org.webrtc.NetworkMonitorAutoDetect$SimpleNetworkCallback.onNetworkChanged+0) 2024-04-18 12:28:12.063 13151-13151 DEBUG pid-13151 A #28 pc 0000000000060dac [anon:dalvik-classes33.dex extracted in memory from /data/app/~~lFNIYzULyDLD2VfRjyfeiA==/com.bambuser.onetoone.dev-QgpzWBLO_PUuaPsu0lnOkw==/base.apk!classes33.dex] (livekit.org.webrtc.NetworkMonitorAutoDetect$SimpleNetworkCallback.onCapabilitiesChanged+0)

SimovicIvan avatar Apr 19 '24 07:04 SimovicIvan

Which version of LiveKit specifically is being used here? 2.0.0? Can you also check which version of io.github.webrtc-sdk is being used (run gradle dependencies)?

davidliu avatar Apr 19 '24 07:04 davidliu

implementation "io.livekit:livekit-android:2.0.0" io.github.webrtc-sdk:android-prefixed:114.5735.07@aar

SimovicIvan avatar Apr 19 '24 07:04 SimovicIvan

How often would you say the error occurs, percentage wise?

davidliu avatar Apr 19 '24 08:04 davidliu

Wait, you wrote a buildPeerConnectionFactory method, but how does that PeerConnectionFactory get injected into our LiveKit SDK?

davidliu avatar Apr 19 '24 08:04 davidliu

On my Pixel 6 android 14, it is happening often. I did about 6 test calls, it crashed twice. The crash is a bit confusing because it happens a few seconds after I end a call. so once it crashed after a call, the other time it crashed right after I started a new one, but I am assuming it is because I ended a call and started a new one very fast

SimovicIvan avatar Apr 19 '24 08:04 SimovicIvan

private val peerConnectionFactory by lazy { buildPeerConnectionFactory() }

val localVideoSource: VideoSource = peerConnectionFactory.createVideoSource(false)

So I use that to create video sources. sorry about the confusion

SimovicIvan avatar Apr 19 '24 08:04 SimovicIvan

Is there a reason why you're not going through LocalParticipant.createVideoTrack()? It sounds like the association between two separate PeerConnectionFactories are causing the issue.

davidliu avatar Apr 19 '24 08:04 davidliu

I am sending video with custom VideoCapturer

private suspend fun startLocalVideo(
        context: Context
    ) {
        val localVideoSource = peerConnectionFactory.createVideoSource(false)
        val surfaceTextureHelper =
            SurfaceTextureHelper.create(Thread.currentThread().name, rootEglBase.eglBaseContext)
        videoCapturer = CustomVideoCapturer { ImageRepo.getInstance().getSegmentedImageForWebRTC() }
        videoCapturer?.let { videoCapturer ->
            (videoCapturer as VideoCapturer).initialize(
                surfaceTextureHelper,
                context,
                localVideoSource.capturerObserver
            )
            localVideoTrack =
                room?.localParticipant?.createVideoTrack(
                    RTCClient.LOCAL_TRACK_ID,
                    videoCapturer
                )
            localVideoTrack?.let { track ->
                room?.localParticipant?.publishVideoTrack(
                    track
                )
            }

            videoCapturer.startCapture(1280, 960, 24)
        }
    }

SimovicIvan avatar Apr 19 '24 08:04 SimovicIvan

Is there a way I can get the capturerObserver from Livekit instead? or will i need to revert to 1.0 Livekit for now?

SimovicIvan avatar Apr 19 '24 09:04 SimovicIvan

createVideoTrack has an overload to pass in your own custom video capturers. You should try that.

davidliu avatar Apr 19 '24 09:04 davidliu

I am doing that :). the problem is my custom video capturer need access to capturerObserver to send frames. and I get that from PeerConnectionFactory. its all in the code above.


val localVideoSource = peerConnectionFactory.createVideoSource(false)
(videoCapturer as VideoCapturer).initialize(
                surfaceTextureHelper,
                context,
                localVideoSource.capturerObserver
            )

    @Synchronized
    override fun initialize(
        surfaceTextureHelper: SurfaceTextureHelper,
        context: Context,
        capturerObserver: CapturerObserver
    ) {
        checkNotDisposed()

        this.context = context
        this.capturerObserver = capturerObserver
        this.surfaceTextureHelper = surfaceTextureHelper
    }

// and later
 capturerObserver?.onFrameCaptured(videoFrame)

So how am I supposed to send a frame in my custom video capturer without creating a videoSource to get the capturer observer?

SimovicIvan avatar Apr 19 '24 09:04 SimovicIvan

LiveKit handles creating the video source and calling VideoCapturer.initialize with the appropriate capturerObserver from our internal PeerConnectionFactory. You don't need to call it yourself.

davidliu avatar Apr 19 '24 10:04 davidliu

Hmm, I am a bit confused as to what my CustomVideoCapturer is supposed to do then. I have a function on it called trySendToServer that I call with a delay of 42 millis. there I fetch a bitmap from my ImageRepository, I do some GLES20/yuvConverter stuff and the part that I understand as crucial is capturerObserver?.onFrameCaptured(videoFrame)

Do you maybe have an example of how I can send my own frames with my custom video capturer?

SimovicIvan avatar Apr 19 '24 10:04 SimovicIvan

The point is you can pass in your CustomVideoCapturer to createVideoTrack without calling initialize.

We will call initialize for you and supply you with the capture observer to use.

Basically, just remove your own creation of the video source and calling of initialize, as well as not creating your own PeerConnectionFactory.

davidliu avatar Apr 19 '24 10:04 davidliu

I understand, thank you

SimovicIvan avatar Apr 19 '24 11:04 SimovicIvan