17ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/*
27ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * Copyright (C) 2011 The Android Open Source Project
37ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens *
47ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * Licensed under the Apache License, Version 2.0 (the "License");
57ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * you may not use this file except in compliance with the License.
67ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * You may obtain a copy of the License at
77ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens *
87ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens *      http://www.apache.org/licenses/LICENSE-2.0
97ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens *
107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * Unless required by applicable law or agreed to in writing, software
117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * distributed under the License is distributed on an "AS IS" BASIS,
127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * See the License for the specific language governing permissions and
147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens * limitations under the License.
157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens */
167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//#define LOG_NDEBUG 0
172df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#define LOG_TAG "SurfaceMediaSource"
187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include <inttypes.h>
207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
212df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <media/stagefright/foundation/ADebug.h>
222df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <media/stagefright/SurfaceMediaSource.h>
232df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <media/stagefright/MediaDefs.h>
247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include <media/stagefright/MetaData.h>
257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include <OMX_IVCommon.h>
267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include <media/hardware/HardwareAPI.h>
272df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <media/hardware/MetadataBufferType.h>
282df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens
292df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <ui/GraphicBuffer.h>
302df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <gui/BufferItem.h>
312df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <gui/ISurfaceComposer.h>
322df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <OMX_Component.h>
332df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens
342df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <utils/Log.h>
352df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <utils/String8.h>
362df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens
372df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens#include <private/gui/ComposerService.h>
387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensnamespace android {
407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas CapensSurfaceMediaSource::SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight) :
422df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    mWidth(bufferWidth),
437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mHeight(bufferHeight),
447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mCurrentSlot(BufferQueue::INVALID_BUFFER_SLOT),
457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mNumPendingBuffers(0),
467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mCurrentTimestamp(0),
477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mFrameRate(30),
482df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    mStarted(false),
497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mNumFramesReceived(0),
507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mNumFramesEncoded(0),
517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mFirstFrameTimestamp(0),
527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mMaxAcquiredBufferCount(4),  // XXX double-check the default
537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mUseAbsoluteTimestamps(false) {
547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("SurfaceMediaSource");
557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (bufferWidth == 0 || bufferHeight == 0) {
577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        ALOGE("Invalid dimensions %dx%d", bufferWidth, bufferHeight);
587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    BufferQueue::createBufferQueue(&mProducer, &mConsumer);
617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight);
627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER |
637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            GRALLOC_USAGE_HW_TEXTURE);
647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // reference once the ctor ends, as that would cause the refcount of 'this'
697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // that's what we create.
717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    status_t err = mConsumer->consumerConnect(proxy, false);
757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (err != NO_ERROR) {
767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        ALOGE("SurfaceMediaSource: error connecting to BufferQueue: %s (%d)",
777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                strerror(-err), err);
787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas CapensSurfaceMediaSource::~SurfaceMediaSource() {
827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("~SurfaceMediaSource");
832df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    CHECK(!mStarted);
847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensnsecs_t SurfaceMediaSource::getTimestamp() {
877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("getTimestamp");
887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return mCurrentTimestamp;
907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid SurfaceMediaSource::setFrameAvailableListener(
937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        const sp<FrameAvailableListener>& listener) {
947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("setFrameAvailableListener");
957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mFrameAvailableListener = listener;
977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid SurfaceMediaSource::dumpState(String8& result) const
1007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens{
1017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    char buffer[1024];
1027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    dumpState(result, "", buffer, 1024);
1037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
1047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid SurfaceMediaSource::dumpState(
1067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        String8& result,
1077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        const char* /* prefix */,
1087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        char* buffer,
1097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        size_t /* SIZE */) const
1107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens{
1117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
1127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    result.append(buffer);
1147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mConsumer->dumpState(result, "");
1157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
1167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstatus_t SurfaceMediaSource::setFrameRate(int32_t fps)
1187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens{
1197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("setFrameRate");
1207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
1217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    const int MAX_FRAME_RATE = 60;
1227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (fps < 0 || fps > MAX_FRAME_RATE) {
1237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        return BAD_VALUE;
1247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
1257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mFrameRate = fps;
1267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return OK;
1277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
1287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas CapensMetadataBufferType SurfaceMediaSource::metaDataStoredInVideoBuffers() const {
1307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("isMetaDataStoredInVideoBuffers");
1317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return kMetadataBufferTypeANWBuffer;
1327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
1337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensint32_t SurfaceMediaSource::getFrameRate( ) const {
1357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("getFrameRate");
1367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
1377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return mFrameRate;
1387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
1397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstatus_t SurfaceMediaSource::start(MetaData *params)
1417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens{
1427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("start");
1437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
1457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    CHECK(!mStarted);
1477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mStartTimeNs = 0;
1497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    int64_t startTimeUs;
1507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    int32_t bufferCount = 0;
1517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (params) {
1522df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens        if (params->findInt64(kKeyTime, &startTimeUs)) {
1537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mStartTimeNs = startTimeUs * 1000;
1547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
1557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        if (!params->findInt32(kKeyNumBuffers, &bufferCount)) {
1577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            ALOGE("Failed to find the advertised buffer count");
1587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            return UNKNOWN_ERROR;
1597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
1607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        if (bufferCount <= 1) {
1627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            ALOGE("bufferCount %d is too small", bufferCount);
1632df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens            return BAD_VALUE;
1647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
1652df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens
1667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        mMaxAcquiredBufferCount = bufferCount;
1672df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    }
1687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    CHECK_GT(mMaxAcquiredBufferCount, 1u);
1707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    status_t err =
1722df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens        mConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBufferCount);
1732df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens
1742df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    if (err != OK) {
1757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        return err;
1767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
1777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mNumPendingBuffers = 0;
1797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mStarted = true;
1807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return OK;
1822df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens}
1837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstatus_t SurfaceMediaSource::setMaxAcquiredBufferCount(size_t count) {
1857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("setMaxAcquiredBufferCount(%zu)", count);
1867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
1877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    CHECK_GT(count, 1u);
1897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mMaxAcquiredBufferCount = count;
1907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return OK;
1927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
1937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstatus_t SurfaceMediaSource::setUseAbsoluteTimestamps() {
1957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("setUseAbsoluteTimestamps");
1967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
1977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mUseAbsoluteTimestamps = true;
1987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
1997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return OK;
2007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
2017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstatus_t SurfaceMediaSource::stop()
2037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens{
2047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("stop");
2057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
2067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (!mStarted) {
2087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        return OK;
2097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
2107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mStarted = false;
2127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mFrameAvailableCondition.signal();
2137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    while (mNumPendingBuffers > 0) {
2157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        ALOGI("Still waiting for %zu buffers to be returned.",
2167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                mNumPendingBuffers);
2177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#if DEBUG_PENDING_BUFFERS
2197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        for (size_t i = 0; i < mPendingBuffers.size(); ++i) {
2207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            ALOGI("%d: %p", i, mPendingBuffers.itemAt(i));
2217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
2227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif
2237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        mMediaBuffersAvailableCondition.wait(mMutex);
2257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
2267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mMediaBuffersAvailableCondition.signal();
2287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return mConsumer->consumerDisconnect();
2307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
2317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenssp<MetaData> SurfaceMediaSource::getFormat()
2337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens{
2347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("getFormat");
2357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
2377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    sp<MetaData> meta = new MetaData;
2382df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens
2397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    meta->setInt32(kKeyWidth, mWidth);
2407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    meta->setInt32(kKeyHeight, mHeight);
2417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // The encoder format is set as an opaque colorformat
2427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // The encoder will later find out the actual colorformat
2437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // from the GL Frames itself.
2447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
2457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    meta->setInt32(kKeyStride, mWidth);
2467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    meta->setInt32(kKeySliceHeight, mHeight);
2477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    meta->setInt32(kKeyFrameRate, mFrameRate);
2487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return meta;
2507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
2517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Pass the data to the MediaBuffer. Pass in only the metadata
2532df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens// Note: Call only when you have the lock
2542df178997d17474042e8c3704cc93ab2db6619bfNicolas Capensvoid SurfaceMediaSource::passMetadataBuffer_l(MediaBuffer **buffer,
2552df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens        ANativeWindowBuffer *bufferHandle) const {
2567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    *buffer = new MediaBuffer(sizeof(VideoNativeMetadata));
2577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    VideoNativeMetadata *data = (VideoNativeMetadata *)(*buffer)->data();
2587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (data == NULL) {
2592df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens        ALOGE("Cannot allocate memory for metadata buffer!");
2602df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens        return;
2612df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    }
2622df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    data->eType = metaDataStoredInVideoBuffers();
2632df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    data->pBuffer = bufferHandle;
2647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    data->nFenceFd = -1;
2657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("handle = %p, offset = %zu, length = %zu",
2667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
2677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
2687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstatus_t SurfaceMediaSource::read(
2702df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens        MediaBuffer **buffer, const ReadOptions * /* options */) {
2712df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    ALOGV("read");
2727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
2737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    *buffer = NULL;
2757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    while (mStarted && mNumPendingBuffers == mMaxAcquiredBufferCount) {
2777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        mMediaBuffersAvailableCondition.wait(mMutex);
2782df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    }
2792df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens
2802df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    // Update the current buffer info
2812df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens    // TODO: mCurrentSlot can be made a bufferstate since there
2827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // can be more than one "current" slots.
2837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    BufferItem item;
2857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // If the recording has started and the queue is empty, then just
2867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // wait here till the frames come in from the client side
2877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    while (mStarted) {
2887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
2897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        status_t err = mConsumer->acquireBuffer(&item, 0);
2907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
2917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            // wait for a buffer to be queued
2927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mFrameAvailableCondition.wait(mMutex);
2937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        } else if (err == OK) {
2942df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens            err = item.mFence->waitForever("SurfaceMediaSource::read");
2952df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens            if (err) {
2962df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens                ALOGW("read: failed to wait for buffer fence: %d", err);
2972df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens            }
2982df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens
2992df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens            // First time seeing the buffer?  Added it to the SMS slot
3002df178997d17474042e8c3704cc93ab2db6619bfNicolas Capens            if (item.mGraphicBuffer != NULL) {
3017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                mSlots[item.mSlot].mGraphicBuffer = item.mGraphicBuffer;
3027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            }
3037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mSlots[item.mSlot].mFrameNumber = item.mFrameNumber;
3047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            // check for the timing of this buffer
3067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            if (mNumFramesReceived == 0 && !mUseAbsoluteTimestamps) {
3077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                mFirstFrameTimestamp = item.mTimestamp;
3087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                // Initial delay
3097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                if (mStartTimeNs > 0) {
3107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                    if (item.mTimestamp < mStartTimeNs) {
3117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                        // This frame predates start of record, discard
3127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                        mConsumer->releaseBuffer(
3137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                                item.mSlot, item.mFrameNumber, EGL_NO_DISPLAY,
3147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                                EGL_NO_SYNC_KHR, Fence::NO_FENCE);
3157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                        continue;
3167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                    }
3177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                    mStartTimeNs = item.mTimestamp - mStartTimeNs;
3187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                }
3197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            }
3207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            item.mTimestamp = mStartTimeNs + (item.mTimestamp - mFirstFrameTimestamp);
3217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mNumFramesReceived++;
3237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            break;
3257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        } else {
3267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            ALOGE("read: acquire failed with error code %d", err);
3277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            return ERROR_END_OF_STREAM;
3287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
3297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
3317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // If the loop was exited as a result of stopping the recording,
3337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // it is OK
3347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (!mStarted) {
3357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        ALOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM.");
3367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        return ERROR_END_OF_STREAM;
3377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
3387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mCurrentSlot = item.mSlot;
3407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // First time seeing the buffer?  Added it to the SMS slot
3427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (item.mGraphicBuffer != NULL) {
3437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        mSlots[item.mSlot].mGraphicBuffer = item.mGraphicBuffer;
3447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
3457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mSlots[item.mSlot].mFrameNumber = item.mFrameNumber;
3467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mCurrentBuffers.push_back(mSlots[mCurrentSlot].mGraphicBuffer);
3487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    int64_t prevTimeStamp = mCurrentTimestamp;
3497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mCurrentTimestamp = item.mTimestamp;
3507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mNumFramesEncoded++;
3527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // Pass the data to the MediaBuffer. Pass in only the metadata
3537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    passMetadataBuffer_l(buffer, mSlots[mCurrentSlot].mGraphicBuffer->getNativeBuffer());
3557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    (*buffer)->setObserver(this);
3577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    (*buffer)->add_ref();
3587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp / 1000);
3597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("Frames encoded = %d, timestamp = %" PRId64 ", time diff = %" PRId64,
3607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mNumFramesEncoded, mCurrentTimestamp / 1000,
3617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mCurrentTimestamp / 1000 - prevTimeStamp / 1000);
3627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ++mNumPendingBuffers;
3647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#if DEBUG_PENDING_BUFFERS
3667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mPendingBuffers.push_back(*buffer);
3677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif
3687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("returning mbuf %p", *buffer);
3707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return OK;
3727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
3737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensstatic buffer_handle_t getMediaBufferHandle(MediaBuffer *buffer) {
3757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // need to convert to char* for pointer arithmetic and then
3767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    // copy the byte stream into our handle
3777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    buffer_handle_t bufferHandle;
3787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    memcpy(&bufferHandle, (char*)(buffer->data()) + 4, sizeof(buffer_handle_t));
3797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    return bufferHandle;
3807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
3817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
3837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("signalBufferReturned");
3847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    bool foundBuffer = false;
3867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
3887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    buffer_handle_t bufferHandle = getMediaBufferHandle(buffer);
3907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    for (size_t i = 0; i < mCurrentBuffers.size(); i++) {
3927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        if (mCurrentBuffers[i]->handle == bufferHandle) {
3937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mCurrentBuffers.removeAt(i);
3947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            foundBuffer = true;
3957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            break;
3967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
3977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
3987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
3997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (!foundBuffer) {
4007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        ALOGW("returned buffer was not found in the current buffer list");
4017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
4027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    for (int id = 0; id < BufferQueue::NUM_BUFFER_SLOTS; id++) {
4047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        if (mSlots[id].mGraphicBuffer == NULL) {
4057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            continue;
4067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
4077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        if (bufferHandle == mSlots[id].mGraphicBuffer->handle) {
4097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            ALOGV("Slot %d returned, matches handle = %p", id,
4107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                    mSlots[id].mGraphicBuffer->handle);
4117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mConsumer->releaseBuffer(id, mSlots[id].mFrameNumber,
4137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                                        EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
4147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens                    Fence::NO_FENCE);
4157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            buffer->setObserver(0);
4177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            buffer->release();
4187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            foundBuffer = true;
4207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            break;
4217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
4227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
4237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (!foundBuffer) {
4257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        CHECK(!"signalBufferReturned: bogus buffer");
4267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
4277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#if DEBUG_PENDING_BUFFERS
4297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    for (size_t i = 0; i < mPendingBuffers.size(); ++i) {
4307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        if (mPendingBuffers.itemAt(i) == buffer) {
4317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            mPendingBuffers.removeAt(i);
4327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens            break;
4337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        }
4347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
4357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif
4367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    --mNumPendingBuffers;
4387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mMediaBuffersAvailableCondition.broadcast();
4397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
4407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Part of the BufferQueue::ConsumerListener
4427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid SurfaceMediaSource::onFrameAvailable(const BufferItem& /* item */) {
4437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("onFrameAvailable");
4447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    sp<FrameAvailableListener> listener;
4467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    { // scope for the lock
4477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        Mutex::Autolock lock(mMutex);
4487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        mFrameAvailableCondition.broadcast();
4497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        listener = mFrameAvailableListener;
4507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
4517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    if (listener != NULL) {
4537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        ALOGV("actually calling onFrameAvailable");
4547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens        listener->onFrameAvailable();
4557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
4567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
4577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// SurfaceMediaSource hijacks this event to assume
4597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// the prodcuer is disconnecting from the BufferQueue
4607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// and that it should stop the recording
4617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid SurfaceMediaSource::onBuffersReleased() {
4627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOGV("onBuffersReleased");
4637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    Mutex::Autolock lock(mMutex);
4657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    mFrameAvailableCondition.signal();
4677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
4697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens       mSlots[i].mGraphicBuffer = 0;
4707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    }
4717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
4727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensvoid SurfaceMediaSource::onSidebandStreamChanged() {
4747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens    ALOG_ASSERT(false, "SurfaceMediaSource can't consume sideband streams");
4757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}
4767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens
4777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} // end of namespace android
4787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens