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