MediaBuffer.cpp revision 63492411cf4abff452b47f59ec7ff6f3e9925c84
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 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 46MediaBuffer::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 59MediaBuffer::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 73MediaBuffer::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 87void 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 106void MediaBuffer::claim() { 107 CHECK(mObserver != NULL); 108 CHECK_EQ(mRefCount, 1); 109 110 mRefCount = 0; 111} 112 113void MediaBuffer::add_ref() { 114 (void) __sync_fetch_and_add(&mRefCount, 1); 115} 116 117void *MediaBuffer::data() const { 118 CHECK(mGraphicBuffer == NULL); 119 return mData; 120} 121 122size_t MediaBuffer::size() const { 123 CHECK(mGraphicBuffer == NULL); 124 return mSize; 125} 126 127size_t MediaBuffer::range_offset() const { 128 return mRangeOffset; 129} 130 131size_t MediaBuffer::range_length() const { 132 return mRangeLength; 133} 134 135void MediaBuffer::set_range(size_t offset, size_t length) { 136 if ((mGraphicBuffer == NULL) && (offset + length > mSize)) { 137 ALOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize); 138 } 139 CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize)); 140 141 mRangeOffset = offset; 142 mRangeLength = length; 143} 144 145sp<GraphicBuffer> MediaBuffer::graphicBuffer() const { 146 return mGraphicBuffer; 147} 148 149sp<MetaData> MediaBuffer::meta_data() { 150 return mMetaData; 151} 152 153void MediaBuffer::reset() { 154 mMetaData->clear(); 155 set_range(0, mSize); 156} 157 158MediaBuffer::~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 172void MediaBuffer::setObserver(MediaBufferObserver *observer) { 173 CHECK(observer == NULL || mObserver == NULL); 174 mObserver = observer; 175} 176 177void MediaBuffer::setNextBuffer(MediaBuffer *buffer) { 178 mNextBuffer = buffer; 179} 180 181MediaBuffer *MediaBuffer::nextBuffer() { 182 return mNextBuffer; 183} 184 185int MediaBuffer::refcount() const { 186 return mRefCount; 187} 188 189MediaBuffer *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