dotnet / android-samples

A collection of .NET for Android sample projects
https://dotnet.microsoft.com/apps/mobile
MIT License
2.21k stars 4.05k forks source link

Camera2VideoSample: Random crash with repeated Record/Preview #343

Closed samohd closed 5 months ago

samohd commented 2 years ago

UPDATE: This appears to be related to https://github.com/android/camera-samples/issues/109, But with Camera2 instead of CameraX.

I've built a test app using Camera2 video and MediaRecoder. This was seemingly working, but I was having random crashes when stopping record when repeatedly starting/stopping recording. The result of this record state change is that the previewBuilder gets rebuilt with previewSurface + recordSurface (record Start), or just previewSurface (record Stop).

To track it down, I made the code cycle 100 times thru a 10 second record/stop at 15 second intervals. With this approach, I can almost always see a crash, though it could be at iteration 3 or at 80, sometimes not until 300. I've done this testing on multiple Galaxy S9/10 devices as well as on a Pixel 4. All fail the same way, eventually.

The crashes appear to happen either at CreateCaptureRequest or at CreateCaptureSession. And the errors vary from crash to crash, usually being one of these:

I have not figured out how to recover from the error to get the app back into an expected state consistently. try/catch isn't working, as the error seems to occur in some async camera2 functionality. I can see that OnConfigureFailed is called, but by the time that's happened, it's already at some other part of the code which will fail. I tried to separate further along steps to be triggered by OnConfgured/OnReady, to isolate where the crash is happening, but it doesn't seem to be consistent, and this didn't stop the crash from happening.

My best guess is that some background activity, outside my app, is in conflict at the random point in time when my recording is changing states. But, I can't be sure of that.

I've added a ton of tracking into my code to try and isolate this, but no matter what I do, the result is the same. I'm stumped.

I also tried to make it so that I did not rebuild the previewBuilder with every record state change. But this didn't work because of the use of MediaRecorder for which there doesn't seem to be a way to Stop/Start it without recreating it.