Search code examples
iosobjective-cios7ios8webrtc

RTCVideoCapturer capturerWithDeviceName:(NSString*) becomes very slow after subsequent calls


I'm building a webrtc based voip app. I call the following code before each call I make:

NSMutableArray *m = [[NSMutableArray alloc] init];
NSMutableArray *o = [[NSMutableArray alloc] init];

//[m addObject:[[RTCPair alloc] initWithKey:@"maxFrameRate" value:@"30"]];
//[m addObject:[[RTCPair alloc] initWithKey:@"maxFrameRate" value:@"24"]];
//[m addObject:[[RTCPair alloc] initWithKey:@"maxHeight" value:@"180"]];
NSString* cameraID = nil;
for (AVCaptureDevice *captureDevice in [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]) {
    if (captureDevice.position == AVCaptureDevicePositionFront) {
        cameraID = [captureDevice localizedName];
        break;
    }
}

capturer = [RTCVideoCapturer capturerWithDeviceName:cameraID]; //why so slow :(

RTCMediaConstraints *videoConstraints = [[RTCMediaConstraints alloc] initWithMandatoryConstraints:m optionalConstraints:o];
videoSource = [peerConnectionFactory videoSourceWithCapturer:capturer constraints:videoConstraints];

localVideoTrack = [peerConnectionFactory videoTrackWithID:@"ARDAMSv0" source:videoSource];

lms = [peerConnectionFactory mediaStreamWithLabel:@"ARDAMS"];

if (localVideoTrack) [lms addVideoTrack:localVideoTrack];
[lms addAudioTrack:[peerConnectionFactory audioTrackWithID:@"ARDAMSa0"]];

[peerConnection addStream:lms constraints:[[RTCMediaConstraints alloc] init]];

dispatch_async(dispatch_get_main_queue(), ^{
    [callViewController setLocalVideo];
});

After the call ends I reset all these variables (mostly just set them to nil). I've seen this approach work very well, but recently a bug has sneaked in there. Every subsequent call increases the execution time of this line

capturer = [RTCVideoCapturer capturerWithDeviceName:cameraID];

I tried setting the capturer just once at the start of the app, but then the app crashes on

videoSource = [peerConnectionFactory videoSourceWithCapturer:capturer constraints:videoConstraints];  

even though all parameters are initialized (I checked using the debugger).

Does anybody have an idea as to what this could be? I'm sure this same code worked perfectly before. I did not update the webrtc library, xcode or iOS.


Solution

  • You're on the right track!

    What you need to do instead is create not only the capturer in the beginning, but videosource, localvideotrack, localaudiostream, and RTCMediaStream object. Once localvideotrack and localaudiostream are created, add em to a RTCMediaStream object that's available class wide. Then, when you want to start a conversation, all you'll need to do is reuse the RTCMediaStream object you've created in the beginning by adding it to a new peerconnection! Just be sure to kill the peerconnection object when conversation is done. Nothing needs to be done at that time to RTCMediaStream object.

    The reason why things are getting so slow is that each time you create a new capturer, it doesn't appropriately kill off any previous instances that might already be about.