Random native crash in Webrtc peerconnection while disconnecting

Viewed 2096

I am using webrtc for making video calls. My use case is such that I connect to users in queue one after another. So connect to user1, end connection with user1 then connect to user2 and so on.

At times while disconnecting from user and disposing off the peerconnection I come across this native crash

E/rtc(6882): #\
05-26 17:30:44.374: E/rtc(6882): # Fatal error in ../../webrtc/sdk/android/src/jni/peerconnection_jni.cc, line 1074\
05-26 17:30:44.374: E/rtc(6882): # last system error: 17\
05-26 17:30:44.374: E/rtc(6882): # Check failed: 0 == (reinterpret_cast<PeerConnectionInterface*>(j_p))->Release() (0 vs. 1)\
05-26 17:30:44.374: E/rtc(6882): # Unexpected refcount.\
05-26 17:30:44.374: E/rtc(6882): #\

This crash happens very randomly and from what I can guess is that something is keeping a reference to peerconnection while disposing.

Here is my code for disposing of peer connection, I am reusing local media stream for new connections.

videoCapturer.stopCapture();
if (peerConnection != null) {
        peerConnection.close();
        peerConnection.removeStream(localMediaStream);
        peerConnection.dispose();
        peerConnection = null;
}

is the above snippet correct way to dispose of peer connection? What could be the reason for randomness for this crash? Is the leaked reference inside Java layer or native layer?

2 Answers

For those troubleshooting similar issues, I was implementing a multiple peerConnection approach in Android where peers would be closed when disconnecting.

It seems that when you call peerConnection.close() from a synchronous thread, the native call never seems to complete. So if you try to create a new peer connection peerConnectionFactory.createPeerConnection(...);, it will hang on the nativeCreatePeerConnection call. Based upon other posts, it seems that the original close call is waiting for other resources to close, but just hangs given it was on a main thread.

The solution Simply call the peerConnection.close() call from an asynchronous executor thread or something similar.

ExecutorService executor = Executors.newSingleThreadExecutor();
executor .execute(() -> {
     this.pc.close();
});

This seems to allow the native connection to close properly and will allow you to continue to create peerConnections from that same factory

Related