Skip to content

Commit 57d234c

Browse files
authored
Improve threading, add CameraOptions.supports() (#13)
* abstract WorkerHandler class, cleanup * Start and stop in our thread * Simplify Camera1 threading * Add CameraOptions.supports() shorthands * Improve supports() shorthands * Rearrange orientation callbacks
1 parent cbac776 commit 57d234c

File tree

8 files changed

+358
-271
lines changed

8 files changed

+358
-271
lines changed

cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java

Lines changed: 36 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import android.os.Handler;
1212
import android.support.annotation.NonNull;
1313
import android.support.annotation.Nullable;
14+
import android.support.annotation.WorkerThread;
1415
import android.util.Log;
1516
import android.view.SurfaceHolder;
1617

@@ -26,24 +27,31 @@ class Camera1 extends CameraController {
2627

2728
private static final String TAG = Camera1.class.getSimpleName();
2829

29-
private static final int DELAY_MILLIS_BEFORE_RESETTING_FOCUS = 3000;
30-
3130
private int mCameraId;
3231
private Camera mCamera;
33-
private ExtraProperties mExtraProperties;
34-
private CameraOptions mOptions;
35-
private Size mPreviewSize;
36-
private Size mCaptureSize;
3732
private MediaRecorder mMediaRecorder;
3833
private File mVideoFile;
3934

40-
private int mDisplayOffset;
41-
private int mDeviceOrientation;
4235
private int mSensorOffset;
4336

4437
private Location mLocation;
4538

46-
private Handler mFocusHandler = new Handler();
39+
private final int mPostFocusResetDelay = 3000;
40+
private Runnable mPostFocusResetRunnable = new Runnable() {
41+
@Override
42+
public void run() {
43+
if (!isCameraOpened()) return;
44+
mCamera.cancelAutoFocus();
45+
synchronized (mLock) {
46+
Camera.Parameters params = mCamera.getParameters();
47+
params.setFocusAreas(null);
48+
params.setMeteringAreas(null);
49+
applyDefaultFocus(params); // Revert to internal focus.
50+
mCamera.setParameters(params);
51+
}
52+
}
53+
};
54+
4755
private Mapper mMapper = new Mapper.Mapper1();
4856
private boolean mIsSetup = false;
4957
private boolean mIsCapturingImage = false;
@@ -129,9 +137,10 @@ private void setup() {
129137
}
130138

131139

140+
@WorkerThread
132141
@Override
133-
void start() {
134-
if (isCameraOpened()) stop();
142+
void onStart() {
143+
if (isCameraOpened()) onStop();
135144
if (collectCameraId()) {
136145
mCamera = Camera.open(mCameraId);
137146

@@ -155,10 +164,10 @@ void start() {
155164
}
156165
}
157166

158-
167+
@WorkerThread
159168
@Override
160-
void stop() {
161-
mFocusHandler.removeCallbacksAndMessages(null);
169+
void onStop() {
170+
mHandler.get().removeCallbacks(mPostFocusResetRunnable);
162171
if (isCameraOpened()) {
163172
if (mIsCapturingVideo) endVideo();
164173
mCamera.stopPreview();
@@ -187,17 +196,6 @@ private boolean collectCameraId() {
187196
return false;
188197
}
189198

190-
@Override
191-
void onDisplayOffset(int displayOrientation) {
192-
// I doubt this will ever change.
193-
this.mDisplayOffset = displayOrientation;
194-
}
195-
196-
@Override
197-
void onDeviceOrientation(int deviceOrientation) {
198-
this.mDeviceOrientation = deviceOrientation;
199-
}
200-
201199

202200
@Override
203201
void setSessionType(SessionType sessionType) {
@@ -260,7 +258,7 @@ void setWhiteBalance(WhiteBalance whiteBalance) {
260258
}
261259

262260
private boolean mergeWhiteBalance(Camera.Parameters params, WhiteBalance oldWhiteBalance) {
263-
if (mOptions.getSupportedWhiteBalance().contains(mWhiteBalance)) {
261+
if (mOptions.supports(mWhiteBalance)) {
264262
params.setWhiteBalance((String) mMapper.map(mWhiteBalance));
265263
return true;
266264
}
@@ -281,7 +279,7 @@ void setHdr(Hdr hdr) {
281279
}
282280

283281
private boolean mergeHdr(Camera.Parameters params, Hdr oldHdr) {
284-
if (mOptions.getSupportedHdr().contains(mHdr)) {
282+
if (mOptions.supports(mHdr)) {
285283
params.setSceneMode((String) mMapper.map(mHdr));
286284
return true;
287285
}
@@ -303,7 +301,7 @@ void setFlash(Flash flash) {
303301

304302

305303
private boolean mergeFlash(Camera.Parameters params, Flash oldFlash) {
306-
if (mOptions.getSupportedFlash().contains(mFlash)) {
304+
if (mOptions.supports(mFlash)) {
307305
params.setFlashMode((String) mMapper.map(mFlash));
308306
return true;
309307
}
@@ -390,9 +388,15 @@ boolean capturePicture() {
390388
mCamera.takePicture(null, null, null,
391389
new Camera.PictureCallback() {
392390
@Override
393-
public void onPictureTaken(byte[] data, Camera camera) {
391+
public void onPictureTaken(byte[] data, final Camera camera) {
394392
mIsCapturingImage = false;
395-
camera.startPreview(); // This is needed, read somewhere in the docs.
393+
mHandler.post(new Runnable() {
394+
@Override
395+
public void run() {
396+
// This is needed, read somewhere in the docs.
397+
camera.startPreview();
398+
}
399+
});
396400
mCameraCallbacks.processImage(data, consistentWithView, exifFlip);
397401
}
398402
});
@@ -443,16 +447,6 @@ public void run() {
443447
return true;
444448
}
445449

446-
@Override
447-
Size getCaptureSize() {
448-
return mCaptureSize;
449-
}
450-
451-
@Override
452-
Size getPreviewSize() {
453-
return mPreviewSize;
454-
}
455-
456450
@Override
457451
boolean shouldFlipSizes() {
458452
return mSensorOffset % 180 != 0;
@@ -463,17 +457,6 @@ boolean isCameraOpened() {
463457
return mCamera != null;
464458
}
465459

466-
@Nullable
467-
@Override
468-
ExtraProperties getExtraProperties() {
469-
return mExtraProperties;
470-
}
471-
472-
@Nullable
473-
@Override
474-
CameraOptions getCameraOptions() {
475-
return mOptions;
476-
}
477460

478461
// Internal:
479462

@@ -715,33 +698,15 @@ boolean startAutoFocus(@Nullable final Gesture gesture, PointF point) {
715698
public void onAutoFocus(boolean success, Camera camera) {
716699
// TODO lock auto exposure and white balance for a while
717700
mCameraCallbacks.dispatchOnFocusEnd(gesture, success, p);
718-
postResetFocus();
701+
mHandler.get().removeCallbacks(mPostFocusResetRunnable);
702+
mHandler.get().postDelayed(mPostFocusResetRunnable, mPostFocusResetDelay);
719703
}
720704
});
721705
}
722706
return true;
723707
}
724708

725709

726-
private void postResetFocus() {
727-
mFocusHandler.removeCallbacksAndMessages(null);
728-
mFocusHandler.postDelayed(new Runnable() {
729-
@Override
730-
public void run() {
731-
if (!isCameraOpened()) return;
732-
mCamera.cancelAutoFocus();
733-
synchronized (mLock) {
734-
Camera.Parameters params = mCamera.getParameters();
735-
params.setFocusAreas(null);
736-
params.setMeteringAreas(null);
737-
applyDefaultFocus(params); // Revert to internal focus.
738-
mCamera.setParameters(params);
739-
}
740-
}
741-
}, DELAY_MILLIS_BEFORE_RESETTING_FOCUS);
742-
}
743-
744-
745710
private List<Camera.Area> computeMeteringAreas(double viewClickX, double viewClickY) {
746711
// Event came in view coordinates. We must rotate to sensor coordinates.
747712
// First, rescale to the -1000 ... 1000 range.

cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java

Lines changed: 6 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import android.location.Location;
1313
import android.support.annotation.NonNull;
1414
import android.support.annotation.Nullable;
15+
import android.support.annotation.WorkerThread;
1516
import android.util.Log;
1617

1718
import java.io.File;
@@ -29,8 +30,6 @@ class Camera2 extends CameraController {
2930

3031
private String mCameraId;
3132

32-
private Size mCaptureSize;
33-
private Size mPreviewSize;
3433

3534
private Mapper mMapper = new Mapper.Mapper2();
3635
private final HashMap<String, ExtraProperties> mExtraPropertiesMap = new HashMap<>();
@@ -79,13 +78,15 @@ public void onSurfaceAvailable() {
7978

8079
// CameraImpl:
8180

81+
@WorkerThread
8282
@Override
83-
void start() {
83+
void onStart() {
8484

8585
}
8686

87+
@WorkerThread
8788
@Override
88-
void stop() {
89+
void onStop() {
8990

9091
}
9192

@@ -186,57 +187,7 @@ boolean endVideo() {
186187
return false;
187188
}
188189

189-
@Override
190-
Size getCaptureSize() {
191-
if (mCaptureSize == null && mCameraCharacteristics != null) {
192-
TreeSet<Size> sizes = new TreeSet<>();
193-
sizes.addAll(getAvailableCaptureResolutions());
194-
195-
/* TreeSet<AspectRatio> aspectRatios = new CommonAspectRatioFilter(
196-
getAvailablePreviewResolutions(),
197-
getAvailableCaptureResolutions()
198-
).filter();
199-
AspectRatio targetRatio = aspectRatios.size() > 0 ? aspectRatios.last() : null;
200-
201-
Iterator<Size> descendingSizes = sizes.descendingIterator();
202-
Size size;
203-
while (descendingSizes.hasNext() && mCaptureSize == null) {
204-
size = descendingSizes.next();
205-
if (targetRatio == null || targetRatio.matches(size)) {
206-
mCaptureSize = size;
207-
break;
208-
}
209-
} */
210-
}
211190

212-
return mCaptureSize;
213-
}
214-
215-
@Override
216-
Size getPreviewSize() {
217-
if (mPreviewSize == null && mCameraCharacteristics != null) {
218-
TreeSet<Size> sizes = new TreeSet<>();
219-
sizes.addAll(getAvailablePreviewResolutions());
220-
221-
/* TreeSet<AspectRatio> aspectRatios = new CommonAspectRatioFilter(
222-
getAvailablePreviewResolutions(),
223-
getAvailableCaptureResolutions()
224-
).filter();
225-
AspectRatio targetRatio = aspectRatios.size() > 0 ? aspectRatios.last() : null;
226-
227-
Iterator<Size> descendingSizes = sizes.descendingIterator();
228-
Size size;
229-
while (descendingSizes.hasNext() && mPreviewSize == null) {
230-
size = descendingSizes.next();
231-
if (targetRatio == null || targetRatio.matches(size)) {
232-
mPreviewSize = size;
233-
break;
234-
}
235-
} */
236-
}
237-
238-
return mPreviewSize;
239-
}
240191

241192
@Override
242193
boolean shouldFlipSizes() {
@@ -253,22 +204,9 @@ boolean startAutoFocus(Gesture gesture, PointF point) {
253204
return true;
254205
}
255206

256-
@Nullable
257-
@Override
258-
ExtraProperties getExtraProperties() {
259-
if (mCamera == null) {
260-
return null;
261-
}
262-
return mExtraPropertiesMap.get(mCamera.getId());
263-
}
264-
// Internal
265207

208+
// Internal
266209

267-
@Nullable
268-
@Override
269-
CameraOptions getCameraOptions() {
270-
return null;
271-
}
272210

273211
private List<Size> getAvailableCaptureResolutions() {
274212
List<Size> output = new ArrayList<>();

0 commit comments

Comments
 (0)