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
MediaBuffer(void * data,size_t size)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
MediaBuffer(size_t size)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
MediaBuffer(const sp<GraphicBuffer> & graphicBuffer)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
MediaBuffer(const sp<ABuffer> & buffer)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
release()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
claim()107 void MediaBuffer::claim() {
108 CHECK(mObserver != NULL);
109 CHECK_EQ(mRefCount, 1);
110
111 mRefCount = 0;
112 }
113
add_ref()114 void MediaBuffer::add_ref() {
115 (void) __atomic_inc(&mRefCount);
116 }
117
data() const118 void *MediaBuffer::data() const {
119 CHECK(mGraphicBuffer == NULL);
120 return mData;
121 }
122
size() const123 size_t MediaBuffer::size() const {
124 CHECK(mGraphicBuffer == NULL);
125 return mSize;
126 }
127
range_offset() const128 size_t MediaBuffer::range_offset() const {
129 return mRangeOffset;
130 }
131
range_length() const132 size_t MediaBuffer::range_length() const {
133 return mRangeLength;
134 }
135
set_range(size_t offset,size_t length)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
graphicBuffer() const146 sp<GraphicBuffer> MediaBuffer::graphicBuffer() const {
147 return mGraphicBuffer;
148 }
149
meta_data()150 sp<MetaData> MediaBuffer::meta_data() {
151 return mMetaData;
152 }
153
reset()154 void MediaBuffer::reset() {
155 mMetaData->clear();
156 set_range(0, mSize);
157 }
158
~MediaBuffer()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
setObserver(MediaBufferObserver * observer)173 void MediaBuffer::setObserver(MediaBufferObserver *observer) {
174 CHECK(observer == NULL || mObserver == NULL);
175 mObserver = observer;
176 }
177
setNextBuffer(MediaBuffer * buffer)178 void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
179 mNextBuffer = buffer;
180 }
181
nextBuffer()182 MediaBuffer *MediaBuffer::nextBuffer() {
183 return mNextBuffer;
184 }
185
refcount() const186 int MediaBuffer::refcount() const {
187 return mRefCount;
188 }
189
clone()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