livekit / client-sdk-android

LiveKit SDK for Android
https://docs.livekit.io
Apache License 2.0
160 stars 63 forks source link

Livekit 2.0 Native crash Fatal signal 11 (SIGSEGV) #415

Open SimovicIvan opened 2 months ago

SimovicIvan commented 2 months ago

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)

davidliu commented 2 months ago

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)?

SimovicIvan commented 2 months ago

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

davidliu commented 2 months ago

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

davidliu commented 2 months ago

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

SimovicIvan commented 2 months ago

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 commented 2 months ago

private val peerConnectionFactory by lazy { buildPeerConnectionFactory() }

val localVideoSource: VideoSource = peerConnectionFactory.createVideoSource(false)

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

davidliu commented 2 months ago

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.

SimovicIvan commented 2 months ago

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 commented 2 months ago

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

davidliu commented 2 months ago

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

SimovicIvan commented 2 months ago

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?

davidliu commented 2 months ago

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.

SimovicIvan commented 2 months ago

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?

davidliu commented 2 months ago

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.

SimovicIvan commented 2 months ago

I understand, thank you