Fix video crashes

pull/572/head
Mattia Iavarone 6 years ago
parent 01d7109ee1
commit 782896dd7b
  1. 44
      cameraview/src/main/java/com/otaliastudios/cameraview/engine/Camera2Engine.java

@ -726,31 +726,38 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
} }
@Override @Override
protected void onStopVideo() { public void onVideoRecordingEnd() {
boolean isFullVideo = mVideoRecorder instanceof Full2VideoRecorder; super.onVideoRecordingEnd();
if (isFullVideo) { // When video ends we must stop the recorder and remove the recorder surface from camera outputs.
// Workaround for #549: when video ends we must stop the recorder and remove the recorder // This is done in onVideoResult. However, on some devices, order matters. If we stop the recorder
// surface from camera outputs. On some devices, order matters. If we stop the recorder
// and AFTER send camera frames to it, the camera will try to fill the recorder "abandoned" // and AFTER send camera frames to it, the camera will try to fill the recorder "abandoned"
// Surface and on some devices with a poor internal implementation (LEGACY?) this crashes. // Surface and on some devices with a poor internal implementation (HW_LEVEL_LEGACY) this crashes.
try { // So if the conditions are met, we restore here. Issue #549.
mSession.stopRepeating(); boolean needsIssue549Workaround = (mVideoRecorder instanceof Full2VideoRecorder) ||
mSession.abortCaptures(); (readCharacteristic(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL, -1)
} catch (CameraAccessException e) { == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY);
throw createCameraException(e); if (needsIssue549Workaround) {
} maybeRestorePreviewTemplateAfterVideo();
} }
super.onStopVideo();
} }
@Override @Override
public void onVideoResult(@Nullable VideoResult.Stub result, @Nullable Exception exception) { public void onVideoResult(@Nullable VideoResult.Stub result, @Nullable Exception exception) {
boolean isFullVideo = mVideoRecorder instanceof Full2VideoRecorder;
super.onVideoResult(result, exception); super.onVideoResult(result, exception);
if (isFullVideo) { maybeRestorePreviewTemplateAfterVideo();
// When video ends, we must restart the repeating request for TEMPLATE_PREVIEW, }
// this time without the video recorder surface.
/**
* Some video recorders might change the camera template to {@link CameraDevice#TEMPLATE_RECORD}.
* After the video is taken, we should restore the template preview, which also means that
* we'll remove any extra surface target that was added by the video recorder.
*
* This method avoids doing this twice by checking the request tag, as set by
* the {@link #createRepeatingRequestBuilder(int)} method.
*/
private void maybeRestorePreviewTemplateAfterVideo() {
int template = (int) mRepeatingRequest.getTag();
if (template != CameraDevice.TEMPLATE_PREVIEW) {
try { try {
createRepeatingRequestBuilder(CameraDevice.TEMPLATE_PREVIEW); createRepeatingRequestBuilder(CameraDevice.TEMPLATE_PREVIEW);
addRepeatingRequestBuilderSurfaces(); addRepeatingRequestBuilderSurfaces();
@ -759,7 +766,6 @@ public class Camera2Engine extends CameraEngine implements ImageReader.OnImageAv
throw createCameraException(e); throw createCameraException(e);
} }
} }
} }
//endregion //endregion

Loading…
Cancel
Save