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