summaryrefslogtreecommitdiffstats
path: root/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/extractor/ts/TsPayloadReader.java
blob: 940c1c7937772b47dadf9268ad76dbb21ec6675f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/*
 * Copyright (C) 2016 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 org.mozilla.thirdparty.com.google.android.exoplayer2.extractor.ts;

import android.util.SparseArray;
import androidx.annotation.IntDef;
import org.mozilla.thirdparty.com.google.android.exoplayer2.ParserException;
import org.mozilla.thirdparty.com.google.android.exoplayer2.extractor.ExtractorOutput;
import org.mozilla.thirdparty.com.google.android.exoplayer2.extractor.TrackOutput;
import org.mozilla.thirdparty.com.google.android.exoplayer2.util.ParsableByteArray;
import org.mozilla.thirdparty.com.google.android.exoplayer2.util.TimestampAdjuster;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.List;

/**
 * Parses TS packet payload data.
 */
public interface TsPayloadReader {

  /**
   * Factory of {@link TsPayloadReader} instances.
   */
  interface Factory {

    /**
     * Returns the initial mapping from PIDs to payload readers.
     * <p>
     * This method allows the injection of payload readers for reserved PIDs, excluding PID 0.
     *
     * @return A {@link SparseArray} that maps PIDs to payload readers.
     */
    SparseArray<TsPayloadReader> createInitialPayloadReaders();

    /**
     * Returns a {@link TsPayloadReader} for a given stream type and elementary stream information.
     * May return null if the stream type is not supported.
     *
     * @param streamType Stream type value as defined in the PMT entry or associated descriptors.
     * @param esInfo Information associated to the elementary stream provided in the PMT.
     * @return A {@link TsPayloadReader} for the packet stream carried by the provided pid.
     *     {@code null} if the stream is not supported.
     */
    TsPayloadReader createPayloadReader(int streamType, EsInfo esInfo);

  }

  /**
   * Holds information associated with a PMT entry.
   */
  final class EsInfo {

    public final int streamType;
    public final String language;
    public final List<DvbSubtitleInfo> dvbSubtitleInfos;
    public final byte[] descriptorBytes;

    /**
     * @param streamType The type of the stream as defined by the
     *     {@link TsExtractor}{@code .TS_STREAM_TYPE_*}.
     * @param language The language of the stream, as defined by ISO/IEC 13818-1, section 2.6.18.
     * @param dvbSubtitleInfos Information about DVB subtitles associated to the stream.
     * @param descriptorBytes The descriptor bytes associated to the stream.
     */
    public EsInfo(int streamType, String language, List<DvbSubtitleInfo> dvbSubtitleInfos,
        byte[] descriptorBytes) {
      this.streamType = streamType;
      this.language = language;
      this.dvbSubtitleInfos =
          dvbSubtitleInfos == null
              ? Collections.emptyList()
              : Collections.unmodifiableList(dvbSubtitleInfos);
      this.descriptorBytes = descriptorBytes;
    }

  }

  /**
   * Holds information about a DVB subtitle, as defined in ETSI EN 300 468 V1.11.1 section 6.2.41.
   */
  final class DvbSubtitleInfo {

    public final String language;
    public final int type;
    public final byte[] initializationData;

    /**
     * @param language The ISO 639-2 three-letter language code.
     * @param type The subtitling type.
     * @param initializationData The composition and ancillary page ids.
     */
    public DvbSubtitleInfo(String language, int type, byte[] initializationData) {
      this.language = language;
      this.type = type;
      this.initializationData = initializationData;
    }

  }

  /**
   * Generates track ids for initializing {@link TsPayloadReader}s' {@link TrackOutput}s.
   */
  final class TrackIdGenerator {

    private static final int ID_UNSET = Integer.MIN_VALUE;

    private final String formatIdPrefix;
    private final int firstTrackId;
    private final int trackIdIncrement;
    private int trackId;
    private String formatId;

    public TrackIdGenerator(int firstTrackId, int trackIdIncrement) {
      this(ID_UNSET, firstTrackId, trackIdIncrement);
    }

    public TrackIdGenerator(int programNumber, int firstTrackId, int trackIdIncrement) {
      this.formatIdPrefix = programNumber != ID_UNSET ? programNumber + "/" : "";
      this.firstTrackId = firstTrackId;
      this.trackIdIncrement = trackIdIncrement;
      trackId = ID_UNSET;
    }

    /**
     * Generates a new set of track and track format ids. Must be called before {@code get*}
     * methods.
     */
    public void generateNewId() {
      trackId = trackId == ID_UNSET ? firstTrackId : trackId + trackIdIncrement;
      formatId = formatIdPrefix + trackId;
    }

    /**
     * Returns the last generated track id. Must be called after the first {@link #generateNewId()}
     * call.
     *
     * @return The last generated track id.
     */
    public int getTrackId() {
      maybeThrowUninitializedError();
      return trackId;
    }

    /**
     * Returns the last generated format id, with the format {@code "programNumber/trackId"}. If no
     * {@code programNumber} was provided, the {@code trackId} alone is used as format id. Must be
     * called after the first {@link #generateNewId()} call.
     *
     * @return The last generated format id, with the format {@code "programNumber/trackId"}. If no
     *     {@code programNumber} was provided, the {@code trackId} alone is used as
     *     format id.
     */
    public String getFormatId() {
      maybeThrowUninitializedError();
      return formatId;
    }

    private void maybeThrowUninitializedError() {
      if (trackId == ID_UNSET) {
        throw new IllegalStateException("generateNewId() must be called before retrieving ids.");
      }
    }

  }

  /**
   * Contextual flags indicating the presence of indicators in the TS packet or PES packet headers.
   */
  @Documented
  @Retention(RetentionPolicy.SOURCE)
  @IntDef(
      flag = true,
      value = {
        FLAG_PAYLOAD_UNIT_START_INDICATOR,
        FLAG_RANDOM_ACCESS_INDICATOR,
        FLAG_DATA_ALIGNMENT_INDICATOR
      })
  @interface Flags {}

  /** Indicates the presence of the payload_unit_start_indicator in the TS packet header. */
  int FLAG_PAYLOAD_UNIT_START_INDICATOR = 1;
  /**
   * Indicates the presence of the random_access_indicator in the TS packet header adaptation field.
   */
  int FLAG_RANDOM_ACCESS_INDICATOR = 1 << 1;
  /** Indicates the presence of the data_alignment_indicator in the PES header. */
  int FLAG_DATA_ALIGNMENT_INDICATOR = 1 << 2;

  /**
   * Initializes the payload reader.
   *
   * @param timestampAdjuster A timestamp adjuster for offsetting and scaling sample timestamps.
   * @param extractorOutput The {@link ExtractorOutput} that receives the extracted data.
   * @param idGenerator A {@link PesReader.TrackIdGenerator} that generates unique track ids for the
   *     {@link TrackOutput}s.
   */
  void init(TimestampAdjuster timestampAdjuster, ExtractorOutput extractorOutput,
      TrackIdGenerator idGenerator);

  /**
   * Notifies the reader that a seek has occurred.
   *
   * <p>Following a call to this method, the data passed to the next invocation of {@link #consume}
   * will not be a continuation of the data that was previously passed. Hence the reader should
   * reset any internal state.
   */
  void seek();

  /**
   * Consumes the payload of a TS packet.
   *
   * @param data The TS packet. The position will be set to the start of the payload.
   * @param flags See {@link Flags}.
   * @throws ParserException If the payload could not be parsed.
   */
  void consume(ParsableByteArray data, @Flags int flags) throws ParserException;
}