blob: bab3a03c4f225a940e293d4e99da7d6f57ddbfcb [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),
Marco Nelissen32f45bf2018-12-12 09:02:47 -080042 mMetaData(new MetaDataBase) {
Andreas Huber20111aa2009-07-14 16:56:47 -070043}
44
45MediaBuffer::MediaBuffer(size_t size)
46 : mObserver(NULL),
Andreas Huber20111aa2009-07-14 16:56:47 -070047 mRefCount(0),
Marco Nelissenb65990f2015-11-09 15:39:49 -080048 mData(NULL),
Andreas Huber20111aa2009-07-14 16:56:47 -070049 mSize(size),
50 mRangeOffset(0),
51 mRangeLength(size),
52 mOwnsData(true),
Marco Nelissen32f45bf2018-12-12 09:02:47 -080053 mMetaData(new MetaDataBase) {
Marco Nelissenff0508b2018-12-14 15:17:58 -080054#ifndef NO_IMEMORY
Andy Hungcfa86b52016-07-29 19:25:07 -070055 if (size < kSharedMemThreshold
56 || std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
Marco Nelissenff0508b2018-12-14 15:17:58 -080057#endif
Marco Nelissenb65990f2015-11-09 15:39:49 -080058 mData = malloc(size);
Marco Nelissenff0508b2018-12-14 15:17:58 -080059#ifndef NO_IMEMORY
Marco Nelissenb65990f2015-11-09 15:39:49 -080060 } else {
Andy Hungf59c0ba2016-06-15 17:59:30 -070061 ALOGV("creating memoryDealer");
62 sp<MemoryDealer> memoryDealer =
63 new MemoryDealer(size + sizeof(SharedControl), "MediaBuffer");
64 mMemory = memoryDealer->allocate(size + sizeof(SharedControl));
Marco Nelissenb65990f2015-11-09 15:39:49 -080065 if (mMemory == NULL) {
66 ALOGW("Failed to allocate shared memory, trying regular allocation!");
67 mData = malloc(size);
68 if (mData == NULL) {
69 ALOGE("Out of memory");
70 }
71 } else {
Andy Hungf59c0ba2016-06-15 17:59:30 -070072 getSharedControl()->clear();
73 mData = (uint8_t *)mMemory->pointer() + sizeof(SharedControl);
Marco Nelissenb65990f2015-11-09 15:39:49 -080074 ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
75 }
76 }
Marco Nelissenff0508b2018-12-14 15:17:58 -080077#endif
Andreas Huber20111aa2009-07-14 16:56:47 -070078}
79
Andreas Huberf89d7802011-08-04 15:05:17 -070080MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
81 : mObserver(NULL),
Andreas Huberf89d7802011-08-04 15:05:17 -070082 mRefCount(0),
83 mData(buffer->data()),
84 mSize(buffer->size()),
85 mRangeOffset(0),
86 mRangeLength(mSize),
87 mBuffer(buffer),
88 mOwnsData(false),
Marco Nelissen32f45bf2018-12-12 09:02:47 -080089 mMetaData(new MetaDataBase) {
Andreas Huberf89d7802011-08-04 15:05:17 -070090}
91
Andreas Huber20111aa2009-07-14 16:56:47 -070092void MediaBuffer::release() {
93 if (mObserver == NULL) {
Andy Hung9bd3c9b2016-09-07 14:42:55 -070094 // Legacy contract for MediaBuffer without a MediaBufferGroup.
Andreas Huber0c891992009-08-26 14:48:20 -070095 CHECK_EQ(mRefCount, 0);
Andreas Huber20111aa2009-07-14 16:56:47 -070096 delete this;
97 return;
98 }
99
Hans Boehmb421f6e2018-05-07 11:50:21 -0700100 int prevCount = mRefCount.fetch_sub(1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700101 if (prevCount == 1) {
102 if (mObserver == NULL) {
103 delete this;
104 return;
105 }
106
107 mObserver->signalBufferReturned(this);
108 }
Andreas Huber0c891992009-08-26 14:48:20 -0700109 CHECK(prevCount > 0);
Andreas Huber20111aa2009-07-14 16:56:47 -0700110}
111
112void MediaBuffer::claim() {
Andreas Huber0c891992009-08-26 14:48:20 -0700113 CHECK(mObserver != NULL);
Hans Boehmb421f6e2018-05-07 11:50:21 -0700114 CHECK_EQ(mRefCount.load(std::memory_order_relaxed), 1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700115
Hans Boehmb421f6e2018-05-07 11:50:21 -0700116 mRefCount.store(0, std::memory_order_relaxed);
Andreas Huber20111aa2009-07-14 16:56:47 -0700117}
118
119void MediaBuffer::add_ref() {
Hans Boehmb421f6e2018-05-07 11:50:21 -0700120 (void) mRefCount.fetch_add(1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700121}
122
123void *MediaBuffer::data() const {
124 return mData;
125}
126
127size_t MediaBuffer::size() const {
128 return mSize;
129}
130
131size_t MediaBuffer::range_offset() const {
132 return mRangeOffset;
133}
134
135size_t MediaBuffer::range_length() const {
136 return mRangeLength;
137}
138
139void MediaBuffer::set_range(size_t offset, size_t length) {
Dongwon Kang2efe43d2017-11-22 11:34:19 -0800140 if (offset + length > mSize) {
Mark Salyzyna5750e02014-06-18 16:34:45 -0700141 ALOGE("offset = %zu, length = %zu, mSize = %zu", offset, length, mSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700142 }
Dongwon Kang2efe43d2017-11-22 11:34:19 -0800143 CHECK(offset + length <= mSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700144
145 mRangeOffset = offset;
146 mRangeLength = length;
147}
148
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800149MetaDataBase& MediaBuffer::meta_data() {
150 return *mMetaData;
Andreas Huber20111aa2009-07-14 16:56:47 -0700151}
152
153void MediaBuffer::reset() {
154 mMetaData->clear();
155 set_range(0, mSize);
156}
157
158MediaBuffer::~MediaBuffer() {
James Dongf1d5aa12012-02-06 23:46:37 -0800159 CHECK(mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700160
Marco Nelissenb65990f2015-11-09 15:39:49 -0800161 if (mOwnsData && mData != NULL && mMemory == NULL) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700162 free(mData);
163 mData = NULL;
164 }
165
Andy Hungf59c0ba2016-06-15 17:59:30 -0700166 if (mMemory.get() != nullptr) {
167 getSharedControl()->setDeadObject();
168 }
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800169 delete mMetaData;
Andreas Huber20111aa2009-07-14 16:56:47 -0700170}
171
172void MediaBuffer::setObserver(MediaBufferObserver *observer) {
Andreas Huber0c891992009-08-26 14:48:20 -0700173 CHECK(observer == NULL || mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700174 mObserver = observer;
175}
176
Andreas Huber20111aa2009-07-14 16:56:47 -0700177} // namespace android