Merge "Camera: Add support for timestamp base"

This commit is contained in:
TreeHugger Robot
2022-02-08 23:03:41 +00:00
committed by Android (Google) Code Review
2 changed files with 153 additions and 4 deletions

View File

@@ -18168,14 +18168,21 @@ package android.hardware.camera2.params {
method @Nullable public android.view.Surface getSurface();
method public int getSurfaceGroupId();
method @NonNull public java.util.List<android.view.Surface> getSurfaces();
method public int getTimestampBase();
method public void removeSensorPixelModeUsed(int);
method public void removeSurface(@NonNull android.view.Surface);
method public void setDynamicRangeProfile(int);
method public void setPhysicalCameraId(@Nullable String);
method public void setStreamUseCase(int);
method public void setTimestampBase(int);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.hardware.camera2.params.OutputConfiguration> CREATOR;
field public static final int SURFACE_GROUP_ID_NONE = -1; // 0xffffffff
field public static final int TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED = 4; // 0x4
field public static final int TIMESTAMP_BASE_DEFAULT = 0; // 0x0
field public static final int TIMESTAMP_BASE_MONOTONIC = 2; // 0x2
field public static final int TIMESTAMP_BASE_REALTIME = 3; // 0x3
field public static final int TIMESTAMP_BASE_SENSOR = 1; // 0x1
}
public final class RecommendedStreamConfigurationMap {

View File

@@ -37,7 +37,6 @@ import android.hardware.camera2.utils.SurfaceUtils;
import android.media.ImageReader;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
@@ -152,6 +151,100 @@ public final class OutputConfiguration implements Parcelable {
*/
public static final int SURFACE_GROUP_ID_NONE = -1;
/**
* Default timestamp base.
*
* <p>The camera device decides the timestamp based on the properties of the
* output surface.</p>
*
* <li> For a SurfaceView output surface, the timestamp base is {@link
* #TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED}. The timestamp is overridden with choreographer
* pulses from the display subsystem for smoother display of camera frames. The timestamp
* is roughly in the same time base as {@link android.os.SystemClock#uptimeMillis}.</li>
* <li> For an output surface of MediaRecorder, MediaCodec, or ImageReader with {@link
* android.hardware.HardwareBuffer#USAGE_VIDEO_ENCODE} usge flag, the timestamp base is
* {@link #TIMESTAMP_BASE_MONOTONIC}, which is roughly the same time base as
* {@link android.os.SystemClock#uptimeMillis}.</li>
* <li> For all other cases, the timestamp base is {@link #TIMESTAMP_BASE_SENSOR}, the same
* as what's specified by {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE}.</li>
*
* @see #TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED
* @see #TIMESTAMP_BASE_MONOTONIC
* @see #TIMESTAMP_BASE_SENSOR
*/
public static final int TIMESTAMP_BASE_DEFAULT = 0;
/**
* Timestamp base of {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE}.
*
* <p>The timestamps of the output images are in the time base as specified by {@link
* CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE}. The application can look up the
* corresponding result metadata for a particular output image using this timestamp.</p>
*/
public static final int TIMESTAMP_BASE_SENSOR = 1;
/**
* Timestamp base roughly the same as {@link android.os.SystemClock#uptimeMillis}.
*
* <p>The timestamps of the output images are monotonically increasing, and are roughly in the
* same time base as {@link android.os.SystemClock#uptimeMillis}. The timestamps with this
* time base can be directly used for audio-video sync in video recording.</p>
*
* <p>If the camera device's {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is
* REALTIME, timestamps with this time base cannot directly match the timestamps in
* {@link CameraCaptureSession.CaptureCallback#onCaptureStarted} or the sensor timestamps in
* {@link android.hardware.camera2.CaptureResult}.</p>
*/
public static final int TIMESTAMP_BASE_MONOTONIC = 2;
/**
* Timestamp base roughly the same as {@link android.os.SystemClock#elapsedRealtime}.
*
* <p>The timestamps of the output images are roughly in the
* same time base as {@link android.os.SystemClock#elapsedRealtime}. The timestamps with this
* time base cannot be directly used for audio-video sync in video recording.</p>
*
* <p>If the camera device's {@link CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is
* UNKNOWN, timestamps with this time base cannot directly match the timestamps in
* {@link CameraCaptureSession.CaptureCallback#onCaptureStarted} or the sensor timestamps in
* {@link android.hardware.camera2.CaptureResult}.</p>
*
* <p>If using a REALTIME timestamp base on a device that supports only
* TIMESTAMP_SOURCE_UNKNOWN, the accuracy of timestamps is only what is guaranteed in the
* documentation for UNKNOWN. In particular, they have no guarantees about being accurate
* enough to use in fusing image data with the output of inertial sensors, for features such as
* image stabilization or augmented reality.</p>
*/
public static final int TIMESTAMP_BASE_REALTIME = 3;
/**
* Timestamp is synchronized to choreographer.
*
* <p>The timestamp of the output images are overridden with choreographer pulses from the
* display subsystem for smoother display of camera frames. An output target of SurfaceView
* uses this time base by default.</p>
*
* <p>The choreographer synchronized timestamps are also reasonable to use when drawing to a
* TextureView. So this timestamp base can be used for a SurfaceTexture as part of a
* TextureView, in addition to SurfaceView.</p>
*
* <p>Timestamps with this time base cannot directly match the timestamps in
* {@link CameraCaptureSession.CaptureCallback#onCaptureStarted} or the sensor timestamps in
* {@link android.hardware.camera2.CaptureResult}. This timestamp base shouldn't be used if the
* timestamp needs to be used for audio-video synchronization.</p>
*/
public static final int TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED = 4;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"TIMESTAMP_BASE_"}, value =
{TIMESTAMP_BASE_DEFAULT,
TIMESTAMP_BASE_SENSOR,
TIMESTAMP_BASE_MONOTONIC,
TIMESTAMP_BASE_REALTIME,
TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED})
public @interface TimestampBase {};
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"SENSOR_PIXEL_MODE_"}, value =
@@ -367,6 +460,7 @@ public final class OutputConfiguration implements Parcelable {
mSensorPixelModesUsed = new ArrayList<Integer>();
mDynamicRangeProfile = DynamicRangeProfiles.STANDARD;
mStreamUseCase = CameraMetadata.SCALER_AVAILABLE_STREAM_USE_CASES_DEFAULT;
mTimestampBase = TIMESTAMP_BASE_DEFAULT;
}
/**
@@ -809,6 +903,47 @@ public final class OutputConfiguration implements Parcelable {
return mStreamUseCase;
}
/**
* Set timestamp base for this output target
*
* <p>Timestamp base describes the time domain of images from this
* camera output and its relationship with {@link
* CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE}.</p>
*
* <p>If this function is not called, the timestamp base for this output
* is {@link #TIMESTAMP_BASE_DEFAULT}, with which the camera device adjusts
* timestamps based on the output target.</p>
*
* <p>See {@link #TIMESTAMP_BASE_DEFAULT}, {@link #TIMESTAMP_BASE_SENSOR},
* and {@link #TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED} for details of each timestamp base.</p>
*
* @param timestampBase The timestamp base to be set.
*
* @throws IllegalArgumentException If the timestamp base isn't within the range of valid
* values.
*/
public void setTimestampBase(@TimestampBase int timestampBase) {
// Verify that the value is in range
if (timestampBase < TIMESTAMP_BASE_DEFAULT ||
timestampBase > TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED) {
throw new IllegalArgumentException("Not a valid timestamp base value " +
timestampBase);
}
mTimestampBase = timestampBase;
}
/**
* Get the current timestamp base
*
* <p>If no {@link #setTimestampBase} is called first, this function returns
* {@link #TIMESTAMP_BASE_DEFAULT}.</p>
*
* @return The currently set timestamp base
*/
public @TimestampBase int getTimestampBase() {
return mTimestampBase;
}
/**
* Create a new {@link OutputConfiguration} instance with another {@link OutputConfiguration}
* instance.
@@ -837,6 +972,7 @@ public final class OutputConfiguration implements Parcelable {
this.mSensorPixelModesUsed = other.mSensorPixelModesUsed;
this.mDynamicRangeProfile = other.mDynamicRangeProfile;
this.mStreamUseCase = other.mStreamUseCase;
this.mTimestampBase = other.mTimestampBase;
}
/**
@@ -861,6 +997,7 @@ public final class OutputConfiguration implements Parcelable {
int dynamicRangeProfile = source.readInt();
DynamicRangeProfiles.checkProfileValue(dynamicRangeProfile);
int timestampBase = source.readInt();
mSurfaceGroupId = surfaceSetId;
mRotation = rotation;
mSurfaces = surfaces;
@@ -885,6 +1022,7 @@ public final class OutputConfiguration implements Parcelable {
mSensorPixelModesUsed = convertIntArrayToIntegerList(sensorPixelModesUsed);
mDynamicRangeProfile = dynamicRangeProfile;
mStreamUseCase = streamUseCase;
mTimestampBase = timestampBase;
}
/**
@@ -1002,6 +1140,7 @@ public final class OutputConfiguration implements Parcelable {
dest.writeIntArray(convertIntegerToIntList(mSensorPixelModesUsed));
dest.writeInt(mDynamicRangeProfile);
dest.writeInt(mStreamUseCase);
dest.writeInt(mTimestampBase);
}
/**
@@ -1033,7 +1172,8 @@ public final class OutputConfiguration implements Parcelable {
mConfiguredGenerationId != other.mConfiguredGenerationId ||
!Objects.equals(mPhysicalCameraId, other.mPhysicalCameraId) ||
mIsMultiResolution != other.mIsMultiResolution ||
mStreamUseCase != other.mStreamUseCase)
mStreamUseCase != other.mStreamUseCase ||
mTimestampBase != other.mTimestampBase)
return false;
if (mSensorPixelModesUsed.size() != other.mSensorPixelModesUsed.size()) {
return false;
@@ -1071,7 +1211,7 @@ public final class OutputConfiguration implements Parcelable {
mSurfaceGroupId, mSurfaceType, mIsShared ? 1 : 0,
mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(),
mDynamicRangeProfile, mStreamUseCase);
mDynamicRangeProfile, mStreamUseCase, mTimestampBase);
}
return HashCodeHelpers.hashCode(
@@ -1080,7 +1220,7 @@ public final class OutputConfiguration implements Parcelable {
mConfiguredDataspace, mSurfaceGroupId, mIsShared ? 1 : 0,
mPhysicalCameraId == null ? 0 : mPhysicalCameraId.hashCode(),
mIsMultiResolution ? 1 : 0, mSensorPixelModesUsed.hashCode(),
mDynamicRangeProfile, mStreamUseCase);
mDynamicRangeProfile, mStreamUseCase, mTimestampBase);
}
private static final String TAG = "OutputConfiguration";
@@ -1116,4 +1256,6 @@ public final class OutputConfiguration implements Parcelable {
private int mDynamicRangeProfile;
// Stream use case
private int mStreamUseCase;
// Timestamp base
private int mTimestampBase;
}