• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.media.tv;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.os.Bundle;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 import android.text.TextUtils;
25 
26 import com.android.internal.util.Preconditions;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 import java.util.Objects;
31 
32 /**
33  * Encapsulates the format of tracks played in {@link TvInputService}.
34  */
35 public final class TvTrackInfo implements Parcelable {
36 
37     /** @hide */
38     @Retention(RetentionPolicy.SOURCE)
39     @IntDef({TYPE_AUDIO, TYPE_VIDEO, TYPE_SUBTITLE})
40     public @interface Type {}
41 
42     /**
43      * The type value for audio tracks.
44      */
45     public static final int TYPE_AUDIO = 0;
46 
47     /**
48      * The type value for video tracks.
49      */
50     public static final int TYPE_VIDEO = 1;
51 
52     /**
53      * The type value for subtitle tracks.
54      */
55     public static final int TYPE_SUBTITLE = 2;
56 
57     private final int mType;
58     private final String mId;
59     private final String mLanguage;
60     private final CharSequence mDescription;
61     private final int mAudioChannelCount;
62     private final int mAudioSampleRate;
63     private final int mVideoWidth;
64     private final int mVideoHeight;
65     private final float mVideoFrameRate;
66     private final float mVideoPixelAspectRatio;
67     private final byte mVideoActiveFormatDescription;
68 
69     private final Bundle mExtra;
70 
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)71     private TvTrackInfo(int type, String id, String language, CharSequence description,
72             int audioChannelCount, int audioSampleRate, int videoWidth, int videoHeight,
73             float videoFrameRate, float videoPixelAspectRatio, byte videoActiveFormatDescription,
74             Bundle extra) {
75         mType = type;
76         mId = id;
77         mLanguage = language;
78         mDescription = description;
79         mAudioChannelCount = audioChannelCount;
80         mAudioSampleRate = audioSampleRate;
81         mVideoWidth = videoWidth;
82         mVideoHeight = videoHeight;
83         mVideoFrameRate = videoFrameRate;
84         mVideoPixelAspectRatio = videoPixelAspectRatio;
85         mVideoActiveFormatDescription = videoActiveFormatDescription;
86         mExtra = extra;
87     }
88 
TvTrackInfo(Parcel in)89     private TvTrackInfo(Parcel in) {
90         mType = in.readInt();
91         mId = in.readString();
92         mLanguage = in.readString();
93         mDescription = in.readString();
94         mAudioChannelCount = in.readInt();
95         mAudioSampleRate = in.readInt();
96         mVideoWidth = in.readInt();
97         mVideoHeight = in.readInt();
98         mVideoFrameRate = in.readFloat();
99         mVideoPixelAspectRatio = in.readFloat();
100         mVideoActiveFormatDescription = in.readByte();
101         mExtra = in.readBundle();
102     }
103 
104     /**
105      * Returns the type of the track. The type should be one of the followings:
106      * {@link #TYPE_AUDIO}, {@link #TYPE_VIDEO} and {@link #TYPE_SUBTITLE}.
107      */
108     @Type
getType()109     public final int getType() {
110         return mType;
111     }
112 
113     /**
114      * Returns the ID of the track.
115      */
getId()116     public final String getId() {
117         return mId;
118     }
119 
120     /**
121      * Returns the language information encoded by either ISO 639-1 or ISO 639-2/T. If the language
122      * is unknown or could not be determined, the corresponding value will be {@code null}.
123      */
getLanguage()124     public final String getLanguage() {
125         return mLanguage;
126     }
127 
128     /**
129      * Returns a user readable description for the current track.
130      */
getDescription()131     public final CharSequence getDescription() {
132         return mDescription;
133     }
134 
135     /**
136      * Returns the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
137      *
138      * @throws IllegalStateException if not called on an audio track
139      */
getAudioChannelCount()140     public final int getAudioChannelCount() {
141         if (mType != TYPE_AUDIO) {
142             throw new IllegalStateException("Not an audio track");
143         }
144         return mAudioChannelCount;
145     }
146 
147     /**
148      * Returns the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO} tracks.
149      *
150      * @throws IllegalStateException if not called on an audio track
151      */
getAudioSampleRate()152     public final int getAudioSampleRate() {
153         if (mType != TYPE_AUDIO) {
154             throw new IllegalStateException("Not an audio track");
155         }
156         return mAudioSampleRate;
157     }
158 
159     /**
160      * Returns the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
161      * tracks.
162      *
163      * @throws IllegalStateException if not called on a video track
164      */
getVideoWidth()165     public final int getVideoWidth() {
166         if (mType != TYPE_VIDEO) {
167             throw new IllegalStateException("Not a video track");
168         }
169         return mVideoWidth;
170     }
171 
172     /**
173      * Returns the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
174      * tracks.
175      *
176      * @throws IllegalStateException if not called on a video track
177      */
getVideoHeight()178     public final int getVideoHeight() {
179         if (mType != TYPE_VIDEO) {
180             throw new IllegalStateException("Not a video track");
181         }
182         return mVideoHeight;
183     }
184 
185     /**
186      * Returns the frame rate of the video, in the unit of fps (frames per second). Valid only for
187      * {@link #TYPE_VIDEO} tracks.
188      *
189      * @throws IllegalStateException if not called on a video track
190      */
getVideoFrameRate()191     public final float getVideoFrameRate() {
192         if (mType != TYPE_VIDEO) {
193             throw new IllegalStateException("Not a video track");
194         }
195         return mVideoFrameRate;
196     }
197 
198     /**
199      * Returns the pixel aspect ratio (the ratio of a pixel's width to its height) of the video.
200      * Valid only for {@link #TYPE_VIDEO} tracks.
201      *
202      * @throws IllegalStateException if not called on a video track
203      */
getVideoPixelAspectRatio()204     public final float getVideoPixelAspectRatio() {
205         if (mType != TYPE_VIDEO) {
206             throw new IllegalStateException("Not a video track");
207         }
208         return mVideoPixelAspectRatio;
209     }
210 
211     /**
212      * Returns the Active Format Description (AFD) code of the video.
213      * Valid only for {@link #TYPE_VIDEO} tracks.
214      *
215      * <p>The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
216      * 4 and SMPTE 2016-1-2007.
217      *
218      * @throws IllegalStateException if not called on a video track
219      */
getVideoActiveFormatDescription()220     public final byte getVideoActiveFormatDescription() {
221         if (mType != TYPE_VIDEO) {
222             throw new IllegalStateException("Not a video track");
223         }
224         return mVideoActiveFormatDescription;
225     }
226 
227     /**
228      * Returns the extra information about the current track.
229      */
getExtra()230     public final Bundle getExtra() {
231         return mExtra;
232     }
233 
234     @Override
describeContents()235     public int describeContents() {
236         return 0;
237     }
238 
239     /**
240      * Used to package this object into a {@link Parcel}.
241      *
242      * @param dest The {@link Parcel} to be written.
243      * @param flags The flags used for parceling.
244      */
245     @Override
writeToParcel(Parcel dest, int flags)246     public void writeToParcel(Parcel dest, int flags) {
247         dest.writeInt(mType);
248         dest.writeString(mId);
249         dest.writeString(mLanguage);
250         dest.writeString(mDescription != null ? mDescription.toString() : null);
251         dest.writeInt(mAudioChannelCount);
252         dest.writeInt(mAudioSampleRate);
253         dest.writeInt(mVideoWidth);
254         dest.writeInt(mVideoHeight);
255         dest.writeFloat(mVideoFrameRate);
256         dest.writeFloat(mVideoPixelAspectRatio);
257         dest.writeByte(mVideoActiveFormatDescription);
258         dest.writeBundle(mExtra);
259     }
260 
261     @Override
equals(Object o)262     public boolean equals(Object o) {
263         if (this == o) {
264           return true;
265         }
266 
267         if (!(o instanceof TvTrackInfo)) {
268           return false;
269         }
270 
271         TvTrackInfo obj = (TvTrackInfo) o;
272         return TextUtils.equals(mId, obj.mId)
273                 && mType == obj.mType
274                 && TextUtils.equals(mLanguage, obj.mLanguage)
275                 && TextUtils.equals(mDescription, obj.mDescription)
276                 && Objects.equals(mExtra, obj.mExtra)
277                 && (mType == TYPE_AUDIO
278                         ? mAudioChannelCount == obj.mAudioChannelCount
279                         && mAudioSampleRate == obj.mAudioSampleRate
280                         : (mType == TYPE_VIDEO
281                                 ? mVideoWidth == obj.mVideoWidth
282                                 && mVideoHeight == obj.mVideoHeight
283                                 && mVideoFrameRate == obj.mVideoFrameRate
284                                 && mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio : true));
285     }
286 
287     @Override
hashCode()288     public int hashCode() {
289         return Objects.hashCode(mId);
290     }
291 
292     public static final Parcelable.Creator<TvTrackInfo> CREATOR =
293             new Parcelable.Creator<TvTrackInfo>() {
294                 @Override
295                 public TvTrackInfo createFromParcel(Parcel in) {
296                     return new TvTrackInfo(in);
297                 }
298 
299                 @Override
300                 public TvTrackInfo[] newArray(int size) {
301                     return new TvTrackInfo[size];
302                 }
303             };
304 
305     /**
306      * A builder class for creating {@link TvTrackInfo} objects.
307      */
308     public static final class Builder {
309         private final String mId;
310         private final int mType;
311         private String mLanguage;
312         private CharSequence mDescription;
313         private int mAudioChannelCount;
314         private int mAudioSampleRate;
315         private int mVideoWidth;
316         private int mVideoHeight;
317         private float mVideoFrameRate;
318         private float mVideoPixelAspectRatio = 1.0f;
319         private byte mVideoActiveFormatDescription;
320         private Bundle mExtra;
321 
322         /**
323          * Create a {@link Builder}. Any field that should be included in the {@link TvTrackInfo}
324          * must be added.
325          *
326          * @param type The type of the track.
327          * @param id The ID of the track that uniquely identifies the current track among all the
328          *            other tracks in the same TV program.
329          * @throws IllegalArgumentException if the type is not any of {@link #TYPE_AUDIO},
330          *                                  {@link #TYPE_VIDEO} and {@link #TYPE_SUBTITLE}
331          */
Builder(@ype int type, @NonNull String id)332         public Builder(@Type int type, @NonNull String id) {
333             if (type != TYPE_AUDIO
334                     && type != TYPE_VIDEO
335                     && type != TYPE_SUBTITLE) {
336                 throw new IllegalArgumentException("Unknown type: " + type);
337             }
338             Preconditions.checkNotNull(id);
339             mType = type;
340             mId = id;
341         }
342 
343         /**
344          * Sets the language information of the current track.
345          *
346          * @param language The language string encoded by either ISO 639-1 or ISO 639-2/T.
347          */
setLanguage(String language)348         public final Builder setLanguage(String language) {
349             mLanguage = language;
350             return this;
351         }
352 
353         /**
354          * Sets a user readable description for the current track.
355          *
356          * @param description The user readable description.
357          */
setDescription(CharSequence description)358         public final Builder setDescription(CharSequence description) {
359             mDescription = description;
360             return this;
361         }
362 
363         /**
364          * Sets the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
365          *
366          * @param audioChannelCount The audio channel count.
367          * @throws IllegalStateException if not called on an audio track
368          */
setAudioChannelCount(int audioChannelCount)369         public final Builder setAudioChannelCount(int audioChannelCount) {
370             if (mType != TYPE_AUDIO) {
371                 throw new IllegalStateException("Not an audio track");
372             }
373             mAudioChannelCount = audioChannelCount;
374             return this;
375         }
376 
377         /**
378          * Sets the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO}
379          * tracks.
380          *
381          * @param audioSampleRate The audio sample rate.
382          * @throws IllegalStateException if not called on an audio track
383          */
setAudioSampleRate(int audioSampleRate)384         public final Builder setAudioSampleRate(int audioSampleRate) {
385             if (mType != TYPE_AUDIO) {
386                 throw new IllegalStateException("Not an audio track");
387             }
388             mAudioSampleRate = audioSampleRate;
389             return this;
390         }
391 
392         /**
393          * Sets the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
394          * tracks.
395          *
396          * @param videoWidth The width of the video.
397          * @throws IllegalStateException if not called on a video track
398          */
setVideoWidth(int videoWidth)399         public final Builder setVideoWidth(int videoWidth) {
400             if (mType != TYPE_VIDEO) {
401                 throw new IllegalStateException("Not a video track");
402             }
403             mVideoWidth = videoWidth;
404             return this;
405         }
406 
407         /**
408          * Sets the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
409          * tracks.
410          *
411          * @param videoHeight The height of the video.
412          * @throws IllegalStateException if not called on a video track
413          */
setVideoHeight(int videoHeight)414         public final Builder setVideoHeight(int videoHeight) {
415             if (mType != TYPE_VIDEO) {
416                 throw new IllegalStateException("Not a video track");
417             }
418             mVideoHeight = videoHeight;
419             return this;
420         }
421 
422         /**
423          * Sets the frame rate of the video, in the unit fps (frames per rate). Valid only for
424          * {@link #TYPE_VIDEO} tracks.
425          *
426          * @param videoFrameRate The frame rate of the video.
427          * @throws IllegalStateException if not called on a video track
428          */
setVideoFrameRate(float videoFrameRate)429         public final Builder setVideoFrameRate(float videoFrameRate) {
430             if (mType != TYPE_VIDEO) {
431                 throw new IllegalStateException("Not a video track");
432             }
433             mVideoFrameRate = videoFrameRate;
434             return this;
435         }
436 
437         /**
438          * Sets the pixel aspect ratio (the ratio of a pixel's width to its height) of the video.
439          * Valid only for {@link #TYPE_VIDEO} tracks.
440          *
441          * <p>This is needed for applications to be able to scale the video properly for some video
442          * formats such as 720x576 4:3 and 720x576 16:9 where pixels are not square. By default,
443          * applications assume the value of 1.0 (square pixels), so it is not necessary to set the
444          * pixel aspect ratio for most video formats.
445          *
446          * @param videoPixelAspectRatio The pixel aspect ratio of the video.
447          * @throws IllegalStateException if not called on a video track
448          */
setVideoPixelAspectRatio(float videoPixelAspectRatio)449         public final Builder setVideoPixelAspectRatio(float videoPixelAspectRatio) {
450             if (mType != TYPE_VIDEO) {
451                 throw new IllegalStateException("Not a video track");
452             }
453             mVideoPixelAspectRatio = videoPixelAspectRatio;
454             return this;
455         }
456 
457         /**
458          * Sets the Active Format Description (AFD) code of the video.
459          * Valid only for {@link #TYPE_VIDEO} tracks.
460          *
461          * <p>This is needed for applications to be able to scale the video properly based on the
462          * information about where in the coded picture the active video is.
463          * The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
464          * 4 and SMPTE 2016-1-2007.
465          *
466          * @param videoActiveFormatDescription The AFD code of the video.
467          * @throws IllegalStateException if not called on a video track
468          */
setVideoActiveFormatDescription(byte videoActiveFormatDescription)469         public final Builder setVideoActiveFormatDescription(byte videoActiveFormatDescription) {
470             if (mType != TYPE_VIDEO) {
471                 throw new IllegalStateException("Not a video track");
472             }
473             mVideoActiveFormatDescription = videoActiveFormatDescription;
474             return this;
475         }
476 
477         /**
478          * Sets the extra information about the current track.
479          *
480          * @param extra The extra information.
481          */
setExtra(Bundle extra)482         public final Builder setExtra(Bundle extra) {
483             mExtra = new Bundle(extra);
484             return this;
485         }
486 
487         /**
488          * Creates a {@link TvTrackInfo} instance with the specified fields.
489          *
490          * @return The new {@link TvTrackInfo} instance
491          */
build()492         public TvTrackInfo build() {
493             return new TvTrackInfo(mType, mId, mLanguage, mDescription, mAudioChannelCount,
494                     mAudioSampleRate, mVideoWidth, mVideoHeight, mVideoFrameRate,
495                     mVideoPixelAspectRatio, mVideoActiveFormatDescription, mExtra);
496         }
497     }
498 }
499