Home | History | Annotate | Download | only in libstagefright
      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 #define LOG_TAG "MediaBuffer"
     18 #include <utils/Log.h>
     19 
     20 #include <errno.h>
     21 #include <pthread.h>
     22 #include <stdlib.h>
     23 
     24 #include <media/stagefright/foundation/ABuffer.h>
     25 #include <media/stagefright/foundation/ADebug.h>
     26 #include <media/stagefright/MediaBuffer.h>
     27 #include <media/stagefright/MetaData.h>
     28 
     29 #include <ui/GraphicBuffer.h>
     30 #include <sys/atomics.h>
     31 
     32 namespace android {
     33 
     34 MediaBuffer::MediaBuffer(void *data, size_t size)
     35     : mObserver(NULL),
     36       mNextBuffer(NULL),
     37       mRefCount(0),
     38       mData(data),
     39       mSize(size),
     40       mRangeOffset(0),
     41       mRangeLength(size),
     42       mOwnsData(false),
     43       mMetaData(new MetaData),
     44       mOriginal(NULL) {
     45 }
     46 
     47 MediaBuffer::MediaBuffer(size_t size)
     48     : mObserver(NULL),
     49       mNextBuffer(NULL),
     50       mRefCount(0),
     51       mData(malloc(size)),
     52       mSize(size),
     53       mRangeOffset(0),
     54       mRangeLength(size),
     55       mOwnsData(true),
     56       mMetaData(new MetaData),
     57       mOriginal(NULL) {
     58 }
     59 
     60 MediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer)
     61     : mObserver(NULL),
     62       mNextBuffer(NULL),
     63       mRefCount(0),
     64       mData(NULL),
     65       mSize(1),
     66       mRangeOffset(0),
     67       mRangeLength(mSize),
     68       mGraphicBuffer(graphicBuffer),
     69       mOwnsData(false),
     70       mMetaData(new MetaData),
     71       mOriginal(NULL) {
     72 }
     73 
     74 MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
     75     : mObserver(NULL),
     76       mNextBuffer(NULL),
     77       mRefCount(0),
     78       mData(buffer->data()),
     79       mSize(buffer->size()),
     80       mRangeOffset(0),
     81       mRangeLength(mSize),
     82       mBuffer(buffer),
     83       mOwnsData(false),
     84       mMetaData(new MetaData),
     85       mOriginal(NULL) {
     86 }
     87 
     88 void MediaBuffer::release() {
     89     if (mObserver == NULL) {
     90         CHECK_EQ(mRefCount, 0);
     91         delete this;
     92         return;
     93     }
     94 
     95     int prevCount = __atomic_dec(&mRefCount);
     96     if (prevCount == 1) {
     97         if (mObserver == NULL) {
     98             delete this;
     99             return;
    100         }
    101 
    102         mObserver->signalBufferReturned(this);
    103     }
    104     CHECK(prevCount > 0);
    105 }
    106 
    107 void MediaBuffer::claim() {
    108     CHECK(mObserver != NULL);
    109     CHECK_EQ(mRefCount, 1);
    110 
    111     mRefCount = 0;
    112 }
    113 
    114 void MediaBuffer::add_ref() {
    115     (void) __atomic_inc(&mRefCount);
    116 }
    117 
    118 void *MediaBuffer::data() const {
    119     CHECK(mGraphicBuffer == NULL);
    120     return mData;
    121 }
    122 
    123 size_t MediaBuffer::size() const {
    124     CHECK(mGraphicBuffer == NULL);
    125     return mSize;
    126 }
    127 
    128 size_t MediaBuffer::range_offset() const {
    129     return mRangeOffset;
    130 }
    131 
    132 size_t MediaBuffer::range_length() const {
    133     return mRangeLength;
    134 }
    135 
    136 void MediaBuffer::set_range(size_t offset, size_t length) {
    137     if ((mGraphicBuffer == NULL) && (offset + length > mSize)) {
    138         ALOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize);
    139     }
    140     CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize));
    141 
    142     mRangeOffset = offset;
    143     mRangeLength = length;
    144 }
    145 
    146 sp<GraphicBuffer> MediaBuffer::graphicBuffer() const {
    147     return mGraphicBuffer;
    148 }
    149 
    150 sp<MetaData> MediaBuffer::meta_data() {
    151     return mMetaData;
    152 }
    153 
    154 void MediaBuffer::reset() {
    155     mMetaData->clear();
    156     set_range(0, mSize);
    157 }
    158 
    159 MediaBuffer::~MediaBuffer() {
    160     CHECK(mObserver == NULL);
    161 
    162     if (mOwnsData && mData != NULL) {
    163         free(mData);
    164         mData = NULL;
    165     }
    166 
    167     if (mOriginal != NULL) {
    168         mOriginal->release();
    169         mOriginal = NULL;
    170     }
    171 }
    172 
    173 void MediaBuffer::setObserver(MediaBufferObserver *observer) {
    174     CHECK(observer == NULL || mObserver == NULL);
    175     mObserver = observer;
    176 }
    177 
    178 void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
    179     mNextBuffer = buffer;
    180 }
    181 
    182 MediaBuffer *MediaBuffer::nextBuffer() {
    183     return mNextBuffer;
    184 }
    185 
    186 int MediaBuffer::refcount() const {
    187     return mRefCount;
    188 }
    189 
    190 MediaBuffer *MediaBuffer::clone() {
    191     CHECK(mGraphicBuffer == NULL);
    192 
    193     MediaBuffer *buffer = new MediaBuffer(mData, mSize);
    194     buffer->set_range(mRangeOffset, mRangeLength);
    195     buffer->mMetaData = new MetaData(*mMetaData.get());
    196 
    197     add_ref();
    198     buffer->mOriginal = this;
    199 
    200     return buffer;
    201 }
    202 
    203 }  // namespace android
    204