public class

Camera2CameraCaptureResult

extends java.lang.Object

implements CameraCaptureResult

 java.lang.Object

↳androidx.camera.camera2.internal.Camera2CameraCaptureResult

Gradle dependencies

compile group: 'androidx.camera', name: 'camera-camera2', version: '1.5.0-alpha01'

  • groupId: androidx.camera
  • artifactId: camera-camera2
  • version: 1.5.0-alpha01

Artifact androidx.camera:camera-camera2:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

The camera2 implementation for the capture result of a single image capture.

Summary

Constructors
publicCamera2CameraCaptureResult(CaptureResult captureResult)

publicCamera2CameraCaptureResult(TagBundle tagBundle, CaptureResult captureResult)

Methods
public CameraCaptureMetaData.AeModegetAeMode()

public CameraCaptureMetaData.AeStategetAeState()

Converts the camera2 CaptureResult to CameraCaptureMetaData.AeState.

public CameraCaptureMetaData.AfModegetAfMode()

Converts the camera2 CaptureResult to CameraCaptureMetaData.AfMode.

public CameraCaptureMetaData.AfStategetAfState()

Converts the camera2 CaptureResult to CameraCaptureMetaData.AfState.

public CameraCaptureMetaData.AwbModegetAwbMode()

public CameraCaptureMetaData.AwbStategetAwbState()

Converts the camera2 CaptureResult to CameraCaptureMetaData.AwbState.

public CaptureResultgetCaptureResult()

public CameraCaptureMetaData.FlashStategetFlashState()

Converts the camera2 CaptureResult to CameraCaptureMetaData.FlashState.

public TagBundlegetTagBundle()

public longgetTimestamp()

public voidpopulateExifData(ExifData.Builder exifData)

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public Camera2CameraCaptureResult(TagBundle tagBundle, CaptureResult captureResult)

public Camera2CameraCaptureResult(CaptureResult captureResult)

Methods

public CameraCaptureMetaData.AfMode getAfMode()

Converts the camera2 CaptureResult to CameraCaptureMetaData.AfMode.

Returns:

the CameraCaptureMetaData.AfMode.

public CameraCaptureMetaData.AfState getAfState()

Converts the camera2 CaptureResult to CameraCaptureMetaData.AfState.

Returns:

the CameraCaptureMetaData.AfState.

public CameraCaptureMetaData.AeState getAeState()

Converts the camera2 CaptureResult to CameraCaptureMetaData.AeState.

Returns:

the CameraCaptureMetaData.AeState.

public CameraCaptureMetaData.AwbState getAwbState()

Converts the camera2 CaptureResult to CameraCaptureMetaData.AwbState.

Returns:

the CameraCaptureMetaData.AwbState.

public CameraCaptureMetaData.FlashState getFlashState()

Converts the camera2 CaptureResult to CameraCaptureMetaData.FlashState.

Returns:

the CameraCaptureMetaData.FlashState.

public CameraCaptureMetaData.AeMode getAeMode()

public CameraCaptureMetaData.AwbMode getAwbMode()

public long getTimestamp()

public TagBundle getTagBundle()

public void populateExifData(ExifData.Builder exifData)

public CaptureResult getCaptureResult()

Source

/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.camera.camera2.internal;

import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureResult;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.camera.core.Logger;
import androidx.camera.core.impl.CameraCaptureMetaData;
import androidx.camera.core.impl.CameraCaptureMetaData.AeMode;
import androidx.camera.core.impl.CameraCaptureMetaData.AeState;
import androidx.camera.core.impl.CameraCaptureMetaData.AfMode;
import androidx.camera.core.impl.CameraCaptureMetaData.AfState;
import androidx.camera.core.impl.CameraCaptureMetaData.AwbMode;
import androidx.camera.core.impl.CameraCaptureMetaData.AwbState;
import androidx.camera.core.impl.CameraCaptureMetaData.FlashState;
import androidx.camera.core.impl.CameraCaptureResult;
import androidx.camera.core.impl.TagBundle;
import androidx.camera.core.impl.utils.ExifData;

import java.nio.BufferUnderflowException;

/** The camera2 implementation for the capture result of a single image capture. */
public class Camera2CameraCaptureResult implements CameraCaptureResult {
    private static final String TAG = "C2CameraCaptureResult";

    private final TagBundle mTagBundle;

    /** The actual camera2 {@link CaptureResult}. */
    private final CaptureResult mCaptureResult;

    public Camera2CameraCaptureResult(@NonNull TagBundle tagBundle,
            @NonNull CaptureResult captureResult) {
        mTagBundle = tagBundle;
        mCaptureResult = captureResult;
    }

    public Camera2CameraCaptureResult(@NonNull CaptureResult captureResult) {
        this(TagBundle.emptyBundle(), captureResult);
    }

    /**
     * Converts the camera2 {@link CaptureResult#CONTROL_AF_MODE} to {@link AfMode}.
     *
     * @return the {@link AfMode}.
     */
    @NonNull
    @Override
    public AfMode getAfMode() {
        Integer mode = mCaptureResult.get(CaptureResult.CONTROL_AF_MODE);
        if (mode == null) {
            return AfMode.UNKNOWN;
        }
        switch (mode) {
            case CaptureResult.CONTROL_AF_MODE_OFF:
            case CaptureResult.CONTROL_AF_MODE_EDOF:
                return AfMode.OFF;
            case CaptureResult.CONTROL_AF_MODE_AUTO:
            case CaptureResult.CONTROL_AF_MODE_MACRO:
                return AfMode.ON_MANUAL_AUTO;
            case CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE:
            case CaptureResult.CONTROL_AF_MODE_CONTINUOUS_VIDEO:
                return AfMode.ON_CONTINUOUS_AUTO;
            default: // fall out
        }
        Logger.e(TAG, "Undefined af mode: " + mode);
        return AfMode.UNKNOWN;
    }

    /**
     * Converts the camera2 {@link CaptureResult#CONTROL_AF_STATE} to {@link AfState}.
     *
     * @return the {@link AfState}.
     */
    @NonNull
    @Override
    public AfState getAfState() {
        Integer state = mCaptureResult.get(CaptureResult.CONTROL_AF_STATE);
        if (state == null) {
            return AfState.UNKNOWN;
        }
        switch (state) {
            case CaptureResult.CONTROL_AF_STATE_INACTIVE:
                return AfState.INACTIVE;
            case CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN:
            case CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN:
                return AfState.SCANNING;
            case CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED:
                return AfState.LOCKED_FOCUSED;
            case CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED:
                return AfState.LOCKED_NOT_FOCUSED;
            case CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED:
                return AfState.PASSIVE_NOT_FOCUSED;
            case CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED:
                return AfState.PASSIVE_FOCUSED;

            default: // fall out
        }
        Logger.e(TAG, "Undefined af state: " + state);
        return AfState.UNKNOWN;
    }

    /**
     * Converts the camera2 {@link CaptureResult#CONTROL_AE_STATE} to {@link AeState}.
     *
     * @return the {@link AeState}.
     */
    @NonNull
    @Override
    public AeState getAeState() {
        Integer state = mCaptureResult.get(CaptureResult.CONTROL_AE_STATE);
        if (state == null) {
            return AeState.UNKNOWN;
        }
        switch (state) {
            case CaptureResult.CONTROL_AE_STATE_INACTIVE:
                return AeState.INACTIVE;
            case CaptureResult.CONTROL_AE_STATE_SEARCHING:
            case CaptureResult.CONTROL_AE_STATE_PRECAPTURE:
                return AeState.SEARCHING;
            case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED:
                return AeState.FLASH_REQUIRED;
            case CaptureResult.CONTROL_AE_STATE_CONVERGED:
                return AeState.CONVERGED;
            case CaptureResult.CONTROL_AE_STATE_LOCKED:
                return AeState.LOCKED;
            default: // fall out
        }
        Logger.e(TAG, "Undefined ae state: " + state);
        return AeState.UNKNOWN;
    }

    /**
     * Converts the camera2 {@link CaptureResult#CONTROL_AWB_STATE} to {@link AwbState}.
     *
     * @return the {@link AwbState}.
     */
    @NonNull
    @Override
    public AwbState getAwbState() {
        Integer state = mCaptureResult.get(CaptureResult.CONTROL_AWB_STATE);
        if (state == null) {
            return AwbState.UNKNOWN;
        }
        switch (state) {
            case CaptureResult.CONTROL_AWB_STATE_INACTIVE:
                return AwbState.INACTIVE;
            case CaptureResult.CONTROL_AWB_STATE_SEARCHING:
                return AwbState.METERING;
            case CaptureResult.CONTROL_AWB_STATE_CONVERGED:
                return AwbState.CONVERGED;
            case CaptureResult.CONTROL_AWB_STATE_LOCKED:
                return AwbState.LOCKED;
            default: // fall out
        }
        Logger.e(TAG, "Undefined awb state: " + state);
        return AwbState.UNKNOWN;
    }

    /**
     * Converts the camera2 {@link CaptureResult#FLASH_STATE} to {@link FlashState}.
     *
     * @return the {@link FlashState}.
     */
    @NonNull
    @Override
    public FlashState getFlashState() {
        Integer state = mCaptureResult.get(CaptureResult.FLASH_STATE);
        if (state == null) {
            return FlashState.UNKNOWN;
        }
        switch (state) {
            case CaptureResult.FLASH_STATE_UNAVAILABLE:
            case CaptureResult.FLASH_STATE_CHARGING:
                return FlashState.NONE;
            case CaptureResult.FLASH_STATE_READY:
                return FlashState.READY;
            case CaptureResult.FLASH_STATE_FIRED:
            case CaptureResult.FLASH_STATE_PARTIAL:
                return FlashState.FIRED;
            default: // fall out
        }
        Logger.e(TAG, "Undefined flash state: " + state);
        return FlashState.UNKNOWN;
    }

    @NonNull
    @Override
    public CameraCaptureMetaData.AeMode getAeMode() {
        Integer aeMode = mCaptureResult.get(CaptureResult.CONTROL_AE_MODE);
        if (aeMode == null) {
            return AeMode.UNKNOWN;
        }
        switch (aeMode) {
            case CaptureResult.CONTROL_AE_MODE_OFF:
                return AeMode.OFF;
            case CaptureResult.CONTROL_AE_MODE_ON:
                return AeMode.ON;
            case CaptureResult.CONTROL_AE_MODE_ON_AUTO_FLASH:
                return AeMode.ON_AUTO_FLASH;
            case CaptureResult.CONTROL_AE_MODE_ON_ALWAYS_FLASH:
                return AeMode.ON_ALWAYS_FLASH;
            case CaptureResult.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
                return AeMode.ON_AUTO_FLASH_REDEYE;
            case CaptureResult.CONTROL_AE_MODE_ON_EXTERNAL_FLASH:
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                    return AeMode.ON_EXTERNAL_FLASH;
                } else {
                    return AeMode.UNKNOWN;
                }
            default:
                return AeMode.UNKNOWN;
        }
    }

    @NonNull
    @Override
    public CameraCaptureMetaData.AwbMode getAwbMode() {
        Integer awbMode = mCaptureResult.get(CaptureResult.CONTROL_AWB_MODE);
        if (awbMode == null) {
            return AwbMode.UNKNOWN;
        }
        switch (awbMode) {
            case CaptureResult.CONTROL_AWB_MODE_OFF:
                return AwbMode.OFF;
            case CaptureResult.CONTROL_AWB_MODE_AUTO:
                return AwbMode.AUTO;
            case CaptureResult.CONTROL_AWB_MODE_INCANDESCENT:
                return AwbMode.INCANDESCENT;
            case CaptureResult.CONTROL_AWB_MODE_FLUORESCENT:
                return AwbMode.FLUORESCENT;
            case CaptureResult.CONTROL_AWB_MODE_WARM_FLUORESCENT:
                return AwbMode.WARM_FLUORESCENT;
            case CaptureResult.CONTROL_AWB_MODE_DAYLIGHT:
                return AwbMode.DAYLIGHT;
            case CaptureResult.CONTROL_AWB_MODE_CLOUDY_DAYLIGHT:
                return AwbMode.CLOUDY_DAYLIGHT;
            case CaptureResult.CONTROL_AWB_MODE_TWILIGHT:
                return AwbMode.TWILIGHT;
            case CaptureResult.CONTROL_AWB_MODE_SHADE:
                return AwbMode.SHADE;
            default:
                return AwbMode.UNKNOWN;
        }
    }

    /** {@inheritDoc} */
    @Override
    public long getTimestamp() {
        Long timestamp = mCaptureResult.get(CaptureResult.SENSOR_TIMESTAMP);
        if (timestamp == null) {
            return -1L;
        }

        return timestamp;
    }

    @NonNull
    @Override
    public TagBundle getTagBundle() {
        return mTagBundle;
    }

    @Override
    public void populateExifData(@NonNull ExifData.Builder exifData) {
        // Call interface default to set flash mode
        CameraCaptureResult.super.populateExifData(exifData);

        // Set orientation
        try {
            Integer jpegOrientation = mCaptureResult.get(CaptureResult.JPEG_ORIENTATION);
            if (jpegOrientation != null) {
                exifData.setOrientationDegrees(jpegOrientation);
            }
        } catch (BufferUnderflowException exception) {
            // On certain devices, e.g. Pixel 3 XL API 31, getting JPEG orientation on YUV stream
            // throws BufferUnderflowException. The value will be overridden in post-processing
            // anyway, so it's safe to ignore.
            Logger.w(TAG, "Failed to get JPEG orientation.");
        }

        // Set exposure time
        Long exposureTimeNs = mCaptureResult.get(CaptureResult.SENSOR_EXPOSURE_TIME);
        if (exposureTimeNs != null) {
            exifData.setExposureTimeNanos(exposureTimeNs);
        }

        // Set the aperture
        Float aperture = mCaptureResult.get(CaptureResult.LENS_APERTURE);
        if (aperture != null) {
            exifData.setLensFNumber(aperture);
        }

        // Set the ISO
        Integer iso = mCaptureResult.get(CaptureResult.SENSOR_SENSITIVITY);
        if (iso != null) {
            if (Build.VERSION.SDK_INT >= 24) {
                Integer postRawSensitivityBoost =
                        mCaptureResult.get(CaptureResult.CONTROL_POST_RAW_SENSITIVITY_BOOST);
                if (postRawSensitivityBoost != null) {
                    iso *= (int) (postRawSensitivityBoost / 100f);
                }
            }
            exifData.setIso(iso);
        }

        // Set the focal length
        Float focalLength = mCaptureResult.get(CaptureResult.LENS_FOCAL_LENGTH);
        if (focalLength != null) {
            exifData.setFocalLength(focalLength);
        }

        // Set white balance MANUAL/AUTO
        Integer whiteBalanceMode = mCaptureResult.get(CaptureResult.CONTROL_AWB_MODE);
        if (whiteBalanceMode != null) {
            ExifData.WhiteBalanceMode wbMode = ExifData.WhiteBalanceMode.AUTO;
            if (whiteBalanceMode == CameraMetadata.CONTROL_AWB_MODE_OFF) {
                wbMode = ExifData.WhiteBalanceMode.MANUAL;
            }
            exifData.setWhiteBalanceMode(wbMode);
        }
    }

    @NonNull
    @Override
    public CaptureResult getCaptureResult() {
        return mCaptureResult;
    }
}