blob: 46243b93198ca4f03e30ff18b27e8635b099e118 [file] [log] [blame]
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef _ACAMERA_DEVICE_H
17#define _ACAMERA_DEVICE_H
18
19#include <memory>
Yin-Chia Yehead91462016-01-06 16:45:08 -080020#include <map>
21#include <set>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080022#include <atomic>
23#include <utils/StrongPointer.h>
24#include <utils/Mutex.h>
25#include <utils/String8.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080026#include <utils/List.h>
27#include <utils/Vector.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080028
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080029#include <android/hardware/camera2/BnCameraDeviceCallbacks.h>
30#include <android/hardware/camera2/ICameraDeviceUser.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080031#include <media/stagefright/foundation/ALooper.h>
32#include <media/stagefright/foundation/AHandler.h>
33#include <media/stagefright/foundation/AMessage.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080034#include <camera/CaptureResult.h>
Yin-Chia Yehead91462016-01-06 16:45:08 -080035#include <camera/camera2/OutputConfiguration.h>
36#include <camera/camera2/CaptureRequest.h>
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080037
38#include <NdkCameraDevice.h>
39#include "ACameraMetadata.h"
40
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080041namespace android {
42
Yin-Chia Yehead91462016-01-06 16:45:08 -080043// Wrap ACameraCaptureFailure so it can be ref-counter
44struct CameraCaptureFailure : public RefBase, public ACameraCaptureFailure {};
45
46class CameraDevice final : public RefBase {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080047 public:
48 CameraDevice(const char* id, ACameraDevice_StateCallbacks* cb,
49 std::unique_ptr<ACameraMetadata> chars,
50 ACameraDevice* wrapper);
51 ~CameraDevice();
52
53 inline const char* getId() const { return mCameraId.string(); }
54
55 camera_status_t createCaptureRequest(
56 ACameraDevice_request_template templateId,
57 ACaptureRequest** request) const;
58
Yin-Chia Yehead91462016-01-06 16:45:08 -080059 camera_status_t createCaptureSession(
60 const ACaptureSessionOutputContainer* outputs,
61 const ACameraCaptureSession_stateCallbacks* callbacks,
62 /*out*/ACameraCaptureSession** session);
63
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080064 // Callbacks from camera service
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080065 class ServiceCallback : public hardware::camera2::BnCameraDeviceCallbacks {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080066 public:
67 ServiceCallback(CameraDevice* device) : mDevice(device) {}
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080068 binder::Status onDeviceError(int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080069 const CaptureResultExtras& resultExtras) override;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080070 binder::Status onDeviceIdle() override;
71 binder::Status onCaptureStarted(const CaptureResultExtras& resultExtras,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080072 int64_t timestamp) override;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080073 binder::Status onResultReceived(const CameraMetadata& metadata,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080074 const CaptureResultExtras& resultExtras) override;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080075 binder::Status onPrepared(int streamId) override;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080076 private:
77 const wp<CameraDevice> mDevice;
78 };
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080079 inline sp<hardware::camera2::ICameraDeviceCallbacks> getServiceCallback() {
80 return mServiceCallback;
81 };
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080082
83 // Camera device is only functional after remote being set
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080084 void setRemoteDevice(sp<hardware::camera2::ICameraDeviceUser> remote);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080085
Yin-Chia Yehead91462016-01-06 16:45:08 -080086 inline ACameraDevice* getWrapper() const { return mWrapper; };
87
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080088 private:
Yin-Chia Yehead91462016-01-06 16:45:08 -080089 friend ACameraCaptureSession;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -080090 camera_status_t checkCameraClosedOrErrorLocked() const;
91
Yin-Chia Yehead91462016-01-06 16:45:08 -080092 // device goes into fatal error state after this
93 void setCameraDeviceErrorLocked(camera_status_t error);
94
95 void disconnectLocked(); // disconnect from camera service
96
97 camera_status_t stopRepeatingLocked();
98
99 camera_status_t waitUntilIdleLocked();
100
101
102 camera_status_t captureLocked(sp<ACameraCaptureSession> session,
103 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
104 int numRequests, ACaptureRequest** requests,
105 /*optional*/int* captureSequenceId);
106
107 camera_status_t setRepeatingRequestsLocked(sp<ACameraCaptureSession> session,
108 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
109 int numRequests, ACaptureRequest** requests,
110 /*optional*/int* captureSequenceId);
111
112 camera_status_t submitRequestsLocked(
113 sp<ACameraCaptureSession> session,
114 /*optional*/ACameraCaptureSession_captureCallbacks* cbs,
115 int numRequests, ACaptureRequest** requests,
116 /*out*/int* captureSequenceId,
117 bool isRepeating);
118
119 static camera_status_t allocateCaptureRequest(
120 const ACaptureRequest* request, sp<CaptureRequest>& outReq);
121
122 static ACaptureRequest* allocateACaptureRequest(sp<CaptureRequest>& req);
123 static void freeACaptureRequest(ACaptureRequest*);
124
125 // only For session to hold device lock
126 // Always grab device lock before grabbing session lock
127 void lockDeviceForSessionOps() const { mDeviceLock.lock(); };
128 void unlockDevice() const { mDeviceLock.unlock(); };
129
130 // For capture session to notify its end of life
131 void notifySessionEndOfLifeLocked(ACameraCaptureSession* session);
132
133 camera_status_t configureStreamsLocked(const ACaptureSessionOutputContainer* outputs);
134
135 static camera_status_t getIGBPfromSessionOutput(
136 const ACaptureSessionOutput& config, sp<IGraphicBufferProducer>& out);
137
138 static camera_status_t getSurfaceFromANativeWindow(
139 ANativeWindow* anw, sp<Surface>& out);
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800140
141 mutable Mutex mDeviceLock;
142 const String8 mCameraId; // Camera ID
143 const ACameraDevice_StateCallbacks mAppCallbacks; // Callback to app
144 const std::unique_ptr<ACameraMetadata> mChars; // Camera characteristics
145 const sp<ServiceCallback> mServiceCallback;
146 ACameraDevice* mWrapper;
147
Yin-Chia Yehead91462016-01-06 16:45:08 -0800148 // stream id -> OutputConfiguration map
149 std::map<int, OutputConfiguration> mConfiguredOutputs;
150
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800151 // TODO: maybe a bool will suffice for synchronous implementation?
152 std::atomic_bool mClosing;
153 inline bool isClosed() { return mClosing; }
154
155 bool mInError;
156 camera_status_t mError;
157 void onCaptureErrorLocked(
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800158 int32_t errorCode,
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800159 const CaptureResultExtras& resultExtras);
160
161 bool mIdle;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800162 // This will avoid a busy session being deleted before it's back to idle state
163 sp<ACameraCaptureSession> mBusySession;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800164
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800165 sp<hardware::camera2::ICameraDeviceUser> mRemote;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800166
167 // Looper thread to handle callback to app
168 sp<ALooper> mCbLooper;
169 // definition of handler and message
170 enum {
Yin-Chia Yehead91462016-01-06 16:45:08 -0800171 // Device state callbacks
172 kWhatOnDisconnected, // onDisconnected
173 kWhatOnError, // onError
174 // Session state callbacks
175 kWhatSessionStateCb, // onReady, onActive
176 // Capture callbacks
177 kWhatCaptureStart, // onCaptureStarted
178 kWhatCaptureResult, // onCaptureProgressed, onCaptureCompleted
179 kWhatCaptureFail, // onCaptureFailed
180 kWhatCaptureSeqEnd, // onCaptureSequenceCompleted
181 kWhatCaptureSeqAbort // onCaptureSequenceAborted
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800182 };
183 static const char* kContextKey;
184 static const char* kDeviceKey;
185 static const char* kErrorCodeKey;
Yin-Chia Yehead91462016-01-06 16:45:08 -0800186 static const char* kCallbackFpKey;
187 static const char* kSessionSpKey;
188 static const char* kCaptureRequestKey;
189 static const char* kTimeStampKey;
190 static const char* kCaptureResultKey;
191 static const char* kCaptureFailureKey;
192 static const char* kSequenceIdKey;
193 static const char* kFrameNumberKey;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800194 class CallbackHandler : public AHandler {
195 public:
196 CallbackHandler() {}
197 void onMessageReceived(const sp<AMessage> &msg) override;
198 };
199 sp<CallbackHandler> mHandler;
200
Yin-Chia Yehead91462016-01-06 16:45:08 -0800201 /***********************************
202 * Capture session related members *
203 ***********************************/
204 // The current active session
205 ACameraCaptureSession* mCurrentSession = nullptr;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800206
Yin-Chia Yehead91462016-01-06 16:45:08 -0800207 int mNextSessionId = 0;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800208 // TODO: might need another looper/handler to handle callbacks from service
209
Yin-Chia Yehead91462016-01-06 16:45:08 -0800210 static const int REQUEST_ID_NONE = -1;
211 int mRepeatingSequenceId = REQUEST_ID_NONE;
212
213 // sequence id -> last frame number map
214 std::map<int, int64_t> mSequenceLastFrameNumberMap;
215
216 struct CallbackHolder {
217 CallbackHolder(sp<ACameraCaptureSession> session,
218 const Vector<sp<CaptureRequest> >& requests,
219 bool isRepeating,
220 ACameraCaptureSession_captureCallbacks* cbs);
221
222 static ACameraCaptureSession_captureCallbacks fillCb(
223 ACameraCaptureSession_captureCallbacks* cbs) {
224 if (cbs != nullptr) {
225 return *cbs;
226 }
227 return { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
228 }
229
230 sp<ACameraCaptureSession> mSession;
231 Vector<sp<CaptureRequest> > mRequests;
232 const bool mIsRepeating;
233 ACameraCaptureSession_captureCallbacks mCallbacks;
234 };
235 // sequence id -> callbacks map
236 std::map<int, CallbackHolder> mSequenceCallbackMap;
237
238 static const int64_t NO_FRAMES_CAPTURED = -1;
239 class FrameNumberTracker {
240 public:
241 // TODO: Called in onResultReceived and onCaptureErrorLocked
242 void updateTracker(int64_t frameNumber, bool isError);
243 inline int64_t getCompletedFrameNumber() { return mCompletedFrameNumber; }
244 private:
245 void update();
246 void updateCompletedFrameNumber(int64_t frameNumber);
247
248 int64_t mCompletedFrameNumber = NO_FRAMES_CAPTURED;
249 List<int64_t> mSkippedFrameNumbers;
250 std::set<int64_t> mFutureErrorSet;
251 };
252 FrameNumberTracker mFrameNumberTracker;
253
254 void checkRepeatingSequenceCompleteLocked(const int sequenceId, const int64_t lastFrameNumber);
255 void checkAndFireSequenceCompleteLocked();
256
257 // Misc variables
258 int32_t mShadingMapSize[2]; // const after constructor
259 int32_t mPartialResultCount; // const after constructor
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800260
261};
262
263} // namespace android;
264
265/**
266 * ACameraDevice opaque struct definition
267 * Leave outside of android namespace because it's NDK struct
268 */
269struct ACameraDevice {
270 ACameraDevice(const char* id, ACameraDevice_StateCallbacks* cb,
271 std::unique_ptr<ACameraMetadata> chars) :
272 mDevice(new CameraDevice(id, cb, std::move(chars), this)) {}
273
274 ~ACameraDevice() {};
275
Yin-Chia Yehead91462016-01-06 16:45:08 -0800276 /*******************
277 * NDK public APIs *
278 *******************/
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800279 inline const char* getId() const { return mDevice->getId(); }
280
281 camera_status_t createCaptureRequest(
282 ACameraDevice_request_template templateId,
283 ACaptureRequest** request) const {
284 return mDevice->createCaptureRequest(templateId, request);
285 }
286
Yin-Chia Yehead91462016-01-06 16:45:08 -0800287 camera_status_t createCaptureSession(
288 const ACaptureSessionOutputContainer* outputs,
289 const ACameraCaptureSession_stateCallbacks* callbacks,
290 /*out*/ACameraCaptureSession** session) {
291 return mDevice->createCaptureSession(outputs, callbacks, session);
292 }
293
294 /***********************
295 * Device interal APIs *
296 ***********************/
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800297 inline android::sp<android::hardware::camera2::ICameraDeviceCallbacks> getServiceCallback() {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800298 return mDevice->getServiceCallback();
299 };
300
301 // Camera device is only functional after remote being set
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800302 inline void setRemoteDevice(android::sp<android::hardware::camera2::ICameraDeviceUser> remote) {
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800303 mDevice->setRemoteDevice(remote);
304 }
305
306 private:
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800307 android::sp<android::CameraDevice> mDevice;
Yin-Chia Yeh0dea57f2015-12-09 16:46:07 -0800308};
309
310#endif // _ACAMERA_DEVICE_H