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 "MediaBufferGroup"
1820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
2120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBuffer.h>
2220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/MediaBufferGroup.h>
2320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2620111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBufferGroup::MediaBufferGroup()
2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mFirstBuffer(NULL),
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mLastBuffer(NULL) {
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberMediaBufferGroup::~MediaBufferGroup() {
3220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    MediaBuffer *next;
3320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (MediaBuffer *buffer = mFirstBuffer; buffer != NULL;
3420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber         buffer = next) {
3520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        next = buffer->nextBuffer();
3620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
370c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber        CHECK_EQ(buffer->refcount(), 0);
3820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        buffer->setObserver(NULL);
4020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        buffer->release();
4120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
4320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4420111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBufferGroup::add_buffer(MediaBuffer *buffer) {
4520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
4620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    buffer->setObserver(this);
4820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mLastBuffer) {
5020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mLastBuffer->setNextBuffer(buffer);
5120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
5220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mFirstBuffer = buffer;
5320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
5420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mLastBuffer = buffer;
5620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
5720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
58c9a11abbb6b48604ea063daedd6118024cfbfa92Lajos Molnarstatus_t MediaBufferGroup::acquire_buffer(
59c9a11abbb6b48604ea063daedd6118024cfbfa92Lajos Molnar        MediaBuffer **out, bool nonBlocking) {
6020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
6120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (;;) {
6320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        for (MediaBuffer *buffer = mFirstBuffer;
6420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber             buffer != NULL; buffer = buffer->nextBuffer()) {
6520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            if (buffer->refcount() == 0) {
6620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                buffer->add_ref();
6720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                buffer->reset();
6820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                *out = buffer;
7020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                goto exit;
7120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
7220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
7320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
74c9a11abbb6b48604ea063daedd6118024cfbfa92Lajos Molnar        if (nonBlocking) {
75c9a11abbb6b48604ea063daedd6118024cfbfa92Lajos Molnar            *out = NULL;
76c9a11abbb6b48604ea063daedd6118024cfbfa92Lajos Molnar            return WOULD_BLOCK;
77c9a11abbb6b48604ea063daedd6118024cfbfa92Lajos Molnar        }
78c9a11abbb6b48604ea063daedd6118024cfbfa92Lajos Molnar
7920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // All buffers are in use. Block until one of them is returned to us.
8020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mCondition.wait(mLock);
8120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
8220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberexit:
8420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
8520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
8620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8720111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubervoid MediaBufferGroup::signalBufferReturned(MediaBuffer *) {
8820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
8920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mCondition.signal();
9020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
9120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
9220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
93