SurfaceMediaSource.cpp revision 6c6b4d0d2b98a7ceee8b697daaf611f8df3254fb
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
381a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag SanketiSurfaceMediaSource::SurfaceMediaSource(uint32_t bufW, uint32_t bufH) :
39b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mDefaultWidth(bufW),
40b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mDefaultHeight(bufH),
41b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mPixelFormat(0),
42b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
43b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mClientBufferCount(0),
44b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
45b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mCurrentSlot(INVALID_BUFFER_SLOT),
46b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mCurrentTimestamp(0),
47b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mSynchronousMode(true),
48b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mConnectedApi(NO_CONNECTED_API),
49b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi                mFrameRate(30),
50df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala                mStopped(false),
510c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                mNumFramesReceived(0),
520c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                mNumFramesEncoded(0),
53df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala                mFirstFrameTimestamp(0) {
543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::SurfaceMediaSource");
553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
591a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag SanketiSurfaceMediaSource::~SurfaceMediaSource() {
603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::~SurfaceMediaSource");
610c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    if (!mStopped) {
6260c2b4ece6528d6d3f4e9e2c7e45772b65c4b87dJames Dong        reset();
633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
661a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisize_t SurfaceMediaSource::getQueuedCount() const {
673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mQueue.size();
693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
711a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::setBufferCountServerLocked(int bufferCount) {
723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount > NUM_BUFFER_SLOTS)
733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // special-case, nothing to do
763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount == mBufferCount)
773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return OK;
783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!mClientBufferCount &&
803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        bufferCount >= mBufferCount) {
813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // easy, we just have more buffers
823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mBufferCount = bufferCount;
833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mServerBufferCount = bufferCount;
843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mDequeueCondition.signal();
853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } else {
863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // we're here because we're either
873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - reducing the number of available buffers
883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - or there is a client-buffer-count in effect
893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // less than 2 buffers is never allowed
913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (bufferCount < 2)
923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            return BAD_VALUE;
933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // when there is non client-buffer-count in effect, the client is not
953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // allowed to dequeue more than one buffer at a time,
963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // so the next time they dequeue a buffer, we know that they don't
973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // own one. the actual resizing will happen during the next
983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // dequeueBuffer.
993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mServerBufferCount = bufferCount;
1013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
1033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// Called from the consumer side
1061a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::setBufferCountServer(int bufferCount) {
1073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
1083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return setBufferCountServerLocked(bufferCount);
1093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1111a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::setBufferCount(int bufferCount) {
1123856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::setBufferCount");
1133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount > NUM_BUFFER_SLOTS) {
11429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setBufferCount: bufferCount is larger than the number of buffer slots");
1153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
1163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
1193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Error out if the user has dequeued buffers
1203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    for (int i = 0 ; i < mBufferCount ; i++) {
1213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
12229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("setBufferCount: client owns some buffers");
1233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            return INVALID_OPERATION;
1243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
1253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount == 0) {
1283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const int minBufferSlots = mSynchronousMode ?
1293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
1303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mClientBufferCount = 0;
1313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        bufferCount = (mServerBufferCount >= minBufferSlots) ?
1323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mServerBufferCount : minBufferSlots;
1333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return setBufferCountServerLocked(bufferCount);
1343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // We don't allow the client to set a buffer-count less than
1373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // MIN_ASYNC_BUFFER_SLOTS (3), there is no reason for it.
1383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (bufferCount < MIN_ASYNC_BUFFER_SLOTS) {
1393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
1403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // here we're guaranteed that the client doesn't have dequeued buffers
1433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // and will release all of its buffer references.
1443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mBufferCount = bufferCount;
1453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mClientBufferCount = bufferCount;
1463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentSlot = INVALID_BUFFER_SLOT;
1473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mQueue.clear();
1483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mDequeueCondition.signal();
1490c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    freeAllBuffersLocked();
1503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
1513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
15329a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennisstatus_t SurfaceMediaSource::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
1543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::requestBuffer");
1553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
15629a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis    if (slot < 0 || mBufferCount <= slot) {
15729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("requestBuffer: slot index out of range [0, %d]: %d",
15829a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis                mBufferCount, slot);
15929a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis        return BAD_VALUE;
1603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
16129a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis    mSlots[slot].mRequestBufferCalled = true;
16229a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis    *buf = mSlots[slot].mGraphicBuffer;
16329a142c7237821b6dc7bd1e8b56bb1efdc56767bJamie Gennis    return NO_ERROR;
1643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1661a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
1673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                                            uint32_t format, uint32_t usage) {
1683856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("dequeueBuffer");
1690c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    Mutex::Autolock lock(mMutex);
1703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Check for the buffer size- the client should just use the
1723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // default width and height, and not try to set those.
1733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // This is needed since
1743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // the getFormat() returns mDefaultWidth/ Height for the OMX. It is
1753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // queried by OMX in the beginning and not every time a frame comes.
1763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Not sure if there is  a way to update the
1773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // frame size while recording. So as of now, the client side
1783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // sets the default values via the constructor, and the encoder is
1793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // setup to encode frames of that size
1803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // The design might need to change in the future.
1813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: Currently just uses mDefaultWidth/Height. In the future
1823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // we might declare mHeight and mWidth and check against those here.
1833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if ((w != 0) || (h != 0)) {
184f76e1672c674620cb056f338a25ee4826d55dfcbPannag Sanketi        if ((w != mDefaultWidth) || (h != mDefaultHeight)) {
18529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("dequeuebuffer: invalid buffer size! Req: %dx%d, Found: %dx%d",
186f76e1672c674620cb056f338a25ee4826d55dfcbPannag Sanketi                    mDefaultWidth, mDefaultHeight, w, h);
187f76e1672c674620cb056f338a25ee4826d55dfcbPannag Sanketi            return BAD_VALUE;
188f76e1672c674620cb056f338a25ee4826d55dfcbPannag Sanketi        }
1893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
1903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    status_t returnFlags(OK);
1923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int found, foundSync;
1933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int dequeuedCount = 0;
1943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    bool tryAgain = true;
1953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    while (tryAgain) {
1963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // We need to wait for the FIFO to drain if the number of buffer
1973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // needs to change.
1983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //
1993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // The condition "number of buffer needs to change" is true if
2003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - the client doesn't care about how many buffers there are
2013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - AND the actual number of buffer is different from what was
2023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //   set in the last setBufferCountServer()
2033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //                         - OR -
2043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //   setBufferCountServer() was set to a value incompatible with
2053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //   the synchronization mode (for instance because the sync mode
2063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //   changed since)
2073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        //
2083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // As long as this condition is true AND the FIFO is not empty, we
2093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // wait on mDequeueCondition.
2103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        int minBufferCountNeeded = mSynchronousMode ?
2123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
2133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mClientBufferCount &&
2153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                ((mServerBufferCount != mBufferCount) ||
2163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                        (mServerBufferCount < minBufferCountNeeded))) {
2173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // wait for the FIFO to drain
2183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            while (!mQueue.isEmpty()) {
2193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("Waiting for the FIFO to drain");
2203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mDequeueCondition.wait(mMutex);
2213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
2220c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            if (mStopped) {
2230c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                return NO_INIT;
2240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            }
2253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // need to check again since the mode could have changed
2263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // while we were waiting
2273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            minBufferCountNeeded = mSynchronousMode ?
2283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                    MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
2293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mClientBufferCount &&
2323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                ((mServerBufferCount != mBufferCount) ||
2333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                        (mServerBufferCount < minBufferCountNeeded))) {
2343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // here we're guaranteed that mQueue is empty
2350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            freeAllBuffersLocked();
2363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mBufferCount = mServerBufferCount;
2373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (mBufferCount < minBufferCountNeeded)
2383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mBufferCount = minBufferCountNeeded;
2393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mCurrentSlot = INVALID_BUFFER_SLOT;
2403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
2413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // look for a free buffer to give to the client
2443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        found = INVALID_BUFFER_SLOT;
2453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        foundSync = INVALID_BUFFER_SLOT;
2463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        dequeuedCount = 0;
2473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        for (int i = 0; i < mBufferCount; i++) {
2483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            const int state = mSlots[i].mBufferState;
2493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (state == BufferSlot::DEQUEUED) {
2503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                dequeuedCount++;
2513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                continue; // won't be continuing if could
2523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // dequeue a non 'FREE' current slot like
2533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // that in SurfaceTexture
2543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
2553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // In case of Encoding, we do not deque the mCurrentSlot buffer
2563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            //  since we follow synchronous mode (unlike possibly in
2573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            //  SurfaceTexture that could be using the asynch mode
2583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            //  or has some mechanism in GL to be able to wait till the
2593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            //  currentslot is done using the data)
2603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // Here, we have to wait for the MPEG4Writer(or equiv)
2613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // to tell us when it's done using the current buffer
2623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (state == BufferSlot::FREE) {
2633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                foundSync = i;
2643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // Unlike that in SurfaceTexture,
2653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // We don't need to worry if it is the
2663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                // currentslot or not as it is in state FREE
2673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                found = i;
2683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                break;
2693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
2703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // clients are not allowed to dequeue more than one buffer
2733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // if they didn't set a buffer count.
2743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mClientBufferCount && dequeuedCount) {
2753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            return -EINVAL;
2763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // See whether a buffer has been queued since the last setBufferCount so
2793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
2803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        bool bufferHasBeenQueued = mCurrentSlot != INVALID_BUFFER_SLOT;
2813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (bufferHasBeenQueued) {
2823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // make sure the client is not trying to dequeue more buffers
2833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // than allowed.
2843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            const int avail = mBufferCount - (dequeuedCount+1);
2853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
28629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded (dequeued=%d)",
2873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                        MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
2883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                        dequeuedCount);
2893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                return -EBUSY;
2903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
2913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
2923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // we're in synchronous mode and didn't find a buffer, we need to wait
2943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // for for some buffers to be consumed
2953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
2963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (tryAgain) {
2973856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Waiting..In synchronous mode and no buffer to dequeue");
2983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mDequeueCondition.wait(mMutex);
2993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
3000c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        if (mStopped) {
3010c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            return NO_INIT;
3020c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        }
3033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
3063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // foundSync guaranteed to be != INVALID_BUFFER_SLOT
3073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        found = foundSync;
3083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (found == INVALID_BUFFER_SLOT) {
3113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return -EBUSY;
3123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3140c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    const int bufIndex = found;
3153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *outBuf = found;
3163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    const bool useDefaultSize = !w && !h;
3183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (useDefaultSize) {
3193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // use the default size
3203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        w = mDefaultWidth;
3213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        h = mDefaultHeight;
3223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    const bool updateFormat = (format != 0);
3253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!updateFormat) {
3263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // keep the current (or default) format
3273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        format = mPixelFormat;
3283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // buffer is now in DEQUEUED (but can also be current at the same time,
3313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // if we're in synchronous mode)
3320c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mSlots[bufIndex].mBufferState = BufferSlot::DEQUEUED;
3333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    const sp<GraphicBuffer>& buffer(mSlots[bufIndex].mGraphicBuffer);
3353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if ((buffer == NULL) ||
3363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        (uint32_t(buffer->width)  != w) ||
3373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        (uint32_t(buffer->height) != h) ||
3383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        (uint32_t(buffer->format) != format) ||
3393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        ((uint32_t(buffer->usage) & usage) != usage)) {
34069aac3e6cd68e8c305a41b2677123db7662efd4bJamie Gennis            // XXX: This will be changed to USAGE_HW_VIDEO_ENCODER once driver
34169aac3e6cd68e8c305a41b2677123db7662efd4bJamie Gennis            // issues with that flag get fixed.
34269aac3e6cd68e8c305a41b2677123db7662efd4bJamie Gennis            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
3433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            status_t error;
3443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            sp<GraphicBuffer> graphicBuffer(
3453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                    mGraphicBufferAlloc->createGraphicBuffer(
3463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                                    w, h, format, usage, &error));
3473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (graphicBuffer == 0) {
34829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
3493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                return error;
3503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
3513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (updateFormat) {
3523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mPixelFormat = format;
3533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
3540c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mSlots[bufIndex].mGraphicBuffer = graphicBuffer;
3550c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mSlots[bufIndex].mRequestBufferCalled = false;
3563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
3573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return returnFlags;
3593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
3603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3610c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// TODO: clean this up
3621a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::setSynchronousMode(bool enabled) {
3633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
3640c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    if (mStopped) {
36529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("setSynchronousMode: SurfaceMediaSource has been stopped!");
3660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        return NO_INIT;
3670c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    }
3683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!enabled) {
3700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        // Async mode is not allowed
37129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("SurfaceMediaSource can be used only synchronous mode!");
3720c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        return INVALID_OPERATION;
3733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mSynchronousMode != enabled) {
3763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - if we're going to asynchronous mode, the queue is guaranteed to be
3773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // empty here
3783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // - if the client set the number of buffers, we're guaranteed that
3793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // we have at least 3 (because we don't allow less)
3803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mSynchronousMode = enabled;
3813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mDequeueCondition.signal();
3823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3830c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    return OK;
3843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
3853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
386820a509687599edb8ff1a7577de8b9295f416263Mathias Agopianstatus_t SurfaceMediaSource::connect(int api,
387820a509687599edb8ff1a7577de8b9295f416263Mathias Agopian        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
3883856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::connect");
3893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
3900c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi
3910c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    if (mStopped) {
39229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Connect: SurfaceMediaSource has been stopped!");
3930c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        return NO_INIT;
3940c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    }
3950c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi
396b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    status_t err = NO_ERROR;
3973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    switch (api) {
3983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_EGL:
3993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_CPU:
4003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_MEDIA:
4013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_CAMERA:
4023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (mConnectedApi != NO_CONNECTED_API) {
4033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                err = -EINVAL;
4043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            } else {
4053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mConnectedApi = api;
406820a509687599edb8ff1a7577de8b9295f416263Mathias Agopian                *outWidth = mDefaultWidth;
407820a509687599edb8ff1a7577de8b9295f416263Mathias Agopian                *outHeight = mDefaultHeight;
408820a509687599edb8ff1a7577de8b9295f416263Mathias Agopian                *outTransform = 0;
4093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
4103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
4113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        default:
4123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            err = -EINVAL;
4133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
4143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return err;
4163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
4173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4180c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// This is called by the client side when it is done
4190c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// TODO: Currently, this also sets mStopped to true which
4200c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// is needed for unblocking the encoder which might be
4210c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// waiting to read more frames. So if on the client side,
4220c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// the same thread supplies the frames and also calls stop
4230c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// on the encoder, the client has to call disconnect before
4240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// it calls stop.
4250c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// In the case of the camera,
4260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// that need not be required since the thread supplying the
4270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi// frames is separate than the one calling stop.
4281a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::disconnect(int api) {
4293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::disconnect");
4303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
4310c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi
4320c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    if (mStopped) {
43329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("disconnect: SurfaceMediaSoource is already stopped!");
4340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        return NO_INIT;
4350c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    }
4360c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi
437b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    status_t err = NO_ERROR;
4383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    switch (api) {
4393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_EGL:
4403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_CPU:
4413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_MEDIA:
4423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        case NATIVE_WINDOW_API_CAMERA:
4433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            if (mConnectedApi == api) {
4443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                mConnectedApi = NO_CONNECTED_API;
4450c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                mStopped = true;
4460c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                mDequeueCondition.signal();
4470c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                mFrameAvailableCondition.signal();
4483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            } else {
4493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                err = -EINVAL;
4503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
4513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
4523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        default:
4533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            err = -EINVAL;
4543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
4553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return err;
4573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
4583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4590c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketistatus_t SurfaceMediaSource::queueBuffer(int bufIndex, int64_t timestamp,
4603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
4613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("queueBuffer");
4623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
4647dc9b309f1ce01308bcfde9948ebfece32dc2870Pannag Sanketi    *outWidth = mDefaultWidth;
4657dc9b309f1ce01308bcfde9948ebfece32dc2870Pannag Sanketi    *outHeight = mDefaultHeight;
4667dc9b309f1ce01308bcfde9948ebfece32dc2870Pannag Sanketi    *outTransform = 0;
4677dc9b309f1ce01308bcfde9948ebfece32dc2870Pannag Sanketi
4680c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    if (bufIndex < 0 || bufIndex >= mBufferCount) {
46929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("queueBuffer: slot index out of range [0, %d]: %d",
4700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                mBufferCount, bufIndex);
4713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return -EINVAL;
4720c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    } else if (mSlots[bufIndex].mBufferState != BufferSlot::DEQUEUED) {
47329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("queueBuffer: slot %d is not owned by the client (state=%d)",
4740c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                bufIndex, mSlots[bufIndex].mBufferState);
4753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return -EINVAL;
4760c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    } else if (!mSlots[bufIndex].mRequestBufferCalled) {
47729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("queueBuffer: slot %d was enqueued without requesting a "
4780c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                "buffer", bufIndex);
4793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return -EINVAL;
4803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
482df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    if (mNumFramesReceived == 0) {
483df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala        mFirstFrameTimestamp = timestamp;
484df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala        // Initial delay
485df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala        if (mStartTimeNs > 0) {
486df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala            if (timestamp < mStartTimeNs) {
487df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala                // This frame predates start of record, discard
488df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala                mSlots[bufIndex].mBufferState = BufferSlot::FREE;
489df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala                mDequeueCondition.signal();
490df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala                return OK;
491df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala            }
492df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala            mStartTimeNs = timestamp - mStartTimeNs;
493df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala        }
494df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    }
495df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    timestamp = mStartTimeNs + (timestamp - mFirstFrameTimestamp);
496df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala
497df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    mNumFramesReceived++;
4983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mSynchronousMode) {
4993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // in synchronous mode we queue all buffers in a FIFO
5000c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        mQueue.push_back(bufIndex);
5013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Client queued buf# %d @slot: %d, Q size = %d, handle = %p, timestamp = %lld",
5020c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mNumFramesReceived, bufIndex, mQueue.size(),
5030c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mSlots[bufIndex].mGraphicBuffer->handle, timestamp);
5043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } else {
5053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        // in asynchronous mode we only keep the most recent buffer
5063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (mQueue.empty()) {
5070c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mQueue.push_back(bufIndex);
5083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        } else {
5093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            Fifo::iterator front(mQueue.begin());
5103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // buffer currently queued is freed
5113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mSlots[*front].mBufferState = BufferSlot::FREE;
5123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            // and we record the new buffer index in the queued list
5130c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            *front = bufIndex;
5143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
5153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5170c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mSlots[bufIndex].mBufferState = BufferSlot::QUEUED;
5180c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mSlots[bufIndex].mTimestamp = timestamp;
5193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: (Confirm) Don't want to signal dequeue here.
5203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // May be just in asynchronous mode?
5213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // mDequeueCondition.signal();
5223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Once the queuing is done, we need to let the listener
5243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // and signal the buffer consumer (encoder) know that a
5253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // buffer is available
5263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    onFrameReceivedLocked();
5273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
5303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder)
5343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// or listeners that a frame has been received
5353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// It is supposed to be called only from queuebuffer.
5363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// The buffer is NOT made available for dequeueing immediately. We need to
5373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// wait to hear from StageFrightRecorder to set the buffer FREE
5383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi// Make sure this is called when the mutex is locked
5391a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::onFrameReceivedLocked() {
5403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("On Frame Received locked");
5413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Signal the encoder that a new frame has arrived
5423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameAvailableCondition.signal();
5433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // call back the listener
5451a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi    // TODO: The listener may not be needed in SurfaceMediaSource at all.
5463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // This can be made a SurfaceTexture specific thing
5473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    sp<FrameAvailableListener> listener;
5483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (mSynchronousMode || mQueue.empty()) {
5493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        listener = mFrameAvailableListener;
5503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (listener != 0) {
5533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        listener->onFrameAvailable();
5543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
5563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5590c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketivoid SurfaceMediaSource::cancelBuffer(int bufIndex) {
5603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::cancelBuffer");
5613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5620c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    if (bufIndex < 0 || bufIndex >= mBufferCount) {
56329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("cancelBuffer: slot index out of range [0, %d]: %d",
5640c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                mBufferCount, bufIndex);
5653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return;
5660c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    } else if (mSlots[bufIndex].mBufferState != BufferSlot::DEQUEUED) {
56729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
5680c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                bufIndex, mSlots[bufIndex].mBufferState);
5693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return;
5703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5710c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mSlots[bufIndex].mBufferState = BufferSlot::FREE;
5723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mDequeueCondition.signal();
5733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5751a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketinsecs_t SurfaceMediaSource::getTimestamp() {
5763856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::getTimestamp");
5773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mCurrentTimestamp;
5793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5821a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::setFrameAvailableListener(
5833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const sp<FrameAvailableListener>& listener) {
5843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("SurfaceMediaSource::setFrameAvailableListener");
5853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5863399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameAvailableListener = listener;
5873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5890c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketivoid SurfaceMediaSource::freeAllBuffersLocked() {
5903856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("freeAllBuffersLocked");
5913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
5923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mSlots[i].mGraphicBuffer = 0;
5933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mSlots[i].mBufferState = BufferSlot::FREE;
5943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
5953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
5963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
5971a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const {
5983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
5993399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mCurrentBuf;
6003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6021a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketiint SurfaceMediaSource::query(int what, int* outValue)
6033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("query");
6053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
6063399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int value;
6073399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    switch (what) {
6083399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    case NATIVE_WINDOW_WIDTH:
6093399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        value = mDefaultWidth;
6103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
6113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            value = mCurrentBuf->width;
6123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        break;
6133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    case NATIVE_WINDOW_HEIGHT:
6143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        value = mDefaultHeight;
6153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
6163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            value = mCurrentBuf->height;
6173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        break;
6183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    case NATIVE_WINDOW_FORMAT:
6193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        value = mPixelFormat;
6203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        break;
6213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
6223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        value = mSynchronousMode ?
6233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
6243399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        break;
6253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    default:
6263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return BAD_VALUE;
6273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
6283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    outValue[0] = value;
6293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return NO_ERROR;
6303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6321a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::dump(String8& result) const
6333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    char buffer[1024];
6353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    dump(result, "", buffer, 1024);
6363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6381a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::dump(String8& result, const char* prefix,
6393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        char* buffer, size_t SIZE) const
6403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock _l(mMutex);
6423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    snprintf(buffer, SIZE,
6433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
6443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            "mPixelFormat=%d, \n",
6453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            prefix, mBufferCount, mSynchronousMode, mDefaultWidth, mDefaultHeight,
6463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mPixelFormat);
6473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    result.append(buffer);
6483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    String8 fifo;
6503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    int fifoSize = 0;
6513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Fifo::const_iterator i(mQueue.begin());
6523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    while (i != mQueue.end()) {
6533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        snprintf(buffer, SIZE, "%02d ", *i++);
6543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        fifoSize++;
6553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        fifo.append(buffer);
6563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
6573399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    result.append(buffer);
6593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    struct {
6613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const char * operator()(int state) const {
6623399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            switch (state) {
6633399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                case BufferSlot::DEQUEUED: return "DEQUEUED";
6643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                case BufferSlot::QUEUED: return "QUEUED";
6653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                case BufferSlot::FREE: return "FREE";
6663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                default: return "Unknown";
6673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            }
6683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
6693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    } stateName;
6703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
6713399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    for (int i = 0; i < mBufferCount; i++) {
6723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const BufferSlot& slot(mSlots[i]);
6733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        snprintf(buffer, SIZE,
6743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                "%s%s[%02d] state=%-8s, "
6753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                "timestamp=%lld\n",
6763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                prefix, (i==mCurrentSlot)?">":" ", i, stateName(slot.mBufferState),
6773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi                slot.mTimestamp
6783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        );
6793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        result.append(buffer);
6803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
6813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
683b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketistatus_t SurfaceMediaSource::setFrameRate(int32_t fps)
6843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
6853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
686b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    const int MAX_FRAME_RATE = 60;
687b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    if (fps < 0 || fps > MAX_FRAME_RATE) {
688b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        return BAD_VALUE;
689b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    }
6903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameRate = fps;
691b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    return OK;
6923399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
6933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
694b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketibool SurfaceMediaSource::isMetaDataStoredInVideoBuffers() const {
6953856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("isMetaDataStoredInVideoBuffers");
696b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    return true;
697b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi}
698b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
699b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketiint32_t SurfaceMediaSource::getFrameRate( ) const {
7003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
7013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mFrameRate;
7023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
7033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7041a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::start(MetaData *params)
7053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
7063856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("started!");
707df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala
708df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    mStartTimeNs = 0;
709df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    int64_t startTimeUs;
710df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    if (params && params->findInt64(kKeyTime, &startTimeUs)) {
711df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala        mStartTimeNs = startTimeUs * 1000;
712df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    }
713df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala
7143399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
7153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
7163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7173399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
71860c2b4ece6528d6d3f4e9e2c7e45772b65c4b87dJames Dongstatus_t SurfaceMediaSource::reset()
7193399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
72060c2b4ece6528d6d3f4e9e2c7e45772b65c4b87dJames Dong    ALOGV("Reset");
7213399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7223399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
7233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: Add waiting on mFrameCompletedCondition here?
7240c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mStopped = true;
7253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameAvailableCondition.signal();
7260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mDequeueCondition.signal();
7270c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mQueue.clear();
7280c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    freeAllBuffersLocked();
7293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
7313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
7323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7331a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisp<MetaData> SurfaceMediaSource::getFormat()
7343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
7353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getFormat");
7363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock autoLock(mMutex);
7373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    sp<MetaData> meta = new MetaData;
738b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
7393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyWidth, mDefaultWidth);
7403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyHeight, mDefaultHeight);
7413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // The encoder format is set as an opaque colorformat
7423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // The encoder will later find out the actual colorformat
7433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // from the GL Frames itself.
7443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
7453399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyStride, mDefaultWidth);
7463399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeySliceHeight, mDefaultHeight);
7473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyFrameRate, mFrameRate);
7483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
7493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return meta;
7503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
7513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7521a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::read( MediaBuffer **buffer,
7530c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                                    const ReadOptions *options)
7543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
7550c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    Mutex::Autolock autoLock(mMutex) ;
7560c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi
7573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Read. Size of queued buffer: %d", mQueue.size());
7583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *buffer = NULL;
7593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // If the recording has started and the queue is empty, then just
7613399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // wait here till the frames come in from the client side
7620c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    while (!mStopped && mQueue.empty()) {
7633856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("NO FRAMES! Recorder waiting for FrameAvailableCondition");
7643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        mFrameAvailableCondition.wait(mMutex);
7653399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
7663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // If the loop was exited as a result of stopping the recording,
7683399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // it is OK
7690c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    if (mStopped) {
7703856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM.");
7713e9bf4061475ae0d01c57e32c13e63808aa3e31fPannag Sanketi        return ERROR_END_OF_STREAM;
7723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
7733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7743399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // Update the current buffer info
7753399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // TODO: mCurrentSlot can be made a bufferstate since there
7763399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // can be more than one "current" slots.
7773399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Fifo::iterator front(mQueue.begin());
7783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentSlot = *front;
7790c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mQueue.erase(front);
7803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer;
7810c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    int64_t prevTimeStamp = mCurrentTimestamp;
7823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp;
783df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala
7840c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mNumFramesEncoded++;
785a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    // Pass the data to the MediaBuffer. Pass in only the metadata
786a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    passMetadataBufferLocked(buffer);
787a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi
7883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    (*buffer)->setObserver(this);
7893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    (*buffer)->add_ref();
7900c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp / 1000);
7913856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Frames encoded = %d, timestamp = %lld, time diff = %lld",
7920c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mNumFramesEncoded, mCurrentTimestamp / 1000,
7930c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mCurrentTimestamp / 1000 - prevTimeStamp / 1000);
7943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
7953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
7963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
7973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
798a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// Pass the data to the MediaBuffer. Pass in only the metadata
799a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// The metadata passed consists of two parts:
800a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// 1. First, there is an integer indicating that it is a GRAlloc
801a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// source (kMetadataBufferTypeGrallocSource)
802a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// 2. This is followed by the buffer_handle_t that is a handle to the
803a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// GRalloc buffer. The encoder needs to interpret this GRalloc handle
804a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// and encode the frames.
805a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// --------------------------------------------------------------
806a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// |  kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
807a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// --------------------------------------------------------------
808a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi// Note: Call only when you have the lock
809a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketivoid SurfaceMediaSource::passMetadataBufferLocked(MediaBuffer **buffer) {
8103856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("passMetadataBuffer");
811a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    // MediaBuffer allocates and owns this data
812a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    MediaBuffer *tempBuffer =
813a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi        new MediaBuffer(4 + sizeof(buffer_handle_t));
814a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    char *data = (char *)tempBuffer->data();
815a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    if (data == NULL) {
81629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Cannot allocate memory for metadata buffer!");
817a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi        return;
818a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    }
819a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    OMX_U32 type = kMetadataBufferTypeGrallocSource;
820a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    memcpy(data, &type, 4);
821a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t));
822a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    *buffer = tempBuffer;
823a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi
8243856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("handle = %p, , offset = %d, length = %d",
8250c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mCurrentBuf->handle, (*buffer)->range_length(), (*buffer)->range_offset());
8260c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi}
827a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi
8281a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
8293856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("signalBufferReturned");
8303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
8313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    bool foundBuffer = false;
8323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock autoLock(mMutex);
8333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
8340c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    if (mStopped) {
8353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("signalBufferReturned: mStopped = true! Nothing to do!");
8363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        return;
8373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
8383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
8390c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    for (int id = 0; id < NUM_BUFFER_SLOTS; id++) {
8400c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        if (mSlots[id].mGraphicBuffer == NULL) {
8410c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            continue;
8420c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        }
8430c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        if (checkBufferMatchesSlot(id, buffer)) {
8443856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Slot %d returned, matches handle = %p", id,
8450c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi                    mSlots[id].mGraphicBuffer->handle);
8460c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mSlots[id].mBufferState = BufferSlot::FREE;
8473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            buffer->setObserver(0);
8483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            buffer->release();
8493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mDequeueCondition.signal();
8503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            mFrameCompleteCondition.signal();
8513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            foundBuffer = true;
8523399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
8533399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
8543399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
8553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
8563399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!foundBuffer) {
857f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong        CHECK(!"signalBufferReturned: bogus buffer");
8583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
8593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
8603399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
861a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketibool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) {
8623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("Check if Buffer matches slot");
863a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    // need to convert to char* for pointer arithmetic and then
864a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    // copy the byte stream into our handle
865a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    buffer_handle_t bufferHandle ;
866a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    memcpy( &bufferHandle, (char *)(buffer->data()) + 4, sizeof(buffer_handle_t));
867a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    return mSlots[slot].mGraphicBuffer->handle  ==  bufferHandle;
868a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi}
8693399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
8703399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} // end of namespace android
871