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

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

Issue 2164473002: ImageCapture: wire PhotoCapabilities' ISO, width, height and PhotoSettings' width and height (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: foolip@ comments. Rebase Created 4 years, 5 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;
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.StreamConfigurationMap; 18 import android.hardware.camera2.params.StreamConfigurationMap;
19 import android.media.Image; 19 import android.media.Image;
20 import android.media.ImageReader; 20 import android.media.ImageReader;
21 import android.os.Build; 21 import android.os.Build;
22 import android.os.Handler; 22 import android.os.Handler;
23 import android.os.HandlerThread; 23 import android.os.HandlerThread;
24 import android.util.Range;
24 import android.util.Size; 25 import android.util.Size;
25 import android.view.Surface; 26 import android.view.Surface;
26 27
27 import org.chromium.base.Log; 28 import org.chromium.base.Log;
28 import org.chromium.base.annotations.JNINamespace; 29 import org.chromium.base.annotations.JNINamespace;
29 30
30 import java.nio.ByteBuffer; 31 import java.nio.ByteBuffer;
31 import java.util.ArrayList; 32 import java.util.ArrayList;
32 import java.util.List; 33 import java.util.List;
33 34
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 } 354 }
354 } 355 }
355 356
356 private void changeCameraStateAndNotify(CameraState state) { 357 private void changeCameraStateAndNotify(CameraState state) {
357 synchronized (mCameraStateLock) { 358 synchronized (mCameraStateLock) {
358 mCameraState = state; 359 mCameraState = state;
359 mCameraStateLock.notifyAll(); 360 mCameraStateLock.notifyAll();
360 } 361 }
361 } 362 }
362 363
364 // Finds the closest Size to (|width|x|height|) in |sizes|, and returns it o r null.
365 // Ignores |width| or |height| if either is zero (== don't care).
366 private static Size findClosestSizeInArray(Size[] sizes, int width, int heig ht) {
367 if (sizes == null) return null;
368 Size closestSize = null;
369 int minDiff = Integer.MAX_VALUE;
370 for (Size size : sizes) {
371 final int diff = ((width > 0) ? Math.abs(size.getWidth() - width) : 0)
372 + ((height > 0) ? Math.abs(size.getHeight() - height) : 0);
373 if (diff < minDiff) {
374 minDiff = diff;
375 closestSize = size;
376 }
377 }
378 if (minDiff == Integer.MAX_VALUE) {
379 Log.e(TAG, "Couldn't find resolution close to (%dx%d)", width, heigh t);
380 return null;
381 }
382 return closestSize;
383 }
384
363 static boolean isLegacyDevice(Context appContext, int id) { 385 static boolean isLegacyDevice(Context appContext, int id) {
364 final CameraCharacteristics cameraCharacteristics = 386 final CameraCharacteristics cameraCharacteristics =
365 getCameraCharacteristics(appContext, id); 387 getCameraCharacteristics(appContext, id);
366 return cameraCharacteristics != null 388 return cameraCharacteristics != null
367 && cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTE D_HARDWARE_LEVEL) 389 && cameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTE D_HARDWARE_LEVEL)
368 == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY; 390 == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
369 } 391 }
370 392
371 static int getNumberOfCameras(Context appContext) { 393 static int getNumberOfCameras(Context appContext) {
372 final CameraManager manager = 394 final CameraManager manager =
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 Log.e(TAG, "allocate() invoked while Camera is busy opening/conf iguring."); 491 Log.e(TAG, "allocate() invoked while Camera is busy opening/conf iguring.");
470 return false; 492 return false;
471 } 493 }
472 } 494 }
473 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId); 495 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId);
474 final StreamConfigurationMap streamMap = 496 final StreamConfigurationMap streamMap =
475 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO NFIGURATION_MAP); 497 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO NFIGURATION_MAP);
476 498
477 // Find closest supported size. 499 // Find closest supported size.
478 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.YUV_4 20_888); 500 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.YUV_4 20_888);
479 if (supportedSizes == null) return false; 501 final Size closestSupportedSize = findClosestSizeInArray(supportedSizes, width, height);
480 Size closestSupportedSize = null; 502 if (closestSupportedSize == null) {
481 int minDiff = Integer.MAX_VALUE;
482 for (Size size : supportedSizes) {
483 final int diff =
484 Math.abs(size.getWidth() - width) + Math.abs(size.getHeight( ) - height);
485 if (diff < minDiff) {
486 minDiff = diff;
487 closestSupportedSize = size;
488 }
489 }
490 if (minDiff == Integer.MAX_VALUE) {
491 Log.e(TAG, "No supported resolutions."); 503 Log.e(TAG, "No supported resolutions.");
492 return false; 504 return false;
493 } 505 }
494 Log.d(TAG, "allocate: matched (%d x %d)", closestSupportedSize.getWidth( ), 506 Log.d(TAG, "allocate: matched (%d x %d)", closestSupportedSize.getWidth( ),
495 closestSupportedSize.getHeight()); 507 closestSupportedSize.getHeight());
496 508
497 // |mCaptureFormat| is also used to configure the ImageReader. 509 // |mCaptureFormat| is also used to configure the ImageReader.
498 mCaptureFormat = new VideoCaptureFormat(closestSupportedSize.getWidth(), 510 mCaptureFormat = new VideoCaptureFormat(closestSupportedSize.getWidth(),
499 closestSupportedSize.getHeight(), frameRate, ImageFormat.YUV_420 _888); 511 closestSupportedSize.getHeight(), frameRate, ImageFormat.YUV_420 _888);
500 int expectedFrameSize = mCaptureFormat.mWidth * mCaptureFormat.mHeight 512 int expectedFrameSize = mCaptureFormat.mWidth * mCaptureFormat.mHeight
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 if (mCameraDevice == null) return false; 567 if (mCameraDevice == null) return false;
556 mCameraDevice.close(); 568 mCameraDevice.close();
557 changeCameraStateAndNotify(CameraState.STOPPED); 569 changeCameraStateAndNotify(CameraState.STOPPED);
558 mCropRect = new Rect(); 570 mCropRect = new Rect();
559 return true; 571 return true;
560 } 572 }
561 573
562 public PhotoCapabilities getPhotoCapabilities() { 574 public PhotoCapabilities getPhotoCapabilities() {
563 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId); 575 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId);
564 576
577 int minIso = 0;
578 int maxIso = 0;
579 final Range<Integer> iso_range =
580 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_SENS ITIVITY_RANGE);
581 if (iso_range != null) {
582 minIso = iso_range.getLower();
583 maxIso = iso_range.getUpper();
584 }
585 final int currentIso = mPreviewRequest.get(CaptureRequest.SENSOR_SENSITI VITY);
586
587 final StreamConfigurationMap streamMap =
588 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO NFIGURATION_MAP);
589 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.JPEG) ;
590 int minWidth = Integer.MAX_VALUE;
591 int minHeight = Integer.MAX_VALUE;
592 int maxWidth = 0;
593 int maxHeight = 0;
594 for (Size size : supportedSizes) {
595 if (size.getWidth() < minWidth) minWidth = size.getWidth();
596 if (size.getHeight() < minHeight) minHeight = size.getHeight();
597 if (size.getWidth() > maxWidth) maxWidth = size.getWidth();
598 if (size.getHeight() > maxHeight) maxHeight = size.getHeight();
599 }
600 final int currentHeight = mCaptureFormat.getHeight();
601 final int currentWidth = mCaptureFormat.getWidth();
602
565 // The Min and Max zoom are returned as x100 by the API to avoid using f loating point. There 603 // The Min and Max zoom are returned as x100 by the API to avoid using f loating point. There
566 // is no min-zoom per se, so clamp it to always 100 (TODO(mcasas): make const member). 604 // is no min-zoom per se, so clamp it to always 100 (TODO(mcasas): make const member).
567 final int minZoom = 100; 605 final int minZoom = 100;
568 final int maxZoom = Math.round(mMaxZoom * 100); 606 final int maxZoom = Math.round(mMaxZoom * 100);
569
570 // Width Ratio x100 is used as measure of current zoom. 607 // Width Ratio x100 is used as measure of current zoom.
571 final int currentZoom = 100 * mPreviewRequest.get(CaptureRequest.SCALER_ CROP_REGION).width() 608 final int currentZoom = 100 * mPreviewRequest.get(CaptureRequest.SCALER_ CROP_REGION).width()
572 / cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_AC TIVE_ARRAY_SIZE) 609 / cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_AC TIVE_ARRAY_SIZE)
573 .width(); 610 .width();
574 611
575 final int focusMode = mPreviewRequest.get(CaptureRequest.CONTROL_AF_MODE ); 612 final int focusMode = mPreviewRequest.get(CaptureRequest.CONTROL_AF_MODE );
576 Log.d(TAG, "focusMode " + focusMode); 613 Log.d(TAG, "focusMode " + focusMode);
577 final boolean isFocusManual = (focusMode == CameraMetadata.CONTROL_AF_MO DE_OFF) 614 final boolean isFocusManual = (focusMode == CameraMetadata.CONTROL_AF_MO DE_OFF)
578 || (focusMode == CameraMetadata.CONTROL_AF_MODE_EDOF); 615 || (focusMode == CameraMetadata.CONTROL_AF_MODE_EDOF);
579 616
580 return new PhotoCapabilities(maxZoom, minZoom, currentZoom, !isFocusManu al); 617 return new PhotoCapabilities(minIso, maxIso, currentIso, maxHeight, minH eight,
618 currentHeight, maxWidth, minWidth, currentWidth, maxZoom, minZoo m, currentZoom,
619 !isFocusManual);
581 } 620 }
582 621
583 @Override 622 @Override
584 public void setZoom(int zoom) { 623 public void setZoom(int zoom) {
585 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId); 624 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId);
586 final Rect canvas = 625 final Rect canvas =
587 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTI VE_ARRAY_SIZE); 626 cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTI VE_ARRAY_SIZE);
588 627
589 final float normalizedZoom = Math.max(100, Math.min(zoom, mMaxZoom * 100 )) / 100; 628 final float normalizedZoom = Math.max(100, Math.min(zoom, mMaxZoom * 100 )) / 100;
590 final float cropFactor = (normalizedZoom - 1) / (2 * normalizedZoom); 629 final float cropFactor = (normalizedZoom - 1) / (2 * normalizedZoom);
591 630
592 mCropRect = new Rect(Math.round(canvas.width() * cropFactor), 631 mCropRect = new Rect(Math.round(canvas.width() * cropFactor),
593 Math.round(canvas.height() * cropFactor), 632 Math.round(canvas.height() * cropFactor),
594 Math.round(canvas.width() * (1 - cropFactor)), 633 Math.round(canvas.width() * (1 - cropFactor)),
595 Math.round(canvas.height() * (1 - cropFactor))); 634 Math.round(canvas.height() * (1 - cropFactor)));
596 Log.d(TAG, "zoom level " + normalizedZoom + ", rectangle: " + mCropRect. toString()); 635 Log.d(TAG, "zoom level " + normalizedZoom + ", rectangle: " + mCropRect. toString());
597 636
598 final Handler mainHandler = new Handler(mContext.getMainLooper()); 637 final Handler mainHandler = new Handler(mContext.getMainLooper());
599 mainHandler.post(new Runnable() { 638 mainHandler.post(new Runnable() {
600 @Override 639 @Override
601 public void run() { 640 public void run() {
602 mPreviewSession.close(); // Asynchronously kill the CaptureSessi on. 641 mPreviewSession.close(); // Asynchronously kill the CaptureSessi on.
603 createPreviewObjects(); 642 createPreviewObjects();
604 } 643 }
605 }); 644 });
606 } 645 }
607 646
608 @Override 647 @Override
609 public boolean takePhoto(final long callbackId) { 648 public boolean takePhoto(final long callbackId, int width, int height) {
610 Log.d(TAG, "takePhoto " + callbackId); 649 Log.d(TAG, "takePhoto " + callbackId);
611 if (mCameraDevice == null || mCameraState != CameraState.STARTED) return false; 650 if (mCameraDevice == null || mCameraState != CameraState.STARTED) return false;
612 651
613 final ImageReader imageReader = ImageReader.newInstance(mCaptureFormat.g etWidth(), 652 final CameraCharacteristics cameraCharacteristics = getCameraCharacteris tics(mContext, mId);
614 mCaptureFormat.getHeight(), ImageFormat.JPEG, 1 /* maxImages */) ; 653 final StreamConfigurationMap streamMap =
654 cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CO NFIGURATION_MAP);
655 final Size[] supportedSizes = streamMap.getOutputSizes(ImageFormat.JPEG) ;
656 final Size closestSize = findClosestSizeInArray(supportedSizes, width, h eight);
657
658 Log.d(TAG, "requested resolution: (%dx%d)", width, height);
659 if (closestSize != null) {
660 Log.d(TAG, " matched (%dx%d)", closestSize.getWidth(), closestSize.g etHeight());
661 }
662 final ImageReader imageReader = ImageReader.newInstance(
663 (closestSize != null) ? closestSize.getWidth() : mCaptureFormat. getWidth(),
664 (closestSize != null) ? closestSize.getHeight() : mCaptureFormat .getHeight(),
665 ImageFormat.JPEG, 1 /* maxImages */);
615 666
616 HandlerThread thread = new HandlerThread("CameraPicture"); 667 HandlerThread thread = new HandlerThread("CameraPicture");
617 thread.start(); 668 thread.start();
618 final Handler backgroundHandler = new Handler(thread.getLooper()); 669 final Handler backgroundHandler = new Handler(thread.getLooper());
619 670
620 final CrPhotoReaderListener photoReaderListener = new CrPhotoReaderListe ner(callbackId); 671 final CrPhotoReaderListener photoReaderListener = new CrPhotoReaderListe ner(callbackId);
621 imageReader.setOnImageAvailableListener(photoReaderListener, backgroundH andler); 672 imageReader.setOnImageAvailableListener(photoReaderListener, backgroundH andler);
622 673
623 final List<Surface> surfaceList = new ArrayList<Surface>(1); 674 final List<Surface> surfaceList = new ArrayList<Surface>(1);
624 surfaceList.add(imageReader.getSurface()); 675 surfaceList.add(imageReader.getSurface());
(...skipping 26 matching lines...) Expand all
651 return false; 702 return false;
652 } 703 }
653 return true; 704 return true;
654 } 705 }
655 706
656 @Override 707 @Override
657 public void deallocate() { 708 public void deallocate() {
658 Log.d(TAG, "deallocate"); 709 Log.d(TAG, "deallocate");
659 } 710 }
660 } 711 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698