Loading _docs/history.html +4 −0 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,10 @@ UPDATED Improvements for loading thumbnails for gallery icon (including fixing o UPDATED Improvements for popup menu and exposure UI when using large font sizes. UPDATED Improvements for popup menu and exposure UI when using large font sizes. UPDATED Made user's font size preference apply to on-screen text. UPDATED Made user's font size preference apply to on-screen text. UPDATED Changes in preparation for back button behaviour for future Android versions. UPDATED Changes in preparation for back button behaviour for future Android versions. UPDATED Better compatibility when debug option Settings/Photo settings/"Enable fast HDR/expo burst" is disabled: also change the preview exposure. Turning this option of fixes HDR/expo for Samsung Galaxy devices. New installs on Samsung Galaxy devices now disable fast HDR/expo burst by default. Version 1.52 (2023/08/13) Version 1.52 (2023/08/13) Loading app/src/main/java/net/sourceforge/opencamera/MainActivity.java +12 −2 Original line number Original line Diff line number Diff line Loading @@ -1036,6 +1036,8 @@ public class MainActivity extends AppCompatActivity { if( MyDebug.LOG ) if( MyDebug.LOG ) Log.d(TAG, "setDeviceDefaults"); Log.d(TAG, "setDeviceDefaults"); final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); boolean is_samsung = Build.MANUFACTURER.toLowerCase(Locale.US).contains("samsung"); //SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); //boolean is_samsung = Build.MANUFACTURER.toLowerCase(Locale.US).contains("samsung"); //boolean is_samsung = Build.MANUFACTURER.toLowerCase(Locale.US).contains("samsung"); //boolean is_oneplus = Build.MANUFACTURER.toLowerCase(Locale.US).contains("oneplus"); //boolean is_oneplus = Build.MANUFACTURER.toLowerCase(Locale.US).contains("oneplus"); //boolean is_nexus = Build.MODEL.toLowerCase(Locale.US).contains("nexus"); //boolean is_nexus = Build.MODEL.toLowerCase(Locale.US).contains("nexus"); Loading Loading @@ -1075,9 +1077,18 @@ public class MainActivity extends AppCompatActivity { if( MyDebug.LOG ) if( MyDebug.LOG ) Log.d(TAG, "disable fast burst for camera2"); Log.d(TAG, "disable fast burst for camera2"); SharedPreferences.Editor editor = sharedPreferences.edit(); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean(PreferenceKeys.getCamera2FastBurstPreferenceKey(), false); editor.putBoolean(PreferenceKeys.Camera2FastBurstPreferenceKey, false); editor.apply(); editor.apply(); }*/ }*/ if( is_samsung && !is_test ) { // Samsung Galaxy devices (including S10e, S24) have problems with HDR/expo - base images come out with wrong exposures. // This can be fixed by not using fast bast, allowing us to adjust the preview exposure to match. if( MyDebug.LOG ) Log.d(TAG, "disable fast burst for camera2"); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean(PreferenceKeys.Camera2FastBurstPreferenceKey, false); editor.apply(); } if( supports_camera2 && !is_test ) { if( supports_camera2 && !is_test ) { // n.b., when testing, we explicitly decide whether to run with Camera2 API or not // n.b., when testing, we explicitly decide whether to run with Camera2 API or not CameraControllerManager2 manager2 = new CameraControllerManager2(this); CameraControllerManager2 manager2 = new CameraControllerManager2(this); Loading @@ -1095,7 +1106,6 @@ public class MainActivity extends AppCompatActivity { boolean default_to_camera2 = false; boolean default_to_camera2 = false; boolean is_google = Build.MANUFACTURER.toLowerCase(Locale.US).contains("google"); boolean is_google = Build.MANUFACTURER.toLowerCase(Locale.US).contains("google"); boolean is_nokia = Build.MANUFACTURER.toLowerCase(Locale.US).contains("hmd global"); boolean is_nokia = Build.MANUFACTURER.toLowerCase(Locale.US).contains("hmd global"); boolean is_samsung = Build.MANUFACTURER.toLowerCase(Locale.US).contains("samsung"); if( is_google && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ) if( is_google && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ) default_to_camera2 = true; default_to_camera2 = true; else if( is_nokia && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ) else if( is_nokia && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ) Loading app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java +120 −43 Original line number Original line Diff line number Diff line Loading @@ -1473,6 +1473,57 @@ public class CameraController2 extends CameraController { return value; return value; } } /** Issues the next slow burst capture, on a post delayed on the handler. */ private void postNextSlowBurst() { if( MyDebug.LOG ) Log.d(TAG, "postNextSlowBurst"); handler.postDelayed(new Runnable() { @Override public void run() { if( MyDebug.LOG ) Log.d(TAG, "take picture after delay for next slow burst"); if( camera != null && hasCaptureSession() ) { // make sure camera wasn't released in the meantime // check for imageQueueWouldBlock needed for focus bracketing if( picture_cb.imageQueueWouldBlock(imageReaderRaw != null ? 1 : 0, 1) ) { if( MyDebug.LOG ) { Log.d(TAG, "...but wait for next bracket, as image queue would block"); } handler.postDelayed(this, 100); //throw new RuntimeException(); // test } else { if( burst_type == BurstType.BURSTTYPE_FOCUS ) { // For focus bracketing mode, we play the shutter sound per shot (so the user can tell when the sequence is complete). // From a user mode, the gap between shots in focus bracketing mode makes this more analogous to the auto-repeat mode // (at the Preview level), which makes the shutter sound per shot. playSound(MediaActionSound.SHUTTER_CLICK); } try { captureSession.capture(slow_burst_capture_requests.get(n_burst_taken), previewCaptureCallback, handler); } catch(CameraAccessException e) { if( MyDebug.LOG ) { Log.e(TAG, "failed to take next focus bracket"); Log.e(TAG, "reason: " + e.getReason()); Log.e(TAG, "message: " + e.getMessage()); } e.printStackTrace(); jpeg_todo = false; raw_todo = false; picture_cb = null; if( take_picture_error_cb != null ) { take_picture_error_cb.onError(); take_picture_error_cb = null; } } } } } }, 500); } private class OnImageAvailableListener implements ImageReader.OnImageAvailableListener { private class OnImageAvailableListener implements ImageReader.OnImageAvailableListener { private boolean skip_next_image = false; // whether to ignore the next image (used for dummy_capture_hack) private boolean skip_next_image = false; // whether to ignore the next image (used for dummy_capture_hack) Loading Loading @@ -1616,7 +1667,7 @@ public class CameraController2 extends CameraController { Log.d(TAG, "time since start: " + (System.currentTimeMillis() - slow_burst_start_ms)); Log.d(TAG, "time since start: " + (System.currentTimeMillis() - slow_burst_start_ms)); } } if( burst_type != BurstType.BURSTTYPE_FOCUS ) { if( burst_type != BurstType.BURSTTYPE_FOCUS ) { try { /*try { if( camera != null && hasCaptureSession() ) { // make sure camera wasn't released in the meantime if( camera != null && hasCaptureSession() ) { // make sure camera wasn't released in the meantime captureSession.capture(slow_burst_capture_requests.get(n_burst_taken), previewCaptureCallback, handler); captureSession.capture(slow_burst_capture_requests.get(n_burst_taken), previewCaptureCallback, handler); } } Loading @@ -1632,6 +1683,32 @@ public class CameraController2 extends CameraController { raw_todo = false; raw_todo = false; picture_cb = null; picture_cb = null; push_take_picture_error_cb = take_picture_error_cb; push_take_picture_error_cb = take_picture_error_cb; }*/ // see note in takePictureBurstBracketing() for why we also set preview for slow burst with expo bracketing - // helps Samsung Galaxy devices if( previewBuilder != null ) { // make sure camera wasn't released in the meantime try { long exposure_time = slow_burst_capture_requests.get(n_burst_taken).get(CaptureRequest.SENSOR_EXPOSURE_TIME); if( MyDebug.LOG ) { Log.d(TAG, "prepare preview for next exposure: " + exposure_time); } previewBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposure_time); setRepeatingRequest(previewBuilder.build()); } catch(CameraAccessException e) { if( MyDebug.LOG ) { Log.e(TAG, "failed to take set exposure for next expo bracketing burst"); Log.e(TAG, "reason: " + e.getReason()); Log.e(TAG, "message: " + e.getMessage()); } e.printStackTrace(); jpeg_todo = false; raw_todo = false; picture_cb = null; push_take_picture_error_cb = take_picture_error_cb; } postNextSlowBurst(); } } } } else if( previewBuilder != null ) { // make sure camera wasn't released in the meantime else if( previewBuilder != null ) { // make sure camera wasn't released in the meantime Loading Loading @@ -1695,47 +1772,7 @@ public class CameraController2 extends CameraController { picture_cb = null; picture_cb = null; push_take_picture_error_cb = take_picture_error_cb; push_take_picture_error_cb = take_picture_error_cb; } } handler.postDelayed(new Runnable(){ postNextSlowBurst(); @Override public void run(){ if( MyDebug.LOG ) Log.d(TAG, "take picture after delay for next focus bracket"); if( camera != null && hasCaptureSession() ) { // make sure camera wasn't released in the meantime if( picture_cb.imageQueueWouldBlock(imageReaderRaw != null ? 1 : 0, 1) ) { if( MyDebug.LOG ) { Log.d(TAG, "...but wait for next focus bracket, as image queue would block"); } handler.postDelayed(this, 100); //throw new RuntimeException(); // test } else { // For focus bracketing mode, we play the shutter sound per shot (so the user can tell when the sequence is complete). // From a user mode, the gap between shots in focus bracketing mode makes this more analogous to the auto-repeat mode // (at the Preview level), which makes the shutter sound per shot. playSound(MediaActionSound.SHUTTER_CLICK); try { captureSession.capture(slow_burst_capture_requests.get(n_burst_taken), previewCaptureCallback, handler); } catch(CameraAccessException e) { if( MyDebug.LOG ) { Log.e(TAG, "failed to take next focus bracket"); Log.e(TAG, "reason: " + e.getReason()); Log.e(TAG, "message: " + e.getMessage()); } e.printStackTrace(); jpeg_todo = false; raw_todo = false; picture_cb = null; if( take_picture_error_cb != null ) { take_picture_error_cb.onError(); take_picture_error_cb = null; } } } } } }, 500); } } } } } } Loading Loading @@ -7151,8 +7188,45 @@ public class CameraController2 extends CameraController { Log.d(TAG, "using slow burst"); Log.d(TAG, "using slow burst"); slow_burst_capture_requests = requests; slow_burst_capture_requests = requests; slow_burst_start_ms = System.currentTimeMillis(); slow_burst_start_ms = System.currentTimeMillis(); if( burst_type == BurstType.BURSTTYPE_EXPO ) { // Set preview to match - some devices (e.g. Samsung Galaxy) don't produce photos with correct exposure if // the exposure is set to a different value than the preview. // Although we don't/can't do this for fast burst, doing so here means such devices can use HDR/expo when // using use_expo_fast_burst==false. try { previewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF); previewBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, slow_burst_capture_requests.get(n_burst_taken).get(CaptureRequest.SENSOR_SENSITIVITY)); previewBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, slow_burst_capture_requests.get(n_burst_taken).get(CaptureRequest.SENSOR_FRAME_DURATION)); long exposure_time = slow_burst_capture_requests.get(n_burst_taken).get(CaptureRequest.SENSOR_EXPOSURE_TIME); if( MyDebug.LOG ) { Log.d(TAG, "prepare preview for next exposure: " + exposure_time); } previewBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposure_time); setRepeatingRequest(previewBuilder.build()); } catch(CameraAccessException e) { if( MyDebug.LOG ) { Log.e(TAG, "failed to take set exposure for next expo bracketing burst"); Log.e(TAG, "reason: " + e.getReason()); Log.e(TAG, "message: " + e.getMessage()); } e.printStackTrace(); jpeg_todo = false; raw_todo = false; picture_cb = null; push_take_picture_error_cb = take_picture_error_cb; } postNextSlowBurst(); } else { // no need to set preview for first focus bracketing shot, the first focus bracketing always // has same focus distance as preview captureSession.capture(requests.get(0), previewCaptureCallback, handler); captureSession.capture(requests.get(0), previewCaptureCallback, handler); } } } playSound(MediaActionSound.SHUTTER_CLICK); // play shutter sound asap, otherwise user has the illusion of being slow to take photos playSound(MediaActionSound.SHUTTER_CLICK); // play shutter sound asap, otherwise user has the illusion of being slow to take photos } } Loading Loading @@ -8896,6 +8970,9 @@ public class CameraController2 extends CameraController { // actual parsing of image data is done in the imageReader's OnImageAvailableListener() // actual parsing of image data is done in the imageReader's OnImageAvailableListener() // need to cancel the autofocus, and restart the preview after taking the photo // need to cancel the autofocus, and restart the preview after taking the photo // Camera2Basic does a capture then sets a repeating request - do the same here just to be safe // Camera2Basic does a capture then sets a repeating request - do the same here just to be safe // update: this is also important when we do an expo burst (BURSTTYPE_EXPO) with option // use_expo_fast_burst==false, since that changes the exposure of the preview, so we need to // reset it here if( previewBuilder != null ) { if( previewBuilder != null ) { previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); if( MyDebug.LOG ) if( MyDebug.LOG ) Loading Loading
_docs/history.html +4 −0 Original line number Original line Diff line number Diff line Loading @@ -70,6 +70,10 @@ UPDATED Improvements for loading thumbnails for gallery icon (including fixing o UPDATED Improvements for popup menu and exposure UI when using large font sizes. UPDATED Improvements for popup menu and exposure UI when using large font sizes. UPDATED Made user's font size preference apply to on-screen text. UPDATED Made user's font size preference apply to on-screen text. UPDATED Changes in preparation for back button behaviour for future Android versions. UPDATED Changes in preparation for back button behaviour for future Android versions. UPDATED Better compatibility when debug option Settings/Photo settings/"Enable fast HDR/expo burst" is disabled: also change the preview exposure. Turning this option of fixes HDR/expo for Samsung Galaxy devices. New installs on Samsung Galaxy devices now disable fast HDR/expo burst by default. Version 1.52 (2023/08/13) Version 1.52 (2023/08/13) Loading
app/src/main/java/net/sourceforge/opencamera/MainActivity.java +12 −2 Original line number Original line Diff line number Diff line Loading @@ -1036,6 +1036,8 @@ public class MainActivity extends AppCompatActivity { if( MyDebug.LOG ) if( MyDebug.LOG ) Log.d(TAG, "setDeviceDefaults"); Log.d(TAG, "setDeviceDefaults"); final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); boolean is_samsung = Build.MANUFACTURER.toLowerCase(Locale.US).contains("samsung"); //SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); //boolean is_samsung = Build.MANUFACTURER.toLowerCase(Locale.US).contains("samsung"); //boolean is_samsung = Build.MANUFACTURER.toLowerCase(Locale.US).contains("samsung"); //boolean is_oneplus = Build.MANUFACTURER.toLowerCase(Locale.US).contains("oneplus"); //boolean is_oneplus = Build.MANUFACTURER.toLowerCase(Locale.US).contains("oneplus"); //boolean is_nexus = Build.MODEL.toLowerCase(Locale.US).contains("nexus"); //boolean is_nexus = Build.MODEL.toLowerCase(Locale.US).contains("nexus"); Loading Loading @@ -1075,9 +1077,18 @@ public class MainActivity extends AppCompatActivity { if( MyDebug.LOG ) if( MyDebug.LOG ) Log.d(TAG, "disable fast burst for camera2"); Log.d(TAG, "disable fast burst for camera2"); SharedPreferences.Editor editor = sharedPreferences.edit(); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean(PreferenceKeys.getCamera2FastBurstPreferenceKey(), false); editor.putBoolean(PreferenceKeys.Camera2FastBurstPreferenceKey, false); editor.apply(); editor.apply(); }*/ }*/ if( is_samsung && !is_test ) { // Samsung Galaxy devices (including S10e, S24) have problems with HDR/expo - base images come out with wrong exposures. // This can be fixed by not using fast bast, allowing us to adjust the preview exposure to match. if( MyDebug.LOG ) Log.d(TAG, "disable fast burst for camera2"); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean(PreferenceKeys.Camera2FastBurstPreferenceKey, false); editor.apply(); } if( supports_camera2 && !is_test ) { if( supports_camera2 && !is_test ) { // n.b., when testing, we explicitly decide whether to run with Camera2 API or not // n.b., when testing, we explicitly decide whether to run with Camera2 API or not CameraControllerManager2 manager2 = new CameraControllerManager2(this); CameraControllerManager2 manager2 = new CameraControllerManager2(this); Loading @@ -1095,7 +1106,6 @@ public class MainActivity extends AppCompatActivity { boolean default_to_camera2 = false; boolean default_to_camera2 = false; boolean is_google = Build.MANUFACTURER.toLowerCase(Locale.US).contains("google"); boolean is_google = Build.MANUFACTURER.toLowerCase(Locale.US).contains("google"); boolean is_nokia = Build.MANUFACTURER.toLowerCase(Locale.US).contains("hmd global"); boolean is_nokia = Build.MANUFACTURER.toLowerCase(Locale.US).contains("hmd global"); boolean is_samsung = Build.MANUFACTURER.toLowerCase(Locale.US).contains("samsung"); if( is_google && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ) if( is_google && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ) default_to_camera2 = true; default_to_camera2 = true; else if( is_nokia && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ) else if( is_nokia && Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ) Loading
app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java +120 −43 Original line number Original line Diff line number Diff line Loading @@ -1473,6 +1473,57 @@ public class CameraController2 extends CameraController { return value; return value; } } /** Issues the next slow burst capture, on a post delayed on the handler. */ private void postNextSlowBurst() { if( MyDebug.LOG ) Log.d(TAG, "postNextSlowBurst"); handler.postDelayed(new Runnable() { @Override public void run() { if( MyDebug.LOG ) Log.d(TAG, "take picture after delay for next slow burst"); if( camera != null && hasCaptureSession() ) { // make sure camera wasn't released in the meantime // check for imageQueueWouldBlock needed for focus bracketing if( picture_cb.imageQueueWouldBlock(imageReaderRaw != null ? 1 : 0, 1) ) { if( MyDebug.LOG ) { Log.d(TAG, "...but wait for next bracket, as image queue would block"); } handler.postDelayed(this, 100); //throw new RuntimeException(); // test } else { if( burst_type == BurstType.BURSTTYPE_FOCUS ) { // For focus bracketing mode, we play the shutter sound per shot (so the user can tell when the sequence is complete). // From a user mode, the gap between shots in focus bracketing mode makes this more analogous to the auto-repeat mode // (at the Preview level), which makes the shutter sound per shot. playSound(MediaActionSound.SHUTTER_CLICK); } try { captureSession.capture(slow_burst_capture_requests.get(n_burst_taken), previewCaptureCallback, handler); } catch(CameraAccessException e) { if( MyDebug.LOG ) { Log.e(TAG, "failed to take next focus bracket"); Log.e(TAG, "reason: " + e.getReason()); Log.e(TAG, "message: " + e.getMessage()); } e.printStackTrace(); jpeg_todo = false; raw_todo = false; picture_cb = null; if( take_picture_error_cb != null ) { take_picture_error_cb.onError(); take_picture_error_cb = null; } } } } } }, 500); } private class OnImageAvailableListener implements ImageReader.OnImageAvailableListener { private class OnImageAvailableListener implements ImageReader.OnImageAvailableListener { private boolean skip_next_image = false; // whether to ignore the next image (used for dummy_capture_hack) private boolean skip_next_image = false; // whether to ignore the next image (used for dummy_capture_hack) Loading Loading @@ -1616,7 +1667,7 @@ public class CameraController2 extends CameraController { Log.d(TAG, "time since start: " + (System.currentTimeMillis() - slow_burst_start_ms)); Log.d(TAG, "time since start: " + (System.currentTimeMillis() - slow_burst_start_ms)); } } if( burst_type != BurstType.BURSTTYPE_FOCUS ) { if( burst_type != BurstType.BURSTTYPE_FOCUS ) { try { /*try { if( camera != null && hasCaptureSession() ) { // make sure camera wasn't released in the meantime if( camera != null && hasCaptureSession() ) { // make sure camera wasn't released in the meantime captureSession.capture(slow_burst_capture_requests.get(n_burst_taken), previewCaptureCallback, handler); captureSession.capture(slow_burst_capture_requests.get(n_burst_taken), previewCaptureCallback, handler); } } Loading @@ -1632,6 +1683,32 @@ public class CameraController2 extends CameraController { raw_todo = false; raw_todo = false; picture_cb = null; picture_cb = null; push_take_picture_error_cb = take_picture_error_cb; push_take_picture_error_cb = take_picture_error_cb; }*/ // see note in takePictureBurstBracketing() for why we also set preview for slow burst with expo bracketing - // helps Samsung Galaxy devices if( previewBuilder != null ) { // make sure camera wasn't released in the meantime try { long exposure_time = slow_burst_capture_requests.get(n_burst_taken).get(CaptureRequest.SENSOR_EXPOSURE_TIME); if( MyDebug.LOG ) { Log.d(TAG, "prepare preview for next exposure: " + exposure_time); } previewBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposure_time); setRepeatingRequest(previewBuilder.build()); } catch(CameraAccessException e) { if( MyDebug.LOG ) { Log.e(TAG, "failed to take set exposure for next expo bracketing burst"); Log.e(TAG, "reason: " + e.getReason()); Log.e(TAG, "message: " + e.getMessage()); } e.printStackTrace(); jpeg_todo = false; raw_todo = false; picture_cb = null; push_take_picture_error_cb = take_picture_error_cb; } postNextSlowBurst(); } } } } else if( previewBuilder != null ) { // make sure camera wasn't released in the meantime else if( previewBuilder != null ) { // make sure camera wasn't released in the meantime Loading Loading @@ -1695,47 +1772,7 @@ public class CameraController2 extends CameraController { picture_cb = null; picture_cb = null; push_take_picture_error_cb = take_picture_error_cb; push_take_picture_error_cb = take_picture_error_cb; } } handler.postDelayed(new Runnable(){ postNextSlowBurst(); @Override public void run(){ if( MyDebug.LOG ) Log.d(TAG, "take picture after delay for next focus bracket"); if( camera != null && hasCaptureSession() ) { // make sure camera wasn't released in the meantime if( picture_cb.imageQueueWouldBlock(imageReaderRaw != null ? 1 : 0, 1) ) { if( MyDebug.LOG ) { Log.d(TAG, "...but wait for next focus bracket, as image queue would block"); } handler.postDelayed(this, 100); //throw new RuntimeException(); // test } else { // For focus bracketing mode, we play the shutter sound per shot (so the user can tell when the sequence is complete). // From a user mode, the gap between shots in focus bracketing mode makes this more analogous to the auto-repeat mode // (at the Preview level), which makes the shutter sound per shot. playSound(MediaActionSound.SHUTTER_CLICK); try { captureSession.capture(slow_burst_capture_requests.get(n_burst_taken), previewCaptureCallback, handler); } catch(CameraAccessException e) { if( MyDebug.LOG ) { Log.e(TAG, "failed to take next focus bracket"); Log.e(TAG, "reason: " + e.getReason()); Log.e(TAG, "message: " + e.getMessage()); } e.printStackTrace(); jpeg_todo = false; raw_todo = false; picture_cb = null; if( take_picture_error_cb != null ) { take_picture_error_cb.onError(); take_picture_error_cb = null; } } } } } }, 500); } } } } } } Loading Loading @@ -7151,8 +7188,45 @@ public class CameraController2 extends CameraController { Log.d(TAG, "using slow burst"); Log.d(TAG, "using slow burst"); slow_burst_capture_requests = requests; slow_burst_capture_requests = requests; slow_burst_start_ms = System.currentTimeMillis(); slow_burst_start_ms = System.currentTimeMillis(); if( burst_type == BurstType.BURSTTYPE_EXPO ) { // Set preview to match - some devices (e.g. Samsung Galaxy) don't produce photos with correct exposure if // the exposure is set to a different value than the preview. // Although we don't/can't do this for fast burst, doing so here means such devices can use HDR/expo when // using use_expo_fast_burst==false. try { previewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_AE_MODE_OFF); previewBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, slow_burst_capture_requests.get(n_burst_taken).get(CaptureRequest.SENSOR_SENSITIVITY)); previewBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, slow_burst_capture_requests.get(n_burst_taken).get(CaptureRequest.SENSOR_FRAME_DURATION)); long exposure_time = slow_burst_capture_requests.get(n_burst_taken).get(CaptureRequest.SENSOR_EXPOSURE_TIME); if( MyDebug.LOG ) { Log.d(TAG, "prepare preview for next exposure: " + exposure_time); } previewBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, exposure_time); setRepeatingRequest(previewBuilder.build()); } catch(CameraAccessException e) { if( MyDebug.LOG ) { Log.e(TAG, "failed to take set exposure for next expo bracketing burst"); Log.e(TAG, "reason: " + e.getReason()); Log.e(TAG, "message: " + e.getMessage()); } e.printStackTrace(); jpeg_todo = false; raw_todo = false; picture_cb = null; push_take_picture_error_cb = take_picture_error_cb; } postNextSlowBurst(); } else { // no need to set preview for first focus bracketing shot, the first focus bracketing always // has same focus distance as preview captureSession.capture(requests.get(0), previewCaptureCallback, handler); captureSession.capture(requests.get(0), previewCaptureCallback, handler); } } } playSound(MediaActionSound.SHUTTER_CLICK); // play shutter sound asap, otherwise user has the illusion of being slow to take photos playSound(MediaActionSound.SHUTTER_CLICK); // play shutter sound asap, otherwise user has the illusion of being slow to take photos } } Loading Loading @@ -8896,6 +8970,9 @@ public class CameraController2 extends CameraController { // actual parsing of image data is done in the imageReader's OnImageAvailableListener() // actual parsing of image data is done in the imageReader's OnImageAvailableListener() // need to cancel the autofocus, and restart the preview after taking the photo // need to cancel the autofocus, and restart the preview after taking the photo // Camera2Basic does a capture then sets a repeating request - do the same here just to be safe // Camera2Basic does a capture then sets a repeating request - do the same here just to be safe // update: this is also important when we do an expo burst (BURSTTYPE_EXPO) with option // use_expo_fast_burst==false, since that changes the exposure of the preview, so we need to // reset it here if( previewBuilder != null ) { if( previewBuilder != null ) { previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL); if( MyDebug.LOG ) if( MyDebug.LOG ) Loading