ProCamera.cpp revision 8aa0f0619ea867e8fb240cf27913d4f8ae767385
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