1 /*
2  * Copyright (C) 2016 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 package com.google.android.exoplayer2.extractor.mp4;
17 
18 import androidx.annotation.IntDef;
19 import androidx.annotation.Nullable;
20 import com.google.android.exoplayer2.C;
21 import com.google.android.exoplayer2.Format;
22 import java.lang.annotation.Documented;
23 import java.lang.annotation.Retention;
24 import java.lang.annotation.RetentionPolicy;
25 
26 /**
27  * Encapsulates information describing an MP4 track.
28  */
29 public final class Track {
30 
31   /**
32    * The transformation to apply to samples in the track, if any. One of {@link
33    * #TRANSFORMATION_NONE} or {@link #TRANSFORMATION_CEA608_CDAT}.
34    */
35   @Documented
36   @Retention(RetentionPolicy.SOURCE)
37   @IntDef({TRANSFORMATION_NONE, TRANSFORMATION_CEA608_CDAT})
38   public @interface Transformation {}
39   /**
40    * A no-op sample transformation.
41    */
42   public static final int TRANSFORMATION_NONE = 0;
43   /**
44    * A transformation for caption samples in cdat atoms.
45    */
46   public static final int TRANSFORMATION_CEA608_CDAT = 1;
47 
48   /**
49    * The track identifier.
50    */
51   public final int id;
52 
53   /**
54    * One of {@link C#TRACK_TYPE_AUDIO}, {@link C#TRACK_TYPE_VIDEO} and {@link C#TRACK_TYPE_TEXT}.
55    */
56   public final int type;
57 
58   /**
59    * The track timescale, defined as the number of time units that pass in one second.
60    */
61   public final long timescale;
62 
63   /**
64    * The movie timescale.
65    */
66   public final long movieTimescale;
67 
68   /**
69    * The duration of the track in microseconds, or {@link C#TIME_UNSET} if unknown.
70    */
71   public final long durationUs;
72 
73   /**
74    * The format.
75    */
76   public final Format format;
77 
78   /**
79    * One of {@code TRANSFORMATION_*}. Defines the transformation to apply before outputting each
80    * sample.
81    */
82   @Transformation public final int sampleTransformation;
83 
84   /**
85    * Durations of edit list segments in the movie timescale. Null if there is no edit list.
86    */
87   @Nullable public final long[] editListDurations;
88 
89   /**
90    * Media times for edit list segments in the track timescale. Null if there is no edit list.
91    */
92   @Nullable public final long[] editListMediaTimes;
93 
94   /**
95    * For H264 video tracks, the length in bytes of the NALUnitLength field in each sample. 0 for
96    * other track types.
97    */
98   public final int nalUnitLengthFieldLength;
99 
100   @Nullable private final TrackEncryptionBox[] sampleDescriptionEncryptionBoxes;
101 
Track(int id, int type, long timescale, long movieTimescale, long durationUs, Format format, @Transformation int sampleTransformation, @Nullable TrackEncryptionBox[] sampleDescriptionEncryptionBoxes, int nalUnitLengthFieldLength, @Nullable long[] editListDurations, @Nullable long[] editListMediaTimes)102   public Track(int id, int type, long timescale, long movieTimescale, long durationUs,
103       Format format, @Transformation int sampleTransformation,
104       @Nullable TrackEncryptionBox[] sampleDescriptionEncryptionBoxes, int nalUnitLengthFieldLength,
105       @Nullable long[] editListDurations, @Nullable long[] editListMediaTimes) {
106     this.id = id;
107     this.type = type;
108     this.timescale = timescale;
109     this.movieTimescale = movieTimescale;
110     this.durationUs = durationUs;
111     this.format = format;
112     this.sampleTransformation = sampleTransformation;
113     this.sampleDescriptionEncryptionBoxes = sampleDescriptionEncryptionBoxes;
114     this.nalUnitLengthFieldLength = nalUnitLengthFieldLength;
115     this.editListDurations = editListDurations;
116     this.editListMediaTimes = editListMediaTimes;
117   }
118 
119   /**
120    * Returns the {@link TrackEncryptionBox} for the given sample description index.
121    *
122    * @param sampleDescriptionIndex The given sample description index
123    * @return The {@link TrackEncryptionBox} for the given sample description index. Maybe null if no
124    *     such entry exists.
125    */
126   @Nullable
getSampleDescriptionEncryptionBox(int sampleDescriptionIndex)127   public TrackEncryptionBox getSampleDescriptionEncryptionBox(int sampleDescriptionIndex) {
128     return sampleDescriptionEncryptionBoxes == null ? null
129         : sampleDescriptionEncryptionBoxes[sampleDescriptionIndex];
130   }
131 
copyWithFormat(Format format)132   public Track copyWithFormat(Format format) {
133     return new Track(
134         id,
135         type,
136         timescale,
137         movieTimescale,
138         durationUs,
139         format,
140         sampleTransformation,
141         sampleDescriptionEncryptionBoxes,
142         nalUnitLengthFieldLength,
143         editListDurations,
144         editListMediaTimes);
145   }
146 }
147