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
19a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn#include <inttypes.h>
20a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn
21f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <media/stagefright/foundation/ADebug.h>
221a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketi#include <media/stagefright/SurfaceMediaSource.h>
233399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <media/stagefright/MediaDefs.h>
24b62f95145293bf1a39959166a4964088bb413224Andreas Huber#include <media/stagefright/MetaData.h>
256c6b4d0d2b98a7ceee8b697daaf611f8df3254fbJames Dong#include <OMX_IVCommon.h>
265e1f08b3917ac7900f8a11118afb7e8bf3e61c64Mathias Agopian#include <media/hardware/MetadataBufferType.h>
273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
28f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong#include <ui/GraphicBuffer.h>
298ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza#include <gui/BufferItem.h>
30df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/ISurfaceComposer.h>
31df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/IGraphicBufferAlloc.h>
323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <OMX_Component.h>
333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/Log.h>
353399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi#include <utils/String8.h>
363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
37404a123bed7f180724ead17f10e037b3eb347701Mathias Agopian#include <private/gui/ComposerService.h>
38404a123bed7f180724ead17f10e037b3eb347701Mathias Agopian
393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketinamespace android {
403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
41bdddc659a941afdb7f4958f582c6901c07246097Daniel LamSurfaceMediaSource::SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeight) :
42bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mWidth(bufferWidth),
43bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mHeight(bufferHeight),
44bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mCurrentSlot(BufferQueue::INVALID_BUFFER_SLOT),
45b62f95145293bf1a39959166a4964088bb413224Andreas Huber    mNumPendingBuffers(0),
46bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mCurrentTimestamp(0),
47bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mFrameRate(30),
48a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber    mStarted(false),
49bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mNumFramesReceived(0),
50bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mNumFramesEncoded(0),
51b62f95145293bf1a39959166a4964088bb413224Andreas Huber    mFirstFrameTimestamp(0),
5290689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber    mMaxAcquiredBufferCount(4),  // XXX double-check the default
5390689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber    mUseAbsoluteTimestamps(false) {
54a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennis    ALOGV("SurfaceMediaSource");
553399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
56bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    if (bufferWidth == 0 || bufferHeight == 0) {
57bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        ALOGE("Invalid dimensions %dx%d", bufferWidth, bufferHeight);
583399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
593399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
605205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    BufferQueue::createBufferQueue(&mProducer, &mConsumer);
615205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mConsumer->setDefaultBufferSize(bufferWidth, bufferHeight);
625205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER |
638add6cf4976de9b7bca7b73b1473a1e5f7201087Eino-Ville Talvala            GRALLOC_USAGE_HW_TEXTURE);
643399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
65bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    sp<ISurfaceComposer> composer(ComposerService::getComposerService());
663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
67bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    // Note that we can't create an sp<...>(this) in a ctor that will not keep a
68bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    // reference once the ctor ends, as that would cause the refcount of 'this'
69bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    // dropping to 0 at the end of the ctor.  Since all we need is a wp<...>
70bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    // that's what we create.
71deeef54487a34034dc0cfaab20b20d557224c07cMathias Agopian    wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
72910813bd66eaf0f6a72769c9b3fa9830dd100a19Mathias Agopian    sp<BufferQueue::ProxyConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
733399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
745205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    status_t err = mConsumer->consumerConnect(proxy, false);
75bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    if (err != NO_ERROR) {
76bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        ALOGE("SurfaceMediaSource: error connecting to BufferQueue: %s (%d)",
77bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                strerror(-err), err);
783399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
793399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
803399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
81bdddc659a941afdb7f4958f582c6901c07246097Daniel LamSurfaceMediaSource::~SurfaceMediaSource() {
82a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennis    ALOGV("~SurfaceMediaSource");
83a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber    CHECK(!mStarted);
843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
861a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketinsecs_t SurfaceMediaSource::getTimestamp() {
87a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennis    ALOGV("getTimestamp");
883399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
893399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mCurrentTimestamp;
903399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
913399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
921a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::setFrameAvailableListener(
933399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        const sp<FrameAvailableListener>& listener) {
94a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennis    ALOGV("setFrameAvailableListener");
953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameAvailableListener = listener;
973399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
991a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::dump(String8& result) const
1003399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
1013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    char buffer[1024];
1023399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    dump(result, "", buffer, 1024);
1033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1043399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
10584333e0475bc911adc16417f4ca327c975cf6c36Andreas Hubervoid SurfaceMediaSource::dump(
10684333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        String8& result,
10784333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        const char* /* prefix */,
10884333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        char* buffer,
10984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        size_t /* SIZE */) const
1103399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
111bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    Mutex::Autolock lock(mMutex);
1123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1133399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    result.append(buffer);
1145205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    mConsumer->dump(result, "");
1153399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1163399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
117b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketistatus_t SurfaceMediaSource::setFrameRate(int32_t fps)
1183399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
119a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennis    ALOGV("setFrameRate");
1203399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
121b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    const int MAX_FRAME_RATE = 60;
122b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    if (fps < 0 || fps > MAX_FRAME_RATE) {
123b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi        return BAD_VALUE;
124b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    }
1253399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    mFrameRate = fps;
126b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    return OK;
1273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
129b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketibool SurfaceMediaSource::isMetaDataStoredInVideoBuffers() const {
1303856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("isMetaDataStoredInVideoBuffers");
131b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi    return true;
132b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi}
133b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
134b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketiint32_t SurfaceMediaSource::getFrameRate( ) const {
135a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennis    ALOGV("getFrameRate");
1363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
1373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return mFrameRate;
1383399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1393399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1401a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketistatus_t SurfaceMediaSource::start(MetaData *params)
1413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
142a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennis    ALOGV("start");
143df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala
14456fc8fb5437e08131a84063041183d5ce8a678ccJames Dong    Mutex::Autolock lock(mMutex);
14556fc8fb5437e08131a84063041183d5ce8a678ccJames Dong
146a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber    CHECK(!mStarted);
147a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber
148df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    mStartTimeNs = 0;
149df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    int64_t startTimeUs;
15056fc8fb5437e08131a84063041183d5ce8a678ccJames Dong    int32_t bufferCount = 0;
15156fc8fb5437e08131a84063041183d5ce8a678ccJames Dong    if (params) {
15256fc8fb5437e08131a84063041183d5ce8a678ccJames Dong        if (params->findInt64(kKeyTime, &startTimeUs)) {
15356fc8fb5437e08131a84063041183d5ce8a678ccJames Dong            mStartTimeNs = startTimeUs * 1000;
15456fc8fb5437e08131a84063041183d5ce8a678ccJames Dong        }
15556fc8fb5437e08131a84063041183d5ce8a678ccJames Dong
15656fc8fb5437e08131a84063041183d5ce8a678ccJames Dong        if (!params->findInt32(kKeyNumBuffers, &bufferCount)) {
15756fc8fb5437e08131a84063041183d5ce8a678ccJames Dong            ALOGE("Failed to find the advertised buffer count");
15856fc8fb5437e08131a84063041183d5ce8a678ccJames Dong            return UNKNOWN_ERROR;
15956fc8fb5437e08131a84063041183d5ce8a678ccJames Dong        }
16056fc8fb5437e08131a84063041183d5ce8a678ccJames Dong
16156fc8fb5437e08131a84063041183d5ce8a678ccJames Dong        if (bufferCount <= 1) {
16256fc8fb5437e08131a84063041183d5ce8a678ccJames Dong            ALOGE("bufferCount %d is too small", bufferCount);
16356fc8fb5437e08131a84063041183d5ce8a678ccJames Dong            return BAD_VALUE;
16456fc8fb5437e08131a84063041183d5ce8a678ccJames Dong        }
165b62f95145293bf1a39959166a4964088bb413224Andreas Huber
166b62f95145293bf1a39959166a4964088bb413224Andreas Huber        mMaxAcquiredBufferCount = bufferCount;
16756fc8fb5437e08131a84063041183d5ce8a678ccJames Dong    }
16856fc8fb5437e08131a84063041183d5ce8a678ccJames Dong
169b62f95145293bf1a39959166a4964088bb413224Andreas Huber    CHECK_GT(mMaxAcquiredBufferCount, 1);
170b62f95145293bf1a39959166a4964088bb413224Andreas Huber
171b62f95145293bf1a39959166a4964088bb413224Andreas Huber    status_t err =
1725205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza        mConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBufferCount);
173b62f95145293bf1a39959166a4964088bb413224Andreas Huber
174b62f95145293bf1a39959166a4964088bb413224Andreas Huber    if (err != OK) {
175b62f95145293bf1a39959166a4964088bb413224Andreas Huber        return err;
176df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala    }
177df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala
178b62f95145293bf1a39959166a4964088bb413224Andreas Huber    mNumPendingBuffers = 0;
179a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber    mStarted = true;
180b62f95145293bf1a39959166a4964088bb413224Andreas Huber
1813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
1823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
1833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
1847f06639d375c44f260e00aa5e18cd883624b38bfAndreas Huberstatus_t SurfaceMediaSource::setMaxAcquiredBufferCount(size_t count) {
185a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("setMaxAcquiredBufferCount(%zu)", count);
186b62f95145293bf1a39959166a4964088bb413224Andreas Huber    Mutex::Autolock lock(mMutex);
187b62f95145293bf1a39959166a4964088bb413224Andreas Huber
188b62f95145293bf1a39959166a4964088bb413224Andreas Huber    CHECK_GT(count, 1);
189b62f95145293bf1a39959166a4964088bb413224Andreas Huber    mMaxAcquiredBufferCount = count;
190b62f95145293bf1a39959166a4964088bb413224Andreas Huber
191b62f95145293bf1a39959166a4964088bb413224Andreas Huber    return OK;
1927f06639d375c44f260e00aa5e18cd883624b38bfAndreas Huber}
1937f06639d375c44f260e00aa5e18cd883624b38bfAndreas Huber
19490689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huberstatus_t SurfaceMediaSource::setUseAbsoluteTimestamps() {
19590689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber    ALOGV("setUseAbsoluteTimestamps");
19690689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber    Mutex::Autolock lock(mMutex);
19790689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber    mUseAbsoluteTimestamps = true;
19890689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber
19990689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber    return OK;
20090689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber}
2013399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
202a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennisstatus_t SurfaceMediaSource::stop()
2033399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
204a0ead0a2d2ce1d114ad3a17d755dddce831abb40Jamie Gennis    ALOGV("stop");
2053399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    Mutex::Autolock lock(mMutex);
206bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
207a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber    if (!mStarted) {
208a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        return OK;
209a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    }
210a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
211456fa912e46edf0b01ea3b7760ea922c01ca1866Chong Zhang    mStarted = false;
212456fa912e46edf0b01ea3b7760ea922c01ca1866Chong Zhang    mFrameAvailableCondition.signal();
213456fa912e46edf0b01ea3b7760ea922c01ca1866Chong Zhang
214a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    while (mNumPendingBuffers > 0) {
215a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn        ALOGI("Still waiting for %zu buffers to be returned.",
216a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber                mNumPendingBuffers);
217a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
218a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber#if DEBUG_PENDING_BUFFERS
219a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        for (size_t i = 0; i < mPendingBuffers.size(); ++i) {
220a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            ALOGI("%d: %p", i, mPendingBuffers.itemAt(i));
221a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        }
222a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber#endif
223a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
224a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        mMediaBuffersAvailableCondition.wait(mMutex);
225a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    }
226a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
227be996645b3118b84edf26fc05cc5e4ff56c163b5Andreas Huber    mMediaBuffersAvailableCondition.signal();
2283399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2295205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza    return mConsumer->consumerDisconnect();
2303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
2313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2321a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketisp<MetaData> SurfaceMediaSource::getFormat()
2333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi{
2343856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("getFormat");
235bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
236bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    Mutex::Autolock lock(mMutex);
2373399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    sp<MetaData> meta = new MetaData;
238b33f3407bab0970a7f9241680723a1140b177c50Pannag Sanketi
239bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    meta->setInt32(kKeyWidth, mWidth);
240bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    meta->setInt32(kKeyHeight, mHeight);
2413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // The encoder format is set as an opaque colorformat
2423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // The encoder will later find out the actual colorformat
2433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // from the GL Frames itself.
2443399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatAndroidOpaque);
245bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    meta->setInt32(kKeyStride, mWidth);
246bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    meta->setInt32(kKeySliceHeight, mHeight);
2473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setInt32(kKeyFrameRate, mFrameRate);
2483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
2493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return meta;
2503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
2513399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
2522cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// Pass the data to the MediaBuffer. Pass in only the metadata
2532cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// The metadata passed consists of two parts:
2542cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// 1. First, there is an integer indicating that it is a GRAlloc
2552cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// source (kMetadataBufferTypeGrallocSource)
2562cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// 2. This is followed by the buffer_handle_t that is a handle to the
2572cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// GRalloc buffer. The encoder needs to interpret this GRalloc handle
2582cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// and encode the frames.
2592cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// --------------------------------------------------------------
2602cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// |  kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
2612cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// --------------------------------------------------------------
2622cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis// Note: Call only when you have the lock
2632cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennisstatic void passMetadataBuffer(MediaBuffer **buffer,
2642cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis        buffer_handle_t bufferHandle) {
265b62f95145293bf1a39959166a4964088bb413224Andreas Huber    *buffer = new MediaBuffer(4 + sizeof(buffer_handle_t));
266b62f95145293bf1a39959166a4964088bb413224Andreas Huber    char *data = (char *)(*buffer)->data();
2672cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    if (data == NULL) {
2682cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis        ALOGE("Cannot allocate memory for metadata buffer!");
2692cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis        return;
2702cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    }
2712cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    OMX_U32 type = kMetadataBufferTypeGrallocSource;
2722cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    memcpy(data, &type, 4);
2732cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    memcpy(data + 4, &bufferHandle, sizeof(buffer_handle_t));
2742cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis
275a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("handle = %p, , offset = %zu, length = %zu",
2762cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis            bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
2772cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis}
2782cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis
27984333e0475bc911adc16417f4ca327c975cf6c36Andreas Huberstatus_t SurfaceMediaSource::read(
28084333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber        MediaBuffer **buffer, const ReadOptions * /* options */) {
281bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    ALOGV("read");
282bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    Mutex::Autolock lock(mMutex);
2830c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi
2843399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    *buffer = NULL;
2853399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
286a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber    while (mStarted && mNumPendingBuffers == mMaxAcquiredBufferCount) {
287b62f95145293bf1a39959166a4964088bb413224Andreas Huber        mMediaBuffersAvailableCondition.wait(mMutex);
288b62f95145293bf1a39959166a4964088bb413224Andreas Huber    }
289b62f95145293bf1a39959166a4964088bb413224Andreas Huber
290bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    // Update the current buffer info
291bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    // TODO: mCurrentSlot can be made a bufferstate since there
292bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    // can be more than one "current" slots.
293bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
2948ed8ceda7cfe29e8417142ef460cd70060204459Dan Stoza    BufferItem item;
2953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // If the recording has started and the queue is empty, then just
2963399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // wait here till the frames come in from the client side
297a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber    while (mStarted) {
298bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
2995205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza        status_t err = mConsumer->acquireBuffer(&item, 0);
300bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
301bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            // wait for a buffer to be queued
302bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            mFrameAvailableCondition.wait(mMutex);
303bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        } else if (err == OK) {
304d76442421eadfa73f2f3a9e50f6caf65b0dd1ce9Mathias Agopian            err = item.mFence->waitForever("SurfaceMediaSource::read");
30510174bfdac537730be6729b9d47ad7d5bafed072Greg Hackmann            if (err) {
30610174bfdac537730be6729b9d47ad7d5bafed072Greg Hackmann                ALOGW("read: failed to wait for buffer fence: %d", err);
30710174bfdac537730be6729b9d47ad7d5bafed072Greg Hackmann            }
308bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
309bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            // First time seeing the buffer?  Added it to the SMS slot
310bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            if (item.mGraphicBuffer != NULL) {
311d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                mSlots[item.mBuf].mGraphicBuffer = item.mGraphicBuffer;
312bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            }
313d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar            mSlots[item.mBuf].mFrameNumber = item.mFrameNumber;
314bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
315bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            // check for the timing of this buffer
31690689fda75c343ab9328ced63e58f45eabaa33ccAndreas Huber            if (mNumFramesReceived == 0 && !mUseAbsoluteTimestamps) {
317bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                mFirstFrameTimestamp = item.mTimestamp;
318bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                // Initial delay
319bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                if (mStartTimeNs > 0) {
320bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                    if (item.mTimestamp < mStartTimeNs) {
321bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                        // This frame predates start of record, discard
3225205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza                        mConsumer->releaseBuffer(
323d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                                item.mBuf, item.mFrameNumber, EGL_NO_DISPLAY,
324f15f6e2e7fc51d48ba95890e1f562908e6e957c0Jesse Hall                                EGL_NO_SYNC_KHR, Fence::NO_FENCE);
325bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                        continue;
326bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                    }
327bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                    mStartTimeNs = item.mTimestamp - mStartTimeNs;
328bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam                }
329bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            }
330bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            item.mTimestamp = mStartTimeNs + (item.mTimestamp - mFirstFrameTimestamp);
331bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
332bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            mNumFramesReceived++;
333bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
334bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            break;
335bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        } else {
336bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            ALOGE("read: acquire failed with error code %d", err);
337bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam            return ERROR_END_OF_STREAM;
338bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        }
339bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
3403399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3413399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3423399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // If the loop was exited as a result of stopping the recording,
3433399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    // it is OK
344a54dee4002624e0885b39451cb29028406f5bf8eAndreas Huber    if (!mStarted) {
3453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Read: SurfaceMediaSource is stopped. Returning ERROR_END_OF_STREAM.");
3463e9bf4061475ae0d01c57e32c13e63808aa3e31fPannag Sanketi        return ERROR_END_OF_STREAM;
3473399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
3483399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
349bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mCurrentSlot = item.mBuf;
350bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
351bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    // First time seeing the buffer?  Added it to the SMS slot
352bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    if (item.mGraphicBuffer != NULL) {
353d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        mSlots[item.mBuf].mGraphicBuffer = item.mGraphicBuffer;
354bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    }
355d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    mSlots[item.mBuf].mFrameNumber = item.mFrameNumber;
3562cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis
357d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    mCurrentBuffers.push_back(mSlots[mCurrentSlot].mGraphicBuffer);
3580c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    int64_t prevTimeStamp = mCurrentTimestamp;
359bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mCurrentTimestamp = item.mTimestamp;
360df4a59c61103e7e0e9332e167a0be67da5d82ff3Eino-Ville Talvala
3610c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    mNumFramesEncoded++;
362a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi    // Pass the data to the MediaBuffer. Pass in only the metadata
363b62f95145293bf1a39959166a4964088bb413224Andreas Huber
364d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar    passMetadataBuffer(buffer, mSlots[mCurrentSlot].mGraphicBuffer->handle);
365a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi
3663399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    (*buffer)->setObserver(this);
3673399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    (*buffer)->add_ref();
3680c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi    (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp / 1000);
369a5750e0dad9e90f2195ce36f2c4457fa04b2b83eMark Salyzyn    ALOGV("Frames encoded = %d, timestamp = %" PRId64 ", time diff = %" PRId64,
3700c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mNumFramesEncoded, mCurrentTimestamp / 1000,
3710c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            mCurrentTimestamp / 1000 - prevTimeStamp / 1000);
3723399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
373b62f95145293bf1a39959166a4964088bb413224Andreas Huber    ++mNumPendingBuffers;
374bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
375a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber#if DEBUG_PENDING_BUFFERS
376a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    mPendingBuffers.push_back(*buffer);
377a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber#endif
378a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
379a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    ALOGV("returning mbuf %p", *buffer);
380a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
3813399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    return OK;
3823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
3833399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3842cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennisstatic buffer_handle_t getMediaBufferHandle(MediaBuffer *buffer) {
3852cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    // need to convert to char* for pointer arithmetic and then
3862cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    // copy the byte stream into our handle
3872cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    buffer_handle_t bufferHandle;
3882cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    memcpy(&bufferHandle, (char*)(buffer->data()) + 4, sizeof(buffer_handle_t));
3892cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    return bufferHandle;
3900c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi}
391a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi
3921a2fafbaa36390a06cc9a066fcbe147c8c47ea77Pannag Sanketivoid SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
3933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("signalBufferReturned");
3943399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3953399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    bool foundBuffer = false;
396bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
397bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    Mutex::Autolock lock(mMutex);
3983399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
3992cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    buffer_handle_t bufferHandle = getMediaBufferHandle(buffer);
4002cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis
4012cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    for (size_t i = 0; i < mCurrentBuffers.size(); i++) {
4022cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis        if (mCurrentBuffers[i]->handle == bufferHandle) {
4032cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis            mCurrentBuffers.removeAt(i);
4042cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis            foundBuffer = true;
4052cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis            break;
4062cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis        }
4072cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    }
4082cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis
4092cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis    if (!foundBuffer) {
4102cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis        ALOGW("returned buffer was not found in the current buffer list");
4113399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4123399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
413bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    for (int id = 0; id < BufferQueue::NUM_BUFFER_SLOTS; id++) {
414d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        if (mSlots[id].mGraphicBuffer == NULL) {
4150c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi            continue;
4160c5c7d2b119d2350c186ae9902919bcf28c3e277Pannag Sanketi        }
4172cd25a9056cc150b9fd3ac9b0bca37a1334ffd47Jamie Gennis
418d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar        if (bufferHandle == mSlots[id].mGraphicBuffer->handle) {
4193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Slot %d returned, matches handle = %p", id,
420d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                    mSlots[id].mGraphicBuffer->handle);
421bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
4225205977929c8a63d3bba026c6bd7b4cc1e236627Dan Stoza            mConsumer->releaseBuffer(id, mSlots[id].mFrameNumber,
423d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar                                        EGL_NO_DISPLAY, EGL_NO_SYNC_KHR,
424f15f6e2e7fc51d48ba95890e1f562908e6e957c0Jesse Hall                    Fence::NO_FENCE);
425bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
4263399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            buffer->setObserver(0);
4273399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            buffer->release();
428bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
4293399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            foundBuffer = true;
4303399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi            break;
4313399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi        }
4323399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
4333399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4343399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    if (!foundBuffer) {
435f1d5aa162c02a16b7195a43a9bcea4d592600ac4James Dong        CHECK(!"signalBufferReturned: bogus buffer");
4363399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi    }
437b62f95145293bf1a39959166a4964088bb413224Andreas Huber
438a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber#if DEBUG_PENDING_BUFFERS
439a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    for (size_t i = 0; i < mPendingBuffers.size(); ++i) {
440a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        if (mPendingBuffers.itemAt(i) == buffer) {
441a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            mPendingBuffers.removeAt(i);
442a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber            break;
443a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber        }
444a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber    }
445a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber#endif
446a7f7e0ac9436a8417bb9f31aecedfec1909d4630Andreas Huber
447b62f95145293bf1a39959166a4964088bb413224Andreas Huber    --mNumPendingBuffers;
448b62f95145293bf1a39959166a4964088bb413224Andreas Huber    mMediaBuffersAvailableCondition.broadcast();
4493399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi}
4503399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
451bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam// Part of the BufferQueue::ConsumerListener
45204f101c35eaa90b1f95939afac30674ec1611e6fDan Stozavoid SurfaceMediaSource::onFrameAvailable(const BufferItem& /* item */) {
453bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    ALOGV("onFrameAvailable");
454bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
455bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    sp<FrameAvailableListener> listener;
456bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    { // scope for the lock
457bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        Mutex::Autolock lock(mMutex);
458bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        mFrameAvailableCondition.broadcast();
459bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        listener = mFrameAvailableListener;
460bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    }
461bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
462bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    if (listener != NULL) {
463bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        ALOGV("actually calling onFrameAvailable");
464bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam        listener->onFrameAvailable();
465bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    }
466bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam}
467bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
468bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam// SurfaceMediaSource hijacks this event to assume
469bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam// the prodcuer is disconnecting from the BufferQueue
470bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam// and that it should stop the recording
471bdddc659a941afdb7f4958f582c6901c07246097Daniel Lamvoid SurfaceMediaSource::onBuffersReleased() {
472bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    ALOGV("onBuffersReleased");
473bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
474bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    Mutex::Autolock lock(mMutex);
475bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
476bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    mFrameAvailableCondition.signal();
477bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam
478bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
479d030447b617105b31bf3013e5e4b39d422b53b77Lajos Molnar       mSlots[i].mGraphicBuffer = 0;
480bdddc659a941afdb7f4958f582c6901c07246097Daniel Lam    }
481a361483bb5dbd3bbf132c5b99b2df7d197c3fc50Pannag Sanketi}
4823399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi
4838dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hallvoid SurfaceMediaSource::onSidebandStreamChanged() {
4848dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall    ALOG_ASSERT(false, "SurfaceMediaSource can't consume sideband streams");
4858dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall}
4868dcc81a2fdb35905347cf7ef46d198afa7ae79cdJesse Hall
4873399b7267185646c69b04352211fca4fad9d7547Pannag Sanketi} // end of namespace android
488