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