Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7962baf authored by Mark Harman's avatar Mark Harman
Browse files

More support code for slow motion video.

parent 0086790f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -249,6 +249,7 @@ public abstract class CameraController {
	 */
	public abstract void setOptimiseAEForDRO(boolean optimise_ae_for_dro);
	public abstract void setRaw(boolean want_raw);
	public abstract void setVideoHighSpeed(boolean setVideoHighSpeed);
	/**
	 * setUseCamera2FakeFlash() should be called after creating the CameraController, and before calling getCameraFeatures() or
	 * starting the preview (as it changes the available flash modes).
+5 −0
Original line number Diff line number Diff line
@@ -756,6 +756,11 @@ public class CameraController1 extends CameraController {
		// not supported for CameraController1
	}

	@Override
	public void setVideoHighSpeed(boolean setVideoHighSpeed) {
		// not supported for CameraController1
	}

	@Override
	public void setVideoStabilization(boolean enabled) {
	    Camera.Parameters parameters = this.getParameters();
+36 −6
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@ public class CameraController2 extends CameraController {
	private DngCreator pending_dngCreator;
	private Image pending_image;
	private ErrorCallback take_picture_error_cb;
	private boolean want_video_high_speed;
	//private ImageReader previewImageReader;
	private SurfaceTexture texture;
	private Surface surface_texture;
@@ -1242,7 +1243,8 @@ public class CameraController2 extends CameraController {
			if( capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW ) {
				capabilities_raw = true;
			}
			else if( capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO ) {
			else if( capability == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
				// we test for at least Android M just to be safe (this is needed for createConstrainedHighSpeedCaptureSession())
				capabilities_high_speed_video = true;
			}
		}
@@ -2076,6 +2078,27 @@ public class CameraController2 extends CameraController {
		this.want_raw = want_raw;
	}

	@Override
	public void setVideoHighSpeed(boolean want_video_high_speed) {
		if( MyDebug.LOG )
			Log.d(TAG, "setVideoHighSpeed: " + want_video_high_speed);
		if( camera == null ) {
			if( MyDebug.LOG )
				Log.e(TAG, "no camera");
			return;
		}
		if( this.want_video_high_speed == want_video_high_speed ) {
			return;
		}
		if( captureSession != null ) {
			// can only call this when captureSession not created - as it affects how we create the session
			if( MyDebug.LOG )
				Log.e(TAG, "can't set high speed when captureSession running!");
			throw new RuntimeException(); // throw as RuntimeException, as this is a programming error
		}
		this.want_video_high_speed = want_video_high_speed;
	}

	@Override
	public void setExpoBracketing(boolean want_expo_bracketing) {
		if( MyDebug.LOG )
@@ -3167,7 +3190,7 @@ public class CameraController2 extends CameraController {

		try {
			if( video_recorder != null ) {
				if( supports_photo_video_recording ) {
				if( supports_photo_video_recording && !want_video_high_speed ) {
					createPictureImageReader();
				}
				else {
@@ -3300,7 +3323,7 @@ public class CameraController2 extends CameraController {
        	Surface preview_surface = getPreviewSurface();
        	List<Surface> surfaces;
        	if( video_recorder != null ) {
				if( supports_photo_video_recording ) {
				if( supports_photo_video_recording && !want_video_high_speed ) {
					surfaces = Arrays.asList(preview_surface, video_recorder.getSurface(), imageReader.getSurface());
				}
				else {
@@ -3332,9 +3355,16 @@ public class CameraController2 extends CameraController {
					}
				}
			}
        	if( want_video_high_speed && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) {
				camera.createConstrainedHighSpeedCaptureSession(surfaces,
					myStateCallback,
					handler);
			}
			else {
				camera.createCaptureSession(surfaces,
					myStateCallback,
					handler);
			}
			if( MyDebug.LOG )
				Log.d(TAG, "wait until session created...");
			synchronized( create_capture_session_lock ) {
+50 −8
Original line number Diff line number Diff line
@@ -211,6 +211,9 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu
	private List<CameraController.Size> sizes;
	private int current_size_index = -1; // this is an index into the sizes array, or -1 if sizes not yet set

	private boolean video_slow_motion;
	private boolean supports_video_slow_motion;
	private CameraController.Size video_slow_motion_size;
	private final VideoQualityHandler video_quality_handler = new VideoQualityHandler();

	private Toast last_toast;
@@ -1249,6 +1252,9 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu
		view_angle_y = 43.0f; // set a sensible default
		sizes = null;
		current_size_index = -1;
		video_slow_motion = false;
		supports_video_slow_motion = false;
		video_slow_motion_size = null;
		video_quality_handler.resetCurrentQuality();
		supported_flash_values = null;
		current_flash_index = -1;
@@ -1620,6 +1626,16 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu
			}
		}

		// Setup for slow motion - must be done after setupCameraParameters() and switching to video mode, but before setPreviewSize()
		if( this.is_video && this.supports_video_slow_motion && false /*&& applicationInterface.isVideoSlowMotionPref()*/ ) {
			video_slow_motion = true;
			camera_controller.setVideoHighSpeed(true);
		}
		else {
			video_slow_motion = false;
			camera_controller.setVideoHighSpeed(false);
		}

		if( do_startup_focus && using_android_l && camera_controller.supportsAutoFocus() ) {
			// need to switch flash off for autofocus - and for Android L, need to do this before starting preview (otherwise it won't work in time); for old camera API, need to do this after starting preview!
			set_flash_value_after_autofocus = "";
@@ -1797,6 +1813,18 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu
			this.supports_raw = camera_features.supports_raw;
			this.view_angle_x = camera_features.view_angle_x;
			this.view_angle_y = camera_features.view_angle_y;
			this.supports_video_slow_motion = camera_features.video_sizes_high_speed != null && camera_features.video_sizes_high_speed.size() > 0;
			if( supports_video_slow_motion ) {
				// only use highest high speed resolution for now
				for(int i=0;i<camera_features.video_sizes_high_speed.size();i++) {
					CameraController.Size size = camera_features.video_sizes_high_speed.get(i);
		        	if( video_slow_motion_size == null || size.width*size.height > video_slow_motion_size.width*video_slow_motion_size.height ) {
		        		video_slow_motion_size = size;
		        	}
		        }
				if( MyDebug.LOG )
					Log.d(TAG, "supports_video_slow_motion, size: " + video_slow_motion_size.width + " x " + video_slow_motion_size.height);
			}
			this.video_quality_handler.setVideoSizes(camera_features.video_sizes);
	        this.supported_preview_sizes = camera_features.preview_sizes;
		}
@@ -2411,9 +2439,15 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu
        	CamcorderProfile profile = getCamcorderProfile();
        	if( MyDebug.LOG )
        		Log.d(TAG, "video size: " + profile.videoFrameWidth + " x " + profile.videoFrameHeight);
        	if( video_slow_motion ) {
        		// picture size must match video resolution for slow motion, see doc for CameraDevice.createConstrainedHighSpeedCaptureSession()
				new_size = new CameraController.Size(profile.videoFrameWidth, profile.videoFrameHeight);
			}
			else {
				double targetRatio = ((double) profile.videoFrameWidth) / (double) profile.videoFrameHeight;
				new_size = getOptimalVideoPictureSize(sizes, targetRatio);
			}
    	}
    	else {
    		if( current_size_index != -1 ) {
    			new_size = sizes.get(current_size_index);
@@ -2512,6 +2546,10 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu
				Log.d(TAG, "camera not opened!");
			return CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH);
		}
		if( video_slow_motion ) {
			Log.e(TAG, "shouldn't call getCamcorderProfile in slow motion mode");
			throw new RuntimeException();
		}
		int cameraId = camera_controller.getCameraId();
		CamcorderProfile camcorder_profile = CamcorderProfile.get(cameraId, CamcorderProfile.QUALITY_HIGH); // default
		try {
@@ -2570,6 +2608,10 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu
				Log.d(TAG, "camera not opened!");
			return CamcorderProfile.get(0, CamcorderProfile.QUALITY_HIGH);
		}
		if( video_slow_motion ) {
			Log.e(TAG, "shouldn't call getCamcorderProfile in slow motion mode");
			throw new RuntimeException();
		}
		CamcorderProfile profile;
		int cameraId = camera_controller.getCameraId();
		if( applicationInterface.getForce4KPref() ) {
@@ -5556,7 +5598,7 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu
    public boolean supportsPhotoVideoRecording() {
		if( MyDebug.LOG )
			Log.d(TAG, "supportsPhotoVideoRecording");
    	return supports_photo_video_recording;
    	return supports_photo_video_recording && !video_slow_motion;
	}
    
    public boolean canDisableShutterSound() {