Search in sources :

Example 36 with Size

use of android.util.Size in project android_frameworks_base by ResurrectionRemix.

the class CameraTestUtils method verifyJpegKeys.

/**
     * Verify the JPEG EXIF and JPEG related keys in a capture result are expected.
     * - Capture request get values are same as were set.
     * - capture result's exif data is the same as was set by
     *   the capture request.
     * - new tags in the result set by the camera service are
     *   present and semantically correct.
     *
     * @param image The output JPEG image to verify.
     * @param captureResult The capture result to verify.
     * @param expectedSize The expected JPEG size.
     * @param expectedThumbnailSize The expected thumbnail size.
     * @param expectedExifData The expected EXIF data
     * @param staticInfo The static metadata for the camera device.
     * @param jpegFilename The filename to dump the jpeg to.
     * @param collector The camera error collector to collect errors.
     */
public static void verifyJpegKeys(Image image, CaptureResult captureResult, Size expectedSize, Size expectedThumbnailSize, ExifTestData expectedExifData, StaticMetadata staticInfo, CameraErrorCollector collector) throws Exception {
    basicValidateJpegImage(image, expectedSize);
    byte[] jpegBuffer = getDataFromImage(image);
    // Have to dump into a file to be able to use ExifInterface
    String jpegFilename = DEBUG_FILE_NAME_BASE + "/verifyJpegKeys.jpeg";
    dumpFile(jpegFilename, jpegBuffer);
    ExifInterface exif = new ExifInterface(jpegFilename);
    if (expectedThumbnailSize.equals(new Size(0, 0))) {
        collector.expectTrue("Jpeg shouldn't have thumbnail when thumbnail size is (0, 0)", !exif.hasThumbnail());
    } else {
        collector.expectTrue("Jpeg must have thumbnail for thumbnail size " + expectedThumbnailSize, exif.hasThumbnail());
    }
    // Validate capture result vs. request
    Size resultThumbnailSize = captureResult.get(CaptureResult.JPEG_THUMBNAIL_SIZE);
    int orientationTested = expectedExifData.jpegOrientation;
    // Legacy shim always doesn't rotate thumbnail size
    if ((orientationTested == 90 || orientationTested == 270) && staticInfo.isHardwareLevelLimitedOrBetter()) {
        int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, /*defaultValue*/
        -1);
        if (exifOrientation == ExifInterface.ORIENTATION_UNDEFINED) {
            // Device physically rotated image+thumbnail data
            // Expect thumbnail size to be also rotated
            resultThumbnailSize = new Size(resultThumbnailSize.getHeight(), resultThumbnailSize.getWidth());
        }
    }
    collector.expectEquals("JPEG thumbnail size result and request should match", expectedThumbnailSize, resultThumbnailSize);
    if (collector.expectKeyValueNotNull(captureResult, CaptureResult.JPEG_GPS_LOCATION) != null) {
        collector.expectTrue("GPS location result and request should match.", areGpsFieldsEqual(expectedExifData.gpsLocation, captureResult.get(CaptureResult.JPEG_GPS_LOCATION)));
    }
    collector.expectEquals("JPEG orientation result and request should match", expectedExifData.jpegOrientation, captureResult.get(CaptureResult.JPEG_ORIENTATION));
    collector.expectEquals("JPEG quality result and request should match", expectedExifData.jpegQuality, captureResult.get(CaptureResult.JPEG_QUALITY));
    collector.expectEquals("JPEG thumbnail quality result and request should match", expectedExifData.thumbnailQuality, captureResult.get(CaptureResult.JPEG_THUMBNAIL_QUALITY));
    // Validate other exif tags for all non-legacy devices
    if (!staticInfo.isHardwareLevelLegacy()) {
        verifyJpegExifExtraTags(exif, expectedSize, captureResult, staticInfo, collector);
    }
}
Also used : Size(android.util.Size) ExifInterface(android.media.ExifInterface)

Example 37 with Size

use of android.util.Size in project android_frameworks_base by ResurrectionRemix.

the class CameraTestUtils method verifyJpegExifExtraTags.

/**
     * Verify extra tags in JPEG EXIF
     */
private static void verifyJpegExifExtraTags(ExifInterface exif, Size jpegSize, CaptureResult result, StaticMetadata staticInfo, CameraErrorCollector collector) throws ParseException {
    /**
         * TAG_IMAGE_WIDTH and TAG_IMAGE_LENGTH and TAG_ORIENTATION.
         * Orientation and exif width/height need to be tested carefully, two cases:
         *
         * 1. Device rotate the image buffer physically, then exif width/height may not match
         * the requested still capture size, we need swap them to check.
         *
         * 2. Device use the exif tag to record the image orientation, it doesn't rotate
         * the jpeg image buffer itself. In this case, the exif width/height should always match
         * the requested still capture size, and the exif orientation should always match the
         * requested orientation.
         *
         */
    int exifWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, /*defaultValue*/
    0);
    int exifHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, /*defaultValue*/
    0);
    Size exifSize = new Size(exifWidth, exifHeight);
    // Orientation could be missing, which is ok, default to 0.
    int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, /*defaultValue*/
    -1);
    // Get requested orientation from result, because they should be same.
    if (collector.expectKeyValueNotNull(result, CaptureResult.JPEG_ORIENTATION) != null) {
        int requestedOrientation = result.get(CaptureResult.JPEG_ORIENTATION);
        final int ORIENTATION_MIN = ExifInterface.ORIENTATION_UNDEFINED;
        final int ORIENTATION_MAX = ExifInterface.ORIENTATION_ROTATE_270;
        boolean orientationValid = collector.expectTrue(String.format("Exif orientation must be in range of [%d, %d]", ORIENTATION_MIN, ORIENTATION_MAX), exifOrientation >= ORIENTATION_MIN && exifOrientation <= ORIENTATION_MAX);
        if (orientationValid) {
            /**
                 * Device captured image doesn't respect the requested orientation,
                 * which means it rotates the image buffer physically. Then we
                 * should swap the exif width/height accordingly to compare.
                 */
            boolean deviceRotatedImage = exifOrientation == ExifInterface.ORIENTATION_UNDEFINED;
            if (deviceRotatedImage) {
                // Case 1.
                boolean needSwap = (requestedOrientation % 180 == 90);
                if (needSwap) {
                    exifSize = new Size(exifHeight, exifWidth);
                }
            } else {
                // Case 2.
                collector.expectEquals("Exif orientaiton should match requested orientation", requestedOrientation, getExifOrientationInDegree(exifOrientation, collector));
            }
        }
    }
    /**
         * Ideally, need check exifSize == jpegSize == actual buffer size. But
         * jpegSize == jpeg decode bounds size(from jpeg jpeg frame
         * header, not exif) was validated in ImageReaderTest, no need to
         * validate again here.
         */
    collector.expectEquals("Exif size should match jpeg capture size", jpegSize, exifSize);
    // TAG_DATETIME, it should be local time
    long currentTimeInMs = System.currentTimeMillis();
    long currentTimeInSecond = currentTimeInMs / 1000;
    Date date = new Date(currentTimeInMs);
    String localDatetime = new SimpleDateFormat("yyyy:MM:dd HH:").format(date);
    String dateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
    if (collector.expectTrue("Exif TAG_DATETIME shouldn't be null", dateTime != null)) {
        collector.expectTrue("Exif TAG_DATETIME is wrong", dateTime.length() == EXIF_DATETIME_LENGTH);
        long exifTimeInSecond = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").parse(dateTime).getTime() / 1000;
        long delta = currentTimeInSecond - exifTimeInSecond;
        collector.expectTrue("Capture time deviates too much from the current time", Math.abs(delta) < EXIF_DATETIME_ERROR_MARGIN_SEC);
        // It should be local time.
        collector.expectTrue("Exif date time should be local time", dateTime.startsWith(localDatetime));
    }
    // TAG_FOCAL_LENGTH.
    float[] focalLengths = staticInfo.getAvailableFocalLengthsChecked();
    float exifFocalLength = (float) exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, -1);
    collector.expectEquals("Focal length should match", getClosestValueInArray(focalLengths, exifFocalLength), exifFocalLength, EXIF_FOCAL_LENGTH_ERROR_MARGIN);
    // More checks for focal length.
    collector.expectEquals("Exif focal length should match capture result", validateFocalLength(result, staticInfo, collector), exifFocalLength);
    // TAG_EXPOSURE_TIME
    // ExifInterface API gives exposure time value in the form of float instead of rational
    String exposureTime = exif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
    collector.expectNotNull("Exif TAG_EXPOSURE_TIME shouldn't be null", exposureTime);
    if (staticInfo.areKeysAvailable(CaptureResult.SENSOR_EXPOSURE_TIME)) {
        if (exposureTime != null) {
            double exposureTimeValue = Double.parseDouble(exposureTime);
            long expTimeResult = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
            double expected = expTimeResult / 1e9;
            double tolerance = expected * EXIF_EXPOSURE_TIME_ERROR_MARGIN_RATIO;
            tolerance = Math.max(tolerance, EXIF_EXPOSURE_TIME_MIN_ERROR_MARGIN_SEC);
            collector.expectEquals("Exif exposure time doesn't match", expected, exposureTimeValue, tolerance);
        }
    }
    // TAG_APERTURE
    // ExifInterface API gives aperture value in the form of float instead of rational
    String exifAperture = exif.getAttribute(ExifInterface.TAG_APERTURE);
    collector.expectNotNull("Exif TAG_APERTURE shouldn't be null", exifAperture);
    if (staticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES)) {
        float[] apertures = staticInfo.getAvailableAperturesChecked();
        if (exifAperture != null) {
            float apertureValue = Float.parseFloat(exifAperture);
            collector.expectEquals("Aperture value should match", getClosestValueInArray(apertures, apertureValue), apertureValue, EXIF_APERTURE_ERROR_MARGIN);
            // More checks for aperture.
            collector.expectEquals("Exif aperture length should match capture result", validateAperture(result, staticInfo, collector), apertureValue);
        }
    }
    /**
         * TAG_FLASH. TODO: For full devices, can check a lot more info
         * (http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html#Flash)
         */
    String flash = exif.getAttribute(ExifInterface.TAG_FLASH);
    collector.expectNotNull("Exif TAG_FLASH shouldn't be null", flash);
    /**
         * TAG_WHITE_BALANCE. TODO: For full devices, with the DNG tags, we
         * should be able to cross-check android.sensor.referenceIlluminant.
         */
    String whiteBalance = exif.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
    collector.expectNotNull("Exif TAG_WHITE_BALANCE shouldn't be null", whiteBalance);
    // TAG_MAKE
    String make = exif.getAttribute(ExifInterface.TAG_MAKE);
    collector.expectEquals("Exif TAG_MAKE is incorrect", Build.MANUFACTURER, make);
    // TAG_MODEL
    String model = exif.getAttribute(ExifInterface.TAG_MODEL);
    collector.expectEquals("Exif TAG_MODEL is incorrect", Build.MODEL, model);
    // TAG_ISO
    int iso = exif.getAttributeInt(ExifInterface.TAG_ISO, /*defaultValue*/
    -1);
    if (staticInfo.areKeysAvailable(CaptureResult.SENSOR_SENSITIVITY)) {
        int expectedIso = result.get(CaptureResult.SENSOR_SENSITIVITY);
        collector.expectEquals("Exif TAG_ISO is incorrect", expectedIso, iso);
    }
    // TAG_DATETIME_DIGITIZED (a.k.a Create time for digital cameras).
    String digitizedTime = exif.getAttribute(ExifInterface.TAG_DATETIME_DIGITIZED);
    collector.expectNotNull("Exif TAG_DATETIME_DIGITIZED shouldn't be null", digitizedTime);
    if (digitizedTime != null) {
        String expectedDateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
        collector.expectNotNull("Exif TAG_DATETIME shouldn't be null", expectedDateTime);
        if (expectedDateTime != null) {
            collector.expectEquals("dataTime should match digitizedTime", expectedDateTime, digitizedTime);
        }
    }
    /**
         * TAG_SUBSEC_TIME. Since the sub second tag strings are truncated to at
         * most 9 digits in ExifInterface implementation, use getAttributeInt to
         * sanitize it. When the default value -1 is returned, it means that
         * this exif tag either doesn't exist or is a non-numerical invalid
         * string. Same rule applies to the rest of sub second tags.
         */
    int subSecTime = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME, /*defaultValue*/
    -1);
    collector.expectTrue("Exif TAG_SUBSEC_TIME value is null or invalid!", subSecTime > 0);
    // TAG_SUBSEC_TIME_ORIG
    int subSecTimeOrig = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME_ORIG, /*defaultValue*/
    -1);
    collector.expectTrue("Exif TAG_SUBSEC_TIME_ORIG value is null or invalid!", subSecTimeOrig > 0);
    // TAG_SUBSEC_TIME_DIG
    int subSecTimeDig = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME_DIG, /*defaultValue*/
    -1);
    collector.expectTrue("Exif TAG_SUBSEC_TIME_DIG value is null or invalid!", subSecTimeDig > 0);
}
Also used : Size(android.util.Size) SimpleDateFormat(java.text.SimpleDateFormat) Date(java.util.Date)

Example 38 with Size

use of android.util.Size in project android_frameworks_base by ResurrectionRemix.

the class CameraTestUtils method getSupportedVideoSizes.

/**
     * Get supported video size list for a given camera device.
     *
     * <p>
     * Filter out the sizes that are larger than the bound. If the bound is
     * null, don't do the size bound filtering.
     * </p>
     */
public static List<Size> getSupportedVideoSizes(String cameraId, CameraManager cameraManager, Size bound) throws CameraAccessException {
    Size[] rawSizes = getSupportedSizeForClass(android.media.MediaRecorder.class, cameraId, cameraManager);
    assertArrayNotEmpty(rawSizes, "Available sizes for MediaRecorder class should not be empty");
    if (VERBOSE) {
        Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(rawSizes));
    }
    if (bound == null) {
        return getAscendingOrderSizes(Arrays.asList(rawSizes), /*ascending*/
        false);
    }
    List<Size> sizes = new ArrayList<Size>();
    for (Size sz : rawSizes) {
        if (sz.getWidth() <= bound.getWidth() && sz.getHeight() <= bound.getHeight()) {
            sizes.add(sz);
        }
    }
    return getAscendingOrderSizes(sizes, /*ascending*/
    false);
}
Also used : Size(android.util.Size) ArrayList(java.util.ArrayList)

Example 39 with Size

use of android.util.Size in project android_frameworks_base by ResurrectionRemix.

the class StaticMetadata method getRawDimensChecked.

/**
     * Get the dimensions to use for RAW16 buffers.
     */
public Size getRawDimensChecked() throws Exception {
    Size[] targetCaptureSizes = getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR, StaticMetadata.StreamDirection.Output);
    Assert.assertTrue("No capture sizes available for RAW format!", targetCaptureSizes.length != 0);
    Rect activeArray = getPreCorrectedActiveArraySizeChecked();
    Size preCorrectionActiveArraySize = new Size(activeArray.width(), activeArray.height());
    Size pixelArraySize = getPixelArraySizeChecked();
    Assert.assertTrue("Missing pre-correction active array size", activeArray.width() > 0 && activeArray.height() > 0);
    Assert.assertTrue("Missing pixel array size", pixelArraySize.getWidth() > 0 && pixelArraySize.getHeight() > 0);
    Size[] allowedArraySizes = new Size[] { preCorrectionActiveArraySize, pixelArraySize };
    return assertArrayContainsAnyOf("Available sizes for RAW format" + " must include either the pre-corrected active array size, or the full " + "pixel array size", targetCaptureSizes, allowedArraySizes);
}
Also used : Rect(android.graphics.Rect) Size(android.util.Size)

Example 40 with Size

use of android.util.Size in project android_frameworks_base by ResurrectionRemix.

the class StaticMetadata method isHighSpeedVideoSupported.

/**
     * Check if high speed video is supported (HIGH_SPEED_VIDEO scene mode is
     * supported, supported high speed fps ranges and sizes are valid).
     *
     * @return true if high speed video is supported.
     */
public boolean isHighSpeedVideoSupported() {
    List<Integer> sceneModes = Arrays.asList(CameraTestUtils.toObject(getAvailableSceneModesChecked()));
    if (sceneModes.contains(CameraCharacteristics.CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO)) {
        StreamConfigurationMap config = getValueFromKeyNonNull(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
        if (config == null) {
            return false;
        }
        Size[] availableSizes = config.getHighSpeedVideoSizes();
        if (availableSizes.length == 0) {
            return false;
        }
        for (Size size : availableSizes) {
            Range<Integer>[] availableFpsRanges = config.getHighSpeedVideoFpsRangesFor(size);
            if (availableFpsRanges.length == 0) {
                return false;
            }
        }
        return true;
    } else {
        return false;
    }
}
Also used : Size(android.util.Size) StreamConfigurationMap(android.hardware.camera2.params.StreamConfigurationMap) Range(android.util.Range)

Aggregations

Size (android.util.Size)320 ArrayList (java.util.ArrayList)66 StreamConfigurationMap (android.hardware.camera2.params.StreamConfigurationMap)41 Rect (android.graphics.Rect)40 CaptureRequest (android.hardware.camera2.CaptureRequest)40 Range (android.util.Range)40 Surface (android.view.Surface)35 SimpleCaptureCallback (com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleCaptureCallback)35 Camera (android.hardware.Camera)30 CameraCharacteristics (android.hardware.camera2.CameraCharacteristics)26 Point (android.graphics.Point)22 Image (android.media.Image)21 SimpleImageReaderListener (com.android.mediaframeworktest.helpers.CameraTestUtils.SimpleImageReaderListener)20 MeteringRectangle (android.hardware.camera2.params.MeteringRectangle)15 CamcorderProfile (android.media.CamcorderProfile)15 Pair (android.util.Pair)15 CameraTestUtils.getDataFromImage (com.android.mediaframeworktest.helpers.CameraTestUtils.getDataFromImage)15 SurfaceTexture (android.graphics.SurfaceTexture)10 Parameters (android.hardware.Camera.Parameters)10 CaptureResult (android.hardware.camera2.CaptureResult)10