Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A VideoCapturer must provide at least one supported VideoFormat #126

Closed
samneolab opened this issue Jun 22, 2017 · 54 comments
Closed

A VideoCapturer must provide at least one supported VideoFormat #126

samneolab opened this issue Jun 22, 2017 · 54 comments
Assignees
Labels

Comments

@samneolab
Copy link

Hi, sometimes I faced this exception and it caused crash. Could you help me to solve this one. Thanks a lot
Caused by java.lang.IllegalStateException: A VideoCapturer must provide at least one supported VideoFormat at com.twilio.video.Preconditions.checkState(Preconditions.java:453) at com.twilio.video.LocalVideoTrack.create(LocalVideoTrack.java:70) at com.twilio.video.LocalVideoTrack.create(LocalVideoTrack.java:44) at com.neo_lab.calling.presentation.ui.video_calling_channel.VideoCallingChannelActivity.channelConferenceConfigureAudioInitAudioAndVideoTracks(VideoCallingChannelActivity.java:670) at com.neo_lab.calling.presentation.ui.video_calling_channel.VideoCallingChannelActivity.onRequestPermissionsResult(VideoCallingChannelActivity.java:593) at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:6582) at android.app.Activity.dispatchActivityResult(Activity.java:6460) at android.app.ActivityThread.deliverResults(ActivityThread.java:3695) at android.app.ActivityThread.handleSendResult(ActivityThread.java:3742) at android.app.ActivityThread.-wrap16(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1393) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

@aaalaniz aaalaniz self-assigned this Jun 22, 2017
@aaalaniz
Copy link
Contributor

Hey @samneolab

Unfortunately this stack trace is misleading. We typically see this stack trace when connection to the Camera fails. Do you only see this issue on certain devices? Are you interacting with the Camera API anytime before creating a LocalVideoTrack?

Thanks!

@erito
Copy link

erito commented Jun 28, 2017

@aaalaniz We're seeing this same stacktrace as well. We dont appear to be doing anything besides initializing the CameraCapturer before attaching to the LocalVideoTrack. Our most problematic devices seem to be the LG G Vista and LG L70. Its also worth noting we use custom VideoConstraints as well.

@aaalaniz
Copy link
Contributor

Thanks for writing in @erito

Do you see this crash occur every time or intermittently on these devices? I also noticed you mentioned local media. What version of the SDK are you using?

@erito
Copy link

erito commented Jun 29, 2017

We're running 1.0.2. That was incorrect when I mentioned LocalMedia, we're attaching the CameraCapturer via the static LocalVideoTrack.create(...) method. It seems to happen consistently with users on those devices, as its a very high crash/user ratio (~7 for every user affected), which seems to indicate it crashes every time they attempt to join a call.

@aaalaniz
Copy link
Contributor

Hey @erito

This is all very helpful information. We have seen this crash occur intermittently on some devices. I will have one of these devices ordered and see if I can reproduce and come up with a bug fix or suitable workaround. Do you mind sharing a snippet of how you are setting customer VideoConstraints ?

Thanks!

@aaalaniz aaalaniz added the bug label Jun 29, 2017
@erito
Copy link

erito commented Jun 29, 2017

Sure, heres the function that initializes the LocalVideoTrack.

private fun constructVideoTrack(initCamera: Boolean) : LocalVideoTrack {

            if (initCamera) {
                val source = cameraCapture.cameraSource
                cameraCapture = CameraCapturer(context, source)
            }

            val constraints = VideoConstraints.Builder()
                    .maxFps(40)
                    .minFps(10)
                    .maxVideoDimensions(VideoDimensions.HD_960P_VIDEO_DIMENSIONS)
                    .build()
            return LocalVideoTrack.create(context, enabled, cameraCapture, constraints)
        }

@aaalaniz
Copy link
Contributor

Kotlin! Nice

Thanks @erito !

@mcorner
Copy link

mcorner commented Jul 2, 2017

We are running into this sporadically as well. We were on 1.0.0 when the errors occurred, but we have just upgraded to the latest so we will find out if it is still a problem.

We saw this on these two devices:
Lenovo TB3-730F
QTASUN1

If there are any effective mitigation strategies, let us know. Could we catch and retry the create?

@aaalaniz
Copy link
Contributor

aaalaniz commented Jul 3, 2017

Hey @samneolab @erito and @mcorner

I'm working on this issue this week. Expect either a fix in 1.1.1 or a workaround soon.

Thanks!

@aaalaniz
Copy link
Contributor

I am now able to reproduce this issue. I am still putting together a workaround. We went ahead and released 1.1.1 without a fix for this issue. Expect a workaround in 1.1.2.

Appreciate everyone's patience.

@AlejandroHCruz
Copy link

Any estimated release date for 1.1.2? :)

@aaalaniz
Copy link
Contributor

One more update....

I think I have a fix for this issue. I deprecated a method in this sprint so going to skip a 1.1.2 and go to 1.2.0. This fix will be available in 1.2.0.

Release will be as early as tomorrow and no later than Friday.

Thanks everyone.

@AlejandroHCruz
Copy link

Amazing @aaalaniz !! Thank you for your help and keeping us posted

@aaalaniz
Copy link
Contributor

1.2.0 has been release. Please update your applications and report if the issue persists. Also, a friendly reminder that all LocalVideoTrack instances created with CameraCapturer or Camera2Capturer must be released in order for the camera resource to be freed. See snippet below:

LocalVideoTrack cameraVideoTrack = LocalVideoTrack.create(context, true, cameraCapturer);

// ... before creating another video track with a camera capturer be sure to release

cameraVideoTrack.release();
cameraVideoTrack = null;

@kesh-1139
Copy link

@aaalaniz I am seeing the issue even after upgrading the version to 1.2.0. I am facing the error after the phone goes to background and comes to foreground. When the phone goes to background I am releasing the localVideoTrack and I am making it null and then I am trying to create the localVideoTrack when phone comes back by using the following code:

LocalVideoTrack.create(mContext, true, va.cameraCapturer);

Let me know how can I solve this issue.

@aaalaniz
Copy link
Contributor

Hey @kesh-1139

What device are you seeing this on and can you provide a full log? Thanks

@kesh-1139
Copy link

@aaalaniz I am able to get the log only with one device that is moto e1 and the crash log is as follows

java.lang.IllegalStateException: A VideoCapturer must provide at least one supported VideoFormat
at com.twilio.video.Preconditions.checkState(Preconditions.java:453)
at com.twilio.video.LocalVideoTrack.create(LocalVideoTrack.java:70)
at com.twilio.video.LocalVideoTrack.create(LocalVideoTrack.java:44)

For all my other devices (moto g3, Asus zenfone1 etc ) its crashing and I am not getting the log in Android studio. Its just crashing.

Please help me out with this.

@kesh-1139
Copy link

@aaalaniz if I do not make localVideoTrack null before going to background, the app does not crash but video does not start and it freezes in the previous state.

@aaalaniz
Copy link
Contributor

@kesh-1139 Can you provide the following information:

  1. Can you confirm that this problem occurs for you even before 1.2.0 release? I want to make sure a regression wasn't introduced.
  2. What version of Android is running on the devices you see the crash on?
  3. Can you post a snippet of your onResume/onPause logic? (or whatever lifecycle methods you are creating and destroying the video track in)

I also want to confirm the reproduction steps. Tell me if this is correct.

Steps to Reproduce

  1. Open app (LocalVideoTrack is created with CameraCapturer)
  2. Background app (Home button or back button or something else?)
  3. Open app again

Expected Result
User should see local camera feed.

Actual Result
Application crashes

Again...any logs you can grab are incredibly helpful.

@kesh-1139
Copy link

kesh-1139 commented Jul 12, 2017

@aaalaniz Please find the information asked below:

  1. Yes. I was seeing the issue before 1.2.0 release. Since you had updated the issue is fixed in 1.2.0, I updated and checked the issue in 1.2.0

  2. I have two devices Moto G3 - Version 6.0.1 and Asus Zenfone1 - Version - 7.1.1

  3. Please find the code snippet used:

I have written the following code in onStop instead of onPause:

public void releaseVideoTrack() {

         /*
         * Release the local video track before going in the background. This ensures that the
         * camera can be used by other applications while this app is in the background.
         */
        if (localVideoTrack != null) {
            /*
             * If this local video track is being shared in a Room, remove from local
             * participant before releasing the video track. Participants will be notified that
             * the track has been removed.
             */
localVideoTrack.removeRenderer(fullScreenStreamingView);
if (localParticipant != null) {
localParticipant.removeVideoTrack(va.localVideoTrack);
 }
cameraCapturer.stopCapture();
localVideoTrack.enable(false);
localVideoTrack.release();
            va.localVideoTrack = null;
            va.cameraCapturer = null;
            fullScreenStreamingView.setVisibility(View.GONE);

        }
    }

I have written the following code in onResume():

 if (cameraCapturer == null) {
 if (GlobalHandler.isFrontCameraPresent(mContext))
cameraCapturer = new CameraCapturer(BaseActivity.mCurrentActivity, CameraCapturer.CameraSource.FRONT_CAMERA);
else
cameraCapturer = new CameraCapturer(mContext, CameraCapturer.CameraSource.BACK_CAMERA);
}
 if (localVideoTrack == null && LivesessionActivity.getLiveChatActivity().checkPermissionForCameraAndMicrophone()) {
localVideoTrack = LocalVideoTrack.create(BaseActivity.mCurrentActivity, true, cameraCapturer);
}
  1. I am not able to get logs and its just crashing Android Monitor is not showing me any logs for the crash. I have copied the logs observed only in moto e1:
java.lang.IllegalStateException: A VideoCapturer must provide at least one supported VideoFormat
at com.twilio.video.Preconditions.checkState(Preconditions.java:453)
at com.twilio.video.LocalVideoTrack.create(LocalVideoTrack.java:70)
at com.twilio.video.LocalVideoTrack.create(LocalVideoTrack.java:44)

@kesh-1139
Copy link

kesh-1139 commented Jul 12, 2017

@aaalaniz Please let me know if you need more details.

Steps,expected and actual results are same. Home button for making the application go to background

@aaalaniz
Copy link
Contributor

Hey @kesh-1139

I have two recommendations.

  1. Remove cameraCapturer.stopCapture(). When you release localVideoTrack the camera capturer will be stopped appropriately.
  2. I recommend scoping your localVideoTrack setup and teardown logic to symmetric lifecycle methods. In other words, if you create the local video track in onResume then release it in onPause. If you prefer to create in onStart then release in onStop

Hope this helps.

@kesh-1139
Copy link

@aaalaniz I will update my code with your recommendations and will update you. Thanks for your help.

@kesh-1139
Copy link

@aaalaniz I have tried your recommendations. I have tried releasing in onPause and creating it in onResume. But its still crashing.

@aaalaniz
Copy link
Contributor

Hey @kesh-1139

At this point I absolutely need a log because I see nothing wrong with the snippets you provided. Have you tried using adb logcat -d ?

@kesh-1139
Copy link

Hey @aaalaniz I have tried with everything possible I am not getting the crash log. I will update you with some more details sooner.

@erito
Copy link

erito commented Jul 12, 2017

@aaalaniz Great! Will update in our next minor release. Did the problem stem from not releasing the LocalMediaTrack?

@aaalaniz
Copy link
Contributor

Hey @erito

There was a race between the teardown of the video track and the releasing of the camera. There were some cases where the camera was not properly released while tearing down the track. The problem would then manifest as a failure to connect to the camera service. The changes in 1.2.0 should fix this race and provide a clearer error message when the camera service cannot be reached instead of the cryptic stack trace originally reported.

@aaalaniz
Copy link
Contributor

Closing for now. If anyone continues experiencing this issue after upgrading to 1.2.0 please re-open.

Thanks!

@kesh-1139
Copy link

kesh-1139 commented Jul 24, 2017

@aaalaniz I am getting crash when starting video second time, after I stop video for the first time,
I will switch from Front to back camera, and then stop video and then will start again and I am getting crash

Below is my code which is producing crash:

if (localVideoTrack == null) {

                if (GlobalHandler.isFrontCameraPresent(activity))
                   cameraCapturer = new CameraCapturer(this, CameraCapturer.CameraSource.FRONT_CAMERA);
                else
                  cameraCapturer = new CameraCapturer(this, CameraCapturer.CameraSource.BACK_CAMERA);
                
                localVideoTrack = LocalVideoTrack.create(this, true, cameraCapturer);
            }

Below are the logs:

java.lang.IllegalStateException: Supported formats could not be retrieved because an error occurred connecting to the camera service
                                                     at com.twilio.video.Preconditions.checkState(Preconditions.java:453)
                                                     at com.twilio.video.CameraCapturer.getSupportedFormats(CameraCapturer.java:321)
                                                     at com.twilio.video.LocalVideoTrack.create(LocalVideoTrack.java:98)
                                                     at com.twilio.video.LocalVideoTrack.create(LocalVideoTrack.java:61)
                             

Can you please help me with this one and let me know what wrong am I doing..

@aaalaniz
Copy link
Contributor

Hey @kesh-1139

Can you share how you are stopping video? Are you calling release() on the LocalVideoTrack created with CameraCapturer?

Thanks

@aaalaniz aaalaniz reopened this Jul 24, 2017
@aaalaniz
Copy link
Contributor

Hey @kesh-1139

Sorry, I mixed up users who have commented. Based on your previous snippets it does appear that you are calling release(). Let me make sure I understand the steps.

  1. Start capturing with front camera
  2. Switch camera to back camera
  3. Stop capturing
  4. Start capturing with back camera

@kesh-1139
Copy link

@aaalaniz I am calling release when stopping video. When I start the video the camera capturer starts with front camera only and not from back camera

@kesh-1139
Copy link

Hey @aaalaniz I am facing an issue in camera capturer, its not related to the above issue...
When we start video and turn the phone to landscape the video turns upside down, can you please let me know why is this happening

@kesh-1139
Copy link

Hey @aaalaniz I have fixed the second one. Thanks for your help.

@aaalaniz
Copy link
Contributor

Hey @kesh-1139

I have this issue in my sprint. I appreciate your patience as I figure out the problem.

I have a pretty nasty workaround you can try

Execute this right after being granted CAMERA permission from user but before creating a LocalVideoTrack.

// This will query camera service and cache supported formats
cameraCapturer.getSupportedFormats();

// Switch cameras so the cache can be updated with supported formats for other source
cameraCapturer.switchCamera();
cameraCapturer.getSupportedFormats();

// Return to original source
cameraCapturer.switchCamera();

// Proceed to create LocalVideoTrack

@kesh-1139
Copy link

Hey @aaalaniz Thanks a lot for the work around. Mentioned work around is for the crash right?

@aaalaniz
Copy link
Contributor

@kesh-1139 yes

@kesh-1139
Copy link

kesh-1139 commented Jul 26, 2017

@aaalaniz ok Thank you. Can you please provide me insights on the following crash:

W/System.err: java.lang.IllegalStateException: Failed to close camera
W/System.err:     at com.twilio.video.Preconditions.checkState(Preconditions.java:453)
W/System.err:     at com.twilio.video.CameraCapturer.stopCapture(CameraCapturer.java:386)
W/System.err:     at com.twilio.video.VideoCapturerDelegate.stopCapture(VideoCapturerDelegate.java:77)
E/rtc: ## Fatal error in /home/jenkins/workspace/video-android-release/library/src/main/jni/com_twilio_video_VideoCapturerDelegate.cpp, line 129
# last system error: 110
# Check failed: !jni()->ExceptionCheck()
# error during VideoCapturer.stopCapture
#

Below is the code which is causing this crash and this is observed while closing the room

 if (room != null){
room.disconnect();
}
  if (cameraCapturer != null) {
if (localVideoTrack != null)
localVideoTrack.release();
cameraCapturer = null
}

@aaalaniz
Copy link
Contributor

Hey @kesh-1139

Does this crash occur every time and on every device your app runs on?

@kesh-1139
Copy link

Hey @aaalaniz Yes it happens every time and on all devices.

@aaalaniz
Copy link
Contributor

Hey @kesh-1139

I'm investigating the original issue you reported about the failure to connect to the camera service. I'm having trouble reproducing the issue. Can you provide the exact steps that reproduce this issue. Code snippets are always helpful and if it is a lot of code I recommend posting as a Github Gist.

Also can you share the logic happening in this method call?

GlobalHandler.isFrontCameraPresent(activity)

Based on the stack trace that you provided, our SDK is not able to connect to the Camera service. This can be caused by either a race condition in our SDK or external code not properly releasing the camera resource.

@kesh-1139
Copy link

kesh-1139 commented Jul 28, 2017

Hey @aaalaniz

Following is the logic in the method call GlobalHandler.isFrontCameraPresent(activity)

PackageManager pm = context.getPackageManager();
        return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);

Before stopping video I am switching to back camera by the following method

cameraCapturer.switchCamera()

Then when again I start the video I am getting this crash.

Video is released properly. The thread itself has my video release code in the above discussions.

If you need more details please let me know

@aaalaniz
Copy link
Contributor

Hey @kesh-1139

This is the test case that I have written. This test is currently passing on my devices and I think it is an accurate representation of the steps you are describing. A couple follow-up questions:

  1. Are all of the calls you have posted executing on the main thread?
  2. What device are you reproducing this issue on?
@Test
@UiThreadTest
public void shouldCaptureFramesAfterCameraSwitchAndRelease() throws InterruptedException {
    final CameraCapturer.CameraSource cameraSource = CameraCapturer.CameraSource.FRONT_CAMERA;
    final AtomicReference<CountDownLatch> firstFrameReceived =
            new AtomicReference<>(new CountDownLatch(1));
    cameraCapturer = new CameraCapturer(cameraCapturerActivity,
            cameraSource,
            new CameraCapturer.Listener() {
                @Override
                public void onFirstFrameAvailable() {
                    firstFrameReceived.get().countDown();
                }

                @Override
                public void onCameraSwitched() {

                }

                @Override
                public void onError(@CameraCapturer.Error int errorCode) {

                }
            });
    localVideoTrack = LocalVideoTrack.create(cameraCapturerActivity,
            true,
            cameraCapturer);

    // Validate we got our first frame
    assertTrue(firstFrameReceived.get().await(CAMERA_CAPTURE_DELAY_MS, TimeUnit.MILLISECONDS));

    // Switch camera
    cameraCapturer.switchCamera();

    // Release track
    localVideoTrack.release();

    // Create new camera capturer with front camera
    firstFrameReceived.set(new CountDownLatch(1));
    CameraCapturer newFrontCameraCapturer = new CameraCapturer(cameraCapturerActivity,
            cameraSource,
            new CameraCapturer.Listener() {
                @Override
                public void onFirstFrameAvailable() {
                    firstFrameReceived.get().countDown();
                }

                @Override
                public void onCameraSwitched() {
                    fail();
                }

                @Override
                public void onError(@CameraCapturer.Error int errorCode) {
                    fail();
                }
            });
    localVideoTrack = LocalVideoTrack.create(cameraCapturerActivity,
            true,
            newFrontCameraCapturer);

    // Validate we got our first frame
    assertTrue(firstFrameReceived.get().await(CAMERA_CAPTURE_DELAY_MS, TimeUnit.MILLISECONDS));

    // Release track
    localVideoTrack.release();
}

@aaalaniz
Copy link
Contributor

Also please post a full log so that I can trace the sequence of events @kesh-1139

Thanks!

@aaalaniz
Copy link
Contributor

Turn up the log level using the following snippet and post a log @kesh-1139

Video.setLogLevel(LogLevel.ALL);

@kesh-1139
Copy link

@aaalaniz I am making another change along with your steps, after releasing the video track I am making localVideoTrack = null, and also cameraCapturer = null, before starting capturing for the second time. I am using old CameraCapturer class and not using Camera2Capturer class.

@kesh-1139
Copy link

kesh-1139 commented Aug 5, 2017

Hey @aaalaniz

The work around is not working I am getting the same exception in the method cameraCapturer.getSupportedFormats

@aaalaniz
Copy link
Contributor

aaalaniz commented Aug 8, 2017

Hey @kesh-1139

Please post a complete log of when you are observing the crash. I cannot provide any further guidance until I see a log.

Thanks

@aaalaniz
Copy link
Contributor

I am closing this bug due to inactivity. Please reopen with a complete log. Thanks!

@rishabhja1994
Copy link

@aaalaniz Hello.. I am also experiencing the same error. What i have done is that created the local video track in onResume and released it in onPause. But when i open another activity trying to use camera, it crashes

@aaalaniz
Copy link
Contributor

Hey @rishabhja1994

Can you open a separate issue for the problem you are describing and provide snippets of how you are using the camera in the other activity?

Thanks!

@rishabhja1994
Copy link

Hi

Thanks for your reply. Should i share my complete code with you?

@aaalaniz
Copy link
Contributor

Hey @rishabhja1994

Open a separate Github issue and share your code there. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants