1 /*
2  * Copyright (C) 2018 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 MEDIA_SOURCE_BASE_H_
18 
19 #define MEDIA_SOURCE_BASE_H_
20 
21 #include <sys/types.h>
22 
23 #include <binder/IMemory.h>
24 #include <binder/MemoryDealer.h>
25 #include <media/MediaExtractorPluginApi.h>
26 #include <media/stagefright/MediaBufferGroup.h>
27 #include <media/stagefright/MediaErrors.h>
28 #include <media/stagefright/MetaData.h>
29 #include <media/MediaExtractorPluginApi.h>
30 #include <utils/Log.h>
31 #include <utils/RefBase.h>
32 #include <utils/Vector.h>
33 
34 namespace android {
35 
36 class MediaBufferBase;
37 struct CMediaTrack;
38 
39 class SourceBaseAllocTracker {
40 public:
SourceBaseAllocTracker()41     SourceBaseAllocTracker() {
42         ALOGD("sourcebase allocated: %p", this);
43     }
~SourceBaseAllocTracker()44     virtual ~SourceBaseAllocTracker() {
45         ALOGD("sourcebase freed: %p", this);
46     }
47 };
48 
49 struct MediaTrack
50 //    : public SourceBaseAllocTracker
51 {
52     MediaTrack();
53 
54     // To be called before any other methods on this object, except
55     // getFormat().
56     virtual status_t start() = 0;
57 
58     // Any blocking read call returns immediately with a result of NO_INIT.
59     // It is an error to call any methods other than start after this call
60     // returns. Any buffers the object may be holding onto at the time of
61     // the stop() call are released.
62     // Also, it is imperative that any buffers output by this object and
63     // held onto by callers be released before a call to stop() !!!
64     virtual status_t stop() = 0;
65 
66     // Returns the format of the data output by this media track.
67     virtual status_t getFormat(MetaDataBase& format) = 0;
68 
69     // Options that modify read() behaviour. The default is to
70     // a) not request a seek
71     // b) not be late, i.e. lateness_us = 0
72     struct ReadOptions {
73         enum SeekMode : int32_t {
74             SEEK_PREVIOUS_SYNC = CMediaTrackReadOptions::SEEK_PREVIOUS_SYNC,
75             SEEK_NEXT_SYNC = CMediaTrackReadOptions::SEEK_NEXT_SYNC,
76             SEEK_CLOSEST_SYNC = CMediaTrackReadOptions::SEEK_CLOSEST_SYNC,
77             SEEK_CLOSEST = CMediaTrackReadOptions::SEEK_CLOSEST,
78             SEEK_FRAME_INDEX = CMediaTrackReadOptions::SEEK_FRAME_INDEX,
79         };
80 
ReadOptionsMediaTrack::ReadOptions81         ReadOptions() {
82             reset();
83         }
84 
85         // Reset everything back to defaults.
resetMediaTrack::ReadOptions86         void reset() {
87             mOptions = 0;
88             mSeekTimeUs = 0;
89             mNonBlocking = false;
90         }
91 
92         void setSeekTo(int64_t time_us, SeekMode mode = SEEK_CLOSEST_SYNC);
clearSeekToMediaTrack::ReadOptions93         void clearSeekTo() {
94             mOptions &= ~kSeekTo_Option;
95             mSeekTimeUs = 0;
96             mSeekMode = SEEK_CLOSEST_SYNC;
97         }
98         bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
99 
100         void setNonBlocking();
101         void clearNonBlocking();
102         bool getNonBlocking() const;
103 
104         // Used to clear all non-persistent options for multiple buffer reads.
clearNonPersistentMediaTrack::ReadOptions105         void clearNonPersistent() {
106             clearSeekTo();
107         }
108 
109     private:
110         enum Options {
111             kSeekTo_Option      = 1,
112         };
113 
114         uint32_t mOptions;
115         int64_t mSeekTimeUs;
116         SeekMode mSeekMode;
117         bool mNonBlocking;
118     } __attribute__((packed)); // sent through Binder
119 
120     // Returns a new buffer of data. Call blocks until a
121     // buffer is available, an error is encountered of the end of the stream
122     // is reached.
123     // End of stream is signalled by a result of ERROR_END_OF_STREAM.
124     // A result of INFO_FORMAT_CHANGED indicates that the format of this
125     // MediaSource has changed mid-stream, the client can continue reading
126     // but should be prepared for buffers of the new configuration.
127     virtual status_t read(
128             MediaBufferBase **buffer, const ReadOptions *options = NULL) = 0;
129 
130     // Returns true if |read| supports nonblocking option, otherwise false.
131     // |readMultiple| if supported, always allows the nonblocking option.
supportNonblockingReadMediaTrack132     virtual bool supportNonblockingRead() {
133         return false;
134     }
135 
136     virtual ~MediaTrack();
137 
138 private:
139     MediaTrack(const MediaTrack &);
140     MediaTrack &operator=(const MediaTrack &);
141 };
142 
143 class MediaTrackCUnwrapper : public MediaTrack {
144 public:
145     static MediaTrackCUnwrapper *create(CMediaTrack *wrapper);
146 
147     virtual status_t start();
148     virtual status_t stop();
149     virtual status_t getFormat(MetaDataBase& format);
150     virtual status_t read(MediaBufferBase **buffer, const ReadOptions *options = NULL);
151 
152     virtual bool supportNonblockingRead();
153 
154 protected:
155     virtual ~MediaTrackCUnwrapper();
156 
157 private:
158     explicit MediaTrackCUnwrapper(CMediaTrack *wrapper);
159     CMediaTrack *wrapper;
160     MediaBufferGroup *bufferGroup;
161 };
162 
163 }  // namespace android
164 
165 #endif  // MEDIA_SOURCE_BASE_H_
166