Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: media/capture/video/android/java/src/org/chromium/media/VideoCaptureCamera2.java

Issue 2239583002: ImageCapture: support enhanced FocusMode getting/setting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 238
239 private final Object mCameraStateLock = new Object(); 239 private final Object mCameraStateLock = new Object();
240 240
241 private CameraDevice mCameraDevice; 241 private CameraDevice mCameraDevice;
242 private CameraCaptureSession mPreviewSession; 242 private CameraCaptureSession mPreviewSession;
243 private CaptureRequest mPreviewRequest; 243 private CaptureRequest mPreviewRequest;
244 244
245 private CameraState mCameraState = CameraState.STOPPED; 245 private CameraState mCameraState = CameraState.STOPPED;
246 private final float mMaxZoom; 246 private final float mMaxZoom;
247 private Rect mCropRect = new Rect(); 247 private Rect mCropRect = new Rect();
248 private int mFocusMode = AndroidFocusMode.CONTINUOUS;
249 private int mPhotoWidth = 0;
250 private int mPhotoHeight = 0;
248 251
249 // Service function to grab CameraCharacteristics and handle exceptions. 252 // Service function to grab CameraCharacteristics and handle exceptions.
250 private static CameraCharacteristics getCameraCharacteristics(Context appCon text, int id) { 253 private static CameraCharacteristics getCameraCharacteristics(Context appCon text, int id) {
251 final CameraManager manager = 254 final CameraManager manager =
252 (CameraManager) appContext.getSystemService(Context.CAMERA_SERVI CE); 255 (CameraManager) appContext.getSystemService(Context.CAMERA_SERVI CE);
253 try { 256 try {
254 return manager.getCameraCharacteristics(Integer.toString(id)); 257 return manager.getCameraCharacteristics(Integer.toString(id));
255 } catch (CameraAccessException ex) { 258 } catch (CameraAccessException ex) {
256 Log.e(TAG, "getCameraCharacteristics: ", ex); 259 Log.e(TAG, "getCameraCharacteristics: ", ex);
257 } 260 }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 // Construct an ImageReader Surface and plug it into our CaptureRequest. Builder. 298 // Construct an ImageReader Surface and plug it into our CaptureRequest. Builder.
296 previewRequestBuilder.addTarget(imageReader.getSurface()); 299 previewRequestBuilder.addTarget(imageReader.getSurface());
297 300
298 // A series of configuration options in the PreviewBuilder 301 // A series of configuration options in the PreviewBuilder
299 previewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CO NTROL_MODE_AUTO); 302 previewRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CO NTROL_MODE_AUTO);
300 previewRequestBuilder.set( 303 previewRequestBuilder.set(
301 CaptureRequest.NOISE_REDUCTION_MODE, CameraMetadata.NOISE_REDUCT ION_MODE_FAST); 304 CaptureRequest.NOISE_REDUCTION_MODE, CameraMetadata.NOISE_REDUCT ION_MODE_FAST);
302 previewRequestBuilder.set(CaptureRequest.EDGE_MODE, CameraMetadata.EDGE_ MODE_FAST); 305 previewRequestBuilder.set(CaptureRequest.EDGE_MODE, CameraMetadata.EDGE_ MODE_FAST);
303 previewRequestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MOD E, 306 previewRequestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MOD E,
304 CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON); 307 CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON);
308 if (mFocusMode == AndroidFocusMode.CONTINUOUS) {
309 Log.d(TAG, "Focus: CONTROL_AF_MODE_CONTINUOUS_PICTURE");
310 previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
311 CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
312 } else if (mFocusMode == AndroidFocusMode.SINGLE_SHOT) {
313 Log.d(TAG, "Focus: triggering a single shot");
314 previewRequestBuilder.set(
315 CaptureRequest.CONTROL_AF_MODE, CameraMetadata.CONTROL_AF_MO DE_AUTO);
316 previewRequestBuilder.set(
317 CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF _TRIGGER_START);
318 }
319
305 // SENSOR_EXPOSURE_TIME ? 320 // SENSOR_EXPOSURE_TIME ?
306 if (!mCropRect.isEmpty()) { 321 if (!mCropRect.isEmpty()) {
307 previewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, mCropRe ct); 322 previewRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, mCropRe ct);
308 } 323 }
309 324
310 List<Surface> surfaceList = new ArrayList<Surface>(1); 325 List<Surface> surfaceList = new ArrayList<Surface>(1);
311 surfaceList.add(imageReader.getSurface()); 326 surfaceList.add(imageReader.getSurface());
312 327
313 mPreviewRequest = previewRequestBuilder.build(); 328 mPreviewRequest = previewRequestBuilder.build();
314 final CrPreviewSessionListener captureSessionListener = 329 final CrPreviewSessionListener captureSessionListener =
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 int minWidth = Integer.MAX_VALUE; 571 int minWidth = Integer.MAX_VALUE;
557 int minHeight = Integer.MAX_VALUE; 572 int minHeight = Integer.MAX_VALUE;
558 int maxWidth = 0; 573 int maxWidth = 0;
559 int maxHeight = 0; 574 int maxHeight = 0;
560 for (Size size : supportedSizes) { 575 for (Size size : supportedSizes) {
561 if (size.getWidth() < minWidth) minWidth = size.getWidth(); 576 if (size.getWidth() < minWidth) minWidth = size.getWidth();
562 if (size.getHeight() < minHeight) minHeight = size.getHeight(); 577 if (size.getHeight() < minHeight) minHeight = size.getHeight();
563 if (size.getWidth() > maxWidth) maxWidth = size.getWidth(); 578 if (size.getWidth() > maxWidth) maxWidth = size.getWidth();
564 if (size.getHeight() > maxHeight) maxHeight = size.getHeight(); 579 if (size.getHeight() > maxHeight) maxHeight = size.getHeight();
565 } 580 }
566 final int currentHeight = mCaptureFormat.getHeight(); 581 final int currentHeight = (mPhotoHeight > 0) ? mPhotoHeight : mCaptureFo rmat.getHeight();
567 final int currentWidth = mCaptureFormat.getWidth(); 582 final int currentWidth = (mPhotoWidth > 0) ? mPhotoWidth : mCaptureForma t.getWidth();
568 583
569 // The Min and Max zoom are returned as x100 by the API to avoid using f loating point. There 584 // The Min and Max zoom are returned as x100 by the API to avoid using f loating point. There
570 // is no min-zoom per se, so clamp it to always 100 (TODO(mcasas): make const member). 585 // is no min-zoom per se, so clamp it to always 100 (TODO(mcasas): make const member).
571 final int minZoom = 100; 586 final int minZoom = 100;
572 final int maxZoom = Math.round(mMaxZoom * 100); 587 final int maxZoom = Math.round(mMaxZoom * 100);
573 // Width Ratio x100 is used as measure of current zoom. 588 // Width Ratio x100 is used as measure of current zoom.
574 final int currentZoom = 100 * mPreviewRequest.get(CaptureRequest.SCALER_ CROP_REGION).width() 589 final int currentZoom = 100
575 / cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_AC TIVE_ARRAY_SIZE) 590 * cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_AC TIVE_ARRAY_SIZE)
576 .width(); 591 .width()
592 / mPreviewRequest.get(CaptureRequest.SCALER_CROP_REGION).width() ;
577 593
578 final int focusMode = mPreviewRequest.get(CaptureRequest.CONTROL_AF_MODE ); 594 final int focusMode = mPreviewRequest.get(CaptureRequest.CONTROL_AF_MODE );
579 Log.d(TAG, "focusMode " + focusMode); 595 Log.d(TAG, "focusMode: %s", focusMode);
580 final boolean isFocusManual = (focusMode == CameraMetadata.CONTROL_AF_MO DE_OFF) 596 // Classify the Focus capabilities. In CONTINUOUS and SINGLE_SHOT, we ca n call
581 || (focusMode == CameraMetadata.CONTROL_AF_MODE_EDOF); 597 // autoFocus(AutoFocusCallback) to configure region(s) to focus onto.
598 int jniFocusMode = AndroidFocusMode.UNAVAILABLE;
599 if (focusMode == CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_VIDEO
600 || focusMode == CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTUR E) {
601 jniFocusMode = AndroidFocusMode.CONTINUOUS;
602 } else if (focusMode == CameraMetadata.CONTROL_AF_MODE_AUTO
603 || focusMode == CameraMetadata.CONTROL_AF_MODE_MACRO) {
604 jniFocusMode = AndroidFocusMode.SINGLE_SHOT;
605 } else if (focusMode == CameraMetadata.CONTROL_AF_MODE_OFF) {
606 jniFocusMode = AndroidFocusMode.FIXED;
607 } else {
608 assert jniFocusMode == CameraMetadata.CONTROL_AF_MODE_EDOF;
609 }
582 610
583 return new PhotoCapabilities(minIso, maxIso, currentIso, maxHeight, minH eight, 611 return new PhotoCapabilities(minIso, maxIso, currentIso, maxHeight, minH eight,
584 currentHeight, maxWidth, minWidth, currentWidth, maxZoom, minZoo m, currentZoom, 612 currentHeight, maxWidth, minWidth, currentWidth, maxZoom, minZoo m, currentZoom,
585 !isFocusManual); 613 jniFocusMode);
586 } 614 }
587 615
588 @Override 616 @Override
589 public void setZoom(int zoom) { 617 public void setPhotoOptions(int zoom, int focusMode, int width, int height) {
590 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId); 618 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId);
591 final Rect canvas = 619 final Rect canvas =
592 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTI VE_ARRAY_SIZE); 620 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTI VE_ARRAY_SIZE);
593 621
594 final float normalizedZoom = Math.max(100, Math.min(zoom, mMaxZoom * 100 )) / 100; 622 if (zoom != 0) {
595 final float cropFactor = (normalizedZoom - 1) / (2 * normalizedZoom); 623 final float normalizedZoom = Math.max(100, Math.min(zoom, mMaxZoom * 100)) / 100;
624 final float cropFactor = (normalizedZoom - 1) / (2 * normalizedZoom) ;
596 625
597 mCropRect = new Rect(Math.round(canvas.width() * cropFactor), 626 mCropRect = new Rect(Math.round(canvas.width() * cropFactor),
598 Math.round(canvas.height() * cropFactor), 627 Math.round(canvas.height() * cropFactor),
599 Math.round(canvas.width() * (1 - cropFactor)), 628 Math.round(canvas.width() * (1 - cropFactor)),
600 Math.round(canvas.height() * (1 - cropFactor))); 629 Math.round(canvas.height() * (1 - cropFactor)));
601 Log.d(TAG, "zoom level " + normalizedZoom + ", rectangle: " + mCropRect. toString()); 630 Log.d(TAG, "zoom level %f, rectangle: %s", normalizedZoom, mCropRect .toString());
631 }
632
633 mFocusMode = focusMode;
634
635 if (width > 0) mPhotoWidth = width;
636 if (height > 0) mPhotoHeight = height;
602 637
603 final Handler mainHandler = new Handler(mContext.getMainLooper()); 638 final Handler mainHandler = new Handler(mContext.getMainLooper());
604 mainHandler.removeCallbacks(mRestartCapture); 639 mainHandler.removeCallbacks(mRestartCapture);
605 mainHandler.post(mRestartCapture); 640 mainHandler.post(mRestartCapture);
606 } 641 }
607 642
608 @Override 643 @Override
609 public boolean takePhoto(final long callbackId, int width, int height) { 644 public boolean takePhoto(final long callbackId) {
610 Log.d(TAG, "takePhoto " + callbackId); 645 Log.d(TAG, "takePhoto " + callbackId);
611 if (mCameraDevice == null || mCameraState != CameraState.STARTED) return false; 646 if (mCameraDevice == null || mCameraState != CameraState.STARTED) return false;
612 647
613 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId); 648 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId);
614 final StreamConfigurationMap streamMap = 649 final StreamConfigurationMap streamMap =
615 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO NFIGURATION_MAP); 650 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO NFIGURATION_MAP);
616 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.JPEG) ; 651 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.JPEG) ;
617 final Size closestSize = findClosestSizeInArray(supportedSizes, width, h eight); 652 final Size closestSize = findClosestSizeInArray(supportedSizes, mPhotoWi dth, mPhotoHeight);
618 653
619 Log.d(TAG, "requested resolution: (%dx%d)", width, height); 654 Log.d(TAG, "requested resolution: (%dx%d)", mPhotoWidth, mPhotoHeight);
620 if (closestSize != null) { 655 if (closestSize != null) {
621 Log.d(TAG, " matched (%dx%d)", closestSize.getWidth(), closestSize.g etHeight()); 656 Log.d(TAG, " matched (%dx%d)", closestSize.getWidth(), closestSize.g etHeight());
622 } 657 }
623 final ImageReader imageReader = ImageReader.newInstance( 658 final ImageReader imageReader = ImageReader.newInstance(
624 (closestSize != null) ? closestSize.getWidth() : mCaptureFormat. getWidth(), 659 (closestSize != null) ? closestSize.getWidth() : mCaptureFormat. getWidth(),
625 (closestSize != null) ? closestSize.getHeight() : mCaptureFormat .getHeight(), 660 (closestSize != null) ? closestSize.getHeight() : mCaptureFormat .getHeight(),
626 ImageFormat.JPEG, 1 /* maxImages */); 661 ImageFormat.JPEG, 1 /* maxImages */);
627 662
628 HandlerThread thread = new HandlerThread("CameraPicture"); 663 HandlerThread thread = new HandlerThread("CameraPicture");
629 thread.start(); 664 thread.start();
(...skipping 16 matching lines...) Expand all
646 if (photoRequestBuilder == null) { 681 if (photoRequestBuilder == null) {
647 Log.e(TAG, "photoRequestBuilder error"); 682 Log.e(TAG, "photoRequestBuilder error");
648 return false; 683 return false;
649 } 684 }
650 photoRequestBuilder.addTarget(imageReader.getSurface()); 685 photoRequestBuilder.addTarget(imageReader.getSurface());
651 photoRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, getCameraRotati on()); 686 photoRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, getCameraRotati on());
652 if (!mCropRect.isEmpty()) { 687 if (!mCropRect.isEmpty()) {
653 photoRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, mCropRect ); 688 photoRequestBuilder.set(CaptureRequest.SCALER_CROP_REGION, mCropRect );
654 } 689 }
655 690
691 if (mFocusMode == AndroidFocusMode.CONTINUOUS) {
692 photoRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
693 CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
694 } else if (mFocusMode == AndroidFocusMode.SINGLE_SHOT) {
695 Log.d(TAG, "triggering auto focus (maybe?)");
696 photoRequestBuilder.set(
697 CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF _TRIGGER_START);
698 }
699
656 final CaptureRequest photoRequest = photoRequestBuilder.build(); 700 final CaptureRequest photoRequest = photoRequestBuilder.build();
657 final CrPhotoSessionListener sessionListener = 701 final CrPhotoSessionListener sessionListener =
658 new CrPhotoSessionListener(photoRequest, callbackId); 702 new CrPhotoSessionListener(photoRequest, callbackId);
659 try { 703 try {
660 mCameraDevice.createCaptureSession(surfaceList, sessionListener, bac kgroundHandler); 704 mCameraDevice.createCaptureSession(surfaceList, sessionListener, bac kgroundHandler);
661 } catch (CameraAccessException | IllegalArgumentException | SecurityExce ption ex) { 705 } catch (CameraAccessException | IllegalArgumentException | SecurityExce ption ex) {
662 Log.e(TAG, "createCaptureSession: " + ex); 706 Log.e(TAG, "createCaptureSession: " + ex);
663 return false; 707 return false;
664 } 708 }
665 return true; 709 return true;
666 } 710 }
667 711
668 @Override 712 @Override
669 public void deallocate() { 713 public void deallocate() {
670 Log.d(TAG, "deallocate"); 714 Log.d(TAG, "deallocate");
671 } 715 }
672 } 716 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698