Intel® Collaboration Suite for WebRTC
Community support and discussions on the Intel® Collaboration Suite for WebRTC (Intel® CS for WebRTC).
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
For the latest information on Intel’s response to the Log4j/Log4Shell vulnerability, please see Intel-SA-00646
1136 Discussions

Android CS 3.4 leaks VideoSource if LocalCameraStreamParameters.hasVideo() == false

lamian
Beginner
107 Views

How to reproduct:

1. prepare a test app which supports both video calls and audio calls.

2. perform video call, everything works normally.

3. preform audio call, everything works normally.

4. perform video call again, camera has no output.

 

After investigation of CS source code, the problem is inside PCFactory.createMediaStream(LocalCameraStreamParameters parameters)

the original code:

static synchronized MediaStream createMediaStream(LocalCameraStreamParameters parameters) throws WoogeenStreamException {
    initHandlerIfNeeded();
    VideoSource videoSource = mediaSourceFactory.getVideoSource(parameters);
    countDownLatch = new CountDownLatch(1);
    mediaStream = null;
    message = factoryHandler.obtainMessage();
    message.what = 5;
    Object[] objects = new Object[]{videoSource, Boolean.valueOf(parameters.hasVideo()), Boolean.valueOf(parameters.hasAudio())};
    message.obj = objects;
    message.sendToTarget();

    try {
        countDownLatch.await();
    } catch (InterruptedException var4) {
        var4.printStackTrace();
    }

    return mediaStream;
}

this function will get video source unconditionally, even if parameters.hasVideo() == false

However, when local stream is closing:

static void onLocalStreamClosed(LocalStream stream) {
    if(stream instanceof LocalCameraStream && stream.hasVideo()) {
        mediaSourceFactory.releaseCameraVideoSourceRef();
    }

    if(stream instanceof LocalScreenStream && stream.hasVideo()) {
        mediaSourceFactory.releaseScreenVideoSourceRef();
    }

    if(stream.hasAudio()) {
        mediaSourceFactory.releaseAudioSourceRef();
    }
}

video source will be released only if stream.hasVideo() == true

so for audio only calls, video source will be leaked and that makes further video call not working.

 

Proposed solution to fix this issue:

static synchronized MediaStream createMediaStream(LocalCameraStreamParameters parameters) throws WoogeenStreamException {
    initHandlerIfNeeded();
    VideoSource videoSource = parameters.hasVideo() ? mediaSourceFactory.getVideoSource(parameters) : null;
    countDownLatch = new CountDownLatch(1);
    mediaStream = null;
    message = factoryHandler.obtainMessage();
    message.what = 5;
    Object[] objects = new Object[]{videoSource, Boolean.valueOf(parameters.hasVideo()), Boolean.valueOf(parameters.hasAudio())};
    message.obj = objects;
    message.sendToTarget();

    try {
        countDownLatch.await();
    } catch (InterruptedException var4) {
        var4.printStackTrace();
    }

    return mediaStream;
}

the fix is quite straightforward, video source will be created only if parameters.hasVideo() ==  true. tested this solution on several devices and the issue no longer exists.

Thank you!

0 Kudos
1 Reply
He_Z_Intel
Employee
107 Views

Thanks lamian! We will fix this in future. 

Reply