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;
17 
18 import androidx.annotation.IntDef;
19 import com.google.android.exoplayer2.C;
20 import java.io.IOException;
21 import java.lang.annotation.Documented;
22 import java.lang.annotation.Retention;
23 import java.lang.annotation.RetentionPolicy;
24 
25 /**
26  * Extracts media data from a container format.
27  */
28 public interface Extractor {
29 
30   /**
31    * Returned by {@link #read(ExtractorInput, PositionHolder)} if the {@link ExtractorInput} passed
32    * to the next {@link #read(ExtractorInput, PositionHolder)} is required to provide data
33    * continuing from the position in the stream reached by the returning call.
34    */
35   int RESULT_CONTINUE = 0;
36   /**
37    * Returned by {@link #read(ExtractorInput, PositionHolder)} if the {@link ExtractorInput} passed
38    * to the next {@link #read(ExtractorInput, PositionHolder)} is required to provide data starting
39    * from a specified position in the stream.
40    */
41   int RESULT_SEEK = 1;
42   /**
43    * Returned by {@link #read(ExtractorInput, PositionHolder)} if the end of the
44    * {@link ExtractorInput} was reached. Equal to {@link C#RESULT_END_OF_INPUT}.
45    */
46   int RESULT_END_OF_INPUT = C.RESULT_END_OF_INPUT;
47 
48   /**
49    * Result values that can be returned by {@link #read(ExtractorInput, PositionHolder)}. One of
50    * {@link #RESULT_CONTINUE}, {@link #RESULT_SEEK} or {@link #RESULT_END_OF_INPUT}.
51    */
52   @Documented
53   @Retention(RetentionPolicy.SOURCE)
54   @IntDef(value = {RESULT_CONTINUE, RESULT_SEEK, RESULT_END_OF_INPUT})
55   @interface ReadResult {}
56 
57   /**
58    * Returns whether this extractor can extract samples from the {@link ExtractorInput}, which must
59    * provide data from the start of the stream.
60    *
61    * <p>If {@code true} is returned, the {@code input}'s reading position may have been modified.
62    * Otherwise, only its peek position may have been modified.
63    *
64    * @param input The {@link ExtractorInput} from which data should be peeked/read.
65    * @return Whether this extractor can read the provided input.
66    * @throws IOException If an error occurred reading from the input.
67    */
sniff(ExtractorInput input)68   boolean sniff(ExtractorInput input) throws IOException;
69 
70   /**
71    * Initializes the extractor with an {@link ExtractorOutput}. Called at most once.
72    *
73    * @param output An {@link ExtractorOutput} to receive extracted data.
74    */
init(ExtractorOutput output)75   void init(ExtractorOutput output);
76 
77   /**
78    * Extracts data read from a provided {@link ExtractorInput}. Must not be called before {@link
79    * #init(ExtractorOutput)}.
80    *
81    * <p>A single call to this method will block until some progress has been made, but will not
82    * block for longer than this. Hence each call will consume only a small amount of input data.
83    *
84    * <p>In the common case, {@link #RESULT_CONTINUE} is returned to indicate that the {@link
85    * ExtractorInput} passed to the next read is required to provide data continuing from the
86    * position in the stream reached by the returning call. If the extractor requires data to be
87    * provided from a different position, then that position is set in {@code seekPosition} and
88    * {@link #RESULT_SEEK} is returned. If the extractor reached the end of the data provided by the
89    * {@link ExtractorInput}, then {@link #RESULT_END_OF_INPUT} is returned.
90    *
91    * <p>When this method throws an {@link IOException}, extraction may continue by providing an
92    * {@link ExtractorInput} with an unchanged {@link ExtractorInput#getPosition() read position} to
93    * a subsequent call to this method.
94    *
95    * @param input The {@link ExtractorInput} from which data should be read.
96    * @param seekPosition If {@link #RESULT_SEEK} is returned, this holder is updated to hold the
97    *     position of the required data.
98    * @return One of the {@code RESULT_} values defined in this interface.
99    * @throws IOException If an error occurred reading from the input.
100    */
101   @ReadResult
read(ExtractorInput input, PositionHolder seekPosition)102   int read(ExtractorInput input, PositionHolder seekPosition) throws IOException;
103 
104   /**
105    * Notifies the extractor that a seek has occurred.
106    * <p>
107    * Following a call to this method, the {@link ExtractorInput} passed to the next invocation of
108    * {@link #read(ExtractorInput, PositionHolder)} is required to provide data starting from {@code
109    * position} in the stream. Valid random access positions are the start of the stream and
110    * positions that can be obtained from any {@link SeekMap} passed to the {@link ExtractorOutput}.
111    *
112    * @param position The byte offset in the stream from which data will be provided.
113    * @param timeUs The seek time in microseconds.
114    */
seek(long position, long timeUs)115   void seek(long position, long timeUs);
116 
117   /**
118    * Releases all kept resources.
119    */
release()120   void release();
121 
122 }
123