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