• 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/MediaBuffer.h>
25 #include <media/stagefright/MediaDebug.h>
26 #include <media/stagefright/MetaData.h>
27 
28 namespace android {
29 
30 // XXX make this truly atomic.
atomic_add(int * value,int delta)31 static int atomic_add(int *value, int delta) {
32     int prev_value = *value;
33     *value += delta;
34 
35     return prev_value;
36 }
37 
MediaBuffer(void * data,size_t size)38 MediaBuffer::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 
MediaBuffer(size_t size)51 MediaBuffer::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 
release()64 void MediaBuffer::release() {
65     if (mObserver == NULL) {
66         CHECK_EQ(mRefCount, 0);
67         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     }
80     CHECK(prevCount > 0);
81 }
82 
claim()83 void MediaBuffer::claim() {
84     CHECK(mObserver != NULL);
85     CHECK_EQ(mRefCount, 1);
86 
87     mRefCount = 0;
88 }
89 
add_ref()90 void MediaBuffer::add_ref() {
91     atomic_add(&mRefCount, 1);
92 }
93 
data() const94 void *MediaBuffer::data() const {
95     return mData;
96 }
97 
size() const98 size_t MediaBuffer::size() const {
99     return mSize;
100 }
101 
range_offset() const102 size_t MediaBuffer::range_offset() const {
103     return mRangeOffset;
104 }
105 
range_length() const106 size_t MediaBuffer::range_length() const {
107     return mRangeLength;
108 }
109 
set_range(size_t offset,size_t length)110 void MediaBuffer::set_range(size_t offset, size_t length) {
111     if (offset < 0 || offset + length > mSize) {
112         LOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize);
113     }
114     CHECK(offset >= 0 && offset + length <= mSize);
115 
116     mRangeOffset = offset;
117     mRangeLength = length;
118 }
119 
meta_data()120 sp<MetaData> MediaBuffer::meta_data() {
121     return mMetaData;
122 }
123 
reset()124 void MediaBuffer::reset() {
125     mMetaData->clear();
126     set_range(0, mSize);
127 }
128 
~MediaBuffer()129 MediaBuffer::~MediaBuffer() {
130     CHECK_EQ(mObserver, NULL);
131 
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 
setObserver(MediaBufferObserver * observer)143 void MediaBuffer::setObserver(MediaBufferObserver *observer) {
144     CHECK(observer == NULL || mObserver == NULL);
145     mObserver = observer;
146 }
147 
setNextBuffer(MediaBuffer * buffer)148 void MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
149     mNextBuffer = buffer;
150 }
151 
nextBuffer()152 MediaBuffer *MediaBuffer::nextBuffer() {
153     return mNextBuffer;
154 }
155 
refcount() const156 int MediaBuffer::refcount() const {
157     return mRefCount;
158 }
159 
clone()160 MediaBuffer *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 
173