The problem was that sometimes onMeasure() was being called after the preview was initialized, so the startPreview() call in the surfaceChanged() method would not do anything.
The only way to force an update of the preview resolution is to pause and resume it, so the capture session is destroyed and can be properly recreated with the new resolutions.
This adds the issue of concurrent calls to startPreview(), some which are actually needed to create the base preview or update the resolution, while others are not. As we cannot create multiple captureSessions, we have to wait for the ongoing init to finish before destroying the session and calling the method again with more up-to-date parameters (via pause-resume).
=====
This fix is a bit of a hack with regards to its handling of concurrent initialization so it needs to be properly tested on multiple devices, with app:previewRatioMode="fitToPicture" in activity_main_alt.xml:
Open the camera, pause/unpause it, rotate the device multiple times, make sure there is NO distortion, NO crashes and NO aspect ratio changes when unpausing (or at least none that distorts the preview, I know one sometimes happens in portrait mode but it is negligible and could be due to camera resolution changing dynamically).
May be worth testing with Camera 1 to see if a backport of this fix is needed, though so far there has been no reports of distortion problems with app:previewRatioMode="fitToPicture" in Camera 1.
The problem was that sometimes
onMeasure()
was being called after the preview was initialized, so thestartPreview()
call in thesurfaceChanged()
method would not do anything.The only way to force an update of the preview resolution is to pause and resume it, so the capture session is destroyed and can be properly recreated with the new resolutions.
This adds the issue of concurrent calls to
startPreview()
, some which are actually needed to create the base preview or update the resolution, while others are not. As we cannot create multiple captureSessions, we have to wait for the ongoing init to finish before destroying the session and calling the method again with more up-to-date parameters (via pause-resume).=====
This fix is a bit of a hack with regards to its handling of concurrent initialization so it needs to be properly tested on multiple devices, with
app:previewRatioMode="fitToPicture"
inactivity_main_alt.xml
:Open the camera, pause/unpause it, rotate the device multiple times, make sure there is NO distortion, NO crashes and NO aspect ratio changes when unpausing (or at least none that distorts the preview, I know one sometimes happens in portrait mode but it is negligible and could be due to camera resolution changing dynamically).
May be worth testing with Camera 1 to see if a backport of this fix is needed, though so far there has been no reports of distortion problems with
app:previewRatioMode="fitToPicture"
in Camera 1.