3package org.qtproject.qt.android.multimedia;
5import android.annotation.SuppressLint;
6import android.annotation.TargetApi;
7import android.content.Context;
8import android.graphics.Rect;
9import android.hardware.camera2.CameraAccessException;
10import android.hardware.camera2.CameraCaptureSession;
11import android.hardware.camera2.CameraDevice;
12import android.hardware.camera2.CameraMetadata;
13import android.hardware.camera2.CameraManager;
14import android.hardware.camera2.CaptureFailure;
15import android.hardware.camera2.CaptureResult;
16import android.hardware.camera2.CaptureRequest;
17import android.hardware.camera2.TotalCaptureResult;
18import android.media.Image;
19import android.media.ImageReader;
20import android.os.Handler;
21import android.os.HandlerThread;
22import android.util.Log;
23import android.util.Range;
24import android.view.Surface;
25import java.lang.Thread;
26import java.util.ArrayList;
29import org.qtproject.qt.android.UsedFromNativeCode;
40 CameraDevice mCameraDevice =
null;
41 QtVideoDeviceManager mVideoDeviceManager =
null;
43 HandlerThread mBackgroundThread;
47 ImageReader mPreviewImageReader =
null;
49 ImageReader mStillPhotoImageReader =
null;
50 CameraManager mCameraManager;
51 CameraCaptureSession mCaptureSession;
52 CaptureRequest.Builder mPreviewRequestBuilder;
53 CaptureRequest mPreviewRequest;
57 private static int MaxNumberFrames = 12;
59 private static final int DEFAULT_FLASH_MODE = CaptureRequest.CONTROL_AE_MODE_ON;
60 private static final int DEFAULT_TORCH_MODE = CameraMetadata.FLASH_MODE_OFF;
62 private static final int DEFAULT_AF_MODE = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
63 private static final float DEFAULT_FOCUS_DISTANCE = 1.f;
64 private static final float DEFAULT_ZOOM_FACTOR = 1.0f;
66 class CameraSettings {
78 public int mStillPhotoFlashMode = DEFAULT_FLASH_MODE;
85 public int mTorchMode = DEFAULT_TORCH_MODE;
93 public int mAFMode = DEFAULT_AF_MODE;
99 public float mFocusDistance = DEFAULT_FOCUS_DISTANCE;
103 public float mZoomFactor = DEFAULT_ZOOM_FACTOR;
105 Range<Integer> mFpsRange =
null;
107 public CameraSettings() { }
109 public CameraSettings(CameraSettings other) {
110 this.mStillPhotoFlashMode = other.mStillPhotoFlashMode;
111 this.mTorchMode = other.mTorchMode;
112 this.mAFMode = other.mAFMode;
113 this.mFocusDistance = other.mFocusDistance;
114 this.mZoomFactor = other.mZoomFactor;
115 if (other.mFpsRange !=
null) {
116 this.mFpsRange =
new Range<Integer>(other.mFpsRange.getLower(), other.mFpsRange.getUpper());
126 class SyncedMembers {
127 private boolean mIsStarted =
false;
129 private boolean mIsTakingStillPhoto =
false;
131 private CameraSettings mCameraSettings =
new CameraSettings();
133 private final SyncedMembers mSyncedMembers =
new SyncedMembers();
137 public void resetControlProperties() {
138 synchronized (mSyncedMembers) {
139 mSyncedMembers.mCameraSettings =
new CameraSettings();
144 private CameraSettings atomicCameraSettingsCopy() {
145 synchronized (mSyncedMembers) {
146 return new CameraSettings(mSyncedMembers.mCameraSettings);
150 private QtExifDataHandler mExifDataHandler =
null;
155 CameraDevice.StateCallback mStateCallback =
new CameraDevice.StateCallback() {
157 public void onOpened(CameraDevice cameraDevice) {
158 if (mCameraDevice !=
null)
159 mCameraDevice.close();
160 mCameraDevice = cameraDevice;
164 public void onDisconnected(CameraDevice cameraDevice) {
165 cameraDevice.close();
166 if (mCameraDevice == cameraDevice)
167 mCameraDevice =
null;
171 public void onError(CameraDevice cameraDevice,
int error) {
172 cameraDevice.close();
173 if (mCameraDevice == cameraDevice)
174 mCameraDevice =
null;
181 CameraCaptureSession.StateCallback mCaptureStateCallback =
new CameraCaptureSession.StateCallback() {
183 public void onConfigured(CameraCaptureSession cameraCaptureSession) {
184 mCaptureSession = cameraCaptureSession;
189 public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
194 public void onActive(CameraCaptureSession cameraCaptureSession) {
195 super.onActive(cameraCaptureSession);
200 public void onClosed(CameraCaptureSession cameraCaptureSession) {
201 super.onClosed(cameraCaptureSession);
212 class PreviewCaptureSessionCallback
extends CameraCaptureSession.CaptureCallback {
214 public void onCaptureFailed(
215 CameraCaptureSession session,
217 CaptureFailure failure)
219 super.onCaptureFailed(session,
request, failure);
227 PreviewCaptureSessionCallback mPreviewCaptureCallback =
new PreviewCaptureSessionCallback();
230 mCameraManager = (CameraManager)
context.getSystemService(
Context.CAMERA_SERVICE);
231 mVideoDeviceManager =
new QtVideoDeviceManager(
context);
232 startBackgroundThread();
235 void startBackgroundThread() {
236 mBackgroundThread =
new HandlerThread(
"CameraBackground");
237 mBackgroundThread.start();
238 mBackgroundHandler =
new Handler(mBackgroundThread.getLooper());
242 void stopBackgroundThread() {
243 mBackgroundThread.quitSafely();
245 mBackgroundThread.join();
246 mBackgroundThread =
null;
247 mBackgroundHandler =
null;
248 }
catch (Exception e) {
253 @SuppressLint(
"MissingPermission")
256 mCameraId = cameraId;
257 mCameraManager.openCamera(cameraId,mStateCallback,mBackgroundHandler);
259 }
catch (Exception e){
260 Log.w(
"QtCamera2",
"Failed to open camera:" + e);
269 ImageReader.OnImageAvailableListener mOnStillPhotoAvailableListener =
new ImageReader.OnImageAvailableListener() {
271 public void onImageAvailable(ImageReader reader) {
272 QtCamera2.this.onStillPhotoAvailable(mCameraId,
reader.acquireLatestImage());
279 ImageReader.OnImageAvailableListener mOnPreviewImageAvailableListener =
new ImageReader.OnImageAvailableListener() {
281 public void onImageAvailable(ImageReader reader) {
285 QtCamera2.this.onPreviewFrameAvailable(mCameraId,
img);
286 }
catch (IllegalStateException e) {
289 Log.e(
"QtCamera2",
"Image processing taking too long. Let's wait 0,5s more " + e);
292 QtCamera2.this.onPreviewFrameAvailable(mCameraId,
reader.acquireLatestImage());
293 }
catch (IllegalStateException | InterruptedException e2) {
294 Log.e(
"QtCamera2",
"Will not wait anymore. Restart camera session. " + e2);
296 String cameraId = mCameraId;
299 mPreviewImageReader.getWidth(),
300 mPreviewImageReader.getHeight(),
301 mPreviewImageReader.getImageFormat());
312 setFrameRate(minFps, maxFps);
317 if (mPreviewImageReader !=
null)
318 removeSurface(mPreviewImageReader.getSurface());
320 if (mStillPhotoImageReader !=
null)
321 removeSurface(mStillPhotoImageReader.getSurface());
323 mPreviewImageReader = ImageReader.newInstance(
width,
height,
format, MaxNumberFrames);
324 mPreviewImageReader.setOnImageAvailableListener(mOnPreviewImageAvailableListener, mBackgroundHandler);
325 addSurface(mPreviewImageReader.getSurface());
327 mStillPhotoImageReader = ImageReader.newInstance(
width,
height,
format, MaxNumberFrames);
328 mStillPhotoImageReader.setOnImageAvailableListener(mOnStillPhotoAvailableListener, mBackgroundHandler);
329 addSurface(mStillPhotoImageReader.getSurface());
332 private void setFrameRate(
int minFrameRate,
int maxFrameRate) {
333 synchronized (mSyncedMembers) {
334 if (minFrameRate <= 0 || maxFrameRate <= 0)
335 mSyncedMembers.mCameraSettings.mFpsRange =
null;
337 mSyncedMembers.mCameraSettings.mFpsRange =
new Range<>(minFrameRate, maxFrameRate);
341 boolean addSurface(Surface surface) {
342 if (mTargetSurfaces.contains(surface))
345 return mTargetSurfaces.add(surface);
348 boolean removeSurface(Surface surface) {
349 return mTargetSurfaces.remove(surface);
353 void clearSurfaces() {
354 mTargetSurfaces.clear();
358 boolean createSession() {
359 if (mCameraDevice ==
null)
365 mCameraDevice.createCaptureSession(mTargetSurfaces, mCaptureStateCallback, mBackgroundHandler);
367 }
catch (Exception exception) {
368 Log.w(
"QtCamera2",
"Failed to create a capture session:" + exception);
375 if (mCameraDevice ==
null)
378 if (mCaptureSession ==
null)
382 synchronized (mSyncedMembers) {
383 setRepeatingRequestToPreview();
384 mSyncedMembers.mIsStarted =
true;
387 }
catch (CameraAccessException exception) {
388 Log.w(
"QtCamera2",
"Failed to start preview:" + exception);
394 void stopAndClose() {
395 synchronized (mSyncedMembers) {
397 if (
null != mCaptureSession) {
398 mCaptureSession.close();
399 mCaptureSession =
null;
401 if (
null != mCameraDevice) {
402 mCameraDevice.close();
403 mCameraDevice =
null;
406 mTargetSurfaces.clear();
407 }
catch (Exception exception) {
408 Log.w(
"QtCamera2",
"Failed to stop and close:" + exception);
410 mSyncedMembers.mIsStarted =
false;
411 mSyncedMembers.mIsTakingStillPhoto =
false;
424 class StillPhotoPrecaptureCallback
extends CameraCaptureSession.CaptureCallback {
425 StillPhotoPrecaptureCallback(
426 CameraSettings cameraSettings,
427 boolean waitForAutoFocus,
428 boolean waitForAutoExposure)
430 this.mCameraSettings = cameraSettings;
431 this.mWaitForAutoFocus = waitForAutoFocus;
432 this.mWaitForAutoExposure = waitForAutoExposure;
437 CameraSettings mCameraSettings =
null;
438 boolean mWaitForAutoFocus =
false;
439 boolean mWaitForAutoExposure =
false;
445 boolean mShouldProcessIncomingEvents =
true;
447 boolean capturingWithAutoFlash() {
448 return mWaitForAutoExposure
449 && mCameraSettings.mStillPhotoFlashMode == CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH;
452 private void onCaptureFailureEvent() {
453 mShouldProcessIncomingEvents =
false;
457 synchronized (mSyncedMembers) {
458 mSyncedMembers.mIsTakingStillPhoto =
false;
463 setRepeatingRequestToPreview();
464 }
catch (CameraAccessException e) {
471 public void onCaptureFailed(
472 CameraCaptureSession session,
474 CaptureFailure failure)
476 onCaptureFailureEvent();
480 private StillPhotoPrecaptureOperation determinePrecaptureOperation(CaptureResult
result) {
481 Integer afState =
result.get(CaptureResult.CONTROL_AF_STATE);
482 Integer aeState =
result.get(CaptureResult.CONTROL_AE_STATE);
487 if (capturingWithAutoFlash() && aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED) {
488 return StillPhotoPrecaptureOperation.RESUBMIT_WITH_FORCED_FLASH;
492 if (!mWaitForAutoFocus && !mWaitForAutoExposure) {
493 return StillPhotoPrecaptureOperation.FINALIZE_CAPTURE;
497 if (mWaitForAutoFocus && QtCamera2.afStateIsReadyForCapture(afState)
498 && !mWaitForAutoExposure)
500 return StillPhotoPrecaptureOperation.FINALIZE_CAPTURE;
504 if (!mWaitForAutoFocus
505 && mWaitForAutoExposure && QtCamera2.aeStateIsReadyForCapture(aeState))
507 return StillPhotoPrecaptureOperation.FINALIZE_CAPTURE;
511 if (mWaitForAutoFocus && QtCamera2.afStateIsReadyForCapture(afState)
512 && mWaitForAutoExposure && QtCamera2.aeStateIsReadyForCapture(aeState))
514 return StillPhotoPrecaptureOperation.FINALIZE_CAPTURE;
517 return StillPhotoPrecaptureOperation.WAIT;
521 public void onCaptureCompleted(
522 CameraCaptureSession
s,
524 TotalCaptureResult
result)
526 if (!mShouldProcessIncomingEvents)
529 final StillPhotoPrecaptureOperation operation = determinePrecaptureOperation(
result);
532 case FINALIZE_CAPTURE:
533 finalizeStillPhoto(mCameraSettings);
535 case RESUBMIT_WITH_FORCED_FLASH:
537 CameraSettings newCameraSettings =
new CameraSettings(mCameraSettings);
538 newCameraSettings.mStillPhotoFlashMode = CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH;
539 submitNewStillPhotoCapture(newCameraSettings);
545 }
catch (CameraAccessException e) {
546 onCaptureFailureEvent();
549 if (operation != StillPhotoPrecaptureOperation.WAIT) {
550 mShouldProcessIncomingEvents =
false;
558 class StillPhotoFinalizerCallback
extends CameraCaptureSession.CaptureCallback {
564 public void onCaptureFailed(
565 CameraCaptureSession session,
567 CaptureFailure failure)
570 synchronized (mSyncedMembers) {
571 mSyncedMembers.mIsTakingStillPhoto =
false;
574 setRepeatingRequestToPreview();
575 }
catch (CameraAccessException e) {
582 public void onCaptureCompleted(
583 CameraCaptureSession session,
585 TotalCaptureResult
result)
588 mExifDataHandler =
new QtExifDataHandler(
result);
589 synchronized (mSyncedMembers) {
592 if (mSyncedMembers.mIsStarted) {
593 setRepeatingRequestToPreview();
598 mSyncedMembers.mIsTakingStillPhoto =
false;
600 }
catch (CameraAccessException e) {
602 }
catch (NullPointerException e) {
611 "Null-pointer access exception thrown when finalizing still photo capture. " +
612 "This should not be possible.");
614 }
catch (IllegalStateException e) {
618 Log.w(
"QtCamera2",
"Session is no longer active.");
626 private void finalizeStillPhoto(CameraSettings cameraSettings)
throws CameraAccessException
628 final CaptureRequest.Builder requestBuilder =
629 mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
630 requestBuilder.addTarget(mStillPhotoImageReader.getSurface());
632 CaptureRequest.CONTROL_CAPTURE_INTENT,
633 CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
635 applyStillPhotoSettingsToCaptureRequestBuilder(
639 mCaptureSession.capture(
640 requestBuilder.build(),
641 new StillPhotoFinalizerCallback(),
662 void beginStillPhotoCapture() {
663 synchronized (mSyncedMembers) {
664 if (mSyncedMembers.mIsTakingStillPhoto) {
669 "beginStillPhotoCapture() was called on camera backend while there " +
670 "is already a still photo in progress. This is not supported. Likely Qt " +
676 final CameraSettings cameraSettings = atomicCameraSettingsCopy();
678 submitNewStillPhotoCapture(cameraSettings);
679 }
catch (CameraAccessException e) {
680 Log.w(
"QtCamera2",
"Cannot get access to the camera: " + e);
688 void submitNewStillPhotoCapture(CameraSettings cameraSettings)
throws CameraAccessException
690 CaptureRequest.Builder requestBuilder = mCameraDevice.createCaptureRequest(
691 CameraDevice.TEMPLATE_STILL_CAPTURE);
694 requestBuilder.addTarget(mPreviewImageReader.getSurface());
696 applyStillPhotoSettingsToCaptureRequestBuilder(
704 final boolean triggerAutoFocus = requestBuilder.get(CaptureRequest.CONTROL_AF_MODE)
705 == CaptureResult.CONTROL_AF_MODE_AUTO;
707 final Integer aeMode = requestBuilder.get(CaptureRequest.CONTROL_AE_MODE);
708 boolean triggerAutoExposure = aeMode !=
null
709 && aeMode != CaptureResult.CONTROL_AE_MODE_OFF;
711 final StillPhotoPrecaptureCallback precaptureCallback =
new StillPhotoPrecaptureCallback(
714 triggerAutoExposure);
716 mCaptureSession.setRepeatingRequest(
717 requestBuilder.build(),
724 if (triggerAutoFocus) {
726 CaptureRequest.CONTROL_AF_TRIGGER,
727 CaptureRequest.CONTROL_AF_TRIGGER_START);
729 if (triggerAutoExposure) {
731 CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
732 CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
736 mCaptureSession.capture(
737 requestBuilder.build(),
741 synchronized (mSyncedMembers) {
742 mSyncedMembers.mIsTakingStillPhoto =
true;
749 if (mExifDataHandler !=
null)
750 mExifDataHandler.save(
path);
752 Log.e(
"QtCamera2",
"No Exif data that could be saved to " +
path);
755 private Rect getScalerCropRegion(
float zoomFactor)
757 Rect activePixels = mVideoDeviceManager.getActiveArraySize(mCameraId);
758 float zoomRatio = 1.0f;
759 if (zoomFactor != 0.0
f)
760 zoomRatio = 1.0f / zoomFactor;
762 int croppedWidth = activePixels.width() - (int)(activePixels.width() * zoomRatio);
763 int croppedHeight = activePixels.height() - (int)(activePixels.height() * zoomRatio);
764 return new Rect(croppedWidth/2, croppedHeight/2, activePixels.width() - croppedWidth/2,
765 activePixels.height() - croppedHeight/2);
768 private void applyZoomSettingsToRequestBuilder(CaptureRequest.Builder requBuilder,
float zoomFactor)
770 if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R) {
771 requBuilder.set(CaptureRequest.SCALER_CROP_REGION, getScalerCropRegion(zoomFactor));
773 requBuilder.set(CaptureRequest.CONTROL_ZOOM_RATIO, zoomFactor);
778 void zoomTo(
float factor)
780 synchronized (mSyncedMembers) {
781 mSyncedMembers.mCameraSettings.mZoomFactor = factor;
783 if (!mSyncedMembers.mIsStarted) {
791 applyZoomSettingsToRequestBuilder(mPreviewRequestBuilder, factor);
792 mPreviewRequest = mPreviewRequestBuilder.build();
794 if (mSyncedMembers.mIsTakingStillPhoto) {
800 mCaptureSession.setRepeatingRequest(
802 mPreviewCaptureCallback,
804 }
catch (Exception exception) {
805 Log.w(
"QtCamera2",
"Failed to set zoom:" + exception);
814 void setFocusMode(
int newFocusMode)
823 if (newFocusMode == 0)
824 newAfMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
825 else if (newFocusMode == 5)
826 newAfMode = CaptureRequest.CONTROL_AF_MODE_OFF;
830 "received a QCamera::FocusMode from native code that is not recognized. " +
831 "Likely Qt developer bug. Ignoring.");
848 synchronized (mSyncedMembers) {
849 mSyncedMembers.mCameraSettings.mAFMode = newAfMode;
853 if (!mSyncedMembers.mIsStarted)
856 applyFocusSettingsToCaptureRequestBuilder(
857 mPreviewRequestBuilder,
858 mSyncedMembers.mCameraSettings,
860 mPreviewRequest = mPreviewRequestBuilder.build();
862 if (mSyncedMembers.mIsTakingStillPhoto) {
868 mCaptureSession.setRepeatingRequest(
870 mPreviewCaptureCallback,
872 }
catch (Exception exception) {
873 Log.w(
"QtCamera2",
"Failed to set focus mode:" + exception);
879 void setFlashMode(
String flashMode)
881 synchronized (mSyncedMembers) {
882 int flashModeValue = mVideoDeviceManager.stringToControlAEMode(flashMode);
883 if (flashModeValue < 0) {
884 Log.w(
"QtCamera2",
"Unknown flash mode");
887 mSyncedMembers.mCameraSettings.mStillPhotoFlashMode = flashModeValue;
897 public void setFocusDistance(
float distanceInput)
899 if (distanceInput < 0.f || distanceInput > 1.
f) {
902 "received out-of-bounds value when setting camera focus-distance. " +
903 "Likely Qt developer bug. Ignoring.");
910 synchronized (mSyncedMembers) {
911 mSyncedMembers.mCameraSettings.mFocusDistance = distanceInput;
915 if (!mSyncedMembers.mIsStarted)
920 if (mSyncedMembers.mCameraSettings.mAFMode == CaptureRequest.CONTROL_AF_MODE_OFF) {
921 applyFocusSettingsToCaptureRequestBuilder(
922 mPreviewRequestBuilder,
923 mSyncedMembers.mCameraSettings,
926 mPreviewRequest = mPreviewRequestBuilder.build();
928 if (mSyncedMembers.mIsTakingStillPhoto) {
935 mCaptureSession.setRepeatingRequest(
937 mPreviewCaptureCallback,
939 }
catch (Exception exception) {
940 Log.w(
"QtCamera2",
"Failed to set focus distance:" + exception);
946 private int getTorchModeValue(
boolean mode)
948 return mode ? CameraMetadata.FLASH_MODE_TORCH : CameraMetadata.FLASH_MODE_OFF;
952 void setTorchMode(
boolean torchMode)
954 synchronized (mSyncedMembers) {
955 mSyncedMembers.mCameraSettings.mTorchMode = getTorchModeValue(torchMode);
957 if (mSyncedMembers.mIsStarted) {
958 mPreviewRequestBuilder.set(CaptureRequest.FLASH_MODE, mSyncedMembers.mCameraSettings.mTorchMode);
959 mPreviewRequest = mPreviewRequestBuilder.build();
961 if (mSyncedMembers.mIsTakingStillPhoto) {
968 mCaptureSession.setRepeatingRequest(
970 mPreviewCaptureCallback,
972 }
catch (Exception exception) {
973 Log.w(
"QtCamera2",
"Failed to set flash mode:" + exception);
982 private void setRepeatingRequestToPreview() throws CameraAccessException {
983 synchronized (mSyncedMembers) {
984 mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
985 mPreviewRequestBuilder.addTarget(mPreviewImageReader.getSurface());
987 applyPreviewSettingsToCaptureRequestBuilder(
988 mPreviewRequestBuilder,
989 mSyncedMembers.mCameraSettings);
991 mPreviewRequest = mPreviewRequestBuilder.build();
992 mCaptureSession.setRepeatingRequest(
994 mPreviewCaptureCallback,
999 private void applyStillPhotoSettingsToCaptureRequestBuilder(
1000 CaptureRequest.Builder requestBuilder,
1001 CameraSettings cameraSettings)
1004 CaptureRequest.CONTROL_CAPTURE_INTENT,
1005 CaptureRequest.CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
1009 CaptureRequest.CONTROL_MODE,
1010 CaptureRequest.CONTROL_MODE_AUTO);
1014 CaptureRequest.CONTROL_AE_MODE,
1015 CaptureRequest.CONTROL_AE_MODE_ON);
1017 applyZoomSettingsToRequestBuilder(requestBuilder, cameraSettings.mZoomFactor);
1019 applyFocusSettingsToCaptureRequestBuilder(
1027 if (cameraSettings.mStillPhotoFlashMode == CaptureRequest.CONTROL_AE_MODE_ON_ALWAYS_FLASH) {
1029 CaptureRequest.CONTROL_AE_MODE,
1030 CaptureRequest.CONTROL_AE_MODE_ON);
1036 CaptureRequest.FLASH_MODE,
1037 CaptureRequest.FLASH_MODE_TORCH);
1038 }
else if (cameraSettings.mStillPhotoFlashMode == CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH) {
1040 CaptureRequest.CONTROL_AE_MODE,
1041 CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
1045 private void applyPreviewSettingsToCaptureRequestBuilder(
1046 CaptureRequest.Builder requestBuilder,
1047 CameraSettings cameraSettings)
1049 requestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CameraMetadata.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
1051 applyFocusSettingsToCaptureRequestBuilder(
1057 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
1058 requestBuilder.set(CaptureRequest.FLASH_MODE, cameraSettings.mTorchMode);
1060 applyZoomSettingsToRequestBuilder(requestBuilder, cameraSettings.mZoomFactor);
1061 if (cameraSettings.mFpsRange !=
null) {
1063 CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
1064 cameraSettings.mFpsRange);
1069 mPreviewRequestBuilder.set(
1070 CaptureRequest.CONTROL_AF_TRIGGER,
1071 CameraMetadata.CONTROL_AF_TRIGGER_IDLE);
1072 mPreviewRequestBuilder.set(
1073 CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
1074 CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
1079 void applyFocusSettingsToCaptureRequestBuilder(
1080 CaptureRequest.Builder requestBuilder,
1081 CameraSettings cameraSettings,
1084 int desiredAfMode = cameraSettings.mAFMode;
1089 if (stillPhoto && desiredAfMode == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE) {
1090 desiredAfMode = CaptureRequest.CONTROL_AF_MODE_AUTO;
1093 if (!isAfModeAvailable(desiredAfMode)) {
1098 if (isAfModeAvailable(CaptureRequest.CONTROL_AF_MODE_OFF)) {
1100 CaptureRequest.CONTROL_AF_MODE,
1101 CaptureRequest.CONTROL_AF_MODE_OFF);
1104 requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE,
null);
1108 requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, desiredAfMode);
1111 if (desiredAfMode == CaptureRequest.CONTROL_AF_MODE_OFF) {
1112 final float lensFocusDistance = calcLensFocusDistanceFromQCameraFocusDistance(
1113 cameraSettings.mFocusDistance);
1114 if (lensFocusDistance < 0) {
1117 "Tried to apply FocusModeManual on a camera that doesn't support "
1118 +
"setting lens distance. Likely Qt developer bug. Ignoring.");
1120 requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, lensFocusDistance);
1123 requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE,
null);
1130 private float calcLensFocusDistanceFromQCameraFocusDistance(
float qCameraFocusDistance) {
1131 float lensMinimumFocusDistance =
1132 mVideoDeviceManager.getLensInfoMinimumFocusDistance(mCameraId);
1133 if (lensMinimumFocusDistance <= 0)
1140 return (1.
f - qCameraFocusDistance) * lensMinimumFocusDistance;
1145 private boolean isAfModeAvailable(
int afMode) {
1146 if (mVideoDeviceManager ==
null || mCameraId ==
null || mCameraId.isEmpty())
1148 return mVideoDeviceManager.isAfModeAvailable(mCameraId, afMode);
1153 static boolean afStateIsReadyForCapture(
Integer afState) {
1154 return afState ==
null
1155 || afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED
1156 || afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED;
1159 static boolean aeStateIsReadyForCapture(
Integer aeState) {
1160 return aeState ==
null
1161 || aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED
1162 || aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED;
static void onPreviewFrameAvailable(JNIEnv *env, jobject obj, jstring cameraId, QtJniTypes::Image image)
static void onCaptureSessionFailed(JNIEnv *env, jobject obj, jstring cameraId, jint reason, jlong framenumber)
static void onSessionClosed(JNIEnv *env, jobject obj, jstring cameraId)
static void onStillPhotoCaptureFailed(JNIEnv *env, jobject obj, jstring cameraId)
static void onCameraError(JNIEnv *env, jobject obj, jstring cameraId, jint error)
static void onCaptureSessionConfigureFailed(JNIEnv *env, jobject obj, jstring cameraId)
static void onCameraOpened(JNIEnv *env, jobject obj, jstring cameraId)
static void onSessionActive(JNIEnv *env, jobject obj, jstring cameraId)
static void onCameraDisconnect(JNIEnv *env, jobject obj, jstring cameraId)
static void onCaptureSessionConfigured(JNIEnv *env, jobject obj, jstring cameraId)
static void onStillPhotoAvailable(JNIEnv *env, jobject obj, jstring cameraId, QtJniTypes::Image image)
static const QString context()
QImageReader reader("image.png")
[1]
DBusConnection const char DBusError * error
GLsizei const GLchar *const * path
file open(QIODevice::ReadOnly)
QNetworkRequest request(url)
[0]