SurfaceMediaSource.cpp revision 8add6cf4976de9b7bca7b73b1473a1e5f7201087
13399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi/* 23399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * Copyright (C) 2011 The Android Open Source Project 33399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * 43399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * Licensed under the Apache License, Version 2.0 (the "License"); 53399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * you may not use this file except in compliance with the License. 63399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * You may obtain a copy of the License at 73399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * 83399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * http://www.apache.org/licenses/LICENSE-2.0 93399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * 103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * Unless required by applicable law or agreed to in writing, software 113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * distributed under the License is distributed on an "AS IS" BASIS, 123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * See the License for the specific language governing permissions and 143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi * limitations under the License. 153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi */ 167dc9b309f1ce01308bcfde9948ebfece32dc2870Pannag Sanketi//#define LOG_NDEBUG 0 171a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi#define LOG_TAG "SurfaceMediaSource" 183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 19f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h> 201a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi#include <media/stagefright/SurfaceMediaSource.h> 213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <media/stagefright/MetaData.h> 223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <media/stagefright/MediaDefs.h> 236c6b4d0d2b98a7ceee8b697daaf611f8df3254fbJames Dong#include <OMX_IVCommon.h> 246c6b4d0d2b98a7ceee8b697daaf611f8df3254fbJames Dong#include <MetadataBufferType.h> 253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 26f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <ui/GraphicBuffer.h> 27df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/ISurfaceComposer.h> 28df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/IGraphicBufferAlloc.h> 293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <OMX_Component.h> 303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/Log.h> 323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/String8.h> 333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 34404a123bed7f180724ead17f10e037b3eb347701Mathias Agopian#include <private/gui/ComposerService.h> 35404a123bed7f180724ead17f10e037b3eb347701Mathias Agopian 363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketinamespace android { 373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 38bdddc659a941afdb7f4958f582c6901c07246097Daniel LamSurfaceMediaSource::SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight) : 39bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mWidth(bufferWidth), 40bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mHeight(bufferHeight), 41bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mCurrentSlot(BufferQueue::INVALID_BUFFER_SLOT), 42bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mCurrentTimestamp(0), 43bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mFrameRate(30), 44bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mStopped(false), 45bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mNumFramesReceived(0), 46bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mNumFramesEncoded(0), 47bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mFirstFrameTimestamp(0) 48bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam{ 493856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("SurfaceMediaSource::SurfaceMediaSource"); 503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 51bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (bufferWidth == 0 || bufferHeight == 0) { 52bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ALOGE("Invalid dimensions %dx%d", bufferWidth, bufferHeight); 533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 55bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferQueue = new BufferQueue(true, MIN_UNDEQUEUED_BUFFERS); 56bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferQueue->setDefaultBufferSize(bufferWidth, bufferHeight); 57bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferQueue->setSynchronousMode(true); 588add6cf4976de9b7bca7b73b1473a1e5f7201087Eino-Ville Talvala mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER | 598add6cf4976de9b7bca7b73b1473a1e5f7201087Eino-Ville Talvala GRALLOC_USAGE_HW_TEXTURE); 603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 61bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 63bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // Note that we can't create an sp<...>(this) in a ctor that will not keep a 64bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // reference once the ctor ends, as that would cause the refcount of 'this' 65bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // dropping to 0 at the end of the ctor. Since all we need is a wp<...> 66bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // that's what we create. 67bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam wp<BufferQueue::ConsumerListener> listener; 68bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam sp<BufferQueue::ConsumerListener> proxy; 69bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam listener = static_cast<BufferQueue::ConsumerListener*>(this); 70bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam proxy = new BufferQueue::ProxyConsumerListener(listener); 713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 72bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam status_t err = mBufferQueue->consumerConnect(proxy); 73bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (err != NO_ERROR) { 74bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ALOGE("SurfaceMediaSource: error connecting to BufferQueue: %s (%d)", 75bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam strerror(-err), err); 763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 79bdddc659a941afdb7f4958f582c6901c07246097Daniel LamSurfaceMediaSource::~SurfaceMediaSource() { 80bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ALOGV("SurfaceMediaSource::~SurfaceMediaSource"); 81bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (!mStopped) { 82bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam reset(); 833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 861a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketinsecs_t SurfaceMediaSource::getTimestamp() { 873856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("SurfaceMediaSource::getTimestamp"); 883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi Mutex::Autolock lock(mMutex); 893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return mCurrentTimestamp; 903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 921a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::setFrameAvailableListener( 933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi const sp<FrameAvailableListener>& listener) { 943856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("SurfaceMediaSource::setFrameAvailableListener"); 953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi Mutex::Autolock lock(mMutex); 963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi mFrameAvailableListener = listener; 973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 991a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const { 1003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi Mutex::Autolock lock(mMutex); 1013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return mCurrentBuf; 1023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 1033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1041a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::dump(String8& result) const 1053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 1063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi char buffer[1024]; 1073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi dump(result, "", buffer, 1024); 1083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 1093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1101a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::dump(String8& result, const char* prefix, 1113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi char* buffer, size_t SIZE) const 1123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 113bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam Mutex::Autolock lock(mMutex); 1143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi result.append(buffer); 116bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferQueue->dump(result); 1173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 1183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 119b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketistatus_t SurfaceMediaSource::setFrameRate(int32_t fps) 1203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 1213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi Mutex::Autolock lock(mMutex); 122b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi const int MAX_FRAME_RATE = 60; 123b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi if (fps < 0 || fps > MAX_FRAME_RATE) { 124b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return BAD_VALUE; 125b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi } 1263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi mFrameRate = fps; 127b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return OK; 1283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 1293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 130b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketibool SurfaceMediaSource::isMetaDataStoredInVideoBuffers() const { 1313856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("isMetaDataStoredInVideoBuffers"); 132b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi return true; 133b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi} 134b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 135b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketiint32_t SurfaceMediaSource::getFrameRate( ) const { 1363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi Mutex::Autolock lock(mMutex); 1373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return mFrameRate; 1383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 1393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1401a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::start(MetaData *params) 1413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 1423856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("started!"); 143df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala 144df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala mStartTimeNs = 0; 145df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala int64_t startTimeUs; 146df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala if (params && params->findInt64(kKeyTime, &startTimeUs)) { 147df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala mStartTimeNs = startTimeUs * 1000; 148df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala } 149df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala 1503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return OK; 1513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 1523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 15460c2b4ece6528d6d3f4e9e2c7e45772b65c4b87dJames Dongstatus_t SurfaceMediaSource::reset() 1553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 15660c2b4ece6528d6d3f4e9e2c7e45772b65c4b87dJames Dong ALOGV("Reset"); 1573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi Mutex::Autolock lock(mMutex); 1593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // TODO: Add waiting on mFrameCompletedCondition here? 1600c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mStopped = true; 161bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 1623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi mFrameAvailableCondition.signal(); 163bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferQueue->consumerDisconnect(); 1643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return OK; 1663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 1673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1681a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisp<MetaData> SurfaceMediaSource::getFormat() 1693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 1703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getFormat"); 171bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 172bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam Mutex::Autolock lock(mMutex); 1733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi sp<MetaData> meta = new MetaData; 174b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi 175bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam meta->setInt32(kKeyWidth, mWidth); 176bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam meta->setInt32(kKeyHeight, mHeight); 1773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // The encoder format is set as an opaque colorformat 1783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // The encoder will later find out the actual colorformat 1793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // from the GL Frames itself. 1803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque); 181bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam meta->setInt32(kKeyStride, mWidth); 182bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam meta->setInt32(kKeySliceHeight, mHeight); 1833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi meta->setInt32(kKeyFrameRate, mFrameRate); 1843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW); 1853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return meta; 1863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 1873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 1881a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::read( MediaBuffer **buffer, 1890c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi const ReadOptions *options) 1903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{ 191bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ALOGV("read"); 192bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam Mutex::Autolock lock(mMutex); 1930c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi 1943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi *buffer = NULL; 1953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 196bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // Update the current buffer info 197bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // TODO: mCurrentSlot can be made a bufferstate since there 198bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // can be more than one "current" slots. 199bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 200bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam BufferQueue::BufferItem item; 2013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // If the recording has started and the queue is empty, then just 2023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // wait here till the frames come in from the client side 203bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam while (!mStopped) { 204bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 205bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam status_t err = mBufferQueue->acquireBuffer(&item); 206bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (err == BufferQueue::NO_BUFFER_AVAILABLE) { 207bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // wait for a buffer to be queued 208bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mFrameAvailableCondition.wait(mMutex); 209bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } else if (err == OK) { 210bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 211bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // First time seeing the buffer? Added it to the SMS slot 212bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (item.mGraphicBuffer != NULL) { 213bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferSlot[item.mBuf] = item.mGraphicBuffer; 214bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 215bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 216bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // check for the timing of this buffer 217bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (mNumFramesReceived == 0) { 218bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mFirstFrameTimestamp = item.mTimestamp; 219bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // Initial delay 220bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (mStartTimeNs > 0) { 221bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (item.mTimestamp < mStartTimeNs) { 222bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // This frame predates start of record, discard 223bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferQueue->releaseBuffer(item.mBuf, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); 224bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam continue; 225bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 226bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mStartTimeNs = item.mTimestamp - mStartTimeNs; 227bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 228bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 229bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam item.mTimestamp = mStartTimeNs + (item.mTimestamp - mFirstFrameTimestamp); 230bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 231bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mNumFramesReceived++; 232bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 233bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam break; 234bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } else { 235bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ALOGE("read: acquire failed with error code %d", err); 236bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam return ERROR_END_OF_STREAM; 237bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 238bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 2393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 2403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 2413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // If the loop was exited as a result of stopping the recording, 2423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi // it is OK 2430c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (mStopped) { 2443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM."); 2453e9bf4061475ae0d01c57e32c13e63808aa3e31fPannag Sanketi return ERROR_END_OF_STREAM; 2463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 2473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 248bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mCurrentSlot = item.mBuf; 249bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 250bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam // First time seeing the buffer? Added it to the SMS slot 251bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (item.mGraphicBuffer != NULL) { 252bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferSlot[mCurrentSlot] = item.mGraphicBuffer; 253bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 254bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mCurrentBuf = mBufferSlot[mCurrentSlot]; 2550c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi int64_t prevTimeStamp = mCurrentTimestamp; 256bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mCurrentTimestamp = item.mTimestamp; 257df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala 2580c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mNumFramesEncoded++; 259a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi // Pass the data to the MediaBuffer. Pass in only the metadata 260a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi passMetadataBufferLocked(buffer); 261a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi 2623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi (*buffer)->setObserver(this); 2633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi (*buffer)->add_ref(); 2640c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp / 1000); 2653856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Frames encoded = %d, timestamp = %lld, time diff = %lld", 2660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mNumFramesEncoded, mCurrentTimestamp / 1000, 2670c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mCurrentTimestamp / 1000 - prevTimeStamp / 1000); 2683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 269bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 2703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return OK; 2713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 2723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 273a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// Pass the data to the MediaBuffer. Pass in only the metadata 274a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// The metadata passed consists of two parts: 275a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// 1. First, there is an integer indicating that it is a GRAlloc 276a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// source (kMetadataBufferTypeGrallocSource) 277a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// 2. This is followed by the buffer_handle_t that is a handle to the 278a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// GRalloc buffer. The encoder needs to interpret this GRalloc handle 279a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// and encode the frames. 280a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// -------------------------------------------------------------- 281a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// | kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) | 282a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// -------------------------------------------------------------- 283a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// Note: Call only when you have the lock 284a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketivoid SurfaceMediaSource::passMetadataBufferLocked(MediaBuffer **buffer) { 2853856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("passMetadataBuffer"); 286a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi // MediaBuffer allocates and owns this data 287a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi MediaBuffer *tempBuffer = 288a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi new MediaBuffer(4 + sizeof(buffer_handle_t)); 289a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi char *data = (char *)tempBuffer->data(); 290a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi if (data == NULL) { 29129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Cannot allocate memory for metadata buffer!"); 292a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi return; 293a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi } 294a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi OMX_U32 type = kMetadataBufferTypeGrallocSource; 295a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi memcpy(data, &type, 4); 296a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t)); 297a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi *buffer = tempBuffer; 298a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi 2993856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("handle = %p, , offset = %d, length = %d", 3000c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi mCurrentBuf->handle, (*buffer)->range_length(), (*buffer)->range_offset()); 3010c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi} 302a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi 3031a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) { 3043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("signalBufferReturned"); 3053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 3063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi bool foundBuffer = false; 307bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 308bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam Mutex::Autolock lock(mMutex); 3093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 3100c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (mStopped) { 3113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("signalBufferReturned: mStopped = true! Nothing to do!"); 3123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi return; 3133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 3143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 315bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam for (int id = 0; id < BufferQueue::NUM_BUFFER_SLOTS; id++) { 316bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (mBufferSlot[id] == NULL) { 3170c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi continue; 3180c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi } 3190c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi if (checkBufferMatchesSlot(id, buffer)) { 3203856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Slot %d returned, matches handle = %p", id, 321bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferSlot[id]->handle); 322bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 323bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferQueue->releaseBuffer(id, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); 324bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 3253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi buffer->setObserver(0); 3263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi buffer->release(); 327bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 3283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi foundBuffer = true; 3293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi break; 3303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 3313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 3323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 3333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi if (!foundBuffer) { 334f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong CHECK(!"signalBufferReturned: bogus buffer"); 3353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi } 3363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} 3373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 338a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketibool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) { 3393856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("Check if Buffer matches slot"); 340a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi // need to convert to char* for pointer arithmetic and then 341a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi // copy the byte stream into our handle 342a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi buffer_handle_t bufferHandle ; 343a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi memcpy( &bufferHandle, (char *)(buffer->data()) + 4, sizeof(buffer_handle_t)); 344bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam return mBufferSlot[slot]->handle == bufferHandle; 345bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam} 346bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 347bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam// Part of the BufferQueue::ConsumerListener 348bdddc659a941afdb7f4958f582c6901c07246097Daniel Lamvoid SurfaceMediaSource::onFrameAvailable() { 349bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ALOGV("onFrameAvailable"); 350bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 351bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam sp<FrameAvailableListener> listener; 352bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam { // scope for the lock 353bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam Mutex::Autolock lock(mMutex); 354bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mFrameAvailableCondition.broadcast(); 355bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam listener = mFrameAvailableListener; 356bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 357bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 358bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam if (listener != NULL) { 359bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ALOGV("actually calling onFrameAvailable"); 360bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam listener->onFrameAvailable(); 361bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 362bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam} 363bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 364bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam// SurfaceMediaSource hijacks this event to assume 365bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam// the prodcuer is disconnecting from the BufferQueue 366bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam// and that it should stop the recording 367bdddc659a941afdb7f4958f582c6901c07246097Daniel Lamvoid SurfaceMediaSource::onBuffersReleased() { 368bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam ALOGV("onBuffersReleased"); 369bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 370bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam Mutex::Autolock lock(mMutex); 371bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 372bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mFrameAvailableCondition.signal(); 373bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mStopped = true; 374bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam 375bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { 376bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam mBufferSlot[i] = 0; 377bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam } 378a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi} 3793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi 3803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} // end of namespace android 381