120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/* 220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project 320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License. 620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at 720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * 1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software 1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and 1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License. 1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */ 1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "MediaBuffer" 1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h> 1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <errno.h> 2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <pthread.h> 2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <stdlib.h> 2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 24f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber#include <media/stagefright/foundation/ABuffer.h> 25f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h> 2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h> 2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 296a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis#include <ui/GraphicBuffer.h> 306a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis 3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android { 3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 3320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer::MediaBuffer(void *data, size_t size) 3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mObserver(NULL), 3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNextBuffer(NULL), 3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRefCount(0), 3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mData(data), 3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSize(size), 3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRangeOffset(0), 4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRangeLength(size), 4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mOwnsData(false), 4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mMetaData(new MetaData), 4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mOriginal(NULL) { 4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 4620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer::MediaBuffer(size_t size) 4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber : mObserver(NULL), 4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNextBuffer(NULL), 4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRefCount(0), 50b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen mData(NULL), 5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mSize(size), 5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRangeOffset(0), 5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRangeLength(size), 5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mOwnsData(true), 5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mMetaData(new MetaData), 5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mOriginal(NULL) { 57b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (size < kSharedMemThreshold) { 58b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen mData = malloc(size); 59b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } else { 60b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen sp<MemoryDealer> memoryDealer = new MemoryDealer(size, "MediaBuffer"); 61b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen mMemory = memoryDealer->allocate(size); 62b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (mMemory == NULL) { 63b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen ALOGW("Failed to allocate shared memory, trying regular allocation!"); 64b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen mData = malloc(size); 65b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (mData == NULL) { 66b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen ALOGE("Out of memory"); 67b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } 68b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } else { 69b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen mData = mMemory->pointer(); 70b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData); 71b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } 72b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen } 7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 756a9da9fc558263548ebfbae2cbf177eb7454a41bJamie GennisMediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer) 766a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis : mObserver(NULL), 776a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mNextBuffer(NULL), 786a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mRefCount(0), 796a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mData(NULL), 806a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mSize(1), 816a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mRangeOffset(0), 826a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mRangeLength(mSize), 836a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mGraphicBuffer(graphicBuffer), 846a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mOwnsData(false), 856a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mMetaData(new MetaData), 866a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis mOriginal(NULL) { 876a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis} 886a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis 89f89d780df70b7fbb8465bce4913c46cca019721fAndreas HuberMediaBuffer::MediaBuffer(const sp<ABuffer> &buffer) 90f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber : mObserver(NULL), 91f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mNextBuffer(NULL), 92f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mRefCount(0), 93f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mData(buffer->data()), 94f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mSize(buffer->size()), 95f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mRangeOffset(0), 96f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mRangeLength(mSize), 97f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mBuffer(buffer), 98f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mOwnsData(false), 99f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mMetaData(new MetaData), 100f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber mOriginal(NULL) { 101f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber} 102f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber 10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::release() { 10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mObserver == NULL) { 1050c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK_EQ(mRefCount, 0); 10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete this; 10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return; 10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11063492411cf4abff452b47f59ec7ff6f3e9925c84Elliott Hughes int prevCount = __sync_fetch_and_sub(&mRefCount, 1); 11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (prevCount == 1) { 11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mObserver == NULL) { 11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber delete this; 11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return; 11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mObserver->signalBufferReturned(this); 11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1190c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(prevCount > 0); 12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::claim() { 1230c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(mObserver != NULL); 1240c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK_EQ(mRefCount, 1); 12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRefCount = 0; 12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::add_ref() { 13063492411cf4abff452b47f59ec7ff6f3e9925c84Elliott Hughes (void) __sync_fetch_and_add(&mRefCount, 1); 13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid *MediaBuffer::data() const { 1346a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis CHECK(mGraphicBuffer == NULL); 13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mData; 13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::size() const { 1396a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis CHECK(mGraphicBuffer == NULL); 14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mSize; 14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::range_offset() const { 14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mRangeOffset; 14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::range_length() const { 14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mRangeLength; 14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::set_range(size_t offset, size_t length) { 1526a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis if ((mGraphicBuffer == NULL) && (offset + length > mSize)) { 153a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn ALOGE("offset = %zu, length = %zu, mSize = %zu", offset, length, mSize); 15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 1556a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize)); 15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRangeOffset = offset; 15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mRangeLength = length; 15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 1616a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennissp<GraphicBuffer> MediaBuffer::graphicBuffer() const { 1626a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis return mGraphicBuffer; 1636a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis} 1646a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis 16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MediaBuffer::meta_data() { 16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mMetaData; 16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::reset() { 17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mMetaData->clear(); 17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber set_range(0, mSize); 17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 17420111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer::~MediaBuffer() { 175f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(mObserver == NULL); 17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 177b65990f4a0cf01db0b9f21c68fcf8824ae03a178Marco Nelissen if (mOwnsData && mData != NULL && mMemory == NULL) { 17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber free(mData); 17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mData = NULL; 18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber if (mOriginal != NULL) { 18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mOriginal->release(); 18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mOriginal = NULL; 18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber } 18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::setObserver(MediaBufferObserver *observer) { 1890c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber CHECK(observer == NULL || mObserver == NULL); 19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mObserver = observer; 19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::setNextBuffer(MediaBuffer *buffer) { 19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber mNextBuffer = buffer; 19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 19720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer *MediaBuffer::nextBuffer() { 19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mNextBuffer; 19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint MediaBuffer::refcount() const { 20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return mRefCount; 20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 20520111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer *MediaBuffer::clone() { 206f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(mGraphicBuffer == NULL); 2076a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis 20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber MediaBuffer *buffer = new MediaBuffer(mData, mSize); 20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->set_range(mRangeOffset, mRangeLength); 21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->mMetaData = new MetaData(*mMetaData.get()); 21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber add_ref(); 21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber buffer->mOriginal = this; 21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber return buffer; 21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} 21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber 21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber} // namespace android 219