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/IProCameraUser.h>
30634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <camera/IProCameraCallbacks.h>
31634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
32634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin#include <gui/IGraphicBufferProducer.h>
33634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
34a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin#include <system/camera_metadata.h>
35a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
36634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinnamespace android {
37634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
38634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinsp<ProCamera> ProCamera::connect(int cameraId)
39634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
40c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin    return CameraBaseT::connect(cameraId, String16(),
41c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                 ICameraService::USE_CALLING_UID);
42634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
43634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
44c073ba525404f3416c2824c435d3d926a9892f1bIgor MurashkinProCamera::ProCamera(int cameraId)
45c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin    : CameraBase(cameraId)
46634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
47634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
48634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
490f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben BrunkCameraTraits<ProCamera>::TCamConnectService CameraTraits<ProCamera>::fnConnectService =
500f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk        &ICameraService::connectPro;
510f61d8f14aa368c9cd7076528e8096e10ed100a0Ruben Brunk
52634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinProCamera::~ProCamera()
53634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
54634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
55634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
56634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
57c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin/* IProCameraUser's implementation */
58634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
59634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// callback from camera service
60634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid ProCamera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
61634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
62c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin    return CameraBaseT::notifyCallback(msgType, ext1, ext2);
63634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
64634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
655376573eff55f370f041889618c9a7a9e1894615Igor Murashkinvoid ProCamera::onLockStatusChanged(
665376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                                 IProCameraCallbacks::LockStatus newLockStatus)
675376573eff55f370f041889618c9a7a9e1894615Igor Murashkin{
685376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    ALOGV("%s: newLockStatus = %d", __FUNCTION__, newLockStatus);
695376573eff55f370f041889618c9a7a9e1894615Igor Murashkin
705376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    sp<ProCameraListener> listener;
715376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    {
725376573eff55f370f041889618c9a7a9e1894615Igor Murashkin        Mutex::Autolock _l(mLock);
735376573eff55f370f041889618c9a7a9e1894615Igor Murashkin        listener = mListener;
745376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    }
755376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    if (listener != NULL) {
765376573eff55f370f041889618c9a7a9e1894615Igor Murashkin        switch (newLockStatus) {
775376573eff55f370f041889618c9a7a9e1894615Igor Murashkin            case IProCameraCallbacks::LOCK_ACQUIRED:
785376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                listener->onLockAcquired();
795376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                break;
805376573eff55f370f041889618c9a7a9e1894615Igor Murashkin            case IProCameraCallbacks::LOCK_RELEASED:
815376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                listener->onLockReleased();
825376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                break;
835376573eff55f370f041889618c9a7a9e1894615Igor Murashkin            case IProCameraCallbacks::LOCK_STOLEN:
845376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                listener->onLockStolen();
855376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                break;
865376573eff55f370f041889618c9a7a9e1894615Igor Murashkin            default:
875376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                ALOGE("%s: Unknown lock status: %d",
885376573eff55f370f041889618c9a7a9e1894615Igor Murashkin                      __FUNCTION__, newLockStatus);
895376573eff55f370f041889618c9a7a9e1894615Igor Murashkin        }
905376573eff55f370f041889618c9a7a9e1894615Igor Murashkin    }
915376573eff55f370f041889618c9a7a9e1894615Igor Murashkin}
925376573eff55f370f041889618c9a7a9e1894615Igor Murashkin
93f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalavoid ProCamera::onResultReceived(int32_t requestId, camera_metadata* result) {
94f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala    ALOGV("%s: requestId = %d, result = %p", __FUNCTION__, requestId, result);
95a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
96a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    sp<ProCameraListener> listener;
97a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    {
98a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        Mutex::Autolock _l(mLock);
99a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        listener = mListener;
100a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    }
101a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
102a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    CameraMetadata tmp(result);
103a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
104a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    // Unblock waitForFrame(id) callers
105a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    {
106a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        Mutex::Autolock al(mWaitMutex);
107a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        mMetadataReady = true;
10865d7986ceac6e35426749ac7e05bbd2a38949db4Igor Murashkin        mLatestMetadata = tmp; // make copy
109a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        mWaitCondition.broadcast();
110a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    }
111a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
112a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    result = tmp.release();
113a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
114a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    if (listener != NULL) {
115f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala        listener->onResultReceived(requestId, result);
116a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    } else {
117a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin        free_camera_metadata(result);
118a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin    }
119a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
120a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin}
121a91537e268f2b35f9f0dfdc0c4f84655c93285aeIgor Murashkin
122634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t ProCamera::exclusiveTryLock()
123634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
124634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
125634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
126634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
127634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->exclusiveTryLock();
128634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
129634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t ProCamera::exclusiveLock()
130634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
131634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
132634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
133634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
134634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->exclusiveLock();
135634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
136634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t ProCamera::exclusiveUnlock()
137634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
138634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
139634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
140634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
141634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->exclusiveUnlock();
142634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
143634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinbool ProCamera::hasExclusiveLock()
144634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
145634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
146634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
147634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
148634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->hasExclusiveLock();
149634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
150634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
151634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// Note that the callee gets a copy of the metadata.
152634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinint ProCamera::submitRequest(const struct camera_metadata* metadata,
153634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                             bool streaming)
154634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
155634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
156634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
157634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
158634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->submitRequest(const_cast<struct camera_metadata*>(metadata),
159634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                            streaming);
160634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
161634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
162634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t ProCamera::cancelRequest(int requestId)
163634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
164634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
165634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
166634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
167634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return c->cancelRequest(requestId);
168634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
169634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1705835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkinstatus_t ProCamera::deleteStream(int streamId)
171634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
172634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp <IProCameraUser> c = mCamera;
173634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (c == 0) return NO_INIT;
174634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
175fa4cf9d310685b4c25877cba772ff7da84caf517Igor Murashkin    status_t s = c->deleteStream(streamId);
1765835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
1775835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    mStreams.removeItem(streamId);
178634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
1795835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    return s;
180634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
181634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
18268506fd58d26748617babe94d5648503cb3690bbIgor Murashkinstatus_t ProCamera::createStream(int width, int height, int format,
183c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                 const sp<Surface>& surface,
184c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                 /*out*/
185c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                 int* streamId)
18668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin{
18768506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    *streamId = -1;
18868506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
18968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
19068506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                                                                       format);
19168506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
192985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (surface == 0) {
19368506fd58d26748617babe94d5648503cb3690bbIgor Murashkin        return BAD_VALUE;
19468506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    }
19568506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
196c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin    return createStream(width, height, format,
197c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                        surface->getIGraphicBufferProducer(),
1985835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                        streamId);
19968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
20068506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
20168506fd58d26748617babe94d5648503cb3690bbIgor Murashkinstatus_t ProCamera::createStream(int width, int height, int format,
202c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                 const sp<IGraphicBufferProducer>& bufferProducer,
203c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                 /*out*/
204c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                 int* streamId) {
2055835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    *streamId = -1;
20668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
20768506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    ALOGV("%s: createStreamT %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
20868506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                                                                       format);
20968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
2105835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if (bufferProducer == 0) {
2115835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        return BAD_VALUE;
2125835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    }
21368506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
2145835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp <IProCameraUser> c = mCamera;
2155835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    status_t stat = c->createStream(width, height, format, bufferProducer,
2165835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                                    streamId);
21768506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
2185835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if (stat == OK) {
2195835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        StreamInfo s(*streamId);
2205835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2215835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        mStreams.add(*streamId, s);
22268506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    }
22368506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
224985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return stat;
22568506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
22668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
2275835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkinstatus_t ProCamera::createStreamCpu(int width, int height, int format,
228c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                    int heapCount,
229c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                    /*out*/
230c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                    sp<CpuConsumer>* cpuConsumer,
231ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin                                    int* streamId) {
232ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin    return createStreamCpu(width, height, format, heapCount,
233ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin                           /*synchronousMode*/true,
234ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin                           cpuConsumer, streamId);
235ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin}
236ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin
237ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkinstatus_t ProCamera::createStreamCpu(int width, int height, int format,
238ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin                                    int heapCount,
239ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin                                    bool synchronousMode,
240ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin                                    /*out*/
241ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin                                    sp<CpuConsumer>* cpuConsumer,
242c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                                    int* streamId)
2435835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin{
2445835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height,
2455835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                                                                        format);
2465835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
247a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    *cpuConsumer = NULL;
248a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
2495835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp <IProCameraUser> c = mCamera;
2505835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if (c == 0) return NO_INIT;
2515835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2528aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    sp<IGraphicBufferProducer> producer;
2538aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    sp<IGraphicBufferConsumer> consumer;
2548aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    BufferQueue::createBufferQueue(&producer, &consumer);
2558aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    sp<CpuConsumer> cc = new CpuConsumer(consumer, heapCount
2568aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza            /*, synchronousMode*/);
2575835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    cc->setName(String8("ProCamera::mCpuConsumer"));
2585835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2598aa0f0619ea867e8fb240cf27913d4f8ae767385Dan Stoza    sp<Surface> stc = new Surface(producer);
2605835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
261c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin    status_t s = createStream(width, height, format,
262c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                              stc->getIGraphicBufferProducer(),
263c073ba525404f3416c2824c435d3d926a9892f1bIgor Murashkin                              streamId);
2645835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2655835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    if (s != OK) {
2665835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        ALOGE("%s: Failure to create stream %dx%d (fmt=0x%x)", __FUNCTION__,
2675835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin                    width, height, format);
2685835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        return s;
2695835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    }
2705835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2715835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp<ProFrameListener> frameAvailableListener =
2725835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        new ProFrameListener(this, *streamId);
2735835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2745835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    getStreamInfo(*streamId).cpuStream = true;
2755835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    getStreamInfo(*streamId).cpuConsumer = cc;
276ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin    getStreamInfo(*streamId).synchronousMode = synchronousMode;
2775835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    getStreamInfo(*streamId).stc = stc;
2785835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    // for lifetime management
2795835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    getStreamInfo(*streamId).frameAvailableListener = frameAvailableListener;
2805835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
2815835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    cc->setFrameAvailableListener(frameAvailableListener);
2825835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
283a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    *cpuConsumer = cc;
284a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
2855835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    return s;
2865835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin}
2875835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
28868506fd58d26748617babe94d5648503cb3690bbIgor Murashkincamera_metadata* ProCamera::getCameraInfo(int cameraId) {
28968506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    ALOGV("%s: cameraId = %d", __FUNCTION__, cameraId);
2907b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
2917b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    sp <IProCameraUser> c = mCamera;
2927b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    if (c == 0) return NULL;
2937b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
2947b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    camera_metadata* ptr = NULL;
2957b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    status_t status = c->getCameraInfo(cameraId, &ptr);
2967b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
2977b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    if (status != OK) {
2987b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin        ALOGE("%s: Failed to get camera info, error = %d", __FUNCTION__, status);
2997b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    }
3007b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin
3017b33a74bbc514b99c16be7fff9a34e892bc19264Igor Murashkin    return ptr;
30268506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
30368506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
30468506fd58d26748617babe94d5648503cb3690bbIgor Murashkinstatus_t ProCamera::createDefaultRequest(int templateId,
30568506fd58d26748617babe94d5648503cb3690bbIgor Murashkin                                             camera_metadata** request) const {
30668506fd58d26748617babe94d5648503cb3690bbIgor Murashkin    ALOGV("%s: templateId = %d", __FUNCTION__, templateId);
30768506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
308985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    sp <IProCameraUser> c = mCamera;
309985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    if (c == 0) return NO_INIT;
310985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin
311985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin    return c->createDefaultRequest(templateId, request);
31268506fd58d26748617babe94d5648503cb3690bbIgor Murashkin}
31368506fd58d26748617babe94d5648503cb3690bbIgor Murashkin
3145835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkinvoid ProCamera::onFrameAvailable(int streamId) {
3155835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    ALOGV("%s: streamId = %d", __FUNCTION__, streamId);
3165835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3175835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    sp<ProCameraListener> listener = mListener;
318a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    StreamInfo& stream = getStreamInfo(streamId);
3195835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
320a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    if (listener.get() != NULL) {
321fa4cf9d310685b4c25877cba772ff7da84caf517Igor Murashkin        listener->onFrameAvailable(streamId, stream.cpuConsumer);
322a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    }
323a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
324a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    // Unblock waitForFrame(id) callers
325a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    {
326a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        Mutex::Autolock al(mWaitMutex);
3274bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        getStreamInfo(streamId).frameReady++;
328a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        mWaitCondition.broadcast();
329a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    }
330a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin}
331a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
3324bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkinint ProCamera::waitForFrameBuffer(int streamId) {
333a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    status_t stat = BAD_VALUE;
334a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    Mutex::Autolock al(mWaitMutex);
3355835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
336a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    StreamInfo& si = getStreamInfo(streamId);
3375835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
3384bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    if (si.frameReady > 0) {
3394bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        int numFrames = si.frameReady;
3404bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        si.frameReady = 0;
3414bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        return numFrames;
342a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    } else {
343a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        while (true) {
344a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            stat = mWaitCondition.waitRelative(mWaitMutex,
345a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                                                mWaitTimeout);
346a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            if (stat != OK) {
347a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                ALOGE("%s: Error while waiting for frame buffer: %d",
348a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                    __FUNCTION__, stat);
349a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                return stat;
350a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            }
351a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
3524bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin            if (si.frameReady > 0) {
3534bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin                int numFrames = si.frameReady;
3544bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin                si.frameReady = 0;
3554bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin                return numFrames;
356a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            }
357a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            // else it was some other stream that got unblocked
3585835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin        }
3595835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    }
360a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
361a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    return stat;
362a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin}
363a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
3644bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkinint ProCamera::dropFrameBuffer(int streamId, int count) {
3654bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    StreamInfo& si = getStreamInfo(streamId);
3664bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
3674bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    if (!si.cpuStream) {
3684bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        return BAD_VALUE;
3694bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    } else if (count < 0) {
3704bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        return BAD_VALUE;
3714bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    }
3724bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
373ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin    if (!si.synchronousMode) {
374ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin        ALOGW("%s: No need to drop frames on asynchronous streams,"
375ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin              " as asynchronous mode only keeps 1 latest frame around.",
376ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin              __FUNCTION__);
377ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin        return BAD_VALUE;
378ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin    }
379ba5ca4ee770fa0fe9e14990fd13b23f1010f5c98Igor Murashkin
3804bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    int numDropped = 0;
3814bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    for (int i = 0; i < count; ++i) {
3824bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        CpuConsumer::LockedBuffer buffer;
3834bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        if (si.cpuConsumer->lockNextBuffer(&buffer) != OK) {
3844bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin            break;
3854bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        }
3864bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
3874bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        si.cpuConsumer->unlockBuffer(buffer);
3884bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin        numDropped++;
3894bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    }
3904bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
3914bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin    return numDropped;
3924bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin}
3934bc4a3845e456fd464556d79d20650a107e873e5Igor Murashkin
394a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkinstatus_t ProCamera::waitForFrameMetadata() {
395a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    status_t stat = BAD_VALUE;
396a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    Mutex::Autolock al(mWaitMutex);
397a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
398a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    if (mMetadataReady) {
399a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        return OK;
400a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    } else {
401a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        while (true) {
402a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            stat = mWaitCondition.waitRelative(mWaitMutex,
403a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                                               mWaitTimeout);
404a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
405a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            if (stat != OK) {
406a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                ALOGE("%s: Error while waiting for metadata: %d",
407a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                        __FUNCTION__, stat);
408a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                return stat;
409a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            }
410a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
411a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            if (mMetadataReady) {
412a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                mMetadataReady = false;
413a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin                return OK;
414a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            }
415a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin            // else it was some other stream or metadata
416a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin        }
417a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    }
418a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
419a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    return stat;
420a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin}
421a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
422a140a6efea1db7837984b3578755cfa4eaa8d92dIgor MurashkinCameraMetadata ProCamera::consumeFrameMetadata() {
423a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    Mutex::Autolock al(mWaitMutex);
424a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
425a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    // Destructive: Subsequent calls return empty metadatas
426a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    CameraMetadata tmp = mLatestMetadata;
42765d7986ceac6e35426749ac7e05bbd2a38949db4Igor Murashkin    mLatestMetadata.clear();
428a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin
429a140a6efea1db7837984b3578755cfa4eaa8d92dIgor Murashkin    return tmp;
4305835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin}
4315835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
4325835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor MurashkinProCamera::StreamInfo& ProCamera::getStreamInfo(int streamId) {
4335835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin    return mStreams.editValueFor(streamId);
4345835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin}
4355835cc46a2f06dbfa5fbdab70e091896ef2fb438Igor Murashkin
436634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}; // namespace android
437