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; |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
271 private int mPhotoHeight; | 271 private int mPhotoHeight; |
272 private int mFocusMode = AndroidMeteringMode.CONTINUOUS; | 272 private int mFocusMode = AndroidMeteringMode.CONTINUOUS; |
273 private int mExposureMode = AndroidMeteringMode.CONTINUOUS; | 273 private int mExposureMode = AndroidMeteringMode.CONTINUOUS; |
274 private MeteringRectangle mAreaOfInterest; | 274 private MeteringRectangle mAreaOfInterest; |
275 private int mExposureCompensation; | 275 private int mExposureCompensation; |
276 private int mWhiteBalanceMode = AndroidMeteringMode.CONTINUOUS; | 276 private int mWhiteBalanceMode = AndroidMeteringMode.CONTINUOUS; |
277 private int mColorTemperature = -1; | 277 private int mColorTemperature = -1; |
278 private int mIso; | 278 private int mIso; |
279 private boolean mRedEyeReduction; | 279 private boolean mRedEyeReduction; |
280 private int mFillLightMode = AndroidFillLightMode.OFF; | 280 private int mFillLightMode = AndroidFillLightMode.OFF; |
281 private boolean mTorch; | |
281 | 282 |
282 // Service function to grab CameraCharacteristics and handle exceptions. | 283 // Service function to grab CameraCharacteristics and handle exceptions. |
283 private static CameraCharacteristics getCameraCharacteristics(Context appCon text, int id) { | 284 private static CameraCharacteristics getCameraCharacteristics(Context appCon text, int id) { |
284 final CameraManager manager = | 285 final CameraManager manager = |
285 (CameraManager) appContext.getSystemService(Context.CAMERA_SERVI CE); | 286 (CameraManager) appContext.getSystemService(Context.CAMERA_SERVI CE); |
286 try { | 287 try { |
287 return manager.getCameraCharacteristics(Integer.toString(id)); | 288 return manager.getCameraCharacteristics(Integer.toString(id)); |
288 } catch (CameraAccessException ex) { | 289 } catch (CameraAccessException ex) { |
289 Log.e(TAG, "getCameraCharacteristics: ", ex); | 290 Log.e(TAG, "getCameraCharacteristics: ", ex); |
290 } | 291 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
364 requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, | 365 requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, |
365 CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE); | 366 CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE); |
366 requestBuilder.set( | 367 requestBuilder.set( |
367 CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF _TRIGGER_START); | 368 CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF _TRIGGER_START); |
368 } else if (mFocusMode == AndroidMeteringMode.FIXED) { | 369 } else if (mFocusMode == AndroidMeteringMode.FIXED) { |
369 requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CO NTROL_AF_MODE_OFF); | 370 requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CO NTROL_AF_MODE_OFF); |
370 // TODO(mcasas): Support controlling LENS_FOCUS_DISTANCE in this mod e, | 371 // TODO(mcasas): Support controlling LENS_FOCUS_DISTANCE in this mod e, |
371 // https://crbug.com/518807. | 372 // https://crbug.com/518807. |
372 } | 373 } |
373 | 374 |
374 // |mExposureMode| and |mFillLightMode| interact to configure the AE and Flash modes. In a | 375 // |mExposureMode|, |mFillLightMode| and |mTorch| interact to configure the AE and Flash |
375 // nutshell, FLASH_MODE is only effective if the auto-exposure is ON/OFF , otherwise the | 376 // modes. In a nutshell, FLASH_MODE is only effective if the auto-exposu re is ON/OFF, |
376 // auto-exposure related flash control (ON_{AUTO,ALWAYS}_FLASH{_REDEYE) takes priority. | 377 // 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. | |
377 if (mExposureMode == AndroidMeteringMode.NONE | 379 if (mExposureMode == AndroidMeteringMode.NONE |
378 || mExposureMode == AndroidMeteringMode.FIXED) { | 380 || mExposureMode == AndroidMeteringMode.FIXED) { |
379 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CO NTROL_AE_MODE_OFF); | 381 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CO NTROL_AE_MODE_OFF); |
380 } else { | 382 } else { |
381 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CO NTROL_AE_MODE_ON); | 383 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CO NTROL_AE_MODE_ON); |
382 requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, mAeFp sRange); | 384 requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, mAeFp sRange); |
383 } | 385 } |
384 switch (mFillLightMode) { | 386 switch (mFillLightMode) { |
385 case AndroidFillLightMode.OFF: | 387 case AndroidFillLightMode.OFF: |
386 requestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLA SH_MODE_OFF); | 388 requestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLA SH_MODE_OFF); |
387 break; | 389 break; |
388 case AndroidFillLightMode.AUTO: | 390 case AndroidFillLightMode.AUTO: |
389 // Setting the AE to CONTROL_AE_MODE_ON_AUTO_FLASH[_REDEYE] over rides FLASH_MODE. | 391 // Setting the AE to CONTROL_AE_MODE_ON_AUTO_FLASH[_REDEYE] over rides FLASH_MODE. |
390 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, mRedEyeReduct ion | 392 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, mRedEyeReduct ion |
391 ? CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_R EDEYE | 393 ? CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_R EDEYE |
392 : CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH); | 394 : CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH); |
393 break; | 395 break; |
394 case AndroidFillLightMode.FLASH: | 396 case AndroidFillLightMode.FLASH: |
395 // Setting the AE to CONTROL_AE_MODE_ON_ALWAYS_FLASH overrides F LASH_MODE. | 397 // Setting the AE to CONTROL_AE_MODE_ON_ALWAYS_FLASH overrides F LASH_MODE. |
396 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, | 398 requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, |
397 CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH); | 399 CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH); |
398 break; | 400 break; |
399 case AndroidFillLightMode.TORCH: | 401 default: |
400 requestBuilder.set( | |
401 CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CONTROL_A E_MODE_ON); | |
402 requestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLA SH_MODE_TORCH); | |
403 break; | |
404 case AndroidFillLightMode.NONE: | |
405 // NONE is only used for getting capabilities, to signify "no fl ash unit". Ignore. | |
406 } | 402 } |
403 if (mTorch) requestBuilder.set(CaptureRequest.FLASH_MODE, CameraMetadata .FLASH_MODE_TORCH); | |
404 | |
407 requestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, mExp osureCompensation); | 405 requestBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, mExp osureCompensation); |
408 | 406 |
409 // White Balance mode AndroidMeteringMode.SINGLE_SHOT is not supported. | 407 // White Balance mode AndroidMeteringMode.SINGLE_SHOT is not supported. |
410 if (mWhiteBalanceMode == AndroidMeteringMode.CONTINUOUS) { | 408 if (mWhiteBalanceMode == AndroidMeteringMode.CONTINUOUS) { |
411 requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, false); | 409 requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, false); |
412 requestBuilder.set( | 410 requestBuilder.set( |
413 CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_ MODE_AUTO); | 411 CaptureRequest.CONTROL_AWB_MODE, CameraMetadata.CONTROL_AWB_ MODE_AUTO); |
414 // TODO(mcasas): support different luminant color temperatures, e.g. DAYLIGHT, SHADE. | 412 // TODO(mcasas): support different luminant color temperatures, e.g. DAYLIGHT, SHADE. |
415 // https://crbug.com/518807 | 413 // https://crbug.com/518807 |
416 } else if (mWhiteBalanceMode == AndroidMeteringMode.NONE) { | 414 } else if (mWhiteBalanceMode == AndroidMeteringMode.NONE) { |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
792 builder.setMinColorTemperature(COLOR_TEMPERATURES_MAP.keyAt(0)); | 790 builder.setMinColorTemperature(COLOR_TEMPERATURES_MAP.keyAt(0)); |
793 builder.setMaxColorTemperature( | 791 builder.setMaxColorTemperature( |
794 COLOR_TEMPERATURES_MAP.keyAt(COLOR_TEMPERATURES_MAP.size() - 1)) ; | 792 COLOR_TEMPERATURES_MAP.keyAt(COLOR_TEMPERATURES_MAP.size() - 1)) ; |
795 final int index = COLOR_TEMPERATURES_MAP.indexOfValue(whiteBalanceMode); | 793 final int index = COLOR_TEMPERATURES_MAP.indexOfValue(whiteBalanceMode); |
796 if (index >= 0) { | 794 if (index >= 0) { |
797 builder.setCurrentColorTemperature(COLOR_TEMPERATURES_MAP.keyAt(inde x)); | 795 builder.setCurrentColorTemperature(COLOR_TEMPERATURES_MAP.keyAt(inde x)); |
798 } | 796 } |
799 builder.setStepColorTemperature(1); | 797 builder.setStepColorTemperature(1); |
800 | 798 |
801 if (!cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABL E)) { | 799 if (!cameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABL E)) { |
802 builder.setFillLightMode(AndroidFillLightMode.NONE); | 800 builder.setTorch(false); |
801 builder.setRedEyeReduction(false); | |
803 } else { | 802 } else { |
804 // CONTROL_AE_MODE overrides FLASH_MODE control unless it's in ON or OFF states. | 803 builder.setTorch(true); |
805 switch (mPreviewRequest.get(CaptureRequest.CONTROL_AE_MODE)) { | 804 builder.setRedEyeReduction(true); |
Reilly Grant (use Gerrit)
2017/03/31 20:13:09
Can you add a comment explaining why these are now
mcasas
2017/03/31 21:14:47
Previously we were retrieving the status of the co
| |
806 case CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE: | 805 |
807 builder.setRedEyeReduction(true); | 806 final int[] flashModes = |
808 builder.setFillLightMode(AndroidFillLightMode.AUTO); | 807 cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE_A VAILABLE_MODES); |
809 break; | 808 ArrayList<Integer> modes = new ArrayList<Integer>(0); |
810 case CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH: | 809 for (int flashMode : flashModes) { |
811 builder.setFillLightMode(AndroidFillLightMode.AUTO); | 810 if (flashMode == CameraMetadata.FLASH_MODE_OFF) { |
812 break; | 811 modes.add(Integer.valueOf(AndroidFillLightMode.OFF)); |
813 case CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH: | 812 } else if (flashMode == CameraMetadata.CONTROL_AE_MODE_ON_AUTO_F LASH) { |
814 builder.setFillLightMode(AndroidFillLightMode.FLASH); | 813 modes.add(Integer.valueOf(AndroidFillLightMode.AUTO)); |
815 break; | 814 } else if (flashMode == CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS _FLASH) { |
816 case CameraMetadata.CONTROL_AE_MODE_OFF: | 815 modes.add(Integer.valueOf(AndroidFillLightMode.FLASH)); |
817 case CameraMetadata.CONTROL_AE_MODE_ON: | 816 } |
818 final Integer flashMode = mPreviewRequest.get(CaptureRequest .FLASH_MODE); | |
819 if (flashMode == CameraMetadata.FLASH_MODE_OFF) { | |
820 builder.setFillLightMode(AndroidFillLightMode.OFF); | |
821 } else if (flashMode == CameraMetadata.FLASH_MODE_SINGLE) { | |
822 builder.setFillLightMode(AndroidFillLightMode.FLASH); | |
823 } else if (flashMode == CameraMetadata.FLASH_MODE_TORCH) { | |
824 builder.setFillLightMode(AndroidFillLightMode.TORCH); | |
825 } | |
826 break; | |
827 default: | |
828 builder.setFillLightMode(AndroidFillLightMode.NONE); | |
829 } | 817 } |
818 int[] modesAsIntArray = new int[modes.size()]; | |
819 for (int i = 0; i < modes.size(); i++) modesAsIntArray[i] = modes.ge t(i).intValue(); | |
820 builder.setFillLightModes(modesAsIntArray); | |
830 } | 821 } |
831 | 822 |
832 return builder.build(); | 823 return builder.build(); |
833 } | 824 } |
834 | 825 |
835 @Override | 826 @Override |
836 public void setPhotoOptions(double zoom, int focusMode, int exposureMode, do uble width, | 827 public void setPhotoOptions(double zoom, int focusMode, int exposureMode, do uble width, |
837 double height, float[] pointsOfInterest2D, boolean hasExposureCompen sation, | 828 double height, float[] pointsOfInterest2D, boolean hasExposureCompen sation, |
838 double exposureCompensation, int whiteBalanceMode, double iso, | 829 double exposureCompensation, int whiteBalanceMode, double iso, |
839 boolean hasRedEyeReduction, boolean redEyeReduction, int fillLightMo de, | 830 boolean hasRedEyeReduction, boolean redEyeReduction, int fillLightMo de, |
840 double colorTemperature) { | 831 boolean hasTorch, boolean torch, double colorTemperature) { |
841 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId); | 832 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId); |
842 final Rect canvas = | 833 final Rect canvas = |
843 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTI VE_ARRAY_SIZE); | 834 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTI VE_ARRAY_SIZE); |
844 | 835 |
845 if (zoom != 0) { | 836 if (zoom != 0) { |
846 final float normalizedZoom = Math.max(1.0f, Math.min((float) zoom, m MaxZoom)); | 837 final float normalizedZoom = Math.max(1.0f, Math.min((float) zoom, m MaxZoom)); |
847 final float cropFactor = (normalizedZoom - 1) / (2 * normalizedZoom) ; | 838 final float cropFactor = (normalizedZoom - 1) / (2 * normalizedZoom) ; |
848 | 839 |
849 mCropRect = new Rect(Math.round(canvas.width() * cropFactor), | 840 mCropRect = new Rect(Math.round(canvas.width() * cropFactor), |
850 Math.round(canvas.height() * cropFactor), | 841 Math.round(canvas.height() * cropFactor), |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
899 | 890 |
900 if (hasExposureCompensation) { | 891 if (hasExposureCompensation) { |
901 mExposureCompensation = (int) Math.round(exposureCompensation | 892 mExposureCompensation = (int) Math.round(exposureCompensation |
902 / cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE _COMPENSATION_STEP) | 893 / cameraCharacteristics.get(CameraCharacteristics.CONTROL_AE _COMPENSATION_STEP) |
903 .floatValue()); | 894 .floatValue()); |
904 } | 895 } |
905 if (iso > 0) mIso = (int) Math.round(iso); | 896 if (iso > 0) mIso = (int) Math.round(iso); |
906 if (mWhiteBalanceMode == AndroidMeteringMode.FIXED && colorTemperature > 0) { | 897 if (mWhiteBalanceMode == AndroidMeteringMode.FIXED && colorTemperature > 0) { |
907 mColorTemperature = (int) Math.round(colorTemperature); | 898 mColorTemperature = (int) Math.round(colorTemperature); |
908 } | 899 } |
900 | |
901 if (hasRedEyeReduction) mRedEyeReduction = redEyeReduction; | |
909 if (fillLightMode != AndroidFillLightMode.NOT_SET) mFillLightMode = fill LightMode; | 902 if (fillLightMode != AndroidFillLightMode.NOT_SET) mFillLightMode = fill LightMode; |
903 if (hasTorch) mTorch = torch; | |
910 | 904 |
911 final Handler mainHandler = new Handler(mContext.getMainLooper()); | 905 final Handler mainHandler = new Handler(mContext.getMainLooper()); |
912 mainHandler.removeCallbacks(mRestartCapture); | 906 mainHandler.removeCallbacks(mRestartCapture); |
913 mainHandler.post(mRestartCapture); | 907 mainHandler.post(mRestartCapture); |
914 } | 908 } |
915 | 909 |
916 @Override | 910 @Override |
917 public boolean takePhoto(final long callbackId) { | 911 public boolean takePhoto(final long callbackId) { |
918 Log.d(TAG, "takePhoto"); | 912 Log.d(TAG, "takePhoto"); |
919 if (mCameraDevice == null || mCameraState != CameraState.STARTED) return false; | 913 if (mCameraDevice == null || mCameraState != CameraState.STARTED) return false; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
971 return false; | 965 return false; |
972 } | 966 } |
973 return true; | 967 return true; |
974 } | 968 } |
975 | 969 |
976 @Override | 970 @Override |
977 public void deallocate() { | 971 public void deallocate() { |
978 Log.d(TAG, "deallocate"); | 972 Log.d(TAG, "deallocate"); |
979 } | 973 } |
980 } | 974 } |
OLD | NEW |