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