Chromium Code Reviews| 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 |