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