1 /*
2  * Copyright (C) 2020 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 #ifndef ANDROID_MEDIA_SAMPLE_READER_H
18 #define ANDROID_MEDIA_SAMPLE_READER_H
19 
20 #include <media/MediaSample.h>
21 #include <media/NdkMediaError.h>
22 #include <media/NdkMediaFormat.h>
23 
24 namespace android {
25 
26 /**
27  * MediaSampleReader is an interface for reading media samples from a container. MediaSampleReader
28  * allows for reading samples from multiple tracks on individual threads independently of each other
29  * while preserving the order of samples. Due to poor non-sequential access performance of the
30  * underlying extractor, MediaSampleReader can optionally enforce sequential sample access by
31  * blocking requests for tracks that the underlying extractor does not currently point to. Waiting
32  * threads are serviced once the reader advances to a sample from the specified track. Due to this
33  * it is important to read samples and advance the reader from all selected tracks to avoid hanging
34  * other tracks. MediaSampleReader implementations are thread safe and sample access should be done
35  * on one thread per selected track.
36  */
37 class MediaSampleReader {
38 public:
39     /**
40      * Returns the file format of the media container as a AMediaFormat.
41      * The caller is responsible for releasing the format when finished with it using
42      * AMediaFormat_delete().
43      * @return The file media format.
44      */
45     virtual AMediaFormat* getFileFormat() = 0;
46 
47     /**
48      * Returns the number of tracks in the media container.
49      * @return The number of tracks.
50      */
51     virtual size_t getTrackCount() const = 0;
52 
53     /**
54      * Returns the media format of a specific track as a AMediaFormat.
55      * The caller is responsible for releasing the format when finished with it using
56      * AMediaFormat_delete().
57      * @param trackIndex The track index (zero-based).
58      * @return The track media format.
59      */
60     virtual AMediaFormat* getTrackFormat(int trackIndex) = 0;
61 
62     /**
63      * Select a track for sample access. Tracks must be selected in order for sample information and
64      * sample data to be available for that track. Samples for selected tracks must be accessed on
65      * its own thread to avoid blocking other tracks.
66      * @param trackIndex The track to select.
67      * @return AMEDIA_OK on success.
68      */
69     virtual media_status_t selectTrack(int trackIndex) = 0;
70 
71     /**
72      * Undo a track selection.
73      * @param trackIndex The track to un-select.
74      * @return AMEDIA_OK on success.
75      */
76     virtual media_status_t unselectTrack(int trackIndex) = 0;
77 
78     /**
79      * Toggles sequential access enforcement on or off. When the reader enforces sequential access
80      * calls to read sample information will block unless the underlying extractor points to the
81      * specified track.
82      * @param enforce True to enforce sequential access.
83      * @return AMEDIA_OK on success.
84      */
85     virtual media_status_t setEnforceSequentialAccess(bool enforce) = 0;
86 
87     /**
88      * Estimates the bitrate of a source track by sampling sample sizes. The bitrate is returned in
89      * megabits per second (Mbps). This method will fail if the track only contains a single sample
90      * and does not have an associated duration.
91      * @param trackIndex The source track index.
92      * @param bitrate Output param for the bitrate.
93      * @return AMEDIA_OK on success.
94      */
95     virtual media_status_t getEstimatedBitrateForTrack(int trackIndex, int32_t* bitrate);
96 
97     /**
98      * Returns the sample information for the current sample in the specified track. Note that this
99      * method will block until the reader advances to a sample belonging to the requested track if
100      * the reader is in sequential access mode.
101      * @param trackIndex The track index (zero-based).
102      * @param info Pointer to a MediaSampleInfo object where the sample information is written.
103      * @return AMEDIA_OK on success, AMEDIA_ERROR_END_OF_STREAM if there are no more samples to read
104      * from the track and AMEDIA_ERROR_INVALID_PARAMETER if trackIndex is out of bounds or the
105      * info pointer is NULL. Other AMEDIA_ERROR_* return values may not be recoverable.
106      */
107     virtual media_status_t getSampleInfoForTrack(int trackIndex, MediaSampleInfo* info) = 0;
108 
109     /**
110      * Returns the sample data for the current sample in the specified track into the supplied
111      * buffer. Note that this method will block until the reader advances to a sample belonging to
112      * the requested track if the reader is in sequential access mode. Upon successful return this
113      * method will also advance the specified track to the next sample.
114      * @param trackIndex The track index (zero-based).
115      * @param buffer The buffer to write the sample's data to.
116      * @param bufferSize The size of the supplied buffer.
117      * @return AMEDIA_OK on success, AMEDIA_ERROR_END_OF_STREAM if there are no more samples to read
118      * from the track and AMEDIA_ERROR_INVALID_PARAMETER if trackIndex is out of bounds, if the
119      * buffer pointer is NULL or if bufferSize is too small for the sample. Other AMEDIA_ERROR_*
120      * return values may not be recoverable.
121      */
122     virtual media_status_t readSampleDataForTrack(int trackIndex, uint8_t* buffer,
123                                                   size_t bufferSize) = 0;
124 
125     /**
126      * Advance the specified track to the next sample. If the reader is in sequential access mode
127      * and the current sample belongs to the specified track, the reader will also advance to the
128      * next sample and wake up any threads waiting on the new track.
129      * @param trackIndex The track index (zero-based).
130      */
131     virtual void advanceTrack(int trackIndex) = 0;
132 
133     /** Destructor. */
134     virtual ~MediaSampleReader() = default;
135 
136     /** Constructor. */
137     MediaSampleReader() = default;
138 
139 private:
140     MediaSampleReader(const MediaSampleReader&) = delete;
141     MediaSampleReader& operator=(const MediaSampleReader&) = delete;
142 };
143 
144 }  // namespace android
145 #endif  // ANDROID_MEDIA_SAMPLE_READER_H
146