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