ProCamera.cpp revision 4bc4a3845e456fd464556d79d20650a107e873e5
1634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin/*
2634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin**
3634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** Copyright (C) 2013, The Android Open Source Project
4634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin**
5634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** Licensed under the Apache License, Version 2.0 (the "License");
6634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** you may not use this file except in compliance with the License.
7634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** You may obtain a copy of the License at
8634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin**
9634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin**     http://www.apache.org/licenses/LICENSE-2.0
10634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin**
11634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** Unless required by applicable law or agreed to in writing, software
12634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** distributed under the License is distributed on an "AS IS" BASIS,
13634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** See the License for the specific language governing permissions and
15634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin** limitations under the License.
16634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin*/
17634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
18634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin//#define LOG_NDEBUG 0
19634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#define LOG_TAG "ProCamera"
20634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <utils/Log.h>
21634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <utils/threads.h>
22634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <utils/Mutex.h>
23634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
24634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <binder/IPCThreadState.h>
25634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <binder/IServiceManager.h>
26634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <binder/IMemory.h>
27634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
28634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <camera/ProCamera.h>
29634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <camera/ICameraService.h>
30634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <camera/IProCameraUser.h>
31634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <camera/IProCameraCallbacks.h>
32634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
33634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <gui/IGraphicBufferProducer.h>
34634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <gui/Surface.h>
35634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
36a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin#include <system/camera_metadata.h>
37a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
38634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinnamespace android {
39634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
40634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// client singleton for camera service binder interface
41634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinMutex ProCamera::mLock;
42634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinsp<ICameraService> ProCamera::mCameraService;
43634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinsp<ProCamera::DeathNotifier> ProCamera::mDeathNotifier;
44634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
45634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// establish binder interface to camera service
46634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinconst sp<ICameraService>& ProCamera::getCameraService()
47634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
48634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    Mutex::Autolock _l(mLock);
49634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (mCameraService.get() == 0) {
50634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        sp<IServiceManager> sm = defaultServiceManager();
51634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        sp<IBinder> binder;
52634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        do {
53634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            binder = sm->getService(String16("media.camera"));
54634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            if (binder != 0)
55634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                break;
56634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            ALOGW("CameraService not published, waiting...");
57634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            usleep(500000); // 0.5 s
58634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        } while(true);
59634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        if (mDeathNotifier == NULL) {
60634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            mDeathNotifier = new DeathNotifier();
61634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
62634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        binder->linkToDeath(mDeathNotifier);
63634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        mCameraService = interface_cast<ICameraService>(binder);
64634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
65634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE_IF(mCameraService==0, "no CameraService!?");
66634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return mCameraService;
67634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
68634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
69634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinsp<ProCamera> ProCamera::connect(int cameraId)
70634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
71634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGV("connect");
72634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<ProCamera> c = new ProCamera();
73634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<IProCameraCallbacks> cl = c;
74634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    const sp<ICameraService>& cs = getCameraService();
75634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (cs != 0) {
76634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        c->mCamera = cs->connect(cl, cameraId);
77634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
78634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c->mCamera != 0) {
79634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        c->mCamera->asBinder()->linkToDeath(c);
80634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        c->mStatus = NO_ERROR;
81634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    } else {
82634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        c.clear();
83634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
84634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c;
85634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
86634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
87634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid ProCamera::disconnect()
88634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
89a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    ALOGV("%s: disconnect", __FUNCTION__);
90634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (mCamera != 0) {
91634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        mCamera->disconnect();
92634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        mCamera->asBinder()->unlinkToDeath(this);
93634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        mCamera = 0;
94634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
95a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    ALOGV("%s: disconnect (done)", __FUNCTION__);
96634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
97634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
98634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinProCamera::ProCamera()
99634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
100634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
101634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
102634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinProCamera::~ProCamera()
103634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
104634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
105634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
106634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
107634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinsp<IProCameraUser> ProCamera::remote()
108634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
109634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return mCamera;
110634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
111634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
112634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid ProCamera::binderDied(const wp<IBinder>& who) {
113634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGW("IProCameraUser died");
114634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0);
115634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
116634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
117634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid ProCamera::DeathNotifier::binderDied(const wp<IBinder>& who) {
118634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGV("binderDied");
119634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    Mutex::Autolock _l(ProCamera::mLock);
120634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ProCamera::mCameraService.clear();
121634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGW("Camera service died!");
122634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
123634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1245376573eff55f370f041889618c9a7a9e1894615Igor Murashkinvoid ProCamera::setListener(const sp<ProCameraListener>& listener)
1255376573eff55f370f041889618c9a7a9e1894615Igor Murashkin{
1265376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    Mutex::Autolock _l(mLock);
1275376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    mListener = listener;
1285376573eff55f370f041889618c9a7a9e1894615Igor Murashkin}
1295376573eff55f370f041889618c9a7a9e1894615Igor Murashkin
130634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
131634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// callback from camera service
132634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid ProCamera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
133634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
134634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<ProCameraListener> listener;
135634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    {
136634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        Mutex::Autolock _l(mLock);
137634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        listener = mListener;
138634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
139634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (listener != NULL) {
140634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        listener->notify(msgType, ext1, ext2);
141634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
142634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
143634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
144634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// callback from camera service when frame or image is ready
145634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid ProCamera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
146634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                          camera_frame_metadata_t *metadata)
147634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
148634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<ProCameraListener> listener;
149634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    {
150634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        Mutex::Autolock _l(mLock);
151634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        listener = mListener;
152634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
153634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (listener != NULL) {
154634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        listener->postData(msgType, dataPtr, metadata);
155634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
156634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
157634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
158634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// callback from camera service when timestamped frame is ready
159634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid ProCamera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
160634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                                                    const sp<IMemory>& dataPtr)
161634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
162634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<ProCameraListener> listener;
163634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    {
164634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        Mutex::Autolock _l(mLock);
165634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        listener = mListener;
166634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
167634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (listener != NULL) {
168634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        listener->postDataTimestamp(timestamp, msgType, dataPtr);
169634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    } else {
170634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        ALOGW("No listener was set. Drop a recording frame.");
171634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
172634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
173634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
174634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin/* IProCameraUser's implementation */
175634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1765376573eff55f370f041889618c9a7a9e1894615Igor Murashkinvoid ProCamera::onLockStatusChanged(
1775376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                                 IProCameraCallbacks::LockStatus newLockStatus)
1785376573eff55f370f041889618c9a7a9e1894615Igor Murashkin{
1795376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    ALOGV("%s: newLockStatus = %d", __FUNCTION__, newLockStatus);
1805376573eff55f370f041889618c9a7a9e1894615Igor Murashkin
1815376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    sp<ProCameraListener> listener;
1825376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    {
1835376573eff55f370f041889618c9a7a9e1894615Igor Murashkin        Mutex::Autolock _l(mLock);
1845376573eff55f370f041889618c9a7a9e1894615Igor Murashkin        listener = mListener;
1855376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    }
1865376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    if (listener != NULL) {
1875376573eff55f370f041889618c9a7a9e1894615Igor Murashkin        switch (newLockStatus) {
1885376573eff55f370f041889618c9a7a9e1894615Igor Murashkin            case IProCameraCallbacks::LOCK_ACQUIRED:
1895376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                listener->onLockAcquired();
1905376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                break;
1915376573eff55f370f041889618c9a7a9e1894615Igor Murashkin            case IProCameraCallbacks::LOCK_RELEASED:
1925376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                listener->onLockReleased();
1935376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                break;
1945376573eff55f370f041889618c9a7a9e1894615Igor Murashkin            case IProCameraCallbacks::LOCK_STOLEN:
1955376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                listener->onLockStolen();
1965376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                break;
1975376573eff55f370f041889618c9a7a9e1894615Igor Murashkin            default:
1985376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                ALOGE("%s: Unknown lock status: %d",
1995376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                      __FUNCTION__, newLockStatus);
2005376573eff55f370f041889618c9a7a9e1894615Igor Murashkin        }
2015376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    }
2025376573eff55f370f041889618c9a7a9e1894615Igor Murashkin}
2035376573eff55f370f041889618c9a7a9e1894615Igor Murashkin
204a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkinvoid ProCamera::onResultReceived(int32_t frameId, camera_metadata* result) {
205a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    ALOGV("%s: frameId = %d, result = %p", __FUNCTION__, frameId, result);
206a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
207a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    sp<ProCameraListener> listener;
208a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    {
209a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        Mutex::Autolock _l(mLock);
210a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        listener = mListener;
211a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    }
212a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
213a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    CameraMetadata tmp(result);
214a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
215a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    // Unblock waitForFrame(id) callers
216a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    {
217a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        Mutex::Autolock al(mWaitMutex);
218a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        mMetadataReady = true;
219a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        mLatestMetadata = tmp;
220a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        mWaitCondition.broadcast();
221a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    }
222a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
223a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    result = tmp.release();
224a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
225a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    if (listener != NULL) {
226a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        listener->onResultReceived(frameId, result);
227a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    } else {
228a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        free_camera_metadata(result);
229a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    }
230a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
231a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin}
232a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
233634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t ProCamera::exclusiveTryLock()
234634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
235634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
236634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
237634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
238634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->exclusiveTryLock();
239634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
240634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t ProCamera::exclusiveLock()
241634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
242634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
243634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
244634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
245634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->exclusiveLock();
246634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
247634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t ProCamera::exclusiveUnlock()
248634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
249634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
250634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
251634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
252634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->exclusiveUnlock();
253634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
254634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinbool ProCamera::hasExclusiveLock()
255634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
256634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
257634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
258634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
259634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->hasExclusiveLock();
260634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
261634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
262634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// Note that the callee gets a copy of the metadata.
263634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinint ProCamera::submitRequest(const struct camera_metadata* metadata,
264634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                             bool streaming)
265634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
266634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
267634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
268634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
269634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->submitRequest(const_cast<struct camera_metadata*>(metadata),
270634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                            streaming);
271634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
272634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
273634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t ProCamera::cancelRequest(int requestId)
274634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
275634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
276634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
277634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
278634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->cancelRequest(requestId);
279634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
280634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2815835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkinstatus_t ProCamera::deleteStream(int streamId)
282634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
283634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
284634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
285634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2865835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    status_t s = c->cancelStream(streamId);
2875835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2885835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    mStreams.removeItem(streamId);
289634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
2905835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    return s;
291634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
292634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
29368506fd58d26748617babe94d5648503cb3690bbIgor Murashkinstatus_t ProCamera::createStream(int width, int height, int format,
294985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin                          const sp<Surface>& surface,
29568506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                          /*out*/
29668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                          int* streamId)
29768506fd58d26748617babe94d5648503cb3690bbIgor Murashkin{
29868506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    *streamId = -1;
29968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
30068506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
30168506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                                                                       format);
30268506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
303985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (surface == 0) {
30468506fd58d26748617babe94d5648503cb3690bbIgor Murashkin        return BAD_VALUE;
30568506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    }
30668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
3075835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    return createStream(width, height, format, surface->getIGraphicBufferProducer(),
3085835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                        streamId);
30968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
31068506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
31168506fd58d26748617babe94d5648503cb3690bbIgor Murashkinstatus_t ProCamera::createStream(int width, int height, int format,
31268506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                          const sp<IGraphicBufferProducer>& bufferProducer,
31368506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                          /*out*/
31468506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                          int* streamId) {
3155835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    *streamId = -1;
31668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
31768506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    ALOGV("%s: createStreamT %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
31868506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                                                                       format);
31968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
3205835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if (bufferProducer == 0) {
3215835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        return BAD_VALUE;
3225835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    }
32368506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
3245835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp <IProCameraUser> c = mCamera;
3255835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    status_t stat = c->createStream(width, height, format, bufferProducer,
3265835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                                    streamId);
32768506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
3285835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if (stat == OK) {
3295835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        StreamInfo s(*streamId);
3305835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3315835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        mStreams.add(*streamId, s);
33268506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    }
33368506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
334985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return stat;
33568506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
33668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
3375835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkinstatus_t ProCamera::createStreamCpu(int width, int height, int format,
3385835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                          int heapCount,
3395835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                          /*out*/
340a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                          sp<CpuConsumer>* cpuConsumer,
3415835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                          int* streamId)
3425835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin{
3435835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
3445835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                                                                        format);
3455835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
346a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    *cpuConsumer = NULL;
347a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
3485835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp <IProCameraUser> c = mCamera;
3495835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if (c == 0) return NO_INIT;
3505835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3515835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp<CpuConsumer> cc = new CpuConsumer(heapCount);
3525835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    cc->setName(String8("ProCamera::mCpuConsumer"));
3535835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3545835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp<Surface> stc = new Surface(
3555835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        cc->getProducerInterface());
3565835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3575835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    status_t s = createStream(width, height, format, stc->getIGraphicBufferProducer(),
3585835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                        streamId);
3595835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3605835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if (s != OK) {
3615835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        ALOGE("%s: Failure to create stream %dx%d (fmt=0x%x)", __FUNCTION__,
3625835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                    width, height, format);
3635835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        return s;
3645835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    }
3655835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3665835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp<ProFrameListener> frameAvailableListener =
3675835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        new ProFrameListener(this, *streamId);
3685835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3695835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    getStreamInfo(*streamId).cpuStream = true;
3705835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    getStreamInfo(*streamId).cpuConsumer = cc;
3715835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    getStreamInfo(*streamId).stc = stc;
3725835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    // for lifetime management
3735835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    getStreamInfo(*streamId).frameAvailableListener = frameAvailableListener;
3745835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3755835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    cc->setFrameAvailableListener(frameAvailableListener);
3765835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
377a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    *cpuConsumer = cc;
378a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
3795835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    return s;
3805835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin}
3815835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
38268506fd58d26748617babe94d5648503cb3690bbIgor Murashkinint ProCamera::getNumberOfCameras() {
3837b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    const sp<ICameraService> cs = getCameraService();
3847b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
3857b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    if (!cs.get()) {
3867b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin        return DEAD_OBJECT;
3877b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    }
3887b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    return cs->getNumberOfCameras();
38968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
39068506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
39168506fd58d26748617babe94d5648503cb3690bbIgor Murashkincamera_metadata* ProCamera::getCameraInfo(int cameraId) {
39268506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    ALOGV("%s: cameraId = %d", __FUNCTION__, cameraId);
3937b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
3947b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    sp <IProCameraUser> c = mCamera;
3957b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    if (c == 0) return NULL;
3967b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
3977b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    camera_metadata* ptr = NULL;
3987b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    status_t status = c->getCameraInfo(cameraId, &ptr);
3997b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
4007b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    if (status != OK) {
4017b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin        ALOGE("%s: Failed to get camera info, error = %d", __FUNCTION__, status);
4027b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    }
4037b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
4047b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    return ptr;
40568506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
40668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
40768506fd58d26748617babe94d5648503cb3690bbIgor Murashkinstatus_t ProCamera::createDefaultRequest(int templateId,
40868506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                                             camera_metadata** request) const {
40968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    ALOGV("%s: templateId = %d", __FUNCTION__, templateId);
41068506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
411985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    sp <IProCameraUser> c = mCamera;
412985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (c == 0) return NO_INIT;
413985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
414985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return c->createDefaultRequest(templateId, request);
41568506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
41668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
4175835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkinvoid ProCamera::onFrameAvailable(int streamId) {
4185835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    ALOGV("%s: streamId = %d", __FUNCTION__, streamId);
4195835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
4205835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp<ProCameraListener> listener = mListener;
421a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    StreamInfo& stream = getStreamInfo(streamId);
4225835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
423a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    CpuConsumer::LockedBuffer buf;
4245835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
425a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    if (listener.get() != NULL) {
426a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        if (listener->useOnFrameAvailable()) {
427a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            listener->onFrameAvailable(streamId, stream.cpuConsumer);
4285835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin            return;
4295835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        }
430a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    }
431a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
432a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    // Unblock waitForFrame(id) callers
433a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    {
434a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        Mutex::Autolock al(mWaitMutex);
4354bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        getStreamInfo(streamId).frameReady++;
436a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        mWaitCondition.broadcast();
437a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    }
438a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin}
439a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
4404bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkinint ProCamera::waitForFrameBuffer(int streamId) {
441a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    status_t stat = BAD_VALUE;
442a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    Mutex::Autolock al(mWaitMutex);
4435835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
444a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    StreamInfo& si = getStreamInfo(streamId);
4455835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
4464bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    if (si.frameReady > 0) {
4474bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        int numFrames = si.frameReady;
4484bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        si.frameReady = 0;
4494bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        return numFrames;
450a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    } else {
451a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        while (true) {
452a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            stat = mWaitCondition.waitRelative(mWaitMutex,
453a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                                                mWaitTimeout);
454a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            if (stat != OK) {
455a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                ALOGE("%s: Error while waiting for frame buffer: %d",
456a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                    __FUNCTION__, stat);
457a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                return stat;
458a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            }
459a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
4604bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin            if (si.frameReady > 0) {
4614bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin                int numFrames = si.frameReady;
4624bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin                si.frameReady = 0;
4634bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin                return numFrames;
464a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            }
465a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            // else it was some other stream that got unblocked
4665835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        }
4675835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    }
468a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
469a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    return stat;
470a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin}
471a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
4724bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkinint ProCamera::dropFrameBuffer(int streamId, int count) {
4734bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    StreamInfo& si = getStreamInfo(streamId);
4744bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
4754bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    if (!si.cpuStream) {
4764bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        return BAD_VALUE;
4774bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    } else if (count < 0) {
4784bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        return BAD_VALUE;
4794bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    }
4804bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
4814bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    int numDropped = 0;
4824bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    for (int i = 0; i < count; ++i) {
4834bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        CpuConsumer::LockedBuffer buffer;
4844bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        if (si.cpuConsumer->lockNextBuffer(&buffer) != OK) {
4854bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin            break;
4864bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        }
4874bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
4884bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        si.cpuConsumer->unlockBuffer(buffer);
4894bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        numDropped++;
4904bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    }
4914bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
4924bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    return numDropped;
4934bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin}
4944bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
495a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkinstatus_t ProCamera::waitForFrameMetadata() {
496a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    status_t stat = BAD_VALUE;
497a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    Mutex::Autolock al(mWaitMutex);
498a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
499a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    if (mMetadataReady) {
500a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        return OK;
501a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    } else {
502a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        while (true) {
503a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            stat = mWaitCondition.waitRelative(mWaitMutex,
504a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                                               mWaitTimeout);
505a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
506a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            if (stat != OK) {
507a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                ALOGE("%s: Error while waiting for metadata: %d",
508a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                        __FUNCTION__, stat);
509a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                return stat;
510a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            }
511a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
512a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            if (mMetadataReady) {
513a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                mMetadataReady = false;
514a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                return OK;
515a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            }
516a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            // else it was some other stream or metadata
517a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        }
518a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    }
519a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
520a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    return stat;
521a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin}
522a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
523a140a6efea1db7837984b3578755cfa4eaa8d92dIgor MurashkinCameraMetadata ProCamera::consumeFrameMetadata() {
524a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    Mutex::Autolock al(mWaitMutex);
525a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
526a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    // Destructive: Subsequent calls return empty metadatas
527a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    CameraMetadata tmp = mLatestMetadata;
528a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    mLatestMetadata.release();
529a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
530a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    return tmp;
5315835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin}
5325835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
5335835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor MurashkinProCamera::StreamInfo& ProCamera::getStreamInfo(int streamId) {
5345835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    return mStreams.editValueFor(streamId);
5355835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin}
5365835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
537634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}; // namespace android
538