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