blob: d197b3f0a7c4a5edfc7c20bc1291d253df1d2b40 [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
29namespace android {
30
Andy Hungcfa86b52016-07-29 19:25:07 -070031/* static */
32std::atomic_int_least32_t MediaBuffer::mUseSharedMemory(0);
33
Andreas Huber20111aa2009-07-14 16:56:47 -070034MediaBuffer::MediaBuffer(void *data, size_t size)
35 : mObserver(NULL),
Andreas Huber20111aa2009-07-14 16:56:47 -070036 mRefCount(0),
37 mData(data),
38 mSize(size),
39 mRangeOffset(0),
40 mRangeLength(size),
41 mOwnsData(false),
Hans Boehmb421f6e2018-05-07 11:50:21 -070042 mMetaData(new MetaDataBase),
Andreas Huber20111aa2009-07-14 16:56:47 -070043 mOriginal(NULL) {
44}
45
46MediaBuffer::MediaBuffer(size_t size)
47 : mObserver(NULL),
Andreas Huber20111aa2009-07-14 16:56:47 -070048 mRefCount(0),
Marco Nelissenb65990f2015-11-09 15:39:49 -080049 mData(NULL),
Andreas Huber20111aa2009-07-14 16:56:47 -070050 mSize(size),
51 mRangeOffset(0),
52 mRangeLength(size),
53 mOwnsData(true),
Hans Boehmb421f6e2018-05-07 11:50:21 -070054 mMetaData(new MetaDataBase),
Andreas Huber20111aa2009-07-14 16:56:47 -070055 mOriginal(NULL) {
Andy Hungcfa86b52016-07-29 19:25:07 -070056 if (size < kSharedMemThreshold
57 || std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
Marco Nelissenb65990f2015-11-09 15:39:49 -080058 mData = malloc(size);
59 } else {
Andy Hungf59c0ba2016-06-15 17:59:30 -070060 ALOGV("creating memoryDealer");
61 sp<MemoryDealer> memoryDealer =
62 new MemoryDealer(size + sizeof(SharedControl), "MediaBuffer");
63 mMemory = memoryDealer->allocate(size + sizeof(SharedControl));
Marco Nelissenb65990f2015-11-09 15:39:49 -080064 if (mMemory == NULL) {
65 ALOGW("Failed to allocate shared memory, trying regular allocation!");
66 mData = malloc(size);
67 if (mData == NULL) {
68 ALOGE("Out of memory");
69 }
70 } else {
Andy Hungf59c0ba2016-06-15 17:59:30 -070071 getSharedControl()->clear();
72 mData = (uint8_t *)mMemory->pointer() + sizeof(SharedControl);
Marco Nelissenb65990f2015-11-09 15:39:49 -080073 ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
74 }
75 }
Andreas Huber20111aa2009-07-14 16:56:47 -070076}
77
Andreas Huberf89d7802011-08-04 15:05:17 -070078MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
79 : mObserver(NULL),
Andreas Huberf89d7802011-08-04 15:05:17 -070080 mRefCount(0),
81 mData(buffer->data()),
82 mSize(buffer->size()),
83 mRangeOffset(0),
84 mRangeLength(mSize),
85 mBuffer(buffer),
86 mOwnsData(false),
Hans Boehmb421f6e2018-05-07 11:50:21 -070087 mMetaData(new MetaDataBase),
Andreas Huberf89d7802011-08-04 15:05:17 -070088 mOriginal(NULL) {
89}
90
Andreas Huber20111aa2009-07-14 16:56:47 -070091void MediaBuffer::release() {
92 if (mObserver == NULL) {
Andy Hung9bd3c9b2016-09-07 14:42:55 -070093 // Legacy contract for MediaBuffer without a MediaBufferGroup.
Andreas Huber0c891992009-08-26 14:48:20 -070094 CHECK_EQ(mRefCount, 0);
Andreas Huber20111aa2009-07-14 16:56:47 -070095 delete this;
96 return;
97 }
98
Hans Boehmb421f6e2018-05-07 11:50:21 -070099 int prevCount = mRefCount.fetch_sub(1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700100 if (prevCount == 1) {
101 if (mObserver == NULL) {
102 delete this;
103 return;
104 }
105
106 mObserver->signalBufferReturned(this);
107 }
Andreas Huber0c891992009-08-26 14:48:20 -0700108 CHECK(prevCount > 0);
Andreas Huber20111aa2009-07-14 16:56:47 -0700109}
110
111void MediaBuffer::claim() {
Andreas Huber0c891992009-08-26 14:48:20 -0700112 CHECK(mObserver != NULL);
Hans Boehmb421f6e2018-05-07 11:50:21 -0700113 CHECK_EQ(mRefCount.load(std::memory_order_relaxed), 1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700114
Hans Boehmb421f6e2018-05-07 11:50:21 -0700115 mRefCount.store(0, std::memory_order_relaxed);
Andreas Huber20111aa2009-07-14 16:56:47 -0700116}
117
118void MediaBuffer::add_ref() {
Hans Boehmb421f6e2018-05-07 11:50:21 -0700119 (void) mRefCount.fetch_add(1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700120}
121
122void *MediaBuffer::data() const {
123 return mData;
124}
125
126size_t MediaBuffer::size() const {
127 return mSize;
128}
129
130size_t MediaBuffer::range_offset() const {
131 return mRangeOffset;
132}
133
134size_t MediaBuffer::range_length() const {
135 return mRangeLength;
136}
137
138void MediaBuffer::set_range(size_t offset, size_t length) {
Dongwon Kang2efe43d2017-11-22 11:34:19 -0800139 if (offset + length > mSize) {
Mark Salyzyna5750e02014-06-18 16:34:45 -0700140 ALOGE("offset = %zu, length = %zu, mSize = %zu", offset, length, mSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700141 }
Dongwon Kang2efe43d2017-11-22 11:34:19 -0800142 CHECK(offset + length <= mSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700143
144 mRangeOffset = offset;
145 mRangeLength = length;
146}
147
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800148MetaDataBase& MediaBuffer::meta_data() {
149 return *mMetaData;
Andreas Huber20111aa2009-07-14 16:56:47 -0700150}
151
152void MediaBuffer::reset() {
153 mMetaData->clear();
154 set_range(0, mSize);
155}
156
157MediaBuffer::~MediaBuffer() {
James Dongf1d5aa12012-02-06 23:46:37 -0800158 CHECK(mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700159
Marco Nelissenb65990f2015-11-09 15:39:49 -0800160 if (mOwnsData && mData != NULL && mMemory == NULL) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700161 free(mData);
162 mData = NULL;
163 }
164
165 if (mOriginal != NULL) {
166 mOriginal->release();
167 mOriginal = NULL;
168 }
Andy Hungf59c0ba2016-06-15 17:59:30 -0700169
170 if (mMemory.get() != nullptr) {
171 getSharedControl()->setDeadObject();
172 }
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800173 delete mMetaData;
Andreas Huber20111aa2009-07-14 16:56:47 -0700174}
175
176void MediaBuffer::setObserver(MediaBufferObserver *observer) {
Andreas Huber0c891992009-08-26 14:48:20 -0700177 CHECK(observer == NULL || mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700178 mObserver = observer;
179}
180
Dongwon Kang1889c3e2018-02-01 13:44:57 -0800181MediaBufferBase *MediaBuffer::clone() {
Andreas Huber20111aa2009-07-14 16:56:47 -0700182 MediaBuffer *buffer = new MediaBuffer(mData, mSize);
183 buffer->set_range(mRangeOffset, mRangeLength);
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800184 buffer->mMetaData = new MetaDataBase(*mMetaData);
Andreas Huber20111aa2009-07-14 16:56:47 -0700185
186 add_ref();
187 buffer->mOriginal = this;
188
189 return buffer;
190}
191
192} // namespace android