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