Home | History | Annotate | Download | only in stagefright
      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:
     41     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 
     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 
    145 protected:
    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 
    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
    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] __attribute__((__unused__)); // 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