SurfaceMediaSource.cpp revision f76e1672c674620cb056f338a25ee4826d55dfcb
10cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard/*
20cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * Copyright (C) 2011 The Android Open Source Project
30cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard *
40cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * Licensed under the Apache License, Version 2.0 (the "License");
50cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * you may not use this file except in compliance with the License.
60cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * You may obtain a copy of the License at
70cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard *
80cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard *      http://www.apache.org/licenses/LICENSE-2.0
90cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard *
100cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * Unless required by applicable law or agreed to in writing, software
110cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * distributed under the License is distributed on an "AS IS" BASIS,
120cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * See the License for the specific language governing permissions and
140cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard * limitations under the License.
150cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard */
160cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
170cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard// #define LOG_NDEBUG 0
180cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#define LOG_TAG "SurfaceMediaSource"
19256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani
200cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <media/stagefright/SurfaceMediaSource.h>
210cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <ui/GraphicBuffer.h>
229a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik#include <media/stagefright/MetaData.h>
230cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <media/stagefright/MediaDefs.h>
240cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <media/stagefright/MediaDebug.h>
250cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <media/stagefright/openmax/OMX_IVCommon.h>
260cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <media/stagefright/MetadataBufferType.h>
270cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
280cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <surfaceflinger/ISurfaceComposer.h>
290cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <surfaceflinger/SurfaceComposerClient.h>
300cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <surfaceflinger/IGraphicBufferAlloc.h>
310cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <OMX_Component.h>
320cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
330cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard#include <utils/Log.h>
349a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik#include <utils/String8.h>
359a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik
369a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheiknamespace android {
370cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
380cc0544a2995c7eb54a830ae54db60af89d4073dJean ChalardSurfaceMediaSource::SurfaceMediaSource(uint32_t bufW, uint32_t bufH) :
390cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mDefaultWidth(bufW),
409a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik                mDefaultHeight(bufH),
410cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mPixelFormat(0),
420cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mBufferCount(MIN_ASYNC_BUFFER_SLOTS),
430cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mClientBufferCount(0),
440cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mServerBufferCount(MIN_ASYNC_BUFFER_SLOTS),
450cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mCurrentSlot(INVALID_BUFFER_SLOT),
460cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mCurrentTimestamp(0),
470cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mSynchronousMode(true),
48a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka                mConnectedApi(NO_CONNECTED_API),
49b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalard                mFrameRate(30),
500cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mStarted(false)   {
510cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    LOGV("SurfaceMediaSource::SurfaceMediaSource");
520cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
530cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
540cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard}
550cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
560cc0544a2995c7eb54a830ae54db60af89d4073dJean ChalardSurfaceMediaSource::~SurfaceMediaSource() {
57e077c014616f7b4e28dbbfab622ba36c8e922268Jean Chalard    LOGV("SurfaceMediaSource::~SurfaceMediaSource");
58e077c014616f7b4e28dbbfab622ba36c8e922268Jean Chalard    if (mStarted) {
590cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        stop();
60256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani    }
610cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    freeAllBuffers();
620cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard}
630cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
640cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardsize_t SurfaceMediaSource::getQueuedCount() const {
650cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    Mutex::Autolock lock(mMutex);
660cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    return mQueue.size();
670cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard}
680cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
690cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardstatus_t SurfaceMediaSource::setBufferCountServerLocked(int bufferCount) {
700cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    if (bufferCount > NUM_BUFFER_SLOTS)
710cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        return BAD_VALUE;
720cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
730cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // special-case, nothing to do
74e077c014616f7b4e28dbbfab622ba36c8e922268Jean Chalard    if (bufferCount == mBufferCount)
750cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        return OK;
76256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani
770cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    if (!mClientBufferCount &&
780cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        bufferCount >= mBufferCount) {
790cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // easy, we just have more buffers
800cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        mBufferCount = bufferCount;
810cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        mServerBufferCount = bufferCount;
820cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        mDequeueCondition.signal();
830cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    } else {
840cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // we're here because we're either
850cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // - reducing the number of available buffers
860cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // - or there is a client-buffer-count in effect
870cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
880cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // less than 2 buffers is never allowed
890cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        if (bufferCount < 2)
900cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard            return BAD_VALUE;
910cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
920cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // when there is non client-buffer-count in effect, the client is not
930cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // allowed to dequeue more than one buffer at a time,
940cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // so the next time they dequeue a buffer, we know that they don't
950cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // own one. the actual resizing will happen during the next
960cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        // dequeueBuffer.
970cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
98b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalard        mServerBufferCount = bufferCount;
99b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalard    }
100b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalard    return OK;
101b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalard}
102b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalard
103b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalard// Called from the consumer side
104b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalardstatus_t SurfaceMediaSource::setBufferCountServer(int bufferCount) {
105b8ff8ca9d9d17f61f3f0e019ed0b62fe13d1a33fJean Chalard    Mutex::Autolock lock(mMutex);
1060cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    return setBufferCountServerLocked(bufferCount);
1070cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard}
1080cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
109256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matanistatus_t SurfaceMediaSource::setBufferCount(int bufferCount) {
110256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani    LOGV("SurfaceMediaSource::setBufferCount");
111256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani    if (bufferCount > NUM_BUFFER_SLOTS) {
112256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani        LOGE("setBufferCount: bufferCount is larger than the number of buffer slots");
113256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani        return BAD_VALUE;
114256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani    }
115256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani
116256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani    Mutex::Autolock lock(mMutex);
117256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani    // Error out if the user has dequeued buffers
118256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani    for (int i = 0 ; i < mBufferCount ; i++) {
119256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani        if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) {
120256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani            LOGE("setBufferCount: client owns some buffers");
1219a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik            return INVALID_OPERATION;
1229a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik        }
1239a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik    }
1249a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik
1259a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik    if (bufferCount == 0) {
1269a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik        const int minBufferSlots = mSynchronousMode ?
1279a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
1289a3598b0ee8ab5d8b90e35d65190ecea1aef7828Mohammadinamul Sheik        mClientBufferCount = 0;
129256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani        bufferCount = (mServerBufferCount >= minBufferSlots) ?
130256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani                mServerBufferCount : minBufferSlots;
131256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani        return setBufferCountServerLocked(bufferCount);
132256b1b2a1e054773987a0672b4ac3c867a4dbd27Jatin Matani    }
1330cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1340cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // We don't allow the client to set a buffer-count less than
1350cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // MIN_ASYNC_BUFFER_SLOTS (3), there is no reason for it.
1360cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    if (bufferCount < MIN_ASYNC_BUFFER_SLOTS) {
1370cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        return BAD_VALUE;
1380cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1390cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1400cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // here we're guaranteed that the client doesn't have dequeued buffers
1410cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // and will release all of its buffer references.
1420cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    freeAllBuffers();
1430cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    mBufferCount = bufferCount;
1440cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    mClientBufferCount = bufferCount;
1450cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    mCurrentSlot = INVALID_BUFFER_SLOT;
1460cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    mQueue.clear();
1470cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    mDequeueCondition.signal();
1480cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    return OK;
1490cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard}
1500cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1510cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardstatus_t SurfaceMediaSource::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
1520cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    LOGV("SurfaceMediaSource::requestBuffer");
1530cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    Mutex::Autolock lock(mMutex);
1540cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    if (slot < 0 || mBufferCount <= slot) {
1550cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        LOGE("requestBuffer: slot index out of range [0, %d]: %d",
1560cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                mBufferCount, slot);
1570cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard        return BAD_VALUE;
1580cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    }
1590cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    mSlots[slot].mRequestBufferCalled = true;
1600cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    *buf = mSlots[slot].mGraphicBuffer;
1610cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    return NO_ERROR;
1620cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard}
1630cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1640cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalardstatus_t SurfaceMediaSource::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
1650cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard                                            uint32_t format, uint32_t usage) {
1660cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    LOGV("dequeueBuffer");
1670cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1680cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard
1690cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // Check for the buffer size- the client should just use the
1700cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // default width and height, and not try to set those.
1710cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // This is needed since
1720cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // the getFormat() returns mDefaultWidth/ Height for the OMX. It is
1730cc0544a2995c7eb54a830ae54db60af89d4073dJean Chalard    // queried by OMX in the beginning and not every time a frame comes.
174    // Not sure if there is  a way to update the
175    // frame size while recording. So as of now, the client side
176    // sets the default values via the constructor, and the encoder is
177    // setup to encode frames of that size
178    // The design might need to change in the future.
179    // TODO: Currently just uses mDefaultWidth/Height. In the future
180    // we might declare mHeight and mWidth and check against those here.
181    if ((w != 0) || (h != 0)) {
182        if ((w != mDefaultWidth) || (h != mDefaultHeight)) {
183            LOGE("dequeuebuffer: invalid buffer size! Req: %dx%d, Found: %dx%d",
184                    mDefaultWidth, mDefaultHeight, w, h);
185            return BAD_VALUE;
186        }
187    }
188
189    Mutex::Autolock lock(mMutex);
190
191    status_t returnFlags(OK);
192
193    int found, foundSync;
194    int dequeuedCount = 0;
195    bool tryAgain = true;
196    while (tryAgain) {
197        // We need to wait for the FIFO to drain if the number of buffer
198        // needs to change.
199        //
200        // The condition "number of buffer needs to change" is true if
201        // - the client doesn't care about how many buffers there are
202        // - AND the actual number of buffer is different from what was
203        //   set in the last setBufferCountServer()
204        //                         - OR -
205        //   setBufferCountServer() was set to a value incompatible with
206        //   the synchronization mode (for instance because the sync mode
207        //   changed since)
208        //
209        // As long as this condition is true AND the FIFO is not empty, we
210        // wait on mDequeueCondition.
211
212        int minBufferCountNeeded = mSynchronousMode ?
213                MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
214
215        if (!mClientBufferCount &&
216                ((mServerBufferCount != mBufferCount) ||
217                        (mServerBufferCount < minBufferCountNeeded))) {
218            // wait for the FIFO to drain
219            while (!mQueue.isEmpty()) {
220                LOGV("Waiting for the FIFO to drain");
221                mDequeueCondition.wait(mMutex);
222            }
223            // need to check again since the mode could have changed
224            // while we were waiting
225            minBufferCountNeeded = mSynchronousMode ?
226                    MIN_SYNC_BUFFER_SLOTS : MIN_ASYNC_BUFFER_SLOTS;
227        }
228
229        if (!mClientBufferCount &&
230                ((mServerBufferCount != mBufferCount) ||
231                        (mServerBufferCount < minBufferCountNeeded))) {
232            // here we're guaranteed that mQueue is empty
233            freeAllBuffers();
234            mBufferCount = mServerBufferCount;
235            if (mBufferCount < minBufferCountNeeded)
236                mBufferCount = minBufferCountNeeded;
237            mCurrentSlot = INVALID_BUFFER_SLOT;
238            returnFlags |= ISurfaceTexture::RELEASE_ALL_BUFFERS;
239        }
240
241        // look for a free buffer to give to the client
242        found = INVALID_BUFFER_SLOT;
243        foundSync = INVALID_BUFFER_SLOT;
244        dequeuedCount = 0;
245        for (int i = 0; i < mBufferCount; i++) {
246            const int state = mSlots[i].mBufferState;
247            if (state == BufferSlot::DEQUEUED) {
248                dequeuedCount++;
249                continue; // won't be continuing if could
250                // dequeue a non 'FREE' current slot like
251                // that in SurfaceTexture
252            }
253            // In case of Encoding, we do not deque the mCurrentSlot buffer
254            //  since we follow synchronous mode (unlike possibly in
255            //  SurfaceTexture that could be using the asynch mode
256            //  or has some mechanism in GL to be able to wait till the
257            //  currentslot is done using the data)
258            // Here, we have to wait for the MPEG4Writer(or equiv)
259            // to tell us when it's done using the current buffer
260            if (state == BufferSlot::FREE) {
261                foundSync = i;
262                // Unlike that in SurfaceTexture,
263                // We don't need to worry if it is the
264                // currentslot or not as it is in state FREE
265                found = i;
266                break;
267            }
268        }
269
270        // clients are not allowed to dequeue more than one buffer
271        // if they didn't set a buffer count.
272        if (!mClientBufferCount && dequeuedCount) {
273            return -EINVAL;
274        }
275
276        // See whether a buffer has been queued since the last setBufferCount so
277        // we know whether to perform the MIN_UNDEQUEUED_BUFFERS check below.
278        bool bufferHasBeenQueued = mCurrentSlot != INVALID_BUFFER_SLOT;
279        if (bufferHasBeenQueued) {
280            // make sure the client is not trying to dequeue more buffers
281            // than allowed.
282            const int avail = mBufferCount - (dequeuedCount+1);
283            if (avail < (MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode))) {
284                LOGE("dequeueBuffer: MIN_UNDEQUEUED_BUFFERS=%d exceeded (dequeued=%d)",
285                        MIN_UNDEQUEUED_BUFFERS-int(mSynchronousMode),
286                        dequeuedCount);
287                return -EBUSY;
288            }
289        }
290
291        // we're in synchronous mode and didn't find a buffer, we need to wait
292        // for for some buffers to be consumed
293        tryAgain = mSynchronousMode && (foundSync == INVALID_BUFFER_SLOT);
294        if (tryAgain) {
295            LOGW("Waiting..In synchronous mode and no buffer to dQ");
296            mDequeueCondition.wait(mMutex);
297        }
298    }
299
300    if (mSynchronousMode && found == INVALID_BUFFER_SLOT) {
301        // foundSync guaranteed to be != INVALID_BUFFER_SLOT
302        found = foundSync;
303    }
304
305    if (found == INVALID_BUFFER_SLOT) {
306        return -EBUSY;
307    }
308
309    const int buf = found;
310    *outBuf = found;
311
312    const bool useDefaultSize = !w && !h;
313    if (useDefaultSize) {
314        // use the default size
315        w = mDefaultWidth;
316        h = mDefaultHeight;
317    }
318
319    const bool updateFormat = (format != 0);
320    if (!updateFormat) {
321        // keep the current (or default) format
322        format = mPixelFormat;
323    }
324
325    // buffer is now in DEQUEUED (but can also be current at the same time,
326    // if we're in synchronous mode)
327    mSlots[buf].mBufferState = BufferSlot::DEQUEUED;
328
329    const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer);
330    if ((buffer == NULL) ||
331        (uint32_t(buffer->width)  != w) ||
332        (uint32_t(buffer->height) != h) ||
333        (uint32_t(buffer->format) != format) ||
334        ((uint32_t(buffer->usage) & usage) != usage)) {
335            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
336            status_t error;
337            sp<GraphicBuffer> graphicBuffer(
338                    mGraphicBufferAlloc->createGraphicBuffer(
339                                    w, h, format, usage, &error));
340            if (graphicBuffer == 0) {
341                LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer failed");
342                return error;
343            }
344            if (updateFormat) {
345                mPixelFormat = format;
346            }
347            mSlots[buf].mGraphicBuffer = graphicBuffer;
348            mSlots[buf].mRequestBufferCalled = false;
349            returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
350    }
351    return returnFlags;
352}
353
354status_t SurfaceMediaSource::setSynchronousMode(bool enabled) {
355    Mutex::Autolock lock(mMutex);
356
357    status_t err = OK;
358    if (!enabled) {
359        // going to asynchronous mode, drain the queue
360        while (mSynchronousMode != enabled && !mQueue.isEmpty()) {
361            mDequeueCondition.wait(mMutex);
362        }
363    }
364
365    if (mSynchronousMode != enabled) {
366        // - if we're going to asynchronous mode, the queue is guaranteed to be
367        // empty here
368        // - if the client set the number of buffers, we're guaranteed that
369        // we have at least 3 (because we don't allow less)
370        mSynchronousMode = enabled;
371        mDequeueCondition.signal();
372    }
373    return err;
374}
375
376status_t SurfaceMediaSource::connect(int api,
377        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
378    LOGV("SurfaceMediaSource::connect");
379    Mutex::Autolock lock(mMutex);
380    status_t err = NO_ERROR;
381    switch (api) {
382        case NATIVE_WINDOW_API_EGL:
383        case NATIVE_WINDOW_API_CPU:
384        case NATIVE_WINDOW_API_MEDIA:
385        case NATIVE_WINDOW_API_CAMERA:
386            if (mConnectedApi != NO_CONNECTED_API) {
387                err = -EINVAL;
388            } else {
389                mConnectedApi = api;
390                *outWidth = mDefaultWidth;
391                *outHeight = mDefaultHeight;
392                *outTransform = 0;
393            }
394            break;
395        default:
396            err = -EINVAL;
397            break;
398    }
399    return err;
400}
401
402status_t SurfaceMediaSource::disconnect(int api) {
403    LOGV("SurfaceMediaSource::disconnect");
404    Mutex::Autolock lock(mMutex);
405    status_t err = NO_ERROR;
406    switch (api) {
407        case NATIVE_WINDOW_API_EGL:
408        case NATIVE_WINDOW_API_CPU:
409        case NATIVE_WINDOW_API_MEDIA:
410        case NATIVE_WINDOW_API_CAMERA:
411            if (mConnectedApi == api) {
412                mConnectedApi = NO_CONNECTED_API;
413            } else {
414                err = -EINVAL;
415            }
416            break;
417        default:
418            err = -EINVAL;
419            break;
420    }
421    return err;
422}
423
424status_t SurfaceMediaSource::queueBuffer(int buf, int64_t timestamp,
425        uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
426    LOGV("queueBuffer");
427
428    Mutex::Autolock lock(mMutex);
429    if (buf < 0 || buf >= mBufferCount) {
430        LOGE("queueBuffer: slot index out of range [0, %d]: %d",
431                mBufferCount, buf);
432        return -EINVAL;
433    } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
434        LOGE("queueBuffer: slot %d is not owned by the client (state=%d)",
435                buf, mSlots[buf].mBufferState);
436        return -EINVAL;
437    } else if (!mSlots[buf].mRequestBufferCalled) {
438        LOGE("queueBuffer: slot %d was enqueued without requesting a "
439                "buffer", buf);
440        return -EINVAL;
441    }
442
443    if (mSynchronousMode) {
444        // in synchronous mode we queue all buffers in a FIFO
445        mQueue.push_back(buf);
446        LOGV("Client queued buffer on slot: %d, Q size = %d",
447                                                buf, mQueue.size());
448    } else {
449        // in asynchronous mode we only keep the most recent buffer
450        if (mQueue.empty()) {
451            mQueue.push_back(buf);
452        } else {
453            Fifo::iterator front(mQueue.begin());
454            // buffer currently queued is freed
455            mSlots[*front].mBufferState = BufferSlot::FREE;
456            // and we record the new buffer index in the queued list
457            *front = buf;
458        }
459    }
460
461    mSlots[buf].mBufferState = BufferSlot::QUEUED;
462    mSlots[buf].mTimestamp = timestamp;
463    // TODO: (Confirm) Don't want to signal dequeue here.
464    // May be just in asynchronous mode?
465    // mDequeueCondition.signal();
466
467    // Once the queuing is done, we need to let the listener
468    // and signal the buffer consumer (encoder) know that a
469    // buffer is available
470    onFrameReceivedLocked();
471
472    *outWidth = mDefaultWidth;
473    *outHeight = mDefaultHeight;
474    *outTransform = 0;
475
476    return OK;
477}
478
479
480// onFrameReceivedLocked informs the buffer consumers (StageFrightRecorder)
481// or listeners that a frame has been received
482// It is supposed to be called only from queuebuffer.
483// The buffer is NOT made available for dequeueing immediately. We need to
484// wait to hear from StageFrightRecorder to set the buffer FREE
485// Make sure this is called when the mutex is locked
486status_t SurfaceMediaSource::onFrameReceivedLocked() {
487    LOGV("On Frame Received");
488    // Signal the encoder that a new frame has arrived
489    mFrameAvailableCondition.signal();
490
491    // call back the listener
492    // TODO: The listener may not be needed in SurfaceMediaSource at all.
493    // This can be made a SurfaceTexture specific thing
494    sp<FrameAvailableListener> listener;
495    if (mSynchronousMode || mQueue.empty()) {
496        listener = mFrameAvailableListener;
497    }
498
499    if (listener != 0) {
500        listener->onFrameAvailable();
501    }
502    return OK;
503}
504
505
506void SurfaceMediaSource::cancelBuffer(int buf) {
507    LOGV("SurfaceMediaSource::cancelBuffer");
508    Mutex::Autolock lock(mMutex);
509    if (buf < 0 || buf >= mBufferCount) {
510        LOGE("cancelBuffer: slot index out of range [0, %d]: %d",
511                mBufferCount, buf);
512        return;
513    } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) {
514        LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)",
515                buf, mSlots[buf].mBufferState);
516        return;
517    }
518    mSlots[buf].mBufferState = BufferSlot::FREE;
519    mDequeueCondition.signal();
520}
521
522nsecs_t SurfaceMediaSource::getTimestamp() {
523    LOGV("SurfaceMediaSource::getTimestamp");
524    Mutex::Autolock lock(mMutex);
525    return mCurrentTimestamp;
526}
527
528
529void SurfaceMediaSource::setFrameAvailableListener(
530        const sp<FrameAvailableListener>& listener) {
531    LOGV("SurfaceMediaSource::setFrameAvailableListener");
532    Mutex::Autolock lock(mMutex);
533    mFrameAvailableListener = listener;
534}
535
536void SurfaceMediaSource::freeAllBuffers() {
537    LOGV("freeAllBuffers");
538    for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
539        mSlots[i].mGraphicBuffer = 0;
540        mSlots[i].mBufferState = BufferSlot::FREE;
541    }
542}
543
544sp<GraphicBuffer> SurfaceMediaSource::getCurrentBuffer() const {
545    Mutex::Autolock lock(mMutex);
546    return mCurrentBuf;
547}
548
549int SurfaceMediaSource::query(int what, int* outValue)
550{
551    LOGV("query");
552    Mutex::Autolock lock(mMutex);
553    int value;
554    switch (what) {
555    case NATIVE_WINDOW_WIDTH:
556        value = mDefaultWidth;
557        if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
558            value = mCurrentBuf->width;
559        break;
560    case NATIVE_WINDOW_HEIGHT:
561        value = mDefaultHeight;
562        if (!mDefaultWidth && !mDefaultHeight && mCurrentBuf != 0)
563            value = mCurrentBuf->height;
564        break;
565    case NATIVE_WINDOW_FORMAT:
566        value = mPixelFormat;
567        break;
568    case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
569        value = mSynchronousMode ?
570                (MIN_UNDEQUEUED_BUFFERS-1) : MIN_UNDEQUEUED_BUFFERS;
571        break;
572    default:
573        return BAD_VALUE;
574    }
575    outValue[0] = value;
576    return NO_ERROR;
577}
578
579void SurfaceMediaSource::dump(String8& result) const
580{
581    char buffer[1024];
582    dump(result, "", buffer, 1024);
583}
584
585void SurfaceMediaSource::dump(String8& result, const char* prefix,
586        char* buffer, size_t SIZE) const
587{
588    Mutex::Autolock _l(mMutex);
589    snprintf(buffer, SIZE,
590            "%smBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], "
591            "mPixelFormat=%d, \n",
592            prefix, mBufferCount, mSynchronousMode, mDefaultWidth, mDefaultHeight,
593            mPixelFormat);
594    result.append(buffer);
595
596    String8 fifo;
597    int fifoSize = 0;
598    Fifo::const_iterator i(mQueue.begin());
599    while (i != mQueue.end()) {
600        snprintf(buffer, SIZE, "%02d ", *i++);
601        fifoSize++;
602        fifo.append(buffer);
603    }
604
605    result.append(buffer);
606
607    struct {
608        const char * operator()(int state) const {
609            switch (state) {
610                case BufferSlot::DEQUEUED: return "DEQUEUED";
611                case BufferSlot::QUEUED: return "QUEUED";
612                case BufferSlot::FREE: return "FREE";
613                default: return "Unknown";
614            }
615        }
616    } stateName;
617
618    for (int i = 0; i < mBufferCount; i++) {
619        const BufferSlot& slot(mSlots[i]);
620        snprintf(buffer, SIZE,
621                "%s%s[%02d] state=%-8s, "
622                "timestamp=%lld\n",
623                prefix, (i==mCurrentSlot)?">":" ", i, stateName(slot.mBufferState),
624                slot.mTimestamp
625        );
626        result.append(buffer);
627    }
628}
629
630status_t SurfaceMediaSource::setFrameRate(int32_t fps)
631{
632    Mutex::Autolock lock(mMutex);
633    const int MAX_FRAME_RATE = 60;
634    if (fps < 0 || fps > MAX_FRAME_RATE) {
635        return BAD_VALUE;
636    }
637    mFrameRate = fps;
638    return OK;
639}
640
641bool SurfaceMediaSource::isMetaDataStoredInVideoBuffers() const {
642    LOGV("isMetaDataStoredInVideoBuffers");
643    return true;
644}
645
646int32_t SurfaceMediaSource::getFrameRate( ) const {
647    Mutex::Autolock lock(mMutex);
648    return mFrameRate;
649}
650
651status_t SurfaceMediaSource::start(MetaData *params)
652{
653    LOGV("start");
654    Mutex::Autolock lock(mMutex);
655    CHECK(!mStarted);
656    mStarted = true;
657    return OK;
658}
659
660
661status_t SurfaceMediaSource::stop()
662{
663    LOGV("Stop");
664
665    Mutex::Autolock lock(mMutex);
666    // TODO: Add waiting on mFrameCompletedCondition here?
667    mStarted = false;
668    mFrameAvailableCondition.signal();
669
670    return OK;
671}
672
673sp<MetaData> SurfaceMediaSource::getFormat()
674{
675    LOGV("getFormat");
676    Mutex::Autolock autoLock(mMutex);
677    sp<MetaData> meta = new MetaData;
678
679    meta->setInt32(kKeyWidth, mDefaultWidth);
680    meta->setInt32(kKeyHeight, mDefaultHeight);
681    // The encoder format is set as an opaque colorformat
682    // The encoder will later find out the actual colorformat
683    // from the GL Frames itself.
684    meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
685    meta->setInt32(kKeyStride, mDefaultWidth);
686    meta->setInt32(kKeySliceHeight, mDefaultHeight);
687    meta->setInt32(kKeyFrameRate, mFrameRate);
688    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
689    return meta;
690}
691
692status_t SurfaceMediaSource::read( MediaBuffer **buffer,
693                                const ReadOptions *options)
694{
695    LOGV("Read. Size of queued buffer: %d", mQueue.size());
696    *buffer = NULL;
697
698    Mutex::Autolock autoLock(mMutex) ;
699    // If the recording has started and the queue is empty, then just
700    // wait here till the frames come in from the client side
701    while (mStarted && mQueue.empty()) {
702        LOGV("NO FRAMES! Recorder waiting for FrameAvailableCondition");
703        mFrameAvailableCondition.wait(mMutex);
704    }
705
706    // If the loop was exited as a result of stopping the recording,
707    // it is OK
708    if (!mStarted) {
709        return OK;
710    }
711
712    // Update the current buffer info
713    // TODO: mCurrentSlot can be made a bufferstate since there
714    // can be more than one "current" slots.
715    Fifo::iterator front(mQueue.begin());
716    mCurrentSlot = *front;
717    mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer;
718    mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp;
719
720    // Pass the data to the MediaBuffer. Pass in only the metadata
721    passMetadataBufferLocked(buffer);
722
723    (*buffer)->setObserver(this);
724    (*buffer)->add_ref();
725    (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp);
726
727    return OK;
728}
729
730// Pass the data to the MediaBuffer. Pass in only the metadata
731// The metadata passed consists of two parts:
732// 1. First, there is an integer indicating that it is a GRAlloc
733// source (kMetadataBufferTypeGrallocSource)
734// 2. This is followed by the buffer_handle_t that is a handle to the
735// GRalloc buffer. The encoder needs to interpret this GRalloc handle
736// and encode the frames.
737// --------------------------------------------------------------
738// |  kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
739// --------------------------------------------------------------
740// Note: Call only when you have the lock
741void SurfaceMediaSource::passMetadataBufferLocked(MediaBuffer **buffer) {
742    LOGV("passMetadataBuffer");
743    // MediaBuffer allocates and owns this data
744    MediaBuffer *tempBuffer =
745        new MediaBuffer(4 + sizeof(buffer_handle_t));
746    char *data = (char *)tempBuffer->data();
747    if (data == NULL) {
748        LOGE("Cannot allocate memory for passing buffer metadata!");
749        return;
750    }
751    OMX_U32 type = kMetadataBufferTypeGrallocSource;
752    memcpy(data, &type, 4);
753    memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t));
754    *buffer = tempBuffer;
755}
756
757
758void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
759    LOGV("signalBufferReturned");
760
761    bool foundBuffer = false;
762    Mutex::Autolock autoLock(mMutex);
763
764    if (!mStarted) {
765        LOGW("signalBufferReturned: mStarted = false! Nothing to do!");
766        return;
767    }
768
769    for (Fifo::iterator it = mQueue.begin(); it != mQueue.end(); ++it) {
770        CHECK(mSlots[*it].mGraphicBuffer != NULL);
771        if (checkBufferMatchesSlot(*it, buffer)) {
772            mSlots[*it].mBufferState = BufferSlot::FREE;
773            mQueue.erase(it);
774            buffer->setObserver(0);
775            buffer->release();
776            mDequeueCondition.signal();
777            mFrameCompleteCondition.signal();
778            foundBuffer = true;
779            break;
780        }
781    }
782
783    if (!foundBuffer) {
784        CHECK_EQ(0, "signalBufferReturned: bogus buffer");
785    }
786}
787
788bool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) {
789    LOGV("Check if Buffer matches slot");
790    // need to convert to char* for pointer arithmetic and then
791    // copy the byte stream into our handle
792    buffer_handle_t bufferHandle ;
793    memcpy( &bufferHandle, (char *)(buffer->data()) + 4, sizeof(buffer_handle_t));
794    return mSlots[slot].mGraphicBuffer->handle  ==  bufferHandle;
795}
796
797
798} // end of namespace android
799