• 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 #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