Line data Source code
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 stagefright {
33 :
34 0 : 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 0 : mMetaData(new MetaData),
44 0 : mOriginal(NULL) {
45 0 : }
46 :
47 0 : MediaBuffer::MediaBuffer(size_t size)
48 : : mObserver(NULL),
49 : mNextBuffer(NULL),
50 : mRefCount(0),
51 : mData(NULL),
52 : mSize(size),
53 : mRangeOffset(0),
54 : mRangeLength(size),
55 : mOwnsData(true),
56 0 : mMetaData(new MetaData),
57 0 : mOriginal(NULL) {
58 0 : ensuresize(size);
59 0 : }
60 :
61 0 : MediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer)
62 : : mObserver(NULL),
63 : mNextBuffer(NULL),
64 : mRefCount(0),
65 : mData(NULL),
66 : mSize(1),
67 : mRangeOffset(0),
68 0 : mRangeLength(mSize),
69 : mGraphicBuffer(graphicBuffer),
70 : mOwnsData(false),
71 0 : mMetaData(new MetaData),
72 0 : mOriginal(NULL) {
73 0 : }
74 :
75 0 : MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
76 : : mObserver(NULL),
77 : mNextBuffer(NULL),
78 : mRefCount(0),
79 0 : mData(buffer->data()),
80 0 : mSize(buffer->size()),
81 : mRangeOffset(0),
82 0 : mRangeLength(mSize),
83 : mBuffer(buffer),
84 : mOwnsData(false),
85 0 : mMetaData(new MetaData),
86 0 : mOriginal(NULL) {
87 0 : }
88 :
89 0 : void MediaBuffer::release() {
90 0 : if (mObserver == NULL) {
91 0 : CHECK_EQ(mRefCount, 0);
92 0 : delete this;
93 0 : return;
94 : }
95 :
96 0 : int prevCount = __atomic_dec(&mRefCount);
97 0 : if (prevCount == 1) {
98 0 : if (mObserver == NULL) {
99 0 : delete this;
100 0 : return;
101 : }
102 :
103 0 : mObserver->signalBufferReturned(this);
104 : }
105 0 : CHECK(prevCount > 0);
106 : }
107 :
108 0 : void MediaBuffer::claim() {
109 0 : CHECK(mObserver != NULL);
110 0 : CHECK_EQ(mRefCount, 1);
111 :
112 0 : mRefCount = 0;
113 0 : }
114 :
115 0 : void MediaBuffer::add_ref() {
116 0 : (void) __atomic_inc(&mRefCount);
117 0 : }
118 :
119 0 : void *MediaBuffer::data() const {
120 0 : CHECK(mGraphicBuffer == NULL);
121 0 : return mData;
122 : }
123 :
124 0 : size_t MediaBuffer::size() const {
125 0 : CHECK(mGraphicBuffer == NULL);
126 0 : return mSize;
127 : }
128 :
129 0 : size_t MediaBuffer::range_offset() const {
130 0 : return mRangeOffset;
131 : }
132 :
133 0 : size_t MediaBuffer::range_length() const {
134 0 : return mRangeLength;
135 : }
136 :
137 0 : void MediaBuffer::set_range(size_t offset, size_t length) {
138 0 : if ((mGraphicBuffer == NULL) && (offset + length > mSize)) {
139 0 : ALOGE("offset = %" PRIuSIZE ", length = %" PRIuSIZE
140 : ", mSize = %" PRIuSIZE,
141 0 : offset, length, mSize);
142 : }
143 0 : CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize));
144 :
145 0 : mRangeOffset = offset;
146 0 : mRangeLength = length;
147 0 : }
148 :
149 0 : sp<GraphicBuffer> MediaBuffer::graphicBuffer() const {
150 0 : return mGraphicBuffer;
151 : }
152 :
153 0 : sp<MetaData> MediaBuffer::meta_data() {
154 0 : return mMetaData;
155 : }
156 :
157 0 : void MediaBuffer::reset() {
158 0 : mMetaData->clear();
159 0 : set_range(0, mSize);
160 0 : }
161 :
162 0 : MediaBuffer::~MediaBuffer() {
163 0 : CHECK(mObserver == NULL);
164 :
165 0 : if (mOriginal != NULL) {
166 0 : mOriginal->release();
167 0 : mOriginal = NULL;
168 : }
169 0 : }
170 :
171 0 : void MediaBuffer::setObserver(MediaBufferObserver *observer) {
172 0 : CHECK(observer == NULL || mObserver == NULL);
173 0 : mObserver = observer;
174 0 : }
175 :
176 0 : void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
177 0 : mNextBuffer = buffer;
178 0 : }
179 :
180 0 : MediaBuffer *MediaBuffer::nextBuffer() {
181 0 : return mNextBuffer;
182 : }
183 :
184 0 : int MediaBuffer::refcount() const {
185 0 : return mRefCount;
186 : }
187 :
188 0 : MediaBuffer *MediaBuffer::clone() {
189 0 : CHECK(mGraphicBuffer == NULL);
190 :
191 0 : MediaBuffer *buffer = new MediaBuffer(mData, mSize);
192 0 : buffer->set_range(mRangeOffset, mRangeLength);
193 0 : buffer->mMetaData = new MetaData(*mMetaData.get());
194 :
195 0 : add_ref();
196 0 : buffer->mOriginal = this;
197 :
198 0 : return buffer;
199 : }
200 :
201 0 : bool MediaBuffer::ensuresize(size_t length) {
202 0 : if (mBufferBackend.Length() >= length) {
203 0 : return true;
204 : }
205 : // Can't reallocate data we don't owned or shared with another.
206 0 : if (!mOwnsData || refcount()) {
207 0 : return false;
208 : }
209 0 : if (!mBufferBackend.SetLength(length, mozilla::fallible)) {
210 0 : return false;
211 : }
212 0 : mData = mBufferBackend.Elements();
213 0 : mSize = length;
214 0 : return true;
215 : }
216 :
217 : } // namespace stagefright
|