blob: b973745b641f06d96510d256accc80a1fbac21a3 [file] [log] [blame]
Andreas Hubere46b7be2009-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 Hubere46b7be2009-07-14 16:56:47 -070020#include <errno.h>
21#include <pthread.h>
22#include <stdlib.h>
23
24#include <media/stagefright/MediaBuffer.h>
Andreas Huberb5ceb9e2009-08-26 14:48:20 -070025#include <media/stagefright/MediaDebug.h>
Andreas Hubere46b7be2009-07-14 16:56:47 -070026#include <media/stagefright/MetaData.h>
27
28namespace android {
29
30// XXX make this truly atomic.
31static int atomic_add(int *value, int delta) {
32 int prev_value = *value;
33 *value += delta;
34
35 return prev_value;
36}
37
38MediaBuffer::MediaBuffer(void *data, size_t size)
39 : mObserver(NULL),
40 mNextBuffer(NULL),
41 mRefCount(0),
42 mData(data),
43 mSize(size),
44 mRangeOffset(0),
45 mRangeLength(size),
46 mOwnsData(false),
47 mMetaData(new MetaData),
48 mOriginal(NULL) {
49}
50
51MediaBuffer::MediaBuffer(size_t size)
52 : mObserver(NULL),
53 mNextBuffer(NULL),
54 mRefCount(0),
55 mData(malloc(size)),
56 mSize(size),
57 mRangeOffset(0),
58 mRangeLength(size),
59 mOwnsData(true),
60 mMetaData(new MetaData),
61 mOriginal(NULL) {
62}
63
64void MediaBuffer::release() {
65 if (mObserver == NULL) {
Andreas Huberb5ceb9e2009-08-26 14:48:20 -070066 CHECK_EQ(mRefCount, 0);
Andreas Hubere46b7be2009-07-14 16:56:47 -070067 delete this;
68 return;
69 }
70
71 int prevCount = atomic_add(&mRefCount, -1);
72 if (prevCount == 1) {
73 if (mObserver == NULL) {
74 delete this;
75 return;
76 }
77
78 mObserver->signalBufferReturned(this);
79 }
Andreas Huberb5ceb9e2009-08-26 14:48:20 -070080 CHECK(prevCount > 0);
Andreas Hubere46b7be2009-07-14 16:56:47 -070081}
82
83void MediaBuffer::claim() {
Andreas Huberb5ceb9e2009-08-26 14:48:20 -070084 CHECK(mObserver != NULL);
85 CHECK_EQ(mRefCount, 1);
Andreas Hubere46b7be2009-07-14 16:56:47 -070086
87 mRefCount = 0;
88}
89
90void MediaBuffer::add_ref() {
91 atomic_add(&mRefCount, 1);
92}
93
94void *MediaBuffer::data() const {
95 return mData;
96}
97
98size_t MediaBuffer::size() const {
99 return mSize;
100}
101
102size_t MediaBuffer::range_offset() const {
103 return mRangeOffset;
104}
105
106size_t MediaBuffer::range_length() const {
107 return mRangeLength;
108}
109
110void MediaBuffer::set_range(size_t offset, size_t length) {
Andreas Huber8d87cd92009-10-13 10:06:37 -0700111 if (offset + length > mSize) {
Andreas Hubere46b7be2009-07-14 16:56:47 -0700112 LOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize);
113 }
Andreas Huber8d87cd92009-10-13 10:06:37 -0700114 CHECK(offset + length <= mSize);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700115
116 mRangeOffset = offset;
117 mRangeLength = length;
118}
119
120sp<MetaData> MediaBuffer::meta_data() {
121 return mMetaData;
122}
123
124void MediaBuffer::reset() {
125 mMetaData->clear();
126 set_range(0, mSize);
127}
128
129MediaBuffer::~MediaBuffer() {
Andreas Huberb5ceb9e2009-08-26 14:48:20 -0700130 CHECK_EQ(mObserver, NULL);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700131
132 if (mOwnsData && mData != NULL) {
133 free(mData);
134 mData = NULL;
135 }
136
137 if (mOriginal != NULL) {
138 mOriginal->release();
139 mOriginal = NULL;
140 }
141}
142
143void MediaBuffer::setObserver(MediaBufferObserver *observer) {
Andreas Huberb5ceb9e2009-08-26 14:48:20 -0700144 CHECK(observer == NULL || mObserver == NULL);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700145 mObserver = observer;
146}
147
148void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
149 mNextBuffer = buffer;
150}
151
152MediaBuffer *MediaBuffer::nextBuffer() {
153 return mNextBuffer;
154}
155
156int MediaBuffer::refcount() const {
157 return mRefCount;
158}
159
160MediaBuffer *MediaBuffer::clone() {
161 MediaBuffer *buffer = new MediaBuffer(mData, mSize);
162 buffer->set_range(mRangeOffset, mRangeLength);
163 buffer->mMetaData = new MetaData(*mMetaData.get());
164
165 add_ref();
166 buffer->mOriginal = this;
167
168 return buffer;
169}
170
171} // namespace android
172