1e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber/*
2e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Copyright (C) 2009 The Android Open Source Project
3e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
4e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * you may not use this file except in compliance with the License.
6e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * You may obtain a copy of the License at
7e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
8e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber *
10e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * Unless required by applicable law or agreed to in writing, software
11e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * See the License for the specific language governing permissions and
14e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber * limitations under the License.
15e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber */
16e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
17e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#define LOG_TAG "MediaBuffer"
18e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <utils/Log.h>
19e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
20e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <errno.h>
21e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <pthread.h>
22e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <stdlib.h>
23e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
24e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MediaBuffer.h>
25b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber#include <media/stagefright/MediaDebug.h>
26e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber#include <media/stagefright/MetaData.h>
27e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
28e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubernamespace android {
29e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
30e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber// XXX make this truly atomic.
31e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberstatic int atomic_add(int *value, int delta) {
32e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int prev_value = *value;
33e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    *value += delta;
34e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
35e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return prev_value;
36e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
37e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
38e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMediaBuffer::MediaBuffer(void *data, size_t size)
39e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mObserver(NULL),
40e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mNextBuffer(NULL),
41e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mRefCount(0),
42e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mData(data),
43e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mSize(size),
44e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mRangeOffset(0),
45e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mRangeLength(size),
46e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mOwnsData(false),
47e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mMetaData(new MetaData),
48e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mOriginal(NULL) {
49e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
50e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
51e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMediaBuffer::MediaBuffer(size_t size)
52e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    : mObserver(NULL),
53e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mNextBuffer(NULL),
54e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mRefCount(0),
55e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mData(malloc(size)),
56e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mSize(size),
57e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mRangeOffset(0),
58e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mRangeLength(size),
59e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mOwnsData(true),
60e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mMetaData(new MetaData),
61e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber      mOriginal(NULL) {
62e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
63e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
64e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid MediaBuffer::release() {
65e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mObserver == NULL) {
66b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber        CHECK_EQ(mRefCount, 0);
67e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        delete this;
68e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        return;
69e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
70e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
71e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    int prevCount = atomic_add(&mRefCount, -1);
72e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (prevCount == 1) {
73e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        if (mObserver == NULL) {
74e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            delete this;
75e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber            return;
76e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        }
77e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
78e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mObserver->signalBufferReturned(this);
79e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
80b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(prevCount > 0);
81e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
82e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
83e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid MediaBuffer::claim() {
84b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(mObserver != NULL);
85b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK_EQ(mRefCount, 1);
86e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
87e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mRefCount = 0;
88e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
89e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
90e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid MediaBuffer::add_ref() {
91e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    atomic_add(&mRefCount, 1);
92e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
93e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
94e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid *MediaBuffer::data() const {
95e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mData;
96e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
97e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
98e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersize_t MediaBuffer::size() const {
99e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mSize;
100e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
101e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
102e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersize_t MediaBuffer::range_offset() const {
103e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mRangeOffset;
104e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
105e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
106e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersize_t MediaBuffer::range_length() const {
107e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mRangeLength;
108e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
109e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
110e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid MediaBuffer::set_range(size_t offset, size_t length) {
111e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (offset < 0 || offset + length > mSize) {
112e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        LOGE("offset = %d, length = %d, mSize = %d", offset, length, mSize);
113e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
114b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(offset >= 0 && offset + length <= mSize);
115e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
116e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mRangeOffset = offset;
117e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mRangeLength = length;
118e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
119e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
120e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubersp<MetaData> MediaBuffer::meta_data() {
121e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mMetaData;
122e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
123e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
124e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid MediaBuffer::reset() {
125e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mMetaData->clear();
126e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    set_range(0, mSize);
127e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
128e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
129e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMediaBuffer::~MediaBuffer() {
130b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK_EQ(mObserver, NULL);
131e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
132e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mOwnsData && mData != NULL) {
133e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        free(mData);
134e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mData = NULL;
135e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
136e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
137e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    if (mOriginal != NULL) {
138e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mOriginal->release();
139e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber        mOriginal = NULL;
140e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    }
141e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
142e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
143e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid MediaBuffer::setObserver(MediaBufferObserver *observer) {
144b5ceb9ee21f37ae0817c16490c1fc148dd3eb5e2Andreas Huber    CHECK(observer == NULL || mObserver == NULL);
145e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mObserver = observer;
146e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
147e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
148e46b7be812d68e49710b34048662cbf18e2a6550Andreas Hubervoid MediaBuffer::setNextBuffer(MediaBuffer *buffer) {
149e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    mNextBuffer = buffer;
150e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
151e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
152e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMediaBuffer *MediaBuffer::nextBuffer() {
153e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mNextBuffer;
154e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
155e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
156e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huberint MediaBuffer::refcount() const {
157e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return mRefCount;
158e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
159e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
160e46b7be812d68e49710b34048662cbf18e2a6550Andreas HuberMediaBuffer *MediaBuffer::clone() {
161e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    MediaBuffer *buffer = new MediaBuffer(mData, mSize);
162e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    buffer->set_range(mRangeOffset, mRangeLength);
163e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    buffer->mMetaData = new MetaData(*mMetaData.get());
164e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
165e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    add_ref();
166e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    buffer->mOriginal = this;
167e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
168e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber    return buffer;
169e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}
170e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
171e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber}  // namespace android
172e46b7be812d68e49710b34048662cbf18e2a6550Andreas Huber
173