SurfaceMediaSource.cpp revision 29a142c7237821b6dc7bd1e8b56bb1efdc56767b
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 */
163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// #define LOG_NDEBUG 0
181a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi#define LOG_TAG "SurfaceMediaSource"
193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
201a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi#include <media/stagefright/SurfaceMediaSource.h>
213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <ui/GraphicBuffer.h>
223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <media/stagefright/MetaData.h>
233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <media/stagefright/MediaDefs.h>
243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <media/stagefright/MediaDebug.h>
253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <media/stagefright/openmax/OMX_IVCommon.h>
263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <surfaceflinger/ISurfaceComposer.h>
283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <surfaceflinger/SurfaceComposerClient.h>
293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <surfaceflinger/IGraphicBufferAlloc.h>
303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <OMX_Component.h>
313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/Log.h>
333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/String8.h>
343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketinamespace android {
363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
371a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag SanketiSurfaceMediaSource::SurfaceMediaSource(uint32_t bufW, uint32_t bufH) :
383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mDefaultWidth(bufW),
393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mDefaultHeight(bufH),
403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mPixelFormat(0),
413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mClientBufferCount(0),
433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentSlot(INVALID_BUFFER_SLOT),
453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentTimestamp(0),
463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mSynchronousMode(true),
473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mConnectedApi(NO_CONNECTED_API),
483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameRate(30),
491a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    mStarted(false)     {
501a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::SurfaceMediaSource");
513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
551a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag SanketiSurfaceMediaSource::~SurfaceMediaSource() {
561a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::~SurfaceMediaSource");
573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mStarted) {
583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        stop();
593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    freeAllBuffers();
613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
631a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisize_t SurfaceMediaSource::getQueuedCount() const {
643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mQueue.size();
663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
681a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::setBufferCountServerLocked(int bufferCount) {
693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount > NUM_BUFFER_SLOTS)
703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // special-case, nothing to do
733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount == mBufferCount)
743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return OK;
753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!mClientBufferCount &&
773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        bufferCount >= mBufferCount) {
783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // easy, we just have more buffers
793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mBufferCount = bufferCount;
803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mServerBufferCount = bufferCount;
813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mDequeueCondition.signal();
823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } else {
833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // we're here because we're either
843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - reducing the number of available buffers
853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - or there is a client-buffer-count in effect
863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // less than 2 buffers is never allowed
883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (bufferCount < 2)
893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            return BAD_VALUE;
903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // when there is non client-buffer-count in effect, the client is not
923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // allowed to dequeue more than one buffer at a time,
933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // so the next time they dequeue a buffer, we know that they don't
943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // own one. the actual resizing will happen during the next
953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // dequeueBuffer.
963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mServerBufferCount = bufferCount;
983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
1003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// Called from the consumer side
1031a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::setBufferCountServer(int bufferCount) {
1043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
1053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return setBufferCountServerLocked(bufferCount);
1063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1081a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::setBufferCount(int bufferCount) {
1091a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::setBufferCount");
1103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount > NUM_BUFFER_SLOTS) {
1113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGE("setBufferCount: bufferCount is larger than the number of buffer slots");
1123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
1133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
1163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Error out if the user has dequeued buffers
1173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    for (int i = 0 ; i < mBufferCount ; i++) {
1183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
1193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            LOGE("setBufferCount: client owns some buffers");
1203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            return INVALID_OPERATION;
1213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
1223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount == 0) {
1253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const int minBufferSlots = mSynchronousMode ?
1263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
1273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mClientBufferCount = 0;
1283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        bufferCount = (mServerBufferCount >= minBufferSlots) ?
1293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mServerBufferCount : minBufferSlots;
1303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return setBufferCountServerLocked(bufferCount);
1313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // We don't allow the client to set a buffer-count less than
1343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // MIN_ASYNC_BUFFER_SLOTS (3), there is no reason for it.
1353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount < MIN_ASYNC_BUFFER_SLOTS) {
1363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
1373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // here we're guaranteed that the client doesn't have dequeued buffers
1403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // and will release all of its buffer references.
1413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    freeAllBuffers();
1423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mBufferCount = bufferCount;
1433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mClientBufferCount = bufferCount;
1443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentSlot = INVALID_BUFFER_SLOT;
1453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mQueue.clear();
1463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mDequeueCondition.signal();
1473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
1483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
15029a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennisstatus_t SurfaceMediaSource::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
1511a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::requestBuffer");
1523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
15329a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis    if (slot < 0 || mBufferCount <= slot) {
1543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGE("requestBuffer: slot index out of range [0, %d]: %d",
15529a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis                mBufferCount, slot);
15629a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis        return BAD_VALUE;
1573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
15829a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis    mSlots[slot].mRequestBufferCalled = true;
15929a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis    *buf = mSlots[slot].mGraphicBuffer;
16029a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis    return NO_ERROR;
1613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1631a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
1643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                                            uint32_t format, uint32_t usage) {
1653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("dequeueBuffer");
1663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Check for the buffer size- the client should just use the
1693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // default width and height, and not try to set those.
1703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // This is needed since
1713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // the getFormat() returns mDefaultWidth/ Height for the OMX. It is
1723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // queried by OMX in the beginning and not every time a frame comes.
1733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Not sure if there is  a way to update the
1743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // frame size while recording. So as of now, the client side
1753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // sets the default values via the constructor, and the encoder is
1763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // setup to encode frames of that size
1773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // The design might need to change in the future.
1783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: Currently just uses mDefaultWidth/Height. In the future
1793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // we might declare mHeight and mWidth and check against those here.
1803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if ((w != 0) || (h != 0)) {
1813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGE("dequeuebuffer: invalid buffer size! Req: %dx%d, Found: %dx%d",
1823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mDefaultWidth, mDefaultHeight, w, h);
1833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
1843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
1873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    status_t returnFlags(OK);
1893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int found, foundSync;
1913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int dequeuedCount = 0;
1923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    bool tryAgain = true;
1933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    while (tryAgain) {
1943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // We need to wait for the FIFO to drain if the number of buffer
1953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // needs to change.
1963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //
1973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // The condition "number of buffer needs to change" is true if
1983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - the client doesn't care about how many buffers there are
1993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - AND the actual number of buffer is different from what was
2003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //   set in the last setBufferCountServer()
2013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //                         - OR -
2023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //   setBufferCountServer() was set to a value incompatible with
2033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //   the synchronization mode (for instance because the sync mode
2043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //   changed since)
2053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //
2063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // As long as this condition is true AND the FIFO is not empty, we
2073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // wait on mDequeueCondition.
2083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        int minBufferCountNeeded = mSynchronousMode ?
2103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
2113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mClientBufferCount &&
2133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                ((mServerBufferCount != mBufferCount) ||
2143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                        (mServerBufferCount < minBufferCountNeeded))) {
2153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // wait for the FIFO to drain
2163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            while (!mQueue.isEmpty()) {
2173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                LOGV("Waiting for the FIFO to drain");
2183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mDequeueCondition.wait(mMutex);
2193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
2203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // need to check again since the mode could have changed
2213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // while we were waiting
2223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            minBufferCountNeeded = mSynchronousMode ?
2233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                    MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
2243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mClientBufferCount &&
2273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                ((mServerBufferCount != mBufferCount) ||
2283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                        (mServerBufferCount < minBufferCountNeeded))) {
2293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // here we're guaranteed that mQueue is empty
2303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            freeAllBuffers();
2313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mBufferCount = mServerBufferCount;
2323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (mBufferCount < minBufferCountNeeded)
2333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mBufferCount = minBufferCountNeeded;
2343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mCurrentSlot = INVALID_BUFFER_SLOT;
2353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
2363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // look for a free buffer to give to the client
2393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        found = INVALID_BUFFER_SLOT;
2403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        foundSync = INVALID_BUFFER_SLOT;
2413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        dequeuedCount = 0;
2423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        for (int i = 0; i < mBufferCount; i++) {
2433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            const int state = mSlots[i].mBufferState;
2443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (state == BufferSlot::DEQUEUED) {
2453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                dequeuedCount++;
2463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                continue; // won't be continuing if could
2473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // dequeue a non 'FREE' current slot like
2483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // that in SurfaceTexture
2493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
2503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // In case of Encoding, we do not deque the mCurrentSlot buffer
2513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            //  since we follow synchronous mode (unlike possibly in
2523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            //  SurfaceTexture that could be using the asynch mode
2533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            //  or has some mechanism in GL to be able to wait till the
2543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            //  currentslot is done using the data)
2553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // Here, we have to wait for the MPEG4Writer(or equiv)
2563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // to tell us when it's done using the current buffer
2573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (state == BufferSlot::FREE) {
2583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                foundSync = i;
2593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // Unlike that in SurfaceTexture,
2603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // We don't need to worry if it is the
2613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // currentslot or not as it is in state FREE
2623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                found = i;
2633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                break;
2643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
2653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // clients are not allowed to dequeue more than one buffer
2683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // if they didn't set a buffer count.
2693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mClientBufferCount && dequeuedCount) {
2703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            return -EINVAL;
2713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // See whether a buffer has been queued since the last setBufferCount so
2743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
2753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        bool bufferHasBeenQueued = mCurrentSlot != INVALID_BUFFER_SLOT;
2763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (bufferHasBeenQueued) {
2773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // make sure the client is not trying to dequeue more buffers
2783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // than allowed.
2793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            const int avail = mBufferCount - (dequeuedCount+1);
2803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
2813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded (dequeued=%d)",
2823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                        MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
2833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                        dequeuedCount);
2843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                return -EBUSY;
2853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
2863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // we're in synchronous mode and didn't find a buffer, we need to wait
2893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // for for some buffers to be consumed
2903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
2913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (tryAgain) {
2923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            LOGW("Waiting..In synchronous mode and no buffer to dQ");
2933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mDequeueCondition.wait(mMutex);
2943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
2963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
2983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // foundSync guaranteed to be != INVALID_BUFFER_SLOT
2993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        found = foundSync;
3003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (found == INVALID_BUFFER_SLOT) {
3033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return -EBUSY;
3043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    const int buf = found;
3073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *outBuf = found;
3083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    const bool useDefaultSize = !w && !h;
3103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (useDefaultSize) {
3113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // use the default size
3123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        w = mDefaultWidth;
3133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        h = mDefaultHeight;
3143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    const bool updateFormat = (format != 0);
3173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!updateFormat) {
3183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // keep the current (or default) format
3193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        format = mPixelFormat;
3203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // buffer is now in DEQUEUED (but can also be current at the same time,
3233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // if we're in synchronous mode)
3243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
3253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
3273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if ((buffer == NULL) ||
3283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        (uint32_t(buffer->width)  != w) ||
3293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        (uint32_t(buffer->height) != h) ||
3303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        (uint32_t(buffer->format) != format) ||
3313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        ((uint32_t(buffer->usage) & usage) != usage)) {
3323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
3333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            status_t error;
3343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            sp<GraphicBuffer> graphicBuffer(
3353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                    mGraphicBufferAlloc->createGraphicBuffer(
3363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                                    w, h, format, usage, &error));
3373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (graphicBuffer == 0) {
3383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
3393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                return error;
3403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
3413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (updateFormat) {
3423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mPixelFormat = format;
3433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
3443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mSlots[buf].mGraphicBuffer = graphicBuffer;
3453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mSlots[buf].mRequestBufferCalled = false;
3463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
3473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return returnFlags;
3493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
3503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3511a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::setSynchronousMode(bool enabled) {
3523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
3533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    status_t err = OK;
3553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!enabled) {
3563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // going to asynchronous mode, drain the queue
3573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        while (mSynchronousMode != enabled && !mQueue.isEmpty()) {
3583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mDequeueCondition.wait(mMutex);
3593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
3603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mSynchronousMode != enabled) {
3633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - if we're going to asynchronous mode, the queue is guaranteed to be
3643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // empty here
3653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - if the client set the number of buffers, we're guaranteed that
3663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // we have at least 3 (because we don't allow less)
3673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mSynchronousMode = enabled;
3683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mDequeueCondition.signal();
3693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return err;
3713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
3723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3731a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::connect(int api) {
3741a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::connect");
3753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
3763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int err = NO_ERROR;
3773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    switch (api) {
3783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_EGL:
3793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_CPU:
3803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_MEDIA:
3813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_CAMERA:
3823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (mConnectedApi != NO_CONNECTED_API) {
3833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                err = -EINVAL;
3843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            } else {
3853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mConnectedApi = api;
3863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
3873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
3883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        default:
3893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            err = -EINVAL;
3903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
3913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return err;
3933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
3943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3951a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::disconnect(int api) {
3961a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::disconnect");
3973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
3983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int err = NO_ERROR;
3993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    switch (api) {
4003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_EGL:
4013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_CPU:
4023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_MEDIA:
4033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_CAMERA:
4043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (mConnectedApi == api) {
4053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mConnectedApi = NO_CONNECTED_API;
4063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            } else {
4073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                err = -EINVAL;
4083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
4093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
4103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        default:
4113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            err = -EINVAL;
4123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
4133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return err;
4153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
4163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4171a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::queueBuffer(int buf, int64_t timestamp,
4183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
4193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("queueBuffer");
4203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
4223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (buf < 0 || buf >= mBufferCount) {
4233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGE("queueBuffer: slot index out of range [0, %d]: %d",
4243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mBufferCount, buf);
4253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return -EINVAL;
4263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
4273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGE("queueBuffer: slot %d is not owned by the client (state=%d)",
4283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                buf, mSlots[buf].mBufferState);
4293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return -EINVAL;
4303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } else if (!mSlots[buf].mRequestBufferCalled) {
4313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGE("queueBuffer: slot %d was enqueued without requesting a "
4323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                "buffer", buf);
4333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return -EINVAL;
4343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mSynchronousMode) {
4373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // in synchronous mode we queue all buffers in a FIFO
4383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mQueue.push_back(buf);
4393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGV("Client queued buffer on slot: %d, Q size = %d",
4403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                                                buf, mQueue.size());
4413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } else {
4423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // in asynchronous mode we only keep the most recent buffer
4433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (mQueue.empty()) {
4443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mQueue.push_back(buf);
4453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        } else {
4463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            Fifo::iterator front(mQueue.begin());
4473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // buffer currently queued is freed
4483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mSlots[*front].mBufferState = BufferSlot::FREE;
4493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // and we record the new buffer index in the queued list
4503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            *front = buf;
4513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
4523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mSlots[buf].mBufferState = BufferSlot::QUEUED;
4553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mSlots[buf].mTimestamp = timestamp;
4563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: (Confirm) Don't want to signal dequeue here.
4573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // May be just in asynchronous mode?
4583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // mDequeueCondition.signal();
4593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Once the queuing is done, we need to let the listener
4613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // and signal the buffer consumer (encoder) know that a
4623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // buffer is available
4633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    onFrameReceivedLocked();
4643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *outWidth = mDefaultWidth;
4663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *outHeight = mDefaultHeight;
4673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *outTransform = 0;
4683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
4703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
4713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder)
4743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// or listeners that a frame has been received
4753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// It is supposed to be called only from queuebuffer.
4763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// The buffer is NOT made available for dequeueing immediately. We need to
4773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// wait to hear from StageFrightRecorder to set the buffer FREE
4783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// Make sure this is called when the mutex is locked
4791a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::onFrameReceivedLocked() {
4803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("On Frame Received");
4813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Signal the encoder that a new frame has arrived
4823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameAvailableCondition.signal();
4833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // call back the listener
4851a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    // TODO: The listener may not be needed in SurfaceMediaSource at all.
4863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // This can be made a SurfaceTexture specific thing
4873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    sp<FrameAvailableListener> listener;
4883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mSynchronousMode || mQueue.empty()) {
4893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        listener = mFrameAvailableListener;
4903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (listener != 0) {
4933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        listener->onFrameAvailable();
4943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
4963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
4973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4991a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::cancelBuffer(int buf) {
5001a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::cancelBuffer");
5013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (buf < 0 || buf >= mBufferCount) {
5033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
5043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mBufferCount, buf);
5053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return;
5063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
5073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
5083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                buf, mSlots[buf].mBufferState);
5093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return;
5103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mSlots[buf].mBufferState = BufferSlot::FREE;
5123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mDequeueCondition.signal();
5133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5151a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketinsecs_t SurfaceMediaSource::getTimestamp() {
5161a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::getTimestamp");
5173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mCurrentTimestamp;
5193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5221a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::setFrameAvailableListener(
5233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const sp<FrameAvailableListener>& listener) {
5241a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    LOGV("SurfaceMediaSource::setFrameAvailableListener");
5253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameAvailableListener = listener;
5273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5291a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::freeAllBuffers() {
5303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("freeAllBuffers");
5313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
5323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mSlots[i].mGraphicBuffer = 0;
5333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mSlots[i].mBufferState = BufferSlot::FREE;
5343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5371a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const {
5383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mCurrentBuf;
5403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5421a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketiint SurfaceMediaSource::query(int what, int* outValue)
5433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
5443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("query");
5453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int value;
5473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    switch (what) {
5483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    case NATIVE_WINDOW_WIDTH:
5493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        value = mDefaultWidth;
5503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
5513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            value = mCurrentBuf->width;
5523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        break;
5533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    case NATIVE_WINDOW_HEIGHT:
5543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        value = mDefaultHeight;
5553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
5563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            value = mCurrentBuf->height;
5573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        break;
5583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    case NATIVE_WINDOW_FORMAT:
5593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        value = mPixelFormat;
5603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        break;
5613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
5623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        value = mSynchronousMode ?
5633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
5643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        break;
5653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    default:
5663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
5673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    outValue[0] = value;
5693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return NO_ERROR;
5703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5721a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::dump(String8& result) const
5733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
5743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    char buffer[1024];
5753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    dump(result, "", buffer, 1024);
5763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5781a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::dump(String8& result, const char* prefix,
5793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        char* buffer, size_t SIZE) const
5803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
5813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock _l(mMutex);
5823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    snprintf(buffer, SIZE,
5833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
5843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            "mPixelFormat=%d, \n",
5853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            prefix, mBufferCount, mSynchronousMode, mDefaultWidth, mDefaultHeight,
5863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mPixelFormat);
5873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    result.append(buffer);
5883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    String8 fifo;
5903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int fifoSize = 0;
5913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Fifo::const_iterator i(mQueue.begin());
5923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    while (i != mQueue.end()) {
5933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        snprintf(buffer, SIZE, "%02d ", *i++);
5943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        fifoSize++;
5953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        fifo.append(buffer);
5963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    result.append(buffer);
5993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    struct {
6013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const char * operator()(int state) const {
6023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            switch (state) {
6033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                case BufferSlot::DEQUEUED: return "DEQUEUED";
6043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                case BufferSlot::QUEUED: return "QUEUED";
6053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                case BufferSlot::FREE: return "FREE";
6063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                default: return "Unknown";
6073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
6083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
6093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } stateName;
6103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    for (int i = 0; i < mBufferCount; i++) {
6123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const BufferSlot& slot(mSlots[i]);
6133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        snprintf(buffer, SIZE,
6143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                "%s%s[%02d] state=%-8s, "
6153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                "timestamp=%lld\n",
6163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                prefix, (i==mCurrentSlot)?">":" ", i, stateName(slot.mBufferState),
6173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                slot.mTimestamp
6183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        );
6193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        result.append(buffer);
6203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
6213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6231a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::setFrameRate(uint32_t fps)
6243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
6263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameRate = fps;
6273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6291a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketiuint32_t SurfaceMediaSource::getFrameRate( ) const {
6303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
6313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mFrameRate;
6323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6341a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::start(MetaData *params)
6353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("start");
6373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
6383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    CHECK(!mStarted);
6393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mStarted = true;
6403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
6413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6441a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::stop()
6453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("Stop");
6473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
6493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: Add waiting on mFrameCompletedCondition here?
6503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mStarted = false;
6513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameAvailableCondition.signal();
6523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
6543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6561a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisp<MetaData> SurfaceMediaSource::getFormat()
6573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("getFormat");
6593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock autoLock(mMutex);
6603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    sp<MetaData> meta = new MetaData;
6613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // XXX: Check if this is right. or should we wait on some
6623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // condition?
6633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyWidth, mDefaultWidth);
6643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyHeight, mDefaultHeight);
6653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // The encoder format is set as an opaque colorformat
6663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // The encoder will later find out the actual colorformat
6673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // from the GL Frames itself.
6683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
6693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyStride, mDefaultWidth);
6703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeySliceHeight, mDefaultHeight);
6713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyFrameRate, mFrameRate);
6723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
6733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return meta;
6743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6761a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::read( MediaBuffer **buffer,
6773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                                const ReadOptions *options)
6783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("Read. Size of queued buffer: %d", mQueue.size());
6803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *buffer = NULL;
6813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock autoLock(mMutex) ;
6833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // If the recording has started and the queue is empty, then just
6843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // wait here till the frames come in from the client side
6853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    while (mStarted && mQueue.empty()) {
6863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGV("NO FRAMES! Recorder waiting for FrameAvailableCondition");
6873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mFrameAvailableCondition.wait(mMutex);
6883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
6893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // If the loop was exited as a result of stopping the recording,
6913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // it is OK
6923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!mStarted) {
6933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return OK;
6943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
6953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Update the current buffer info
6973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: mCurrentSlot can be made a bufferstate since there
6983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // can be more than one "current" slots.
6993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Fifo::iterator front(mQueue.begin());
7003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentSlot = *front;
7013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer;
7023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp;
7033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Pass the data to the MediaBuffer
7053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: Change later to pass in only the metadata
7063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *buffer = new MediaBuffer(mCurrentBuf);
7073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    (*buffer)->setObserver(this);
7083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    (*buffer)->add_ref();
7093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp);
7103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
7123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
7133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7141a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
7153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    LOGV("signalBufferReturned");
7163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    bool foundBuffer = false;
7183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock autoLock(mMutex);
7193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!mStarted) {
7213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        LOGV("started = false. Nothing to do");
7223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return;
7233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
7243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    for (Fifo::iterator it = mQueue.begin(); it != mQueue.end(); ++it) {
7263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (mSlots[*it].mGraphicBuffer  ==  buffer->graphicBuffer()) {
7273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            LOGV("Buffer %d returned. Setting it 'FREE'. New Queue size = %d",
7283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                    *it, mQueue.size()-1);
7293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mSlots[*it].mBufferState = BufferSlot::FREE;
7303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mQueue.erase(it);
7313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            buffer->setObserver(0);
7323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            buffer->release();
7333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mDequeueCondition.signal();
7343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mFrameCompleteCondition.signal();
7353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            foundBuffer = true;
7363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
7373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
7383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
7393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!foundBuffer) {
7413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        CHECK_EQ(0, "signalBufferReturned: bogus buffer");
7423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
7433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
7443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} // end of namespace android
748