• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 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_BUFFER_H_
18 
19 #define MEDIA_BUFFER_H_
20 
21 #include <atomic>
22 #include <list>
23 #include <media/stagefright/foundation/MediaBufferBase.h>
24 
25 #include <pthread.h>
26 
27 #include <binder/MemoryDealer.h>
28 #include <utils/Errors.h>
29 #include <utils/RefBase.h>
30 
31 namespace android {
32 
33 struct ABuffer;
34 class GraphicBuffer;
35 class MediaBuffer;
36 class MediaBufferObserver;
37 class MetaData;
38 
39 class MediaBufferObserver {
40 public:
MediaBufferObserver()41     MediaBufferObserver() {}
~MediaBufferObserver()42     virtual ~MediaBufferObserver() {}
43 
44     virtual void signalBufferReturned(MediaBuffer *buffer) = 0;
45 
46 private:
47     MediaBufferObserver(const MediaBufferObserver &);
48     MediaBufferObserver &operator=(const MediaBufferObserver &);
49 };
50 
51 class MediaBuffer : public MediaBufferBase {
52 public:
53     // allocations larger than or equal to this will use shared memory.
54     static const size_t kSharedMemThreshold = 64 * 1024;
55 
56     // The underlying data remains the responsibility of the caller!
57     MediaBuffer(void *data, size_t size);
58 
59     explicit MediaBuffer(size_t size);
60 
61     explicit MediaBuffer(const sp<GraphicBuffer>& graphicBuffer);
62 
63     explicit MediaBuffer(const sp<ABuffer> &buffer);
64 
MediaBuffer(const sp<IMemory> & mem)65     MediaBuffer(const sp<IMemory> &mem) :
66         MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) {
67         // delegate and override mMemory
68         mMemory = mem;
69     }
70 
71     // If MediaBufferGroup is set, decrement the local reference count;
72     // if the local reference count drops to 0, return the buffer to the
73     // associated MediaBufferGroup.
74     //
75     // If no MediaBufferGroup is set, the local reference count must be zero
76     // when called, whereupon the MediaBuffer is deleted.
77     virtual void release();
78 
79     // Increments the local reference count.
80     // Use only when MediaBufferGroup is set.
81     virtual void add_ref();
82 
83     void *data() const;
84     size_t size() const;
85 
86     size_t range_offset() const;
87     size_t range_length() const;
88 
89     void set_range(size_t offset, size_t length);
90 
91     sp<GraphicBuffer> graphicBuffer() const;
92 
93     sp<MetaData> meta_data();
94 
95     // Clears meta data and resets the range to the full extent.
96     void reset();
97 
98     void setObserver(MediaBufferObserver *group);
99 
100     // Returns a clone of this MediaBuffer increasing its reference count.
101     // The clone references the same data but has its own range and
102     // MetaData.
103     MediaBuffer *clone();
104 
105     // sum of localRefcount() and remoteRefcount()
refcount()106     int refcount() const {
107         return localRefcount() + remoteRefcount();
108     }
109 
localRefcount()110     int localRefcount() const {
111         return mRefCount;
112     }
113 
remoteRefcount()114     int remoteRefcount() const {
115         if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
116         int32_t remoteRefcount =
117                 reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount();
118         // Sanity check so that remoteRefCount() is non-negative.
119         return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
120     }
121 
122     // returns old value
addRemoteRefcount(int32_t value)123     int addRemoteRefcount(int32_t value) {
124         if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
125         return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value);
126     }
127 
isDeadObject()128     bool isDeadObject() const {
129         return isDeadObject(mMemory);
130     }
131 
isDeadObject(const sp<IMemory> & memory)132     static bool isDeadObject(const sp<IMemory> &memory) {
133         if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
134         return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
135     }
136 
137     // Sticky on enabling of shared memory MediaBuffers. By default we don't use
138     // shared memory for MediaBuffers, but we enable this for those processes
139     // that export MediaBuffers.
useSharedMemory()140     static void useSharedMemory() {
141         std::atomic_store_explicit(
142                 &mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
143     }
144 
145 protected:
146     // true if MediaBuffer is observed (part of a MediaBufferGroup).
isObserved()147     inline bool isObserved() const {
148         return mObserver != nullptr;
149     }
150 
151     virtual ~MediaBuffer();
152 
153     sp<IMemory> mMemory;
154 
155 private:
156     friend class MediaBufferGroup;
157     friend class OMXDecoder;
158     friend class BnMediaSource;
159     friend class BpMediaSource;
160 
161     // For use by OMXDecoder, reference count must be 1, drop reference
162     // count to 0 without signalling the observer.
163     void claim();
164 
165     MediaBufferObserver *mObserver;
166     int mRefCount;
167 
168     void *mData;
169     size_t mSize, mRangeOffset, mRangeLength;
170     sp<GraphicBuffer> mGraphicBuffer;
171     sp<ABuffer> mBuffer;
172 
173     bool mOwnsData;
174 
175     sp<MetaData> mMetaData;
176 
177     MediaBuffer *mOriginal;
178 
179     static std::atomic_int_least32_t mUseSharedMemory;
180 
181     MediaBuffer(const MediaBuffer &);
182     MediaBuffer &operator=(const MediaBuffer &);
183 
184     // SharedControl block at the start of IMemory.
185     struct SharedControl {
186         enum {
187             FLAG_DEAD_OBJECT = (1 << 0),
188         };
189 
190         // returns old value
addRemoteRefcountSharedControl191         inline int32_t addRemoteRefcount(int32_t value) {
192             return std::atomic_fetch_add_explicit(
193                     &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
194         }
195 
getRemoteRefcountSharedControl196         inline int32_t getRemoteRefcount() const {
197             return std::atomic_load_explicit(&mRemoteRefcount, std::memory_order_seq_cst);
198         }
199 
setRemoteRefcountSharedControl200         inline void setRemoteRefcount(int32_t value) {
201             std::atomic_store_explicit(
202                     &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
203         }
204 
isDeadObjectSharedControl205         inline bool isDeadObject() const {
206             return (std::atomic_load_explicit(
207                     &mFlags, std::memory_order_seq_cst) & FLAG_DEAD_OBJECT) != 0;
208         }
209 
setDeadObjectSharedControl210         inline void setDeadObject() {
211             (void)std::atomic_fetch_or_explicit(
212                     &mFlags, (int_least32_t)FLAG_DEAD_OBJECT, std::memory_order_seq_cst);
213         }
214 
clearSharedControl215         inline void clear() {
216             std::atomic_store_explicit(
217                     &mFlags, (int_least32_t)0, std::memory_order_seq_cst);
218             std::atomic_store_explicit(
219                     &mRemoteRefcount, (int_least32_t)0, std::memory_order_seq_cst);
220         }
221 
222     private:
223         // Caution: atomic_int_fast32_t is 64 bits on LP64.
224         std::atomic_int_least32_t mFlags;
225         std::atomic_int_least32_t mRemoteRefcount;
226         int32_t unused[6] __attribute__((__unused__)); // additional buffer space
227     };
228 
getSharedControl()229     inline SharedControl *getSharedControl() const {
230          return reinterpret_cast<SharedControl *>(mMemory->pointer());
231      }
232 };
233 
234 }  // namespace android
235 
236 #endif  // MEDIA_BUFFER_H_
237