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