blob: 11b80bf42429baed71658a0f9b54e764bb6eb4e4 [file] [log] [blame]
Andreas Huber20111aa2009-07-14 16:56:47 -07001/*
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
Andreas Huber20111aa2009-07-14 16:56:47 -070020#include <errno.h>
21#include <pthread.h>
22#include <stdlib.h>
23
Andreas Huberf89d7802011-08-04 15:05:17 -070024#include <media/stagefright/foundation/ABuffer.h>
James Dongf1d5aa12012-02-06 23:46:37 -080025#include <media/stagefright/foundation/ADebug.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070026#include <media/stagefright/MediaBuffer.h>
27#include <media/stagefright/MetaData.h>
28
Jamie Gennis6a9da9f2010-10-07 14:08:38 -070029#include <ui/GraphicBuffer.h>
Glenn Kasten4dafe5b2011-01-12 09:22:07 -080030#include <sys/atomics.h>
Jamie Gennis6a9da9f2010-10-07 14:08:38 -070031
Andreas Huber20111aa2009-07-14 16:56:47 -070032namespace android {
33
Andreas Huber20111aa2009-07-14 16:56:47 -070034MediaBuffer::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
47MediaBuffer::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
Jamie Gennis6a9da9f2010-10-07 14:08:38 -070060MediaBuffer::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
Andreas Huberf89d7802011-08-04 15:05:17 -070074MediaBuffer::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
Andreas Huber20111aa2009-07-14 16:56:47 -070088void MediaBuffer::release() {
89 if (mObserver == NULL) {
Andreas Huber0c891992009-08-26 14:48:20 -070090 CHECK_EQ(mRefCount, 0);
Andreas Huber20111aa2009-07-14 16:56:47 -070091 delete this;
92 return;
93 }
94
Glenn Kasten4dafe5b2011-01-12 09:22:07 -080095 int prevCount = __atomic_dec(&mRefCount);
Andreas Huber20111aa2009-07-14 16:56:47 -070096 if (prevCount == 1) {
97 if (mObserver == NULL) {
98 delete this;
99 return;
100 }
101
102 mObserver->signalBufferReturned(this);
103 }
Andreas Huber0c891992009-08-26 14:48:20 -0700104 CHECK(prevCount > 0);
Andreas Huber20111aa2009-07-14 16:56:47 -0700105}
106
107void MediaBuffer::claim() {
Andreas Huber0c891992009-08-26 14:48:20 -0700108 CHECK(mObserver != NULL);
109 CHECK_EQ(mRefCount, 1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700110
111 mRefCount = 0;
112}
113
114void MediaBuffer::add_ref() {
Glenn Kasten4dafe5b2011-01-12 09:22:07 -0800115 (void) __atomic_inc(&mRefCount);
Andreas Huber20111aa2009-07-14 16:56:47 -0700116}
117
118void *MediaBuffer::data() const {
Jamie Gennis6a9da9f2010-10-07 14:08:38 -0700119 CHECK(mGraphicBuffer == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700120 return mData;
121}
122
123size_t MediaBuffer::size() const {
Jamie Gennis6a9da9f2010-10-07 14:08:38 -0700124 CHECK(mGraphicBuffer == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700125 return mSize;
126}
127
128size_t MediaBuffer::range_offset() const {
129 return mRangeOffset;
130}
131
132size_t MediaBuffer::range_length() const {
133 return mRangeLength;
134}
135
136void MediaBuffer::set_range(size_t offset, size_t length) {
Jamie Gennis6a9da9f2010-10-07 14:08:38 -0700137 if ((mGraphicBuffer == NULL) && (offset + length > mSize)) {
Steve Block29357bc2012-01-06 19:20:56 +0000138 ALOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700139 }
Jamie Gennis6a9da9f2010-10-07 14:08:38 -0700140 CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize));
Andreas Huber20111aa2009-07-14 16:56:47 -0700141
142 mRangeOffset = offset;
143 mRangeLength = length;
144}
145
Jamie Gennis6a9da9f2010-10-07 14:08:38 -0700146sp<GraphicBuffer> MediaBuffer::graphicBuffer() const {
147 return mGraphicBuffer;
148}
149
Andreas Huber20111aa2009-07-14 16:56:47 -0700150sp<MetaData> MediaBuffer::meta_data() {
151 return mMetaData;
152}
153
154void MediaBuffer::reset() {
155 mMetaData->clear();
156 set_range(0, mSize);
157}
158
159MediaBuffer::~MediaBuffer() {
James Dongf1d5aa12012-02-06 23:46:37 -0800160 CHECK(mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700161
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
173void MediaBuffer::setObserver(MediaBufferObserver *observer) {
Andreas Huber0c891992009-08-26 14:48:20 -0700174 CHECK(observer == NULL || mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700175 mObserver = observer;
176}
177
178void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
179 mNextBuffer = buffer;
180}
181
182MediaBuffer *MediaBuffer::nextBuffer() {
183 return mNextBuffer;
184}
185
186int MediaBuffer::refcount() const {
187 return mRefCount;
188}
189
190MediaBuffer *MediaBuffer::clone() {
James Dongf1d5aa12012-02-06 23:46:37 -0800191 CHECK(mGraphicBuffer == NULL);
Jamie Gennis6a9da9f2010-10-07 14:08:38 -0700192
Andreas Huber20111aa2009-07-14 16:56:47 -0700193 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