blob: 8142979977f10eeacccf3bab4d52ee7a81462871 [file] [log] [blame]
/*
* Copyright (C) 2014 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.tv;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Encapsulates the format of tracks played in {@link TvInputService}.
*/
public final class TvTrackInfo implements Parcelable {
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef({TYPE_AUDIO, TYPE_VIDEO, TYPE_SUBTITLE})
public @interface Type {}
/**
* The type value for audio tracks.
*/
public static final int TYPE_AUDIO = 0;
/**
* The type value for video tracks.
*/
public static final int TYPE_VIDEO = 1;
/**
* The type value for subtitle tracks.
*/
public static final int TYPE_SUBTITLE = 2;
private final int mType;
private final String mId;
private final String mLanguage;
private final CharSequence mDescription;
private final int mAudioChannelCount;
private final int mAudioSampleRate;
private final int mVideoWidth;
private final int mVideoHeight;
private final float mVideoFrameRate;
private final float mVideoPixelAspectRatio;
private final byte mVideoActiveFormatDescription;
private final Bundle mExtra;
private TvTrackInfo(int type, String id, String language, CharSequence description,
int audioChannelCount, int audioSampleRate, int videoWidth, int videoHeight,
float videoFrameRate, float videoPixelAspectRatio, byte videoActiveFormatDescription,
Bundle extra) {
mType = type;
mId = id;
mLanguage = language;
mDescription = description;
mAudioChannelCount = audioChannelCount;
mAudioSampleRate = audioSampleRate;
mVideoWidth = videoWidth;
mVideoHeight = videoHeight;
mVideoFrameRate = videoFrameRate;
mVideoPixelAspectRatio = videoPixelAspectRatio;
mVideoActiveFormatDescription = videoActiveFormatDescription;
mExtra = extra;
}
private TvTrackInfo(Parcel in) {
mType = in.readInt();
mId = in.readString();
mLanguage = in.readString();
mDescription = in.readString();
mAudioChannelCount = in.readInt();
mAudioSampleRate = in.readInt();
mVideoWidth = in.readInt();
mVideoHeight = in.readInt();
mVideoFrameRate = in.readFloat();
mVideoPixelAspectRatio = in.readFloat();
mVideoActiveFormatDescription = in.readByte();
mExtra = in.readBundle();
}
/**
* Returns the type of the track. The type should be one of the followings:
* {@link #TYPE_AUDIO}, {@link #TYPE_VIDEO} and {@link #TYPE_SUBTITLE}.
*/
@Type
public final int getType() {
return mType;
}
/**
* Returns the ID of the track.
*/
public final String getId() {
return mId;
}
/**
* Returns the language information encoded by either ISO 639-1 or ISO 639-2/T. If the language
* is unknown or could not be determined, the corresponding value will be {@code null}.
*/
public final String getLanguage() {
return mLanguage;
}
/**
* Returns a user readable description for the current track.
*/
public final CharSequence getDescription() {
return mDescription;
}
/**
* Returns the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
*
* @throws IllegalStateException if not called on an audio track
*/
public final int getAudioChannelCount() {
if (mType != TYPE_AUDIO) {
throw new IllegalStateException("Not an audio track");
}
return mAudioChannelCount;
}
/**
* Returns the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO} tracks.
*
* @throws IllegalStateException if not called on an audio track
*/
public final int getAudioSampleRate() {
if (mType != TYPE_AUDIO) {
throw new IllegalStateException("Not an audio track");
}
return mAudioSampleRate;
}
/**
* Returns the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
* tracks.
*
* @throws IllegalStateException if not called on a video track
*/
public final int getVideoWidth() {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
return mVideoWidth;
}
/**
* Returns the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
* tracks.
*
* @throws IllegalStateException if not called on a video track
*/
public final int getVideoHeight() {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
return mVideoHeight;
}
/**
* Returns the frame rate of the video, in the unit of fps (frames per second). Valid only for
* {@link #TYPE_VIDEO} tracks.
*
* @throws IllegalStateException if not called on a video track
*/
public final float getVideoFrameRate() {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
return mVideoFrameRate;
}
/**
* Returns the pixel aspect ratio (the ratio of a pixel's width to its height) of the video.
* Valid only for {@link #TYPE_VIDEO} tracks.
*
* @throws IllegalStateException if not called on a video track
*/
public final float getVideoPixelAspectRatio() {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
return mVideoPixelAspectRatio;
}
/**
* Returns the Active Format Description (AFD) code of the video.
* Valid only for {@link #TYPE_VIDEO} tracks.
*
* <p>The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
* 4 and SMPTE 2016-1-2007.
*
* @throws IllegalStateException if not called on a video track
*/
public final byte getVideoActiveFormatDescription() {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
return mVideoActiveFormatDescription;
}
/**
* Returns the extra information about the current track.
*/
public final Bundle getExtra() {
return mExtra;
}
@Override
public int describeContents() {
return 0;
}
/**
* Used to package this object into a {@link Parcel}.
*
* @param dest The {@link Parcel} to be written.
* @param flags The flags used for parceling.
*/
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeString(mId);
dest.writeString(mLanguage);
dest.writeString(mDescription != null ? mDescription.toString() : null);
dest.writeInt(mAudioChannelCount);
dest.writeInt(mAudioSampleRate);
dest.writeInt(mVideoWidth);
dest.writeInt(mVideoHeight);
dest.writeFloat(mVideoFrameRate);
dest.writeFloat(mVideoPixelAspectRatio);
dest.writeByte(mVideoActiveFormatDescription);
dest.writeBundle(mExtra);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof TvTrackInfo)) {
return false;
}
TvTrackInfo obj = (TvTrackInfo) o;
return TextUtils.equals(mId, obj.mId)
&& mType == obj.mType
&& TextUtils.equals(mLanguage, obj.mLanguage)
&& TextUtils.equals(mDescription, obj.mDescription)
&& Objects.equals(mExtra, obj.mExtra)
&& (mType == TYPE_AUDIO
? mAudioChannelCount == obj.mAudioChannelCount
&& mAudioSampleRate == obj.mAudioSampleRate
: (mType == TYPE_VIDEO
? mVideoWidth == obj.mVideoWidth
&& mVideoHeight == obj.mVideoHeight
&& mVideoFrameRate == obj.mVideoFrameRate
&& mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio : true));
}
@Override
public int hashCode() {
return Objects.hashCode(mId);
}
public static final @android.annotation.NonNull Parcelable.Creator<TvTrackInfo> CREATOR =
new Parcelable.Creator<TvTrackInfo>() {
@Override
public TvTrackInfo createFromParcel(Parcel in) {
return new TvTrackInfo(in);
}
@Override
public TvTrackInfo[] newArray(int size) {
return new TvTrackInfo[size];
}
};
/**
* A builder class for creating {@link TvTrackInfo} objects.
*/
public static final class Builder {
private final String mId;
private final int mType;
private String mLanguage;
private CharSequence mDescription;
private int mAudioChannelCount;
private int mAudioSampleRate;
private int mVideoWidth;
private int mVideoHeight;
private float mVideoFrameRate;
private float mVideoPixelAspectRatio = 1.0f;
private byte mVideoActiveFormatDescription;
private Bundle mExtra;
/**
* Create a {@link Builder}. Any field that should be included in the {@link TvTrackInfo}
* must be added.
*
* @param type The type of the track.
* @param id The ID of the track that uniquely identifies the current track among all the
* other tracks in the same TV program.
* @throws IllegalArgumentException if the type is not any of {@link #TYPE_AUDIO},
* {@link #TYPE_VIDEO} and {@link #TYPE_SUBTITLE}
*/
public Builder(@Type int type, @NonNull String id) {
if (type != TYPE_AUDIO
&& type != TYPE_VIDEO
&& type != TYPE_SUBTITLE) {
throw new IllegalArgumentException("Unknown type: " + type);
}
Preconditions.checkNotNull(id);
mType = type;
mId = id;
}
/**
* Sets the language information of the current track.
*
* @param language The language string encoded by either ISO 639-1 or ISO 639-2/T.
*/
public final Builder setLanguage(String language) {
mLanguage = language;
return this;
}
/**
* Sets a user readable description for the current track.
*
* @param description The user readable description.
*/
public final Builder setDescription(CharSequence description) {
mDescription = description;
return this;
}
/**
* Sets the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
*
* @param audioChannelCount The audio channel count.
* @throws IllegalStateException if not called on an audio track
*/
public final Builder setAudioChannelCount(int audioChannelCount) {
if (mType != TYPE_AUDIO) {
throw new IllegalStateException("Not an audio track");
}
mAudioChannelCount = audioChannelCount;
return this;
}
/**
* Sets the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO}
* tracks.
*
* @param audioSampleRate The audio sample rate.
* @throws IllegalStateException if not called on an audio track
*/
public final Builder setAudioSampleRate(int audioSampleRate) {
if (mType != TYPE_AUDIO) {
throw new IllegalStateException("Not an audio track");
}
mAudioSampleRate = audioSampleRate;
return this;
}
/**
* Sets the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
* tracks.
*
* @param videoWidth The width of the video.
* @throws IllegalStateException if not called on a video track
*/
public final Builder setVideoWidth(int videoWidth) {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
mVideoWidth = videoWidth;
return this;
}
/**
* Sets the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
* tracks.
*
* @param videoHeight The height of the video.
* @throws IllegalStateException if not called on a video track
*/
public final Builder setVideoHeight(int videoHeight) {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
mVideoHeight = videoHeight;
return this;
}
/**
* Sets the frame rate of the video, in the unit fps (frames per rate). Valid only for
* {@link #TYPE_VIDEO} tracks.
*
* @param videoFrameRate The frame rate of the video.
* @throws IllegalStateException if not called on a video track
*/
public final Builder setVideoFrameRate(float videoFrameRate) {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
mVideoFrameRate = videoFrameRate;
return this;
}
/**
* Sets the pixel aspect ratio (the ratio of a pixel's width to its height) of the video.
* Valid only for {@link #TYPE_VIDEO} tracks.
*
* <p>This is needed for applications to be able to scale the video properly for some video
* formats such as 720x576 4:3 and 720x576 16:9 where pixels are not square. By default,
* applications assume the value of 1.0 (square pixels), so it is not necessary to set the
* pixel aspect ratio for most video formats.
*
* @param videoPixelAspectRatio The pixel aspect ratio of the video.
* @throws IllegalStateException if not called on a video track
*/
public final Builder setVideoPixelAspectRatio(float videoPixelAspectRatio) {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
mVideoPixelAspectRatio = videoPixelAspectRatio;
return this;
}
/**
* Sets the Active Format Description (AFD) code of the video.
* Valid only for {@link #TYPE_VIDEO} tracks.
*
* <p>This is needed for applications to be able to scale the video properly based on the
* information about where in the coded picture the active video is.
* The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
* 4 and SMPTE 2016-1-2007.
*
* @param videoActiveFormatDescription The AFD code of the video.
* @throws IllegalStateException if not called on a video track
*/
public final Builder setVideoActiveFormatDescription(byte videoActiveFormatDescription) {
if (mType != TYPE_VIDEO) {
throw new IllegalStateException("Not a video track");
}
mVideoActiveFormatDescription = videoActiveFormatDescription;
return this;
}
/**
* Sets the extra information about the current track.
*
* @param extra The extra information.
*/
public final Builder setExtra(Bundle extra) {
mExtra = new Bundle(extra);
return this;
}
/**
* Creates a {@link TvTrackInfo} instance with the specified fields.
*
* @return The new {@link TvTrackInfo} instance
*/
public TvTrackInfo build() {
return new TvTrackInfo(mType, mId, mLanguage, mDescription, mAudioChannelCount,
mAudioSampleRate, mVideoWidth, mVideoHeight, mVideoFrameRate,
mVideoPixelAspectRatio, mVideoActiveFormatDescription, mExtra);
}
}
}