• 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     MediaBuffer(size_t size);
60 
61     MediaBuffer(const sp<GraphicBuffer>& graphicBuffer);
62 
63     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     // Decrements the reference count and returns the buffer to its
72     // associated MediaBufferGroup if the reference count drops to 0.
73     virtual void release();
74 
75     // Increments the reference count.
76     virtual void add_ref();
77 
78     void *data() const;
79     size_t size() const;
80 
81     size_t range_offset() const;
82     size_t range_length() const;
83 
84     void set_range(size_t offset, size_t length);
85 
86     sp<GraphicBuffer> graphicBuffer() const;
87 
88     sp<MetaData> meta_data();
89 
90     // Clears meta data and resets the range to the full extent.
91     void reset();
92 
93     void setObserver(MediaBufferObserver *group);
94 
95     // Returns a clone of this MediaBuffer increasing its reference count.
96     // The clone references the same data but has its own range and
97     // MetaData.
98     MediaBuffer *clone();
99 
100     int refcount() const;
101 
isDeadObject()102     bool isDeadObject() const {
103         return isDeadObject(mMemory);
104     }
105 
isDeadObject(const sp<IMemory> & memory)106     static bool isDeadObject(const sp<IMemory> &memory) {
107         if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
108         return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
109     }
110 
111     // Sticky on enabling of shared memory MediaBuffers. By default we don't use
112     // shared memory for MediaBuffers, but we enable this for those processes
113     // that export MediaBuffers.
useSharedMemory()114     static void useSharedMemory() {
115         std::atomic_store_explicit(
116                 &mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
117     }
118 
119 protected:
120     // MediaBuffer remote releases are handled through a
121     // pending release count variable stored in a SharedControl block
122     // at the start of the IMemory.
123 
124     // Returns old value of pending release count.
addPendingRelease(int32_t value)125     inline int32_t addPendingRelease(int32_t value) {
126         return getSharedControl()->addPendingRelease(value);
127     }
128 
129     // Issues all pending releases (works in parallel).
130     // Assumes there is a MediaBufferObserver.
resolvePendingRelease()131     inline void resolvePendingRelease() {
132         if (mMemory.get() == nullptr) return;
133         while (addPendingRelease(-1) > 0) {
134             release();
135         }
136         addPendingRelease(1);
137     }
138 
139     // true if MediaBuffer is observed (part of a MediaBufferGroup).
isObserved()140     inline bool isObserved() const {
141         return mObserver != nullptr;
142     }
143 
144     virtual ~MediaBuffer();
145 
146     sp<IMemory> mMemory;
147 
148 private:
149     friend class MediaBufferGroup;
150     friend class OMXDecoder;
151     friend class BnMediaSource;
152     friend class BpMediaSource;
153 
154     // For use by OMXDecoder, reference count must be 1, drop reference
155     // count to 0 without signalling the observer.
156     void claim();
157 
158     MediaBufferObserver *mObserver;
159     int mRefCount;
160 
161     void *mData;
162     size_t mSize, mRangeOffset, mRangeLength;
163     sp<GraphicBuffer> mGraphicBuffer;
164     sp<ABuffer> mBuffer;
165 
166     bool mOwnsData;
167 
168     sp<MetaData> mMetaData;
169 
170     MediaBuffer *mOriginal;
171 
172     static std::atomic_int_least32_t mUseSharedMemory;
173 
174     MediaBuffer(const MediaBuffer &);
175     MediaBuffer &operator=(const MediaBuffer &);
176 
177     // SharedControl block at the start of IMemory.
178     struct SharedControl {
179         enum {
180             FLAG_DEAD_OBJECT = (1 << 0),
181         };
182 
183         // returns old value
addPendingReleaseSharedControl184         inline int32_t addPendingRelease(int32_t value) {
185             return std::atomic_fetch_add_explicit(
186                     &mPendingRelease, (int_least32_t)value, std::memory_order_seq_cst);
187         }
188 
getPendingReleaseSharedControl189         inline int32_t getPendingRelease() const {
190             return std::atomic_load_explicit(&mPendingRelease, std::memory_order_seq_cst);
191         }
192 
setPendingReleaseSharedControl193         inline void setPendingRelease(int32_t value) {
194             std::atomic_store_explicit(
195                     &mPendingRelease, (int_least32_t)value, std::memory_order_seq_cst);
196         }
197 
isDeadObjectSharedControl198         inline bool isDeadObject() const {
199             return (std::atomic_load_explicit(
200                     &mFlags, std::memory_order_seq_cst) & FLAG_DEAD_OBJECT) != 0;
201         }
202 
setDeadObjectSharedControl203         inline void setDeadObject() {
204             (void)std::atomic_fetch_or_explicit(
205                     &mFlags, (int_least32_t)FLAG_DEAD_OBJECT, std::memory_order_seq_cst);
206         }
207 
clearSharedControl208         inline void clear() {
209             std::atomic_store_explicit(
210                     &mFlags, (int_least32_t)0, std::memory_order_seq_cst);
211             std::atomic_store_explicit(
212                     &mPendingRelease, (int_least32_t)0, std::memory_order_seq_cst);
213         }
214 
215     private:
216         // Caution: atomic_int_fast32_t is 64 bits on LP64.
217         std::atomic_int_least32_t mFlags;
218         std::atomic_int_least32_t mPendingRelease;
219         int32_t unused[6]; // additional buffer space
220     };
221 
getSharedControl()222     inline SharedControl *getSharedControl() const {
223          return reinterpret_cast<SharedControl *>(mMemory->pointer());
224      }
225 };
226 
227 }  // namespace android
228 
229 #endif  // MEDIA_BUFFER_H_
230