MediaBuffer.h revision e2b43843fd12783188edd2c54188ea8d26864788
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
31namespace android {
32
33struct ABuffer;
34class GraphicBuffer;
35class MediaBuffer;
36class MediaBufferObserver;
37class MetaData;
38
39class MediaBufferObserver {
40public:
41    MediaBufferObserver() {}
42    virtual ~MediaBufferObserver() {}
43
44    virtual void signalBufferReturned(MediaBuffer *buffer) = 0;
45
46private:
47    MediaBufferObserver(const MediaBufferObserver &);
48    MediaBufferObserver &operator=(const MediaBufferObserver &);
49};
50
51class MediaBuffer : public MediaBufferBase {
52public:
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
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()
106    int refcount() const {
107        return localRefcount() + remoteRefcount();
108    }
109
110    int localRefcount() const {
111        return mRefCount;
112    }
113
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
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
128    bool isDeadObject() const {
129        return isDeadObject(mMemory);
130    }
131
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.
140    static void useSharedMemory() {
141        std::atomic_store_explicit(
142                &mUseSharedMemory, (int_least32_t)1, std::memory_order_seq_cst);
143    }
144
145protected:
146    // true if MediaBuffer is observed (part of a MediaBufferGroup).
147    inline bool isObserved() const {
148        return mObserver != nullptr;
149    }
150
151    virtual ~MediaBuffer();
152
153    sp<IMemory> mMemory;
154
155private:
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
191        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
196        inline int32_t getRemoteRefcount() const {
197            return std::atomic_load_explicit(&mRemoteRefcount, std::memory_order_seq_cst);
198        }
199
200        inline void setRemoteRefcount(int32_t value) {
201            std::atomic_store_explicit(
202                    &mRemoteRefcount, (int_least32_t)value, std::memory_order_seq_cst);
203        }
204
205        inline bool isDeadObject() const {
206            return (std::atomic_load_explicit(
207                    &mFlags, std::memory_order_seq_cst) & FLAG_DEAD_OBJECT) != 0;
208        }
209
210        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
215        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]; // additional buffer space
227    };
228
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