MediaBuffer.cpp revision 0c89199745bc1bf05b997fc7c342017807676b6f
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
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h>
250c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber#include <media/stagefright/MediaDebug.h>
2620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MetaData.h>
2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber// XXX make this truly atomic.
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatic int atomic_add(int *value, int delta) {
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int prev_value = *value;
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *value += delta;
3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return prev_value;
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
3720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer::MediaBuffer(void *data, size_t size)
3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mObserver(NULL),
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNextBuffer(NULL),
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mRefCount(0),
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mData(data),
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSize(size),
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mRangeOffset(0),
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mRangeLength(size),
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mOwnsData(false),
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mMetaData(new MetaData),
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mOriginal(NULL) {
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer::MediaBuffer(size_t size)
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mObserver(NULL),
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNextBuffer(NULL),
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mRefCount(0),
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mData(malloc(size)),
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSize(size),
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mRangeOffset(0),
5820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mRangeLength(size),
5920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mOwnsData(true),
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mMetaData(new MetaData),
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mOriginal(NULL) {
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::release() {
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mObserver == NULL) {
660c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber        CHECK_EQ(mRefCount, 0);
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        delete this;
6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return;
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    int prevCount = atomic_add(&mRefCount, -1);
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (prevCount == 1) {
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mObserver == NULL) {
7420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            delete this;
7520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return;
7620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
7720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mObserver->signalBufferReturned(this);
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
800c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(prevCount > 0);
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::claim() {
840c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(mObserver != NULL);
850c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK_EQ(mRefCount, 1);
8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mRefCount = 0;
8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::add_ref() {
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    atomic_add(&mRefCount, 1);
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
9320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid *MediaBuffer::data() const {
9520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mData;
9620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
9720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::size() const {
9920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mSize;
10020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10220111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::range_offset() const {
10320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mRangeOffset;
10420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
10620111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersize_t MediaBuffer::range_length() const {
10720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mRangeLength;
10820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::set_range(size_t offset, size_t length) {
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (offset < 0 || offset + length > mSize) {
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        LOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize);
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
1140c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(offset >= 0 && offset + length <= mSize);
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mRangeOffset = offset;
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mRangeLength = length;
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubersp<MetaData> MediaBuffer::meta_data() {
12120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mMetaData;
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
12320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::reset() {
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mMetaData->clear();
12620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    set_range(0, mSize);
12720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
12920111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer::~MediaBuffer() {
1300c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK_EQ(mObserver, NULL);
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mOwnsData && mData != NULL) {
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        free(mData);
13420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mData = NULL;
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mOriginal != NULL) {
13820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mOriginal->release();
13920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mOriginal = NULL;
14020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
14120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
14220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14320111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::setObserver(MediaBufferObserver *observer) {
1440c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(observer == NULL || mObserver == NULL);
14520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mObserver = observer;
14620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
14720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
14820111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNextBuffer = buffer;
15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15220111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer *MediaBuffer::nextBuffer() {
15320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNextBuffer;
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
15620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberint MediaBuffer::refcount() const {
15720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mRefCount;
15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16020111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBuffer *MediaBuffer::clone() {
16120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBuffer *buffer = new MediaBuffer(mData, mSize);
16220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    buffer->set_range(mRangeOffset, mRangeLength);
16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    buffer->mMetaData = new MetaData(*mMetaData.get());
16420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    add_ref();
16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    buffer->mOriginal = this;
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return buffer;
16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
173