OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.media; | 5 package org.chromium.media; |
6 | 6 |
7 import android.annotation.TargetApi; | 7 import android.annotation.TargetApi; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.graphics.ImageFormat; | 9 import android.graphics.ImageFormat; |
10 import android.graphics.Rect; | 10 import android.graphics.Rect; |
11 import android.hardware.camera2.CameraAccessException; | 11 import android.hardware.camera2.CameraAccessException; |
12 import android.hardware.camera2.CameraCaptureSession; | 12 import android.hardware.camera2.CameraCaptureSession; |
13 import android.hardware.camera2.CameraCharacteristics; | 13 import android.hardware.camera2.CameraCharacteristics; |
14 import android.hardware.camera2.CameraDevice; | 14 import android.hardware.camera2.CameraDevice; |
15 import android.hardware.camera2.CameraManager; | 15 import android.hardware.camera2.CameraManager; |
16 import android.hardware.camera2.CameraMetadata; | 16 import android.hardware.camera2.CameraMetadata; |
17 import android.hardware.camera2.CaptureRequest; | 17 import android.hardware.camera2.CaptureRequest; |
18 import android.hardware.camera2.params.MeteringRectangle; | 18 import android.hardware.camera2.params.MeteringRectangle; |
19 import android.hardware.camera2.params.StreamConfigurationMap; | 19 import android.hardware.camera2.params.StreamConfigurationMap; |
20 import android.media.Image; | 20 import android.media.Image; |
21 import android.media.ImageReader; | 21 import android.media.ImageReader; |
22 import android.os.Build; | 22 import android.os.Build; |
23 import android.os.Handler; | 23 import android.os.Handler; |
24 import android.os.HandlerThread; | 24 import android.os.HandlerThread; |
25 import android.util.Range; | 25 import android.util.Range; |
26 import android.util.Size; | 26 import android.util.Size; |
27 import android.util.SparseIntArray; | 27 import android.util.SparseIntArray; |
28 import android.view.Surface; | 28 import android.view.Surface; |
29 | 29 |
| 30 import org.chromium.base.ContextUtils; |
30 import org.chromium.base.Log; | 31 import org.chromium.base.Log; |
31 import org.chromium.base.annotations.JNINamespace; | 32 import org.chromium.base.annotations.JNINamespace; |
32 | 33 |
33 import java.nio.ByteBuffer; | 34 import java.nio.ByteBuffer; |
34 import java.util.ArrayList; | 35 import java.util.ArrayList; |
35 import java.util.Arrays; | 36 import java.util.Arrays; |
36 import java.util.List; | 37 import java.util.List; |
37 | 38 |
38 /** | 39 /** |
39 * This class implements Video Capture using Camera2 API, introduced in Android | 40 * This class implements Video Capture using Camera2 API, introduced in Android |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 notifyTakePhotoError(mCallbackId); | 220 notifyTakePhotoError(mCallbackId); |
220 return; | 221 return; |
221 } | 222 } |
222 | 223 |
223 if (createPreviewObjects()) return; | 224 if (createPreviewObjects()) return; |
224 | 225 |
225 nativeOnError(mNativeVideoCaptureDeviceAndroid, "Error restarting pr
eview"); | 226 nativeOnError(mNativeVideoCaptureDeviceAndroid, "Error restarting pr
eview"); |
226 } | 227 } |
227 }; | 228 }; |
228 | 229 |
229 // Inner Runnable to restart capture, must be run on |mContext| looper. | 230 // Inner Runnable to restart capture, must be run on application context loo
per. |
230 private final Runnable mRestartCapture = new Runnable() { | 231 private final Runnable mRestartCapture = new Runnable() { |
231 @Override | 232 @Override |
232 public void run() { | 233 public void run() { |
233 mPreviewSession.close(); // Asynchronously kill the CaptureSession. | 234 mPreviewSession.close(); // Asynchronously kill the CaptureSession. |
234 createPreviewObjects(); | 235 createPreviewObjects(); |
235 } | 236 } |
236 }; | 237 }; |
237 | 238 |
238 private static final double kNanoSecondsToFps = 1.0E-9; | 239 private static final double kNanoSecondsToFps = 1.0E-9; |
239 private static final String TAG = "VideoCapture"; | 240 private static final String TAG = "VideoCapture"; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 private MeteringRectangle mAreaOfInterest; | 275 private MeteringRectangle mAreaOfInterest; |
275 private int mExposureCompensation; | 276 private int mExposureCompensation; |
276 private int mWhiteBalanceMode = AndroidMeteringMode.CONTINUOUS; | 277 private int mWhiteBalanceMode = AndroidMeteringMode.CONTINUOUS; |
277 private int mColorTemperature = -1; | 278 private int mColorTemperature = -1; |
278 private int mIso; | 279 private int mIso; |
279 private boolean mRedEyeReduction; | 280 private boolean mRedEyeReduction; |
280 private int mFillLightMode = AndroidFillLightMode.OFF; | 281 private int mFillLightMode = AndroidFillLightMode.OFF; |
281 private boolean mTorch; | 282 private boolean mTorch; |
282 | 283 |
283 // Service function to grab CameraCharacteristics and handle exceptions. | 284 // Service function to grab CameraCharacteristics and handle exceptions. |
284 private static CameraCharacteristics getCameraCharacteristics(Context appCon
text, int id) { | 285 private static CameraCharacteristics getCameraCharacteristics(int id) { |
285 final CameraManager manager = | 286 final CameraManager manager = |
286 (CameraManager) appContext.getSystemService(Context.CAMERA_SERVI
CE); | 287 (CameraManager) ContextUtils.getApplicationContext().getSystemSe
rvice( |
| 288 Context.CAMERA_SERVICE); |
287 try { | 289 try { |
288 return manager.getCameraCharacteristics(Integer.toString(id)); | 290 return manager.getCameraCharacteristics(Integer.toString(id)); |
289 } catch (CameraAccessException ex) { | 291 } catch (CameraAccessException ex) { |
290 Log.e(TAG, "getCameraCharacteristics: ", ex); | 292 Log.e(TAG, "getCameraCharacteristics: ", ex); |
291 } | 293 } |
292 return null; | 294 return null; |
293 } | 295 } |
294 | 296 |
295 // {@link nativeOnPhotoTaken()} needs to be called back if there's any | 297 // {@link nativeOnPhotoTaken()} needs to be called back if there's any |
296 // problem after {@link takePhoto()} has returned true. | 298 // problem after {@link takePhoto()} has returned true. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 // |mExposureMode|, |mFillLightMode| and |mTorch| interact to configure
the AE and Flash | 377 // |mExposureMode|, |mFillLightMode| and |mTorch| interact to configure
the AE and Flash |
376 // modes. In a nutshell, FLASH_MODE is only effective if the auto-exposu
re is ON/OFF, | 378 // modes. In a nutshell, FLASH_MODE is only effective if the auto-exposu
re is ON/OFF, |
377 // otherwise the auto-exposure related flash control (ON_{AUTO,ALWAYS}_F
LASH{_REDEYE) takes | 379 // otherwise the auto-exposure related flash control (ON_{AUTO,ALWAYS}_F
LASH{_REDEYE) takes |
378 // priority. |mTorch| mode overrides any previous |mFillLightMode| flas
h control. | 380 // priority. |mTorch| mode overrides any previous |mFillLightMode| flas
h control. |
379 if (mExposureMode == AndroidMeteringMode.NONE | 381 if (mExposureMode == AndroidMeteringMode.NONE |
380 || mExposureMode == AndroidMeteringMode.FIXED) { | 382 || mExposureMode == AndroidMeteringMode.FIXED) { |
381 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CO
NTROL_AE_MODE_OFF); | 383 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CO
NTROL_AE_MODE_OFF); |
382 | 384 |
383 // We need to configure by hand the exposure time when AE mode is of
f. Set it to the | 385 // We need to configure by hand the exposure time when AE mode is of
f. Set it to the |
384 // middle of the allowed range. Further tuning will be done via |mIs
o|. | 386 // middle of the allowed range. Further tuning will be done via |mIs
o|. |
385 final CameraCharacteristics cameraCharacteristics = | 387 final CameraCharacteristics cameraCharacteristics = getCameraCharact
eristics(mId); |
386 getCameraCharacteristics(mContext, mId); | |
387 Range<Long> range = cameraCharacteristics.get( | 388 Range<Long> range = cameraCharacteristics.get( |
388 CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE); | 389 CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE); |
389 requestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, | 390 requestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, |
390 range.getLower() + (range.getUpper() + range.getLower()) / 2
/* nanoseconds*/); | 391 range.getLower() + (range.getUpper() + range.getLower()) / 2
/* nanoseconds*/); |
391 | 392 |
392 } else { | 393 } else { |
393 requestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTR
OL_MODE_AUTO); | 394 requestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTR
OL_MODE_AUTO); |
394 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CO
NTROL_AE_MODE_ON); | 395 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CO
NTROL_AE_MODE_ON); |
395 requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, mAeFp
sRange); | 396 requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, mAeFp
sRange); |
396 } | 397 } |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 | 498 |
498 for (int i = 0; i < COLOR_TEMPERATURES_MAP.size(); ++i) { | 499 for (int i = 0; i < COLOR_TEMPERATURES_MAP.size(); ++i) { |
499 final int diff = Math.abs(colorTemperature - COLOR_TEMPERATURES_MAP.
keyAt(i)); | 500 final int diff = Math.abs(colorTemperature - COLOR_TEMPERATURES_MAP.
keyAt(i)); |
500 if (diff >= minDiff) continue; | 501 if (diff >= minDiff) continue; |
501 minDiff = diff; | 502 minDiff = diff; |
502 matchedTemperature = COLOR_TEMPERATURES_MAP.valueAt(i); | 503 matchedTemperature = COLOR_TEMPERATURES_MAP.valueAt(i); |
503 } | 504 } |
504 return matchedTemperature; | 505 return matchedTemperature; |
505 } | 506 } |
506 | 507 |
507 static boolean isLegacyDevice(Context appContext, int id) { | 508 static boolean isLegacyDevice(int id) { |
508 final CameraCharacteristics cameraCharacteristics = | 509 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(id); |
509 getCameraCharacteristics(appContext, id); | |
510 return cameraCharacteristics != null | 510 return cameraCharacteristics != null |
511 && cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTE
D_HARDWARE_LEVEL) | 511 && cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTE
D_HARDWARE_LEVEL) |
512 == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY; | 512 == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY; |
513 } | 513 } |
514 | 514 |
515 static int getNumberOfCameras(Context appContext) { | 515 static int getNumberOfCameras() { |
516 final CameraManager manager = | 516 final CameraManager manager = |
517 (CameraManager) appContext.getSystemService(Context.CAMERA_SERVI
CE); | 517 (CameraManager) ContextUtils.getApplicationContext().getSystemSe
rvice( |
| 518 Context.CAMERA_SERVICE); |
518 try { | 519 try { |
519 return manager.getCameraIdList().length; | 520 return manager.getCameraIdList().length; |
520 } catch (CameraAccessException | SecurityException ex) { | 521 } catch (CameraAccessException | SecurityException ex) { |
521 // SecurityException is undocumented but seen in the wild: https://c
rbug/605424. | 522 // SecurityException is undocumented but seen in the wild: https://c
rbug/605424. |
522 Log.e(TAG, "getNumberOfCameras: getCameraIdList(): ", ex); | 523 Log.e(TAG, "getNumberOfCameras: getCameraIdList(): ", ex); |
523 return 0; | 524 return 0; |
524 } | 525 } |
525 } | 526 } |
526 | 527 |
527 static int getCaptureApiType(int id, Context appContext) { | 528 static int getCaptureApiType(int id) { |
528 final CameraCharacteristics cameraCharacteristics = | 529 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(id); |
529 getCameraCharacteristics(appContext, id); | |
530 if (cameraCharacteristics == null) { | 530 if (cameraCharacteristics == null) { |
531 return VideoCaptureApi.UNKNOWN; | 531 return VideoCaptureApi.UNKNOWN; |
532 } | 532 } |
533 | 533 |
534 final int supportedHWLevel = | 534 final int supportedHWLevel = |
535 cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_H
ARDWARE_LEVEL); | 535 cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_H
ARDWARE_LEVEL); |
536 switch (supportedHWLevel) { | 536 switch (supportedHWLevel) { |
537 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY: | 537 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY: |
538 return VideoCaptureApi.ANDROID_API2_LEGACY; | 538 return VideoCaptureApi.ANDROID_API2_LEGACY; |
539 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL: | 539 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_FULL: |
540 return VideoCaptureApi.ANDROID_API2_FULL; | 540 return VideoCaptureApi.ANDROID_API2_FULL; |
541 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED: | 541 case CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED: |
542 return VideoCaptureApi.ANDROID_API2_LIMITED; | 542 return VideoCaptureApi.ANDROID_API2_LIMITED; |
543 default: | 543 default: |
544 return VideoCaptureApi.ANDROID_API2_LEGACY; | 544 return VideoCaptureApi.ANDROID_API2_LEGACY; |
545 } | 545 } |
546 } | 546 } |
547 | 547 |
548 static String getName(int id, Context appContext) { | 548 static String getName(int id) { |
549 final CameraCharacteristics cameraCharacteristics = | 549 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(id); |
550 getCameraCharacteristics(appContext, id); | |
551 if (cameraCharacteristics == null) return null; | 550 if (cameraCharacteristics == null) return null; |
552 final int facing = cameraCharacteristics.get(CameraCharacteristics.LENS_
FACING); | 551 final int facing = cameraCharacteristics.get(CameraCharacteristics.LENS_
FACING); |
553 return "camera2 " + id + ", facing " | 552 return "camera2 " + id + ", facing " |
554 + ((facing == CameraCharacteristics.LENS_FACING_FRONT) ? "front"
: "back"); | 553 + ((facing == CameraCharacteristics.LENS_FACING_FRONT) ? "front"
: "back"); |
555 } | 554 } |
556 | 555 |
557 static VideoCaptureFormat[] getDeviceSupportedFormats(Context appContext, in
t id) { | 556 static VideoCaptureFormat[] getDeviceSupportedFormats(int id) { |
558 final CameraCharacteristics cameraCharacteristics = | 557 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(id); |
559 getCameraCharacteristics(appContext, id); | |
560 if (cameraCharacteristics == null) return null; | 558 if (cameraCharacteristics == null) return null; |
561 | 559 |
562 final int[] capabilities = | 560 final int[] capabilities = |
563 cameraCharacteristics.get(CameraCharacteristics.REQUEST_AVAILABL
E_CAPABILITIES); | 561 cameraCharacteristics.get(CameraCharacteristics.REQUEST_AVAILABL
E_CAPABILITIES); |
564 // Per-format frame rate via getOutputMinFrameDuration() is only availab
le if the | 562 // Per-format frame rate via getOutputMinFrameDuration() is only availab
le if the |
565 // property REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR is set. | 563 // property REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR is set. |
566 boolean minFrameDurationAvailable = false; | 564 boolean minFrameDurationAvailable = false; |
567 for (int cap : capabilities) { | 565 for (int cap : capabilities) { |
568 if (cap == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANU
AL_SENSOR) { | 566 if (cap == CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANU
AL_SENSOR) { |
569 minFrameDurationAvailable = true; | 567 minFrameDurationAvailable = true; |
(...skipping 20 matching lines...) Expand all Loading... |
590 // Hint: perhaps using SCALER_AVAILABLE_PROCESSED_MIN_DURATI
ONS. | 588 // Hint: perhaps using SCALER_AVAILABLE_PROCESSED_MIN_DURATI
ONS. |
591 minFrameRate = 0.0; | 589 minFrameRate = 0.0; |
592 } | 590 } |
593 formatList.add(new VideoCaptureFormat( | 591 formatList.add(new VideoCaptureFormat( |
594 size.getWidth(), size.getHeight(), (int) minFrameRate, 0
)); | 592 size.getWidth(), size.getHeight(), (int) minFrameRate, 0
)); |
595 } | 593 } |
596 } | 594 } |
597 return formatList.toArray(new VideoCaptureFormat[formatList.size()]); | 595 return formatList.toArray(new VideoCaptureFormat[formatList.size()]); |
598 } | 596 } |
599 | 597 |
600 VideoCaptureCamera2(Context context, int id, long nativeVideoCaptureDeviceAn
droid) { | 598 VideoCaptureCamera2(int id, long nativeVideoCaptureDeviceAndroid) { |
601 super(context, id, nativeVideoCaptureDeviceAndroid); | 599 super(id, nativeVideoCaptureDeviceAndroid); |
602 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(context, id); | 600 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(id); |
603 mMaxZoom = | 601 mMaxZoom = |
604 cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE
_MAX_DIGITAL_ZOOM); | 602 cameraCharacteristics.get(CameraCharacteristics.SCALER_AVAILABLE
_MAX_DIGITAL_ZOOM); |
605 } | 603 } |
606 | 604 |
607 @Override | 605 @Override |
608 public boolean allocate(int width, int height, int frameRate) { | 606 public boolean allocate(int width, int height, int frameRate) { |
609 Log.d(TAG, "allocate: requested (%d x %d) @%dfps", width, height, frameR
ate); | 607 Log.d(TAG, "allocate: requested (%d x %d) @%dfps", width, height, frameR
ate); |
610 synchronized (mCameraStateLock) { | 608 synchronized (mCameraStateLock) { |
611 if (mCameraState == CameraState.OPENING || mCameraState == CameraSta
te.CONFIGURING) { | 609 if (mCameraState == CameraState.OPENING || mCameraState == CameraSta
te.CONFIGURING) { |
612 Log.e(TAG, "allocate() invoked while Camera is busy opening/conf
iguring."); | 610 Log.e(TAG, "allocate() invoked while Camera is busy opening/conf
iguring."); |
613 return false; | 611 return false; |
614 } | 612 } |
615 } | 613 } |
616 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(mContext, mId); | 614 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(mId); |
617 final StreamConfigurationMap streamMap = | 615 final StreamConfigurationMap streamMap = |
618 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO
NFIGURATION_MAP); | 616 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO
NFIGURATION_MAP); |
619 | 617 |
620 // Find closest supported size. | 618 // Find closest supported size. |
621 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.YUV_4
20_888); | 619 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.YUV_4
20_888); |
622 final Size closestSupportedSize = findClosestSizeInArray(supportedSizes,
width, height); | 620 final Size closestSupportedSize = findClosestSizeInArray(supportedSizes,
width, height); |
623 if (closestSupportedSize == null) { | 621 if (closestSupportedSize == null) { |
624 Log.e(TAG, "No supported resolutions."); | 622 Log.e(TAG, "No supported resolutions."); |
625 return false; | 623 return false; |
626 } | 624 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
658 cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) | 656 cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) |
659 == CameraCharacteristics.LENS_FACING_BACK; | 657 == CameraCharacteristics.LENS_FACING_BACK; |
660 return true; | 658 return true; |
661 } | 659 } |
662 | 660 |
663 @Override | 661 @Override |
664 public boolean startCapture() { | 662 public boolean startCapture() { |
665 Log.d(TAG, "startCapture"); | 663 Log.d(TAG, "startCapture"); |
666 changeCameraStateAndNotify(CameraState.OPENING); | 664 changeCameraStateAndNotify(CameraState.OPENING); |
667 final CameraManager manager = | 665 final CameraManager manager = |
668 (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE
); | 666 (CameraManager) ContextUtils.getApplicationContext().getSystemSe
rvice( |
| 667 Context.CAMERA_SERVICE); |
669 | 668 |
670 if (!mUseBackgroundThreadForTesting) { | 669 if (!mUseBackgroundThreadForTesting) { |
671 mMainHandler = new Handler(mContext.getMainLooper()); | 670 mMainHandler = new Handler(ContextUtils.getApplicationContext().getM
ainLooper()); |
672 } else { | 671 } else { |
673 // Usually we deliver frames on |mContext|s thread, but unit tests | 672 // Usually we deliver frames on application context thread, but unit
tests |
674 // occupy its Looper; deliver frames on a background thread instead. | 673 // occupy its Looper; deliver frames on a background thread instead. |
675 HandlerThread thread = new HandlerThread("CameraPicture"); | 674 HandlerThread thread = new HandlerThread("CameraPicture"); |
676 thread.start(); | 675 thread.start(); |
677 mMainHandler = new Handler(thread.getLooper()); | 676 mMainHandler = new Handler(thread.getLooper()); |
678 } | 677 } |
679 | 678 |
680 final CrStateListener stateListener = new CrStateListener(); | 679 final CrStateListener stateListener = new CrStateListener(); |
681 try { | 680 try { |
682 manager.openCamera(Integer.toString(mId), stateListener, mMainHandle
r); | 681 manager.openCamera(Integer.toString(mId), stateListener, mMainHandle
r); |
683 } catch (CameraAccessException | IllegalArgumentException | SecurityExce
ption ex) { | 682 } catch (CameraAccessException | IllegalArgumentException | SecurityExce
ption ex) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 | 716 |
718 if (mUseBackgroundThreadForTesting) mMainHandler.getLooper().quit(); | 717 if (mUseBackgroundThreadForTesting) mMainHandler.getLooper().quit(); |
719 | 718 |
720 changeCameraStateAndNotify(CameraState.STOPPED); | 719 changeCameraStateAndNotify(CameraState.STOPPED); |
721 mCropRect = new Rect(); | 720 mCropRect = new Rect(); |
722 return true; | 721 return true; |
723 } | 722 } |
724 | 723 |
725 @Override | 724 @Override |
726 public PhotoCapabilities getPhotoCapabilities() { | 725 public PhotoCapabilities getPhotoCapabilities() { |
727 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(mContext, mId); | 726 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(mId); |
728 PhotoCapabilities.Builder builder = new PhotoCapabilities.Builder(); | 727 PhotoCapabilities.Builder builder = new PhotoCapabilities.Builder(); |
729 | 728 |
730 int minIso = 0; | 729 int minIso = 0; |
731 int maxIso = 0; | 730 int maxIso = 0; |
732 final Range<Integer> iso_range = | 731 final Range<Integer> iso_range = |
733 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENS
ITIVITY_RANGE); | 732 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENS
ITIVITY_RANGE); |
734 if (iso_range != null) { | 733 if (iso_range != null) { |
735 minIso = iso_range.getLower(); | 734 minIso = iso_range.getLower(); |
736 maxIso = iso_range.getUpper(); | 735 maxIso = iso_range.getUpper(); |
737 } | 736 } |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
912 | 911 |
913 return builder.build(); | 912 return builder.build(); |
914 } | 913 } |
915 | 914 |
916 @Override | 915 @Override |
917 public void setPhotoOptions(double zoom, int focusMode, int exposureMode, do
uble width, | 916 public void setPhotoOptions(double zoom, int focusMode, int exposureMode, do
uble width, |
918 double height, float[] pointsOfInterest2D, boolean hasExposureCompen
sation, | 917 double height, float[] pointsOfInterest2D, boolean hasExposureCompen
sation, |
919 double exposureCompensation, int whiteBalanceMode, double iso, | 918 double exposureCompensation, int whiteBalanceMode, double iso, |
920 boolean hasRedEyeReduction, boolean redEyeReduction, int fillLightMo
de, | 919 boolean hasRedEyeReduction, boolean redEyeReduction, int fillLightMo
de, |
921 boolean hasTorch, boolean torch, double colorTemperature) { | 920 boolean hasTorch, boolean torch, double colorTemperature) { |
922 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(mContext, mId); | 921 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(mId); |
923 final Rect canvas = | 922 final Rect canvas = |
924 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTI
VE_ARRAY_SIZE); | 923 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTI
VE_ARRAY_SIZE); |
925 | 924 |
926 if (zoom != 0) { | 925 if (zoom != 0) { |
927 final float normalizedZoom = Math.max(1.0f, Math.min((float) zoom, m
MaxZoom)); | 926 final float normalizedZoom = Math.max(1.0f, Math.min((float) zoom, m
MaxZoom)); |
928 final float cropFactor = (normalizedZoom - 1) / (2 * normalizedZoom)
; | 927 final float cropFactor = (normalizedZoom - 1) / (2 * normalizedZoom)
; |
929 | 928 |
930 mCropRect = new Rect(Math.round(canvas.width() * cropFactor), | 929 mCropRect = new Rect(Math.round(canvas.width() * cropFactor), |
931 Math.round(canvas.height() * cropFactor), | 930 Math.round(canvas.height() * cropFactor), |
932 Math.round(canvas.width() * (1 - cropFactor)), | 931 Math.round(canvas.width() * (1 - cropFactor)), |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 } | 984 } |
986 if (iso > 0) mIso = (int) Math.round(iso); | 985 if (iso > 0) mIso = (int) Math.round(iso); |
987 if (mWhiteBalanceMode == AndroidMeteringMode.FIXED && colorTemperature >
0) { | 986 if (mWhiteBalanceMode == AndroidMeteringMode.FIXED && colorTemperature >
0) { |
988 mColorTemperature = (int) Math.round(colorTemperature); | 987 mColorTemperature = (int) Math.round(colorTemperature); |
989 } | 988 } |
990 | 989 |
991 if (hasRedEyeReduction) mRedEyeReduction = redEyeReduction; | 990 if (hasRedEyeReduction) mRedEyeReduction = redEyeReduction; |
992 if (fillLightMode != AndroidFillLightMode.NOT_SET) mFillLightMode = fill
LightMode; | 991 if (fillLightMode != AndroidFillLightMode.NOT_SET) mFillLightMode = fill
LightMode; |
993 if (hasTorch) mTorch = torch; | 992 if (hasTorch) mTorch = torch; |
994 | 993 |
995 final Handler mainHandler = new Handler(mContext.getMainLooper()); | 994 final Handler mainHandler = |
| 995 new Handler(ContextUtils.getApplicationContext().getMainLooper()
); |
996 mainHandler.removeCallbacks(mRestartCapture); | 996 mainHandler.removeCallbacks(mRestartCapture); |
997 mainHandler.post(mRestartCapture); | 997 mainHandler.post(mRestartCapture); |
998 } | 998 } |
999 | 999 |
1000 @Override | 1000 @Override |
1001 public boolean takePhoto(final long callbackId) { | 1001 public boolean takePhoto(final long callbackId) { |
1002 Log.d(TAG, "takePhoto"); | 1002 Log.d(TAG, "takePhoto"); |
1003 if (mCameraDevice == null || mCameraState != CameraState.STARTED) return
false; | 1003 if (mCameraDevice == null || mCameraState != CameraState.STARTED) return
false; |
1004 | 1004 |
1005 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(mContext, mId); | 1005 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris
tics(mId); |
1006 final StreamConfigurationMap streamMap = | 1006 final StreamConfigurationMap streamMap = |
1007 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO
NFIGURATION_MAP); | 1007 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO
NFIGURATION_MAP); |
1008 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.JPEG)
; | 1008 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.JPEG)
; |
1009 final Size closestSize = findClosestSizeInArray(supportedSizes, mPhotoWi
dth, mPhotoHeight); | 1009 final Size closestSize = findClosestSizeInArray(supportedSizes, mPhotoWi
dth, mPhotoHeight); |
1010 | 1010 |
1011 Log.d(TAG, "requested resolution: (%dx%d)", mPhotoWidth, mPhotoHeight); | 1011 Log.d(TAG, "requested resolution: (%dx%d)", mPhotoWidth, mPhotoHeight); |
1012 if (closestSize != null) { | 1012 if (closestSize != null) { |
1013 Log.d(TAG, " matched (%dx%d)", closestSize.getWidth(), closestSize.g
etHeight()); | 1013 Log.d(TAG, " matched (%dx%d)", closestSize.getWidth(), closestSize.g
etHeight()); |
1014 } | 1014 } |
1015 final ImageReader imageReader = ImageReader.newInstance( | 1015 final ImageReader imageReader = ImageReader.newInstance( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 return false; | 1055 return false; |
1056 } | 1056 } |
1057 return true; | 1057 return true; |
1058 } | 1058 } |
1059 | 1059 |
1060 @Override | 1060 @Override |
1061 public void deallocate() { | 1061 public void deallocate() { |
1062 Log.d(TAG, "deallocate"); | 1062 Log.d(TAG, "deallocate"); |
1063 } | 1063 } |
1064 } | 1064 } |
OLD | NEW |