• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
MediaBuffer(void * data,size_t size)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 
MediaBuffer(size_t size)46 MediaBuffer::MediaBuffer(size_t size)
47     : mObserver(NULL),
48       mNextBuffer(NULL),
49       mRefCount(0),
50       mData(NULL),
51       mSize(size),
52       mRangeOffset(0),
53       mRangeLength(size),
54       mOwnsData(true),
55       mMetaData(new MetaData),
56       mOriginal(NULL) {
57     if (size < kSharedMemThreshold) {
58         mData = malloc(size);
59     } else {
60         sp<MemoryDealer> memoryDealer = new MemoryDealer(size, "MediaBuffer");
61         mMemory = memoryDealer->allocate(size);
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             mData = mMemory->pointer();
70             ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
71         }
72     }
73 }
74 
MediaBuffer(const sp<GraphicBuffer> & graphicBuffer)75 MediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer)
76     : mObserver(NULL),
77       mNextBuffer(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 
MediaBuffer(const sp<ABuffer> & buffer)89 MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
90     : mObserver(NULL),
91       mNextBuffer(NULL),
92       mRefCount(0),
93       mData(buffer->data()),
94       mSize(buffer->size()),
95       mRangeOffset(0),
96       mRangeLength(mSize),
97       mBuffer(buffer),
98       mOwnsData(false),
99       mMetaData(new MetaData),
100       mOriginal(NULL) {
101 }
102 
release()103 void MediaBuffer::release() {
104     if (mObserver == NULL) {
105         CHECK_EQ(mRefCount, 0);
106         delete this;
107         return;
108     }
109 
110     int prevCount = __sync_fetch_and_sub(&mRefCount, 1);
111     if (prevCount == 1) {
112         if (mObserver == NULL) {
113             delete this;
114             return;
115         }
116 
117         mObserver->signalBufferReturned(this);
118     }
119     CHECK(prevCount > 0);
120 }
121 
claim()122 void MediaBuffer::claim() {
123     CHECK(mObserver != NULL);
124     CHECK_EQ(mRefCount, 1);
125 
126     mRefCount = 0;
127 }
128 
add_ref()129 void MediaBuffer::add_ref() {
130     (void) __sync_fetch_and_add(&mRefCount, 1);
131 }
132 
data() const133 void *MediaBuffer::data() const {
134     CHECK(mGraphicBuffer == NULL);
135     return mData;
136 }
137 
size() const138 size_t MediaBuffer::size() const {
139     CHECK(mGraphicBuffer == NULL);
140     return mSize;
141 }
142 
range_offset() const143 size_t MediaBuffer::range_offset() const {
144     return mRangeOffset;
145 }
146 
range_length() const147 size_t MediaBuffer::range_length() const {
148     return mRangeLength;
149 }
150 
set_range(size_t offset,size_t length)151 void MediaBuffer::set_range(size_t offset, size_t length) {
152     if ((mGraphicBuffer == NULL) && (offset + length > mSize)) {
153         ALOGE("offset = %zu, length = %zu, mSize = %zu", offset, length, mSize);
154     }
155     CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize));
156 
157     mRangeOffset = offset;
158     mRangeLength = length;
159 }
160 
graphicBuffer() const161 sp<GraphicBuffer> MediaBuffer::graphicBuffer() const {
162     return mGraphicBuffer;
163 }
164 
meta_data()165 sp<MetaData> MediaBuffer::meta_data() {
166     return mMetaData;
167 }
168 
reset()169 void MediaBuffer::reset() {
170     mMetaData->clear();
171     set_range(0, mSize);
172 }
173 
~MediaBuffer()174 MediaBuffer::~MediaBuffer() {
175     CHECK(mObserver == NULL);
176 
177     if (mOwnsData && mData != NULL && mMemory == NULL) {
178         free(mData);
179         mData = NULL;
180     }
181 
182     if (mOriginal != NULL) {
183         mOriginal->release();
184         mOriginal = NULL;
185     }
186 }
187 
setObserver(MediaBufferObserver * observer)188 void MediaBuffer::setObserver(MediaBufferObserver *observer) {
189     CHECK(observer == NULL || mObserver == NULL);
190     mObserver = observer;
191 }
192 
setNextBuffer(MediaBuffer * buffer)193 void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
194     mNextBuffer = buffer;
195 }
196 
nextBuffer()197 MediaBuffer *MediaBuffer::nextBuffer() {
198     return mNextBuffer;
199 }
200 
refcount() const201 int MediaBuffer::refcount() const {
202     return mRefCount;
203 }
204 
clone()205 MediaBuffer *MediaBuffer::clone() {
206     CHECK(mGraphicBuffer == NULL);
207 
208     MediaBuffer *buffer = new MediaBuffer(mData, mSize);
209     buffer->set_range(mRangeOffset, mRangeLength);
210     buffer->mMetaData = new MetaData(*mMetaData.get());
211 
212     add_ref();
213     buffer->mOriginal = this;
214 
215     return buffer;
216 }
217 
218 }  // namespace android
219