• 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.annotation.Nullable;
22 import android.os.Bundle;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 import android.text.TextUtils;
26 
27 import com.android.internal.util.Preconditions;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.util.Objects;
32 
33 /**
34  * Encapsulates the format of tracks played in {@link TvInputService}.
35  */
36 public final class TvTrackInfo implements Parcelable {
37 
38     /** @hide */
39     @Retention(RetentionPolicy.SOURCE)
40     @IntDef({TYPE_AUDIO, TYPE_VIDEO, TYPE_SUBTITLE})
41     public @interface Type {}
42 
43     /**
44      * The type value for audio tracks.
45      */
46     public static final int TYPE_AUDIO = 0;
47 
48     /**
49      * The type value for video tracks.
50      */
51     public static final int TYPE_VIDEO = 1;
52 
53     /**
54      * The type value for subtitle tracks.
55      */
56     public static final int TYPE_SUBTITLE = 2;
57 
58     private final int mType;
59     private final String mId;
60     private final String mLanguage;
61     private final CharSequence mDescription;
62     @Nullable
63     private final String mEncoding;
64     private final boolean mEncrypted;
65     private final int mAudioChannelCount;
66     private final int mAudioSampleRate;
67     private final boolean mAudioDescription;
68     private final boolean mHardOfHearing;
69     private final boolean mSpokenSubtitle;
70     private final int mVideoWidth;
71     private final int mVideoHeight;
72     private final float mVideoFrameRate;
73     private final float mVideoPixelAspectRatio;
74     private final byte mVideoActiveFormatDescription;
75 
76     private final Bundle mExtra;
77 
TvTrackInfo(int type, String id, String language, CharSequence description, String encoding, boolean encrypted, int audioChannelCount, int audioSampleRate, boolean audioDescription, boolean hardOfHearing, boolean spokenSubtitle, int videoWidth, int videoHeight, float videoFrameRate, float videoPixelAspectRatio, byte videoActiveFormatDescription, Bundle extra)78     private TvTrackInfo(int type, String id, String language, CharSequence description,
79             String encoding, boolean encrypted, int audioChannelCount, int audioSampleRate,
80             boolean audioDescription, boolean hardOfHearing, boolean spokenSubtitle, int videoWidth,
81             int videoHeight, float videoFrameRate, float videoPixelAspectRatio,
82             byte videoActiveFormatDescription, Bundle extra) {
83         mType = type;
84         mId = id;
85         mLanguage = language;
86         mDescription = description;
87         mEncoding = encoding;
88         mEncrypted = encrypted;
89         mAudioChannelCount = audioChannelCount;
90         mAudioSampleRate = audioSampleRate;
91         mAudioDescription = audioDescription;
92         mHardOfHearing = hardOfHearing;
93         mSpokenSubtitle = spokenSubtitle;
94         mVideoWidth = videoWidth;
95         mVideoHeight = videoHeight;
96         mVideoFrameRate = videoFrameRate;
97         mVideoPixelAspectRatio = videoPixelAspectRatio;
98         mVideoActiveFormatDescription = videoActiveFormatDescription;
99         mExtra = extra;
100     }
101 
TvTrackInfo(Parcel in)102     private TvTrackInfo(Parcel in) {
103         mType = in.readInt();
104         mId = in.readString();
105         mLanguage = in.readString();
106         mDescription = in.readString();
107         mEncoding = in.readString();
108         mEncrypted = in.readInt() != 0;
109         mAudioChannelCount = in.readInt();
110         mAudioSampleRate = in.readInt();
111         mAudioDescription = in.readInt() != 0;
112         mHardOfHearing = in.readInt() != 0;
113         mSpokenSubtitle = in.readInt() != 0;
114         mVideoWidth = in.readInt();
115         mVideoHeight = in.readInt();
116         mVideoFrameRate = in.readFloat();
117         mVideoPixelAspectRatio = in.readFloat();
118         mVideoActiveFormatDescription = in.readByte();
119         mExtra = in.readBundle();
120     }
121 
122     /**
123      * Returns the type of the track. The type should be one of the followings:
124      * {@link #TYPE_AUDIO}, {@link #TYPE_VIDEO} and {@link #TYPE_SUBTITLE}.
125      */
126     @Type
getType()127     public final int getType() {
128         return mType;
129     }
130 
131     /**
132      * Returns the ID of the track.
133      */
getId()134     public final String getId() {
135         return mId;
136     }
137 
138     /**
139      * Returns the language information encoded by either ISO 639-1 or ISO 639-2/T. If the language
140      * is unknown or could not be determined, the corresponding value will be {@code null}.
141      */
getLanguage()142     public final String getLanguage() {
143         return mLanguage;
144     }
145 
146     /**
147      * Returns a user readable description for the current track.
148      */
getDescription()149     public final CharSequence getDescription() {
150         return mDescription;
151     }
152 
153     /**
154      * Returns the codec in the form of mime type. If the encoding is unknown or could not be
155      * determined, the corresponding value will be {@code null}.
156      *
157      * <p>For example of broadcast, codec information may be referred to broadcast standard (e.g.
158      * Component Descriptor of ETSI EN 300 468). In the case that track type is subtitle, mime type
159      * could be defined in broadcast standard (e.g. "text/dvb.subtitle" or "text/dvb.teletext" in
160      * ETSI TS 102 812 V1.3.1 section 7.6).
161      */
162     @Nullable
getEncoding()163     public String getEncoding() {
164         return mEncoding;
165     }
166 
167     /**
168      * Returns {@code true} if the track is encrypted, {@code false} otherwise. If the encryption
169      * status is unknown or could not be determined, the corresponding value will be {@code false}.
170      *
171      * <p>For example: ISO/IEC 13818-1 defines a CA descriptor that can be used to determine the
172      * encryption status of some broadcast streams.
173      */
isEncrypted()174     public boolean isEncrypted() {
175         return mEncrypted;
176     }
177 
178     /**
179      * Returns the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
180      *
181      * @throws IllegalStateException if not called on an audio track
182      */
getAudioChannelCount()183     public final int getAudioChannelCount() {
184         if (mType != TYPE_AUDIO) {
185             throw new IllegalStateException("Not an audio track");
186         }
187         return mAudioChannelCount;
188     }
189 
190     /**
191      * Returns the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO} tracks.
192      *
193      * @throws IllegalStateException if not called on an audio track
194      */
getAudioSampleRate()195     public final int getAudioSampleRate() {
196         if (mType != TYPE_AUDIO) {
197             throw new IllegalStateException("Not an audio track");
198         }
199         return mAudioSampleRate;
200     }
201 
202     /**
203      * Returns {@code true} if the track is an audio description intended for people with visual
204      * impairment, {@code false} otherwise. Valid only for {@link #TYPE_AUDIO} tracks.
205      *
206      * <p>For example of broadcast, audio description information may be referred to broadcast
207      * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio Language
208      * Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN 300 468).
209      *
210      * @throws IllegalStateException if not called on an audio track
211      */
isAudioDescription()212     public boolean isAudioDescription() {
213         if (mType != TYPE_AUDIO) {
214             throw new IllegalStateException("Not an audio track");
215         }
216         return mAudioDescription;
217     }
218 
219     /**
220      * Returns {@code true} if the track is intended for people with hearing impairment, {@code
221      * false} otherwise. Valid only for {@link #TYPE_AUDIO} and {@link #TYPE_SUBTITLE} tracks.
222      *
223      * <p>For example of broadcast, hard of hearing information may be referred to broadcast
224      * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio Language
225      * Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN 300 468).
226      *
227      * @throws IllegalStateException if not called on an audio track or a subtitle track
228      */
isHardOfHearing()229     public boolean isHardOfHearing() {
230         if (mType != TYPE_AUDIO && mType != TYPE_SUBTITLE) {
231             throw new IllegalStateException("Not an audio or a subtitle track");
232         }
233         return mHardOfHearing;
234     }
235 
236     /**
237      * Returns {@code true} if the track is a spoken subtitle for people with visual impairment,
238      * {@code false} otherwise. Valid only for {@link #TYPE_AUDIO} tracks.
239      *
240      * <p>For example of broadcast, spoken subtitle information may be referred to broadcast
241      * standard (e.g. Supplementary Audio Language Descriptor of ETSI EN 300 468).
242      *
243      * @throws IllegalStateException if not called on an audio track
244      */
isSpokenSubtitle()245     public boolean isSpokenSubtitle() {
246         if (mType != TYPE_AUDIO) {
247             throw new IllegalStateException("Not an audio track");
248         }
249         return mSpokenSubtitle;
250     }
251 
252     /**
253      * Returns the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
254      * tracks.
255      *
256      * @throws IllegalStateException if not called on a video track
257      */
getVideoWidth()258     public final int getVideoWidth() {
259         if (mType != TYPE_VIDEO) {
260             throw new IllegalStateException("Not a video track");
261         }
262         return mVideoWidth;
263     }
264 
265     /**
266      * Returns the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
267      * tracks.
268      *
269      * @throws IllegalStateException if not called on a video track
270      */
getVideoHeight()271     public final int getVideoHeight() {
272         if (mType != TYPE_VIDEO) {
273             throw new IllegalStateException("Not a video track");
274         }
275         return mVideoHeight;
276     }
277 
278     /**
279      * Returns the frame rate of the video, in the unit of fps (frames per second). Valid only for
280      * {@link #TYPE_VIDEO} tracks.
281      *
282      * @throws IllegalStateException if not called on a video track
283      */
getVideoFrameRate()284     public final float getVideoFrameRate() {
285         if (mType != TYPE_VIDEO) {
286             throw new IllegalStateException("Not a video track");
287         }
288         return mVideoFrameRate;
289     }
290 
291     /**
292      * Returns the pixel aspect ratio (the ratio of a pixel's width to its height) of the video.
293      * Valid only for {@link #TYPE_VIDEO} tracks.
294      *
295      * @throws IllegalStateException if not called on a video track
296      */
getVideoPixelAspectRatio()297     public final float getVideoPixelAspectRatio() {
298         if (mType != TYPE_VIDEO) {
299             throw new IllegalStateException("Not a video track");
300         }
301         return mVideoPixelAspectRatio;
302     }
303 
304     /**
305      * Returns the Active Format Description (AFD) code of the video.
306      * Valid only for {@link #TYPE_VIDEO} tracks.
307      *
308      * <p>The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
309      * 4 and SMPTE 2016-1-2007.
310      *
311      * @throws IllegalStateException if not called on a video track
312      */
getVideoActiveFormatDescription()313     public final byte getVideoActiveFormatDescription() {
314         if (mType != TYPE_VIDEO) {
315             throw new IllegalStateException("Not a video track");
316         }
317         return mVideoActiveFormatDescription;
318     }
319 
320     /**
321      * Returns the extra information about the current track.
322      */
getExtra()323     public final Bundle getExtra() {
324         return mExtra;
325     }
326 
327     @Override
describeContents()328     public int describeContents() {
329         return 0;
330     }
331 
332     /**
333      * Used to package this object into a {@link Parcel}.
334      *
335      * @param dest The {@link Parcel} to be written.
336      * @param flags The flags used for parceling.
337      */
338     @Override
writeToParcel(@onNull Parcel dest, int flags)339     public void writeToParcel(@NonNull Parcel dest, int flags) {
340         Preconditions.checkNotNull(dest);
341         dest.writeInt(mType);
342         dest.writeString(mId);
343         dest.writeString(mLanguage);
344         dest.writeString(mDescription != null ? mDescription.toString() : null);
345         dest.writeString(mEncoding);
346         dest.writeInt(mEncrypted ? 1 : 0);
347         dest.writeInt(mAudioChannelCount);
348         dest.writeInt(mAudioSampleRate);
349         dest.writeInt(mAudioDescription ? 1 : 0);
350         dest.writeInt(mHardOfHearing ? 1 : 0);
351         dest.writeInt(mSpokenSubtitle ? 1 : 0);
352         dest.writeInt(mVideoWidth);
353         dest.writeInt(mVideoHeight);
354         dest.writeFloat(mVideoFrameRate);
355         dest.writeFloat(mVideoPixelAspectRatio);
356         dest.writeByte(mVideoActiveFormatDescription);
357         dest.writeBundle(mExtra);
358     }
359 
360     @Override
equals(Object o)361     public boolean equals(Object o) {
362         if (this == o) {
363             return true;
364         }
365 
366         if (!(o instanceof TvTrackInfo)) {
367             return false;
368         }
369 
370         TvTrackInfo obj = (TvTrackInfo) o;
371 
372         if (!TextUtils.equals(mId, obj.mId) || mType != obj.mType
373                 || !TextUtils.equals(mLanguage, obj.mLanguage)
374                 || !TextUtils.equals(mDescription, obj.mDescription)
375                 || !TextUtils.equals(mEncoding, obj.mEncoding)
376                 || mEncrypted != obj.mEncrypted) {
377             return false;
378         }
379 
380         switch (mType) {
381             case TYPE_AUDIO:
382                 return mAudioChannelCount == obj.mAudioChannelCount
383                         && mAudioSampleRate == obj.mAudioSampleRate
384                         && mAudioDescription == obj.mAudioDescription
385                         && mHardOfHearing == obj.mHardOfHearing
386                         && mSpokenSubtitle == obj.mSpokenSubtitle;
387 
388             case TYPE_VIDEO:
389                 return mVideoWidth == obj.mVideoWidth
390                         && mVideoHeight == obj.mVideoHeight
391                         && mVideoFrameRate == obj.mVideoFrameRate
392                         && mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio
393                         && mVideoActiveFormatDescription == obj.mVideoActiveFormatDescription;
394 
395             case TYPE_SUBTITLE:
396                 return mHardOfHearing == obj.mHardOfHearing;
397         }
398 
399         return true;
400     }
401 
402     @Override
hashCode()403     public int hashCode() {
404         int result = Objects.hash(mId, mType, mLanguage, mDescription);
405 
406         if (mType == TYPE_AUDIO) {
407             result = Objects.hash(result, mAudioChannelCount, mAudioSampleRate);
408         } else if (mType == TYPE_VIDEO) {
409             result = Objects.hash(result, mVideoWidth, mVideoHeight, mVideoFrameRate,
410                     mVideoPixelAspectRatio);
411         }
412 
413         return result;
414     }
415 
416     public static final @android.annotation.NonNull Parcelable.Creator<TvTrackInfo> CREATOR =
417             new Parcelable.Creator<TvTrackInfo>() {
418                 @Override
419                 @NonNull
420                 public TvTrackInfo createFromParcel(Parcel in) {
421                     return new TvTrackInfo(in);
422                 }
423 
424                 @Override
425                 @NonNull
426                 public TvTrackInfo[] newArray(int size) {
427                     return new TvTrackInfo[size];
428                 }
429             };
430 
431     /**
432      * A builder class for creating {@link TvTrackInfo} objects.
433      */
434     public static final class Builder {
435         private final String mId;
436         private final int mType;
437         private String mLanguage;
438         private CharSequence mDescription;
439         private String mEncoding;
440         private boolean mEncrypted;
441         private int mAudioChannelCount;
442         private int mAudioSampleRate;
443         private boolean mAudioDescription;
444         private boolean mHardOfHearing;
445         private boolean mSpokenSubtitle;
446         private int mVideoWidth;
447         private int mVideoHeight;
448         private float mVideoFrameRate;
449         private float mVideoPixelAspectRatio = 1.0f;
450         private byte mVideoActiveFormatDescription;
451         private Bundle mExtra;
452 
453         /**
454          * Create a {@link Builder}. Any field that should be included in the {@link TvTrackInfo}
455          * must be added.
456          *
457          * @param type The type of the track.
458          * @param id The ID of the track that uniquely identifies the current track among all the
459          *            other tracks in the same TV program.
460          * @throws IllegalArgumentException if the type is not any of {@link #TYPE_AUDIO},
461          *                                  {@link #TYPE_VIDEO} and {@link #TYPE_SUBTITLE}
462          */
Builder(@ype int type, @NonNull String id)463         public Builder(@Type int type, @NonNull String id) {
464             if (type != TYPE_AUDIO
465                     && type != TYPE_VIDEO
466                     && type != TYPE_SUBTITLE) {
467                 throw new IllegalArgumentException("Unknown type: " + type);
468             }
469             Preconditions.checkNotNull(id);
470             mType = type;
471             mId = id;
472         }
473 
474         /**
475          * Sets the language information of the current track.
476          *
477          * @param language The language string encoded by either ISO 639-1 or ISO 639-2/T.
478          */
479         @NonNull
setLanguage(@onNull String language)480         public  Builder setLanguage(@NonNull String language) {
481             Preconditions.checkNotNull(language);
482             mLanguage = language;
483             return this;
484         }
485 
486         /**
487          * Sets a user readable description for the current track.
488          *
489          * @param description The user readable description.
490          */
491         @NonNull
setDescription(@onNull CharSequence description)492         public  Builder setDescription(@NonNull CharSequence description) {
493             Preconditions.checkNotNull(description);
494             mDescription = description;
495             return this;
496         }
497 
498         /**
499          * Sets the encoding of the track.
500          *
501          * <p>For example of broadcast, codec information may be referred to broadcast standard
502          * (e.g. Component Descriptor of ETSI EN 300 468). In the case that track type is subtitle,
503          * mime type could be defined in broadcast standard (e.g. "text/dvb.subtitle" or
504          * "text/dvb.teletext" in ETSI TS 102 812 V1.3.1 section 7.6).
505          *
506          * @param encoding The encoding of the track in the form of mime type.
507          */
508         @NonNull
setEncoding(@ullable String encoding)509         public Builder setEncoding(@Nullable String encoding) {
510             mEncoding = encoding;
511             return this;
512         }
513 
514         /**
515          * Sets the encryption status of the track.
516          *
517          * <p>For example: ISO/IEC 13818-1 defines a CA descriptor that can be used to determine the
518          * encryption status of some broadcast streams.
519          *
520          * @param encrypted The encryption status of the track.
521          */
522         @NonNull
setEncrypted(boolean encrypted)523         public Builder setEncrypted(boolean encrypted) {
524             mEncrypted = encrypted;
525             return this;
526         }
527 
528         /**
529          * Sets the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
530          *
531          * @param audioChannelCount The audio channel count.
532          * @throws IllegalStateException if not called on an audio track
533          */
534         @NonNull
setAudioChannelCount(int audioChannelCount)535         public Builder setAudioChannelCount(int audioChannelCount) {
536             if (mType != TYPE_AUDIO) {
537                 throw new IllegalStateException("Not an audio track");
538             }
539             mAudioChannelCount = audioChannelCount;
540             return this;
541         }
542 
543         /**
544          * Sets the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO}
545          * tracks.
546          *
547          * @param audioSampleRate The audio sample rate.
548          * @throws IllegalStateException if not called on an audio track
549          */
550         @NonNull
setAudioSampleRate(int audioSampleRate)551         public Builder setAudioSampleRate(int audioSampleRate) {
552             if (mType != TYPE_AUDIO) {
553                 throw new IllegalStateException("Not an audio track");
554             }
555             mAudioSampleRate = audioSampleRate;
556             return this;
557         }
558 
559         /**
560          * Sets the audio description attribute of the audio. Valid only for {@link #TYPE_AUDIO}
561          * tracks.
562          *
563          * <p>For example of broadcast, audio description information may be referred to broadcast
564          * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio
565          * Language Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN
566          * 300 468).
567          *
568          * @param audioDescription The audio description attribute of the audio.
569          * @throws IllegalStateException if not called on an audio track
570          */
571         @NonNull
setAudioDescription(boolean audioDescription)572         public Builder setAudioDescription(boolean audioDescription) {
573             if (mType != TYPE_AUDIO) {
574                 throw new IllegalStateException("Not an audio track");
575             }
576             mAudioDescription = audioDescription;
577             return this;
578         }
579 
580         /**
581          * Sets the hard of hearing attribute of the track. Valid only for {@link #TYPE_AUDIO} and
582          * {@link #TYPE_SUBTITLE} tracks.
583          *
584          * <p>For example of broadcast, hard of hearing information may be referred to broadcast
585          * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio
586          * Language Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN
587          * 300 468).
588          *
589          * @param hardOfHearing The hard of hearing attribute of the track.
590          * @throws IllegalStateException if not called on an audio track or a subtitle track
591          */
592         @NonNull
setHardOfHearing(boolean hardOfHearing)593         public Builder setHardOfHearing(boolean hardOfHearing) {
594             if (mType != TYPE_AUDIO && mType != TYPE_SUBTITLE) {
595                 throw new IllegalStateException("Not an audio track or a subtitle track");
596             }
597             mHardOfHearing = hardOfHearing;
598             return this;
599         }
600 
601         /**
602          * Sets the spoken subtitle attribute of the audio. Valid only for {@link #TYPE_AUDIO}
603          * tracks.
604          *
605          * <p>For example of broadcast, spoken subtitle information may be referred to broadcast
606          * standard (e.g. Supplementary Audio Language Descriptor of ETSI EN 300 468).
607          *
608          * @param spokenSubtitle The spoken subtitle attribute of the audio.
609          * @throws IllegalStateException if not called on an audio track
610          */
611         @NonNull
setSpokenSubtitle(boolean spokenSubtitle)612         public Builder setSpokenSubtitle(boolean spokenSubtitle) {
613             if (mType != TYPE_AUDIO) {
614                 throw new IllegalStateException("Not an audio track");
615             }
616             mSpokenSubtitle = spokenSubtitle;
617             return this;
618         }
619 
620         /**
621          * Sets the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
622          * tracks.
623          *
624          * @param videoWidth The width of the video.
625          * @throws IllegalStateException if not called on a video track
626          */
627         @NonNull
setVideoWidth(int videoWidth)628         public Builder setVideoWidth(int videoWidth) {
629             if (mType != TYPE_VIDEO) {
630                 throw new IllegalStateException("Not a video track");
631             }
632             mVideoWidth = videoWidth;
633             return this;
634         }
635 
636         /**
637          * Sets the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
638          * tracks.
639          *
640          * @param videoHeight The height of the video.
641          * @throws IllegalStateException if not called on a video track
642          */
643         @NonNull
setVideoHeight(int videoHeight)644         public Builder setVideoHeight(int videoHeight) {
645             if (mType != TYPE_VIDEO) {
646                 throw new IllegalStateException("Not a video track");
647             }
648             mVideoHeight = videoHeight;
649             return this;
650         }
651 
652         /**
653          * Sets the frame rate of the video, in the unit fps (frames per rate). Valid only for
654          * {@link #TYPE_VIDEO} tracks.
655          *
656          * @param videoFrameRate The frame rate of the video.
657          * @throws IllegalStateException if not called on a video track
658          */
659         @NonNull
setVideoFrameRate(float videoFrameRate)660         public Builder setVideoFrameRate(float videoFrameRate) {
661             if (mType != TYPE_VIDEO) {
662                 throw new IllegalStateException("Not a video track");
663             }
664             mVideoFrameRate = videoFrameRate;
665             return this;
666         }
667 
668         /**
669          * Sets the pixel aspect ratio (the ratio of a pixel's width to its height) of the video.
670          * Valid only for {@link #TYPE_VIDEO} tracks.
671          *
672          * <p>This is needed for applications to be able to scale the video properly for some video
673          * formats such as 720x576 4:3 and 720x576 16:9 where pixels are not square. By default,
674          * applications assume the value of 1.0 (square pixels), so it is not necessary to set the
675          * pixel aspect ratio for most video formats.
676          *
677          * @param videoPixelAspectRatio The pixel aspect ratio of the video.
678          * @throws IllegalStateException if not called on a video track
679          */
680         @NonNull
setVideoPixelAspectRatio(float videoPixelAspectRatio)681         public Builder setVideoPixelAspectRatio(float videoPixelAspectRatio) {
682             if (mType != TYPE_VIDEO) {
683                 throw new IllegalStateException("Not a video track");
684             }
685             mVideoPixelAspectRatio = videoPixelAspectRatio;
686             return this;
687         }
688 
689         /**
690          * Sets the Active Format Description (AFD) code of the video.
691          * Valid only for {@link #TYPE_VIDEO} tracks.
692          *
693          * <p>This is needed for applications to be able to scale the video properly based on the
694          * information about where in the coded picture the active video is.
695          * The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
696          * 4 and SMPTE 2016-1-2007.
697          *
698          * @param videoActiveFormatDescription The AFD code of the video.
699          * @throws IllegalStateException if not called on a video track
700          */
701         @NonNull
setVideoActiveFormatDescription(byte videoActiveFormatDescription)702         public Builder setVideoActiveFormatDescription(byte videoActiveFormatDescription) {
703             if (mType != TYPE_VIDEO) {
704                 throw new IllegalStateException("Not a video track");
705             }
706             mVideoActiveFormatDescription = videoActiveFormatDescription;
707             return this;
708         }
709 
710         /**
711          * Sets the extra information about the current track.
712          *
713          * @param extra The extra information.
714          */
715         @NonNull
setExtra(@onNull Bundle extra)716         public Builder setExtra(@NonNull Bundle extra) {
717             Preconditions.checkNotNull(extra);
718             mExtra = new Bundle(extra);
719             return this;
720         }
721 
722         /**
723          * Creates a {@link TvTrackInfo} instance with the specified fields.
724          *
725          * @return The new {@link TvTrackInfo} instance
726          */
727         @NonNull
build()728         public TvTrackInfo build() {
729             return new TvTrackInfo(mType, mId, mLanguage, mDescription, mEncoding, mEncrypted,
730                     mAudioChannelCount, mAudioSampleRate, mAudioDescription, mHardOfHearing,
731                     mSpokenSubtitle, mVideoWidth, mVideoHeight, mVideoFrameRate,
732                     mVideoPixelAspectRatio, mVideoActiveFormatDescription, mExtra);
733         }
734     }
735 }
736