blob: dac3d50b07fd3b3e964f094cdeba4f1fdde905f8 [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),
42 mMetaData(new MetaData),
43 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),
54 mMetaData(new MetaData),
55 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),
87 mMetaData(new MetaData),
88 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
Elliott Hughes63492412014-05-22 14:20:39 -070099 int prevCount = __sync_fetch_and_sub(&mRefCount, 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);
113 CHECK_EQ(mRefCount, 1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700114
115 mRefCount = 0;
116}
117
118void MediaBuffer::add_ref() {
Elliott Hughes63492412014-05-22 14:20:39 -0700119 (void) __sync_fetch_and_add(&mRefCount, 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
148sp<MetaData> MediaBuffer::meta_data() {
149 return mMetaData;
150}
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 }
Andreas Huber20111aa2009-07-14 16:56:47 -0700173}
174
175void MediaBuffer::setObserver(MediaBufferObserver *observer) {
Andreas Huber0c891992009-08-26 14:48:20 -0700176 CHECK(observer == NULL || mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700177 mObserver = observer;
178}
179
Dongwon Kang1889c3e2018-02-01 13:44:57 -0800180MediaBufferBase *MediaBuffer::clone() {
Andreas Huber20111aa2009-07-14 16:56:47 -0700181 MediaBuffer *buffer = new MediaBuffer(mData, mSize);
182 buffer->set_range(mRangeOffset, mRangeLength);
183 buffer->mMetaData = new MetaData(*mMetaData.get());
184
185 add_ref();
186 buffer->mOriginal = this;
187
188 return buffer;
189}
190
191} // namespace android