blob: 26d0bd40fb50a3ea1f1cf9aeaa8c46b834666d08 [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) {
Andy Hungcfa86b52016-07-29 19:25:07 -070054 if (size < kSharedMemThreshold
55 || std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
Marco Nelissenb65990f2015-11-09 15:39:49 -080056 mData = malloc(size);
57 } else {
Andy Hungf59c0ba2016-06-15 17:59:30 -070058 ALOGV("creating memoryDealer");
59 sp<MemoryDealer> memoryDealer =
60 new MemoryDealer(size + sizeof(SharedControl), "MediaBuffer");
61 mMemory = memoryDealer->allocate(size + sizeof(SharedControl));
Marco Nelissenb65990f2015-11-09 15:39:49 -080062 if (mMemory == NULL) {
63 ALOGW("Failed to allocate shared memory, trying regular allocation!");
64 mData = malloc(size);
65 if (mData == NULL) {
66 ALOGE("Out of memory");
67 }
68 } else {
Andy Hungf59c0ba2016-06-15 17:59:30 -070069 getSharedControl()->clear();
70 mData = (uint8_t *)mMemory->pointer() + sizeof(SharedControl);
Marco Nelissenb65990f2015-11-09 15:39:49 -080071 ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
72 }
73 }
Andreas Huber20111aa2009-07-14 16:56:47 -070074}
75
Andreas Huberf89d7802011-08-04 15:05:17 -070076MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
77 : mObserver(NULL),
Andreas Huberf89d7802011-08-04 15:05:17 -070078 mRefCount(0),
79 mData(buffer->data()),
80 mSize(buffer->size()),
81 mRangeOffset(0),
82 mRangeLength(mSize),
83 mBuffer(buffer),
84 mOwnsData(false),
Marco Nelissen32f45bf2018-12-12 09:02:47 -080085 mMetaData(new MetaDataBase) {
Andreas Huberf89d7802011-08-04 15:05:17 -070086}
87
Andreas Huber20111aa2009-07-14 16:56:47 -070088void MediaBuffer::release() {
89 if (mObserver == NULL) {
Andy Hung9bd3c9b2016-09-07 14:42:55 -070090 // Legacy contract for MediaBuffer without a MediaBufferGroup.
Andreas Huber0c891992009-08-26 14:48:20 -070091 CHECK_EQ(mRefCount, 0);
Andreas Huber20111aa2009-07-14 16:56:47 -070092 delete this;
93 return;
94 }
95
Hans Boehmb421f6e2018-05-07 11:50:21 -070096 int prevCount = mRefCount.fetch_sub(1);
Andreas Huber20111aa2009-07-14 16:56:47 -070097 if (prevCount == 1) {
98 if (mObserver == NULL) {
99 delete this;
100 return;
101 }
102
103 mObserver->signalBufferReturned(this);
104 }
Andreas Huber0c891992009-08-26 14:48:20 -0700105 CHECK(prevCount > 0);
Andreas Huber20111aa2009-07-14 16:56:47 -0700106}
107
108void MediaBuffer::claim() {
Andreas Huber0c891992009-08-26 14:48:20 -0700109 CHECK(mObserver != NULL);
Hans Boehmb421f6e2018-05-07 11:50:21 -0700110 CHECK_EQ(mRefCount.load(std::memory_order_relaxed), 1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700111
Hans Boehmb421f6e2018-05-07 11:50:21 -0700112 mRefCount.store(0, std::memory_order_relaxed);
Andreas Huber20111aa2009-07-14 16:56:47 -0700113}
114
115void MediaBuffer::add_ref() {
Hans Boehmb421f6e2018-05-07 11:50:21 -0700116 (void) mRefCount.fetch_add(1);
Andreas Huber20111aa2009-07-14 16:56:47 -0700117}
118
119void *MediaBuffer::data() const {
120 return mData;
121}
122
123size_t MediaBuffer::size() const {
124 return mSize;
125}
126
127size_t MediaBuffer::range_offset() const {
128 return mRangeOffset;
129}
130
131size_t MediaBuffer::range_length() const {
132 return mRangeLength;
133}
134
135void MediaBuffer::set_range(size_t offset, size_t length) {
Dongwon Kang2efe43d2017-11-22 11:34:19 -0800136 if (offset + length > mSize) {
Mark Salyzyna5750e02014-06-18 16:34:45 -0700137 ALOGE("offset = %zu, length = %zu, mSize = %zu", offset, length, mSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700138 }
Dongwon Kang2efe43d2017-11-22 11:34:19 -0800139 CHECK(offset + length <= mSize);
Andreas Huber20111aa2009-07-14 16:56:47 -0700140
141 mRangeOffset = offset;
142 mRangeLength = length;
143}
144
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800145MetaDataBase& MediaBuffer::meta_data() {
146 return *mMetaData;
Andreas Huber20111aa2009-07-14 16:56:47 -0700147}
148
149void MediaBuffer::reset() {
150 mMetaData->clear();
151 set_range(0, mSize);
152}
153
154MediaBuffer::~MediaBuffer() {
James Dongf1d5aa12012-02-06 23:46:37 -0800155 CHECK(mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700156
Marco Nelissenb65990f2015-11-09 15:39:49 -0800157 if (mOwnsData && mData != NULL && mMemory == NULL) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700158 free(mData);
159 mData = NULL;
160 }
161
Andy Hungf59c0ba2016-06-15 17:59:30 -0700162 if (mMemory.get() != nullptr) {
163 getSharedControl()->setDeadObject();
164 }
Marco Nelissen3d21ae32018-02-16 08:24:08 -0800165 delete mMetaData;
Andreas Huber20111aa2009-07-14 16:56:47 -0700166}
167
168void MediaBuffer::setObserver(MediaBufferObserver *observer) {
Andreas Huber0c891992009-08-26 14:48:20 -0700169 CHECK(observer == NULL || mObserver == NULL);
Andreas Huber20111aa2009-07-14 16:56:47 -0700170 mObserver = observer;
171}
172
Andreas Huber20111aa2009-07-14 16:56:47 -0700173} // namespace android