Kevin
Kevin

Reputation: 2730

How to properly close a peerconnection

I have a voip app using webrtc. I recently redesigned a lot of the code to make the signaling a lot more consistent. The only big problem I have now is that when I close the peerconnection the app crashes on some internal opengl code. I use this code to close the connection:

[peerConnection removeStream:lms];
[peerConnection close];
peerConnection = nil;

The code I used previously deleted pretty much anything related to webrtc, but I found out that a lot of object can be reused and only have to be inited at the start of the app. What do I have to do to make sure the app doesn't crash everything I end a call?

Edit:
I moved the above code to a background thread and it no longer crashes. But now, after a few calls, my log gets spammed with the following line (about 3 or 4 times per second):

Failed to make complete framebuffer object 8cdd

This is the last part of the log history when this happens:

2014-10-14 11:53:45.045 BeeldZorgApp[4912:3903] peerConnection iceConnectionChanged:(RTCICEConnectionState)2
2014-10-14 11:53:45.046 BeeldZorgApp[4912:3903] peerConnection iceConnectionChanged:(RTCICEConnectionState)3
2014-10-14 11:53:50.732 BeeldZorgApp[4912:3903] peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)<RTCPeerConnection: 0x157c9640>
2014-10-14 11:53:50.742 BeeldZorgApp[4912:3903] peerConnection iceConnectionChanged:(RTCICEConnectionState)6
2014-10-14 11:53:50.743 BeeldZorgApp[4912:3903] peerConnection signalingStateChanged:(RTCSignalingState)5
2014-10-14 11:53:59.955 BeeldZorgApp[4912:3903] peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)<RTCPeerConnection: 0x19a62e30>
2014-10-14 11:53:59.980 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.028 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.091 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.119 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.152 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.185 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.218 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.252 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.284 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.319 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.352 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.384 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.417 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.451 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.486 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.518 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd
2014-10-14 11:54:00.552 BeeldZorgApp[4912:60b] Failed to make complete framebuffer object 8cdd

Upvotes: 4

Views: 4149

Answers (3)

Jaswant Singh
Jaswant Singh

Reputation: 10709

On my code I did something like this. I was facing an issue where the microphone yellow dot was visible even after ending the call. This code fixed everything:

if let capturer = self.videoCapturer as? RTCCameraVideoCapturer{
        capturer.stopCapture()
    }
    
    self.screenCapturer = nil
    
    if(self.peerConnection != nil) {
        for mStream in self.peerConnection!.localStreams {
            peerConnection?.remove(mStream)
        }
    }
    
    for participant in remoteParticipants {
        participant.peerConnection?.close()
    }
    
    self.peerConnection?.close()
    self.webSocketListener?.endConnection()
    
    self.delegate = nil
    self.remoteParticipants.removeAll()
    self.webSocket = nil
    localVideoTrack = nil
    remoteVideoTracks.removeAll()
    localDataChannel = nil
    remoteDataChannel = nil
    self.peerConnection = nil
}

Upvotes: 0

Sercan &#246;zen
Sercan &#246;zen

Reputation: 161

If you set peerConnection as nil, you'll get an error about this in view controller when you try call someone again (in second time). I think it sets as nil of peerConnection value of PeerConnectionFactory static class. So when you call peerConnectionWithConfiguration method of the factory, you'll get nil value. My suggestion is that the close() method is enough (with swift):

self.remoteVideoView.removeFromSuperview()
self.localVideoView.removeFromSuperview()
self.peerConnection.removeStream(self.mediaStream)
self.peerConnection.close()

PS: I'm using lastest version of webrtc library

Upvotes: 2

Kevin
Kevin

Reputation: 2730

It turns out the RTCEAGLVideoViews need to be removed from their superview before navigating away from the view controller. I now use the following code to clean up:

//these are both RTCEAGLVideoViews
[remoteVideoView removeFromSuperview];
[localVideoView removeFromSuperview];
[peerConnection removeStream:lms];
[peerConnection close];
peerConnection = nil;

Upvotes: 9

Related Questions