572 lines
20 KiB
Java
572 lines
20 KiB
Java
/*
|
|
* Copyright (C) 2024 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 android.media.metrics;
|
|
|
|
import static com.android.media.editing.flags.Flags.FLAG_ADD_MEDIA_METRICS_EDITING;
|
|
|
|
import android.annotation.FlaggedApi;
|
|
import android.annotation.FloatRange;
|
|
import android.annotation.IntDef;
|
|
import android.annotation.IntRange;
|
|
import android.annotation.LongDef;
|
|
import android.annotation.NonNull;
|
|
import android.annotation.Nullable;
|
|
import android.annotation.SuppressLint;
|
|
import android.hardware.DataSpace;
|
|
import android.media.MediaCodec;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
import android.util.Size;
|
|
|
|
import java.lang.annotation.Retention;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
|
|
/** Represents information about a piece of media (for example, an audio or video file). */
|
|
@FlaggedApi(FLAG_ADD_MEDIA_METRICS_EDITING)
|
|
public final class MediaItemInfo implements Parcelable {
|
|
|
|
/** @hide */
|
|
@IntDef(
|
|
prefix = {"SOURCE_TYPE_"},
|
|
value = {
|
|
SOURCE_TYPE_UNSPECIFIED,
|
|
SOURCE_TYPE_GALLERY,
|
|
SOURCE_TYPE_CAMERA,
|
|
SOURCE_TYPE_EDITING_SESSION,
|
|
SOURCE_TYPE_LOCAL_FILE,
|
|
SOURCE_TYPE_REMOTE_FILE,
|
|
SOURCE_TYPE_REMOTE_LIVE_STREAM,
|
|
SOURCE_TYPE_GENERATED,
|
|
})
|
|
@Retention(java.lang.annotation.RetentionPolicy.SOURCE)
|
|
public @interface SourceType {}
|
|
|
|
/** The media item's source is not known. */
|
|
public static final int SOURCE_TYPE_UNSPECIFIED = 0;
|
|
|
|
/** The media item came from the device gallery. */
|
|
public static final int SOURCE_TYPE_GALLERY = 1;
|
|
|
|
/** The media item came directly from camera capture. */
|
|
public static final int SOURCE_TYPE_CAMERA = 2;
|
|
|
|
/** The media item was output by a previous editing session. */
|
|
public static final int SOURCE_TYPE_EDITING_SESSION = 3;
|
|
|
|
/** The media item is stored on the local device's file system. */
|
|
public static final int SOURCE_TYPE_LOCAL_FILE = 4;
|
|
|
|
/** The media item is a remote file (for example, it's loaded from an HTTP server). */
|
|
public static final int SOURCE_TYPE_REMOTE_FILE = 5;
|
|
|
|
/** The media item is a remotely-served live stream. */
|
|
public static final int SOURCE_TYPE_REMOTE_LIVE_STREAM = 6;
|
|
|
|
/** The media item was generated by another system. */
|
|
public static final int SOURCE_TYPE_GENERATED = 7;
|
|
|
|
/** @hide */
|
|
@LongDef(
|
|
prefix = {"DATA_TYPE_"},
|
|
flag = true,
|
|
value = {
|
|
DATA_TYPE_IMAGE,
|
|
DATA_TYPE_VIDEO,
|
|
DATA_TYPE_AUDIO,
|
|
DATA_TYPE_METADATA,
|
|
DATA_TYPE_DEPTH,
|
|
DATA_TYPE_GAIN_MAP,
|
|
DATA_TYPE_HIGH_FRAME_RATE,
|
|
DATA_TYPE_SPEED_SETTING_CUE_POINTS,
|
|
DATA_TYPE_GAPLESS,
|
|
DATA_TYPE_SPATIAL_AUDIO,
|
|
DATA_TYPE_HIGH_DYNAMIC_RANGE_VIDEO,
|
|
})
|
|
@Retention(java.lang.annotation.RetentionPolicy.SOURCE)
|
|
public @interface DataType {}
|
|
|
|
/** The media item includes image data. */
|
|
public static final long DATA_TYPE_IMAGE = 1L;
|
|
|
|
/** The media item includes video data. */
|
|
public static final long DATA_TYPE_VIDEO = 1L << 1;
|
|
|
|
/** The media item includes audio data. */
|
|
public static final long DATA_TYPE_AUDIO = 1L << 2;
|
|
|
|
/**
|
|
* The media item includes static media container metadata (for example, capture frame rate or
|
|
* location information).
|
|
*/
|
|
public static final long DATA_TYPE_METADATA = 1L << 3;
|
|
|
|
/** The media item includes depth (z-distance) information. */
|
|
public static final long DATA_TYPE_DEPTH = 1L << 4;
|
|
|
|
/** The media item includes gain map information (for example, an Ultra HDR gain map). */
|
|
public static final long DATA_TYPE_GAIN_MAP = 1L << 5;
|
|
|
|
/** The media item includes high frame rate video data. */
|
|
public static final long DATA_TYPE_HIGH_FRAME_RATE = 1L << 6;
|
|
|
|
/**
|
|
* The media item includes time-dependent speed information (for example, slow motion cue
|
|
* points).
|
|
*/
|
|
public static final long DATA_TYPE_SPEED_SETTING_CUE_POINTS = 1L << 7;
|
|
|
|
/** The media item includes gapless audio metadata. */
|
|
public static final long DATA_TYPE_GAPLESS = 1L << 8;
|
|
|
|
/** The media item includes spatial audio data. */
|
|
public static final long DATA_TYPE_SPATIAL_AUDIO = 1L << 9;
|
|
|
|
/** The media item includes high dynamic range (HDR) video. */
|
|
public static final long DATA_TYPE_HIGH_DYNAMIC_RANGE_VIDEO = 1L << 10;
|
|
|
|
/** Special value for numerical fields where the value was not specified. */
|
|
public static final int VALUE_UNSPECIFIED = -1;
|
|
|
|
private final @SourceType int mSourceType;
|
|
private final @DataType long mDataTypes;
|
|
private final long mDurationMillis;
|
|
private final long mClipDurationMillis;
|
|
@Nullable private final String mContainerMimeType;
|
|
private final List<String> mSampleMimeTypes;
|
|
private final List<String> mCodecNames;
|
|
private final int mAudioSampleRateHz;
|
|
private final int mAudioChannelCount;
|
|
private final long mAudioSampleCount;
|
|
private final Size mVideoSize;
|
|
private final int mVideoDataSpace;
|
|
private final float mVideoFrameRate;
|
|
private final long mVideoSampleCount;
|
|
|
|
private MediaItemInfo(
|
|
@SourceType int sourceType,
|
|
@DataType long dataTypes,
|
|
long durationMillis,
|
|
long clipDurationMillis,
|
|
@Nullable String containerMimeType,
|
|
List<String> sampleMimeTypes,
|
|
List<String> codecNames,
|
|
int audioSampleRateHz,
|
|
int audioChannelCount,
|
|
long audioSampleCount,
|
|
Size videoSize,
|
|
int videoDataSpace,
|
|
float videoFrameRate,
|
|
long videoSampleCount) {
|
|
mSourceType = sourceType;
|
|
mDataTypes = dataTypes;
|
|
mDurationMillis = durationMillis;
|
|
mClipDurationMillis = clipDurationMillis;
|
|
mContainerMimeType = containerMimeType;
|
|
mSampleMimeTypes = sampleMimeTypes;
|
|
mCodecNames = codecNames;
|
|
mAudioSampleRateHz = audioSampleRateHz;
|
|
mAudioChannelCount = audioChannelCount;
|
|
mAudioSampleCount = audioSampleCount;
|
|
mVideoSize = videoSize;
|
|
mVideoDataSpace = videoDataSpace;
|
|
mVideoFrameRate = videoFrameRate;
|
|
mVideoSampleCount = videoSampleCount;
|
|
}
|
|
|
|
/**
|
|
* Returns where the media item came from, or {@link #SOURCE_TYPE_UNSPECIFIED} if not specified.
|
|
*/
|
|
public @SourceType int getSourceType() {
|
|
return mSourceType;
|
|
}
|
|
|
|
/** Returns the data types that are present in the media item. */
|
|
public @DataType long getDataTypes() {
|
|
return mDataTypes;
|
|
}
|
|
|
|
/**
|
|
* Returns the duration of the media item, in milliseconds, or {@link #VALUE_UNSPECIFIED} if not
|
|
* specified.
|
|
*/
|
|
public long getDurationMillis() {
|
|
return mDurationMillis;
|
|
}
|
|
|
|
/**
|
|
* Returns the duration of the clip taken from the media item, in milliseconds, or {@link
|
|
* #VALUE_UNSPECIFIED} if not specified.
|
|
*/
|
|
public long getClipDurationMillis() {
|
|
return mClipDurationMillis;
|
|
}
|
|
|
|
/** Returns the MIME type of the media container, or {@code null} if unspecified. */
|
|
@Nullable
|
|
public String getContainerMimeType() {
|
|
return mContainerMimeType;
|
|
}
|
|
|
|
/**
|
|
* Returns the MIME types of samples stored in the media container, or an empty list if not
|
|
* known.
|
|
*/
|
|
@NonNull
|
|
public List<String> getSampleMimeTypes() {
|
|
return new ArrayList<>(mSampleMimeTypes);
|
|
}
|
|
|
|
/**
|
|
* Returns the {@linkplain MediaCodec#getName() media codec names} for codecs that were used as
|
|
* part of encoding/decoding this media item, or an empty list if not known or not applicable.
|
|
*/
|
|
@NonNull
|
|
public List<String> getCodecNames() {
|
|
return new ArrayList<>(mCodecNames);
|
|
}
|
|
|
|
/**
|
|
* Returns the sample rate of audio, in Hertz, or {@link #VALUE_UNSPECIFIED} if not specified.
|
|
*/
|
|
public int getAudioSampleRateHz() {
|
|
return mAudioSampleRateHz;
|
|
}
|
|
|
|
/** Returns the number of audio channels, or {@link #VALUE_UNSPECIFIED} if not specified. */
|
|
public int getAudioChannelCount() {
|
|
return mAudioChannelCount;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of audio frames in the item, after clipping (if applicable), or {@link
|
|
* #VALUE_UNSPECIFIED} if not specified.
|
|
*/
|
|
public long getAudioSampleCount() {
|
|
return mAudioSampleCount;
|
|
}
|
|
|
|
/**
|
|
* Returns the video size, in pixels, or a {@link Size} with width and height set to {@link
|
|
* #VALUE_UNSPECIFIED} if not specified.
|
|
*/
|
|
@NonNull
|
|
public Size getVideoSize() {
|
|
return mVideoSize;
|
|
}
|
|
|
|
/** Returns the {@linkplain DataSpace data space} for video, as a packed integer. */
|
|
@SuppressLint("MethodNameUnits") // Packed integer for an android.hardware.DataSpace.
|
|
public int getVideoDataSpace() {
|
|
return mVideoDataSpace;
|
|
}
|
|
|
|
/**
|
|
* Returns the average video frame rate, in frames per second, or {@link #VALUE_UNSPECIFIED} if
|
|
* not specified.
|
|
*/
|
|
public float getVideoFrameRate() {
|
|
return mVideoFrameRate;
|
|
}
|
|
|
|
/**
|
|
* Returns the number of video frames, aftrer clipping (if applicable), or {@link
|
|
* #VALUE_UNSPECIFIED} if not specified.
|
|
*/
|
|
public long getVideoSampleCount() {
|
|
return mVideoSampleCount;
|
|
}
|
|
|
|
/** Builder for {@link MediaItemInfo}. */
|
|
@FlaggedApi(FLAG_ADD_MEDIA_METRICS_EDITING)
|
|
public static final class Builder {
|
|
|
|
private @SourceType int mSourceType;
|
|
private @DataType long mDataTypes;
|
|
private long mDurationMillis;
|
|
private long mClipDurationMillis;
|
|
@Nullable private String mContainerMimeType;
|
|
private final ArrayList<String> mSampleMimeTypes;
|
|
private final ArrayList<String> mCodecNames;
|
|
private int mAudioSampleRateHz;
|
|
private int mAudioChannelCount;
|
|
private long mAudioSampleCount;
|
|
@Nullable private Size mVideoSize;
|
|
private int mVideoDataSpace;
|
|
private float mVideoFrameRate;
|
|
private long mVideoSampleCount;
|
|
|
|
/** Creates a new builder. */
|
|
public Builder() {
|
|
mSourceType = SOURCE_TYPE_UNSPECIFIED;
|
|
mDurationMillis = VALUE_UNSPECIFIED;
|
|
mClipDurationMillis = VALUE_UNSPECIFIED;
|
|
mSampleMimeTypes = new ArrayList<>();
|
|
mCodecNames = new ArrayList<>();
|
|
mAudioSampleRateHz = VALUE_UNSPECIFIED;
|
|
mAudioChannelCount = VALUE_UNSPECIFIED;
|
|
mAudioSampleCount = VALUE_UNSPECIFIED;
|
|
mVideoSize = new Size(VALUE_UNSPECIFIED, VALUE_UNSPECIFIED);
|
|
mVideoFrameRate = VALUE_UNSPECIFIED;
|
|
mVideoSampleCount = VALUE_UNSPECIFIED;
|
|
}
|
|
|
|
/** Sets where the media item came from. */
|
|
public @NonNull Builder setSourceType(@SourceType int sourceType) {
|
|
mSourceType = sourceType;
|
|
return this;
|
|
}
|
|
|
|
/** Adds an additional data type represented as part of the media item. */
|
|
public @NonNull Builder addDataType(@DataType long dataType) {
|
|
mDataTypes |= dataType;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the duration of the media item, in milliseconds. */
|
|
public @NonNull Builder setDurationMillis(long durationMillis) {
|
|
mDurationMillis = durationMillis;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the duration of the clip taken from the media item, in milliseconds. */
|
|
public @NonNull Builder setClipDurationMillis(long clipDurationMillis) {
|
|
mClipDurationMillis = clipDurationMillis;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the MIME type of the media container. */
|
|
public @NonNull Builder setContainerMimeType(@NonNull String containerMimeType) {
|
|
mContainerMimeType = Objects.requireNonNull(containerMimeType);
|
|
return this;
|
|
}
|
|
|
|
/** Adds a sample MIME type stored in the media container. */
|
|
public @NonNull Builder addSampleMimeType(@NonNull String mimeType) {
|
|
mSampleMimeTypes.add(Objects.requireNonNull(mimeType));
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Adds an {@linkplain MediaCodec#getName() media codec name} that was used as part of
|
|
* decoding/encoding this media item.
|
|
*/
|
|
public @NonNull Builder addCodecName(@NonNull String codecName) {
|
|
mCodecNames.add(Objects.requireNonNull(codecName));
|
|
return this;
|
|
}
|
|
|
|
/** Sets the sample rate of audio, in Hertz. */
|
|
public @NonNull Builder setAudioSampleRateHz(@IntRange(from = 0) int audioSampleRateHz) {
|
|
mAudioSampleRateHz = audioSampleRateHz;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the number of audio channels. */
|
|
public @NonNull Builder setAudioChannelCount(@IntRange(from = 0) int audioChannelCount) {
|
|
mAudioChannelCount = audioChannelCount;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the number of audio frames in the item, after clipping (if applicable). */
|
|
public @NonNull Builder setAudioSampleCount(@IntRange(from = 0) long audioSampleCount) {
|
|
mAudioSampleCount = audioSampleCount;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the video size, in pixels. */
|
|
public @NonNull Builder setVideoSize(@NonNull Size videoSize) {
|
|
mVideoSize = Objects.requireNonNull(videoSize);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Sets the {@link DataSpace} of video frames.
|
|
*
|
|
* @param videoDataSpace The data space, returned by {@link DataSpace#pack(int, int, int)}.
|
|
*/
|
|
public @NonNull Builder setVideoDataSpace(int videoDataSpace) {
|
|
mVideoDataSpace = videoDataSpace;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the average video frame rate, in frames per second. */
|
|
public @NonNull Builder setVideoFrameRate(@FloatRange(from = 0) float videoFrameRate) {
|
|
mVideoFrameRate = videoFrameRate;
|
|
return this;
|
|
}
|
|
|
|
/** Sets the number of video frames, after clipping (if applicable). */
|
|
public @NonNull Builder setVideoSampleCount(@IntRange(from = 0) long videoSampleCount) {
|
|
mVideoSampleCount = videoSampleCount;
|
|
return this;
|
|
}
|
|
|
|
/** Builds an instance. */
|
|
@NonNull
|
|
public MediaItemInfo build() {
|
|
return new MediaItemInfo(
|
|
mSourceType,
|
|
mDataTypes,
|
|
mDurationMillis,
|
|
mClipDurationMillis,
|
|
mContainerMimeType,
|
|
mSampleMimeTypes,
|
|
mCodecNames,
|
|
mAudioSampleRateHz,
|
|
mAudioChannelCount,
|
|
mAudioSampleCount,
|
|
mVideoSize,
|
|
mVideoDataSpace,
|
|
mVideoFrameRate,
|
|
mVideoSampleCount);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@NonNull
|
|
public String toString() {
|
|
return "MediaItemInfo { "
|
|
+ "sourceType = "
|
|
+ mSourceType
|
|
+ ", "
|
|
+ "dataTypes = "
|
|
+ mDataTypes
|
|
+ ", "
|
|
+ "durationMillis = "
|
|
+ mDurationMillis
|
|
+ ", "
|
|
+ "clipDurationMillis = "
|
|
+ mClipDurationMillis
|
|
+ ", "
|
|
+ "containerMimeType = "
|
|
+ mContainerMimeType
|
|
+ ", "
|
|
+ "sampleMimeTypes = "
|
|
+ mSampleMimeTypes
|
|
+ ", "
|
|
+ "codecNames = "
|
|
+ mCodecNames
|
|
+ ", "
|
|
+ "audioSampleRateHz = "
|
|
+ mAudioSampleRateHz
|
|
+ ", "
|
|
+ "audioChannelCount = "
|
|
+ mAudioChannelCount
|
|
+ ", "
|
|
+ "audioSampleCount = "
|
|
+ mAudioSampleCount
|
|
+ ", "
|
|
+ "videoSize = "
|
|
+ mVideoSize
|
|
+ ", "
|
|
+ "videoDataSpace = "
|
|
+ mVideoDataSpace
|
|
+ ", "
|
|
+ "videoFrameRate = "
|
|
+ mVideoFrameRate
|
|
+ ", "
|
|
+ "videoSampleCount = "
|
|
+ mVideoSampleCount
|
|
+ " }";
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(@Nullable Object o) {
|
|
if (this == o) return true;
|
|
if (o == null || getClass() != o.getClass()) return false;
|
|
MediaItemInfo that = (MediaItemInfo) o;
|
|
return mSourceType == that.mSourceType
|
|
&& mDataTypes == that.mDataTypes
|
|
&& mDurationMillis == that.mDurationMillis
|
|
&& mClipDurationMillis == that.mClipDurationMillis
|
|
&& Objects.equals(mContainerMimeType, that.mContainerMimeType)
|
|
&& mSampleMimeTypes.equals(that.mSampleMimeTypes)
|
|
&& mCodecNames.equals(that.mCodecNames)
|
|
&& mAudioSampleRateHz == that.mAudioSampleRateHz
|
|
&& mAudioChannelCount == that.mAudioChannelCount
|
|
&& mAudioSampleCount == that.mAudioSampleCount
|
|
&& Objects.equals(mVideoSize, that.mVideoSize)
|
|
&& Objects.equals(mVideoDataSpace, that.mVideoDataSpace)
|
|
&& mVideoFrameRate == that.mVideoFrameRate
|
|
&& mVideoSampleCount == that.mVideoSampleCount;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return Objects.hash(mSourceType, mDataTypes);
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
|
dest.writeInt(mSourceType);
|
|
dest.writeLong(mDataTypes);
|
|
dest.writeLong(mDurationMillis);
|
|
dest.writeLong(mClipDurationMillis);
|
|
dest.writeString(mContainerMimeType);
|
|
dest.writeStringList(mSampleMimeTypes);
|
|
dest.writeStringList(mCodecNames);
|
|
dest.writeInt(mAudioSampleRateHz);
|
|
dest.writeInt(mAudioChannelCount);
|
|
dest.writeLong(mAudioSampleCount);
|
|
dest.writeInt(mVideoSize.getWidth());
|
|
dest.writeInt(mVideoSize.getHeight());
|
|
dest.writeInt(mVideoDataSpace);
|
|
dest.writeFloat(mVideoFrameRate);
|
|
dest.writeLong(mVideoSampleCount);
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
return 0;
|
|
}
|
|
|
|
private MediaItemInfo(@NonNull Parcel in) {
|
|
mSourceType = in.readInt();
|
|
mDataTypes = in.readLong();
|
|
mDurationMillis = in.readLong();
|
|
mClipDurationMillis = in.readLong();
|
|
mContainerMimeType = in.readString();
|
|
mSampleMimeTypes = new ArrayList<>();
|
|
in.readStringList(mSampleMimeTypes);
|
|
mCodecNames = new ArrayList<>();
|
|
in.readStringList(mCodecNames);
|
|
mAudioSampleRateHz = in.readInt();
|
|
mAudioChannelCount = in.readInt();
|
|
mAudioSampleCount = in.readLong();
|
|
int videoSizeWidth = in.readInt();
|
|
int videoSizeHeight = in.readInt();
|
|
mVideoSize = new Size(videoSizeWidth, videoSizeHeight);
|
|
mVideoDataSpace = in.readInt();
|
|
mVideoFrameRate = in.readFloat();
|
|
mVideoSampleCount = in.readLong();
|
|
}
|
|
|
|
public static final @NonNull Creator<MediaItemInfo> CREATOR =
|
|
new Creator<>() {
|
|
@Override
|
|
public MediaItemInfo[] newArray(int size) {
|
|
return new MediaItemInfo[size];
|
|
}
|
|
|
|
@Override
|
|
public MediaItemInfo createFromParcel(@NonNull Parcel in) {
|
|
return new MediaItemInfo(in);
|
|
}
|
|
};
|
|
}
|