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(malloc(size)),
51 mSize(size),
52 mRangeOffset(0),
53 mRangeLength(size),
54 mOwnsData(true),
55 mMetaData(new MetaData),
56 mOriginal(NULL) {
57 }
58
MediaBuffer(const sp<GraphicBuffer> & graphicBuffer)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
MediaBuffer(const sp<ABuffer> & buffer)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
release()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
claim()106 void MediaBuffer::claim() {
107 CHECK(mObserver != NULL);
108 CHECK_EQ(mRefCount, 1);
109
110 mRefCount = 0;
111 }
112
add_ref()113 void MediaBuffer::add_ref() {
114 (void) __sync_fetch_and_add(&mRefCount, 1);
115 }
116
data() const117 void *MediaBuffer::data() const {
118 CHECK(mGraphicBuffer == NULL);
119 return mData;
120 }
121
size() const122 size_t MediaBuffer::size() const {
123 CHECK(mGraphicBuffer == NULL);
124 return mSize;
125 }
126
range_offset() const127 size_t MediaBuffer::range_offset() const {
128 return mRangeOffset;
129 }
130
range_length() const131 size_t MediaBuffer::range_length() const {
132 return mRangeLength;
133 }
134
set_range(size_t offset,size_t length)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
graphicBuffer() const145 sp<GraphicBuffer> MediaBuffer::graphicBuffer() const {
146 return mGraphicBuffer;
147 }
148
meta_data()149 sp<MetaData> MediaBuffer::meta_data() {
150 return mMetaData;
151 }
152
reset()153 void MediaBuffer::reset() {
154 mMetaData->clear();
155 set_range(0, mSize);
156 }
157
~MediaBuffer()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
setObserver(MediaBufferObserver * observer)172 void MediaBuffer::setObserver(MediaBufferObserver *observer) {
173 CHECK(observer == NULL || mObserver == NULL);
174 mObserver = observer;
175 }
176
setNextBuffer(MediaBuffer * buffer)177 void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
178 mNextBuffer = buffer;
179 }
180
nextBuffer()181 MediaBuffer *MediaBuffer::nextBuffer() {
182 return mNextBuffer;
183 }
184
refcount() const185 int MediaBuffer::refcount() const {
186 return mRefCount;
187 }
188
clone()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