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),
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mData(malloc(size)),
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) {
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
596a9da9fc558263548ebfbae2cbf177eb7454a41bJamie GennisMediaBuffer::MediaBuffer(const sp<GraphicBuffer>& graphicBuffer)
606a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    : mObserver(NULL),
616a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mNextBuffer(NULL),
626a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mRefCount(0),
636a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mData(NULL),
646a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mSize(1),
656a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mRangeOffset(0),
666a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mRangeLength(mSize),
676a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mGraphicBuffer(graphicBuffer),
686a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mOwnsData(false),
696a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mMetaData(new MetaData),
706a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis      mOriginal(NULL) {
716a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis}
726a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
73f89d780df70b7fbb8465bce4913c46cca019721fAndreas HuberMediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
74f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber    : mObserver(NULL),
75f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mNextBuffer(NULL),
76f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mRefCount(0),
77f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mData(buffer->data()),
78f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mSize(buffer->size()),
79f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mRangeOffset(0),
80f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mRangeLength(mSize),
81f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mBuffer(buffer),
82f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mOwnsData(false),
83f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mMetaData(new MetaData),
84f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber      mOriginal(NULL) {
85f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber}
86f89d780df70b7fbb8465bce4913c46cca019721fAndreas Huber
8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::release() {
8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mObserver == NULL) {
890c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber        CHECK_EQ(mRefCount, 0);
9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        delete this;
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return;
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9463492411cf4abff452b47f59ec7ff6f3e9925c84Elliott Hughes    int prevCount = __sync_fetch_and_sub(&mRefCount, 1);
9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (prevCount == 1) {
9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mObserver == NULL) {
9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            delete this;
9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return;
9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mObserver->signalBufferReturned(this);
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
1030c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(prevCount > 0);
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::claim() {
1070c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mObserver != NULL);
1080c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK_EQ(mRefCount, 1);
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mRefCount = 0;
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::add_ref() {
11463492411cf4abff452b47f59ec7ff6f3e9925c84Elliott Hughes    (void) __sync_fetch_and_add(&mRefCount, 1);
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid *MediaBuffer::data() const {
1186a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    CHECK(mGraphicBuffer == NULL);
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mData;
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::size() const {
1236a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    CHECK(mGraphicBuffer == NULL);
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mSize;
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::range_offset() const {
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mRangeOffset;
12920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
13020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::range_length() const {
13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mRangeLength;
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::set_range(size_t offset, size_t length) {
1366a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    if ((mGraphicBuffer == NULL) && (offset + length > mSize)) {
137a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGE("offset = %zu, length = %zu, mSize = %zu", offset, length, mSize);
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
1396a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    CHECK((mGraphicBuffer != NULL) || (offset + length <= mSize));
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mRangeOffset = offset;
14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mRangeLength = length;
14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
14420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1456a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennissp<GraphicBuffer> MediaBuffer::graphicBuffer() const {
1466a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis    return mGraphicBuffer;
1476a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis}
1486a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MediaBuffer::meta_data() {
15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mMetaData;
15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::reset() {
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mMetaData->clear();
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    set_range(0, mSize);
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer::~MediaBuffer() {
159f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(mObserver == NULL);
16020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mOwnsData && mData != NULL) {
16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        free(mData);
16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mData = NULL;
16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mOriginal != NULL) {
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mOriginal->release();
16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mOriginal = NULL;
16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::setObserver(MediaBufferObserver *observer) {
1730c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(observer == NULL || mObserver == NULL);
17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mObserver = observer;
17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNextBuffer = buffer;
17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer *MediaBuffer::nextBuffer() {
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNextBuffer;
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint MediaBuffer::refcount() const {
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mRefCount;
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer *MediaBuffer::clone() {
190f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong    CHECK(mGraphicBuffer == NULL);
1916a9da9fc558263548ebfbae2cbf177eb7454a41bJamie Gennis
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBuffer *buffer = new MediaBuffer(mData, mSize);
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    buffer->set_range(mRangeOffset, mRangeLength);
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    buffer->mMetaData = new MetaData(*mMetaData.get());
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    add_ref();
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    buffer->mOriginal = this;
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return buffer;
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
203