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