blob: 33c91795eb65b1951585fc3764c839e6d92b44ce [file] [log] [blame]
Igor Murashkin634a5152013-02-20 17:15:11 -08001/*
2 * Copyright (C) 2013 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
17#include <gtest/gtest.h>
18#include <iostream>
19
Igor Murashkin53765732013-02-20 17:41:57 -080020#include <binder/IPCThreadState.h>
21#include <utils/Thread.h>
22
Igor Murashkin634a5152013-02-20 17:15:11 -080023#include "Camera.h"
24#include "ProCamera.h"
Igor Murashkin53765732013-02-20 17:41:57 -080025#include <utils/Vector.h>
26#include <utils/Mutex.h>
27#include <utils/Condition.h>
Igor Murashkin634a5152013-02-20 17:15:11 -080028
Igor Murashkin68506fd2013-02-20 17:57:31 -080029#include <gui/SurfaceComposerClient.h>
30#include <gui/Surface.h>
31
32#include <system/camera_metadata.h>
33#include <hardware/camera2.h> // for CAMERA2_TEMPLATE_PREVIEW only
Igor Murashkindcb07d52013-02-21 14:18:10 -080034#include <camera/CameraMetadata.h>
Igor Murashkin68506fd2013-02-20 17:57:31 -080035
Igor Murashkin634a5152013-02-20 17:15:11 -080036namespace android {
37namespace camera2 {
38namespace tests {
39namespace client {
40
41#define CAMERA_ID 0
42#define TEST_DEBUGGING 0
43
Igor Murashkin68506fd2013-02-20 17:57:31 -080044#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout
Igor Murashkin5835cc42013-02-20 19:29:53 -080045#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead
46
Igor Murashkineb72e172013-02-21 11:43:14 -080047#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8
Igor Murashkin5835cc42013-02-20 19:29:53 -080048#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16
49
Igor Murashkindcb07d52013-02-21 14:18:10 -080050// defaults for display "test"
51#define TEST_DISPLAY_FORMAT HAL_PIXEL_FORMAT_Y16
52#define TEST_DISPLAY_WIDTH 1280
53#define TEST_DISPLAY_HEIGHT 960
54
Igor Murashkin5835cc42013-02-20 19:29:53 -080055#define TEST_CPU_FRAME_COUNT 2
56#define TEST_CPU_HEAP_COUNT 5
Igor Murashkin53765732013-02-20 17:41:57 -080057
Igor Murashkin634a5152013-02-20 17:15:11 -080058#if TEST_DEBUGGING
59#define dout std::cerr
60#else
61#define dout if (0) std::cerr
62#endif
63
Igor Murashkin39f79f72013-01-30 10:14:24 -080064#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
65#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
66
67class ProCameraTest;
68
Igor Murashkin5835cc42013-02-20 19:29:53 -080069enum ProEvent {
Igor Murashkin53765732013-02-20 17:41:57 -080070 UNKNOWN,
71 ACQUIRED,
72 RELEASED,
Igor Murashkin5835cc42013-02-20 19:29:53 -080073 STOLEN,
74 BUFFER_RECEIVED,
Igor Murashkina91537e2013-02-21 12:02:29 -080075 RESULT_RECEIVED,
Igor Murashkin53765732013-02-20 17:41:57 -080076};
77
Igor Murashkina91537e2013-02-21 12:02:29 -080078inline int ProEvent_Mask(ProEvent e) {
79 return (1 << static_cast<int>(e));
80}
81
Igor Murashkin5835cc42013-02-20 19:29:53 -080082typedef Vector<ProEvent> EventList;
Igor Murashkin53765732013-02-20 17:41:57 -080083
84class ProCameraTestThread : public Thread
85{
86public:
87 ProCameraTestThread() {
88 }
89
90 virtual bool threadLoop() {
91 mProc = ProcessState::self();
92 mProc->startThreadPool();
93
94 IPCThreadState *ptr = IPCThreadState::self();
95
Igor Murashkin53765732013-02-20 17:41:57 -080096 ptr->joinThreadPool();
Igor Murashkin53765732013-02-20 17:41:57 -080097
98 return false;
99 }
100
101 sp<ProcessState> mProc;
102};
103
104class ProCameraTestListener : public ProCameraListener {
105
106public:
Igor Murashkina91537e2013-02-21 12:02:29 -0800107 static const int EVENT_MASK_ALL = 0xFFFFFFFF;
108
109 ProCameraTestListener() {
110 mEventMask = EVENT_MASK_ALL;
111 }
112
Igor Murashkin53765732013-02-20 17:41:57 -0800113 status_t WaitForEvent() {
114 Mutex::Autolock cal(mConditionMutex);
115
116 {
117 Mutex::Autolock al(mListenerMutex);
118
Igor Murashkin5835cc42013-02-20 19:29:53 -0800119 if (mProEventList.size() > 0) {
Igor Murashkin53765732013-02-20 17:41:57 -0800120 return OK;
121 }
122 }
123
124 return mListenerCondition.waitRelative(mConditionMutex,
125 TEST_LISTENER_TIMEOUT);
126 }
127
128 /* Read events into out. Existing queue is flushed */
129 void ReadEvents(EventList& out) {
130 Mutex::Autolock al(mListenerMutex);
131
Igor Murashkin5835cc42013-02-20 19:29:53 -0800132 for (size_t i = 0; i < mProEventList.size(); ++i) {
133 out.push(mProEventList[i]);
Igor Murashkin53765732013-02-20 17:41:57 -0800134 }
135
Igor Murashkin5835cc42013-02-20 19:29:53 -0800136 mProEventList.clear();
Igor Murashkin53765732013-02-20 17:41:57 -0800137 }
138
139 /**
140 * Dequeue 1 event from the event queue.
141 * Returns UNKNOWN if queue is empty
142 */
Igor Murashkin5835cc42013-02-20 19:29:53 -0800143 ProEvent ReadEvent() {
Igor Murashkin53765732013-02-20 17:41:57 -0800144 Mutex::Autolock al(mListenerMutex);
145
Igor Murashkin5835cc42013-02-20 19:29:53 -0800146 if (mProEventList.size() == 0) {
Igor Murashkin53765732013-02-20 17:41:57 -0800147 return UNKNOWN;
148 }
149
Igor Murashkin5835cc42013-02-20 19:29:53 -0800150 ProEvent ev = mProEventList[0];
151 mProEventList.removeAt(0);
Igor Murashkin53765732013-02-20 17:41:57 -0800152
153 return ev;
154 }
155
Igor Murashkina91537e2013-02-21 12:02:29 -0800156 void SetEventMask(int eventMask) {
157 Mutex::Autolock al(mListenerMutex);
158 mEventMask = eventMask;
159 }
160
Igor Murashkin53765732013-02-20 17:41:57 -0800161private:
Igor Murashkin5835cc42013-02-20 19:29:53 -0800162 void QueueEvent(ProEvent ev) {
Igor Murashkina91537e2013-02-21 12:02:29 -0800163 bool eventAdded = false;
Igor Murashkin53765732013-02-20 17:41:57 -0800164 {
165 Mutex::Autolock al(mListenerMutex);
Igor Murashkina91537e2013-02-21 12:02:29 -0800166
167 if (ProEvent_Mask(ev) & mEventMask) {
168 mProEventList.push(ev);
169 eventAdded = true;
170 }
Igor Murashkin53765732013-02-20 17:41:57 -0800171 }
172
Igor Murashkina91537e2013-02-21 12:02:29 -0800173 if (eventAdded) {
174 mListenerCondition.broadcast();
175 }
Igor Murashkin53765732013-02-20 17:41:57 -0800176 }
177
178protected:
179
180 //////////////////////////////////////////////////
181 ///////// ProCameraListener //////////////////////
182 //////////////////////////////////////////////////
183
184
185 // Lock has been acquired. Write operations now available.
186 virtual void onLockAcquired() {
187 QueueEvent(ACQUIRED);
188 }
189 // Lock has been released with exclusiveUnlock
190 virtual void onLockReleased() {
191 QueueEvent(RELEASED);
192 }
193
194 // Lock has been stolen by another client.
195 virtual void onLockStolen() {
196 QueueEvent(STOLEN);
197 }
198
199 // Lock free.
200 virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
201
202 dout << "Trigger notify: " << ext1 << " " << ext2
203 << " " << ext3 << std::endl;
204 }
205
Igor Murashkin5835cc42013-02-20 19:29:53 -0800206 virtual void onBufferReceived(int streamId,
207 const CpuConsumer::LockedBuffer& buf) {
208
209 dout << "Buffer received on streamId = " << streamId <<
Igor Murashkina140a6e2013-02-21 14:45:03 -0800210 ", dataPtr = " << (void*)buf.data <<
211 ", timestamp = " << buf.timestamp << std::endl;
Igor Murashkin5835cc42013-02-20 19:29:53 -0800212
213 QueueEvent(BUFFER_RECEIVED);
214
215 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800216 virtual void onResultReceived(int32_t frameId,
217 camera_metadata* request) {
218 dout << "Result received frameId = " << frameId
219 << ", requestPtr = " << (void*)request << std::endl;
220 QueueEvent(RESULT_RECEIVED);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800221 free_camera_metadata(request);
222 }
223
Igor Murashkin53765732013-02-20 17:41:57 -0800224 // TODO: remove
225
226 virtual void notify(int32_t , int32_t , int32_t ) {}
227 virtual void postData(int32_t , const sp<IMemory>& ,
228 camera_frame_metadata_t *) {}
229 virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {}
230
231
Igor Murashkin5835cc42013-02-20 19:29:53 -0800232 Vector<ProEvent> mProEventList;
Igor Murashkin53765732013-02-20 17:41:57 -0800233 Mutex mListenerMutex;
234 Mutex mConditionMutex;
235 Condition mListenerCondition;
Igor Murashkina91537e2013-02-21 12:02:29 -0800236 int mEventMask;
Igor Murashkin53765732013-02-20 17:41:57 -0800237};
238
Igor Murashkin634a5152013-02-20 17:15:11 -0800239class ProCameraTest : public ::testing::Test {
240
Igor Murashkin53765732013-02-20 17:41:57 -0800241public:
242 ProCameraTest() {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800243 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
244 if (displaySecsEnv != NULL) {
245 mDisplaySecs = atoi(displaySecsEnv);
246 if (mDisplaySecs < 0) {
247 mDisplaySecs = 0;
248 }
249 } else {
250 mDisplaySecs = 0;
251 }
252
253 char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT");
254 if (displayFmtEnv != NULL) {
255 mDisplayFmt = FormatFromString(displayFmtEnv);
256 } else {
257 mDisplayFmt = TEST_DISPLAY_FORMAT;
258 }
259
260 char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH");
261 if (displayWidthEnv != NULL) {
262 mDisplayW = atoi(displayWidthEnv);
263 if (mDisplayW < 0) {
264 mDisplayW = 0;
265 }
266 } else {
267 mDisplayW = TEST_DISPLAY_WIDTH;
268 }
269
270 char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT");
271 if (displayHeightEnv != NULL) {
272 mDisplayH = atoi(displayHeightEnv);
273 if (mDisplayH < 0) {
274 mDisplayH = 0;
275 }
276 } else {
277 mDisplayH = TEST_DISPLAY_HEIGHT;
278 }
Igor Murashkin53765732013-02-20 17:41:57 -0800279 }
280
Igor Murashkin39f79f72013-01-30 10:14:24 -0800281 static void SetUpTestCase() {
282 // Binder Thread Pool Initialization
Igor Murashkin53765732013-02-20 17:41:57 -0800283 mTestThread = new ProCameraTestThread();
284 mTestThread->run("ProCameraTestThread");
Igor Murashkin39f79f72013-01-30 10:14:24 -0800285 }
Igor Murashkin53765732013-02-20 17:41:57 -0800286
Igor Murashkin39f79f72013-01-30 10:14:24 -0800287 virtual void SetUp() {
Igor Murashkin634a5152013-02-20 17:15:11 -0800288 mCamera = ProCamera::connect(CAMERA_ID);
289 ASSERT_NE((void*)NULL, mCamera.get());
Igor Murashkin53765732013-02-20 17:41:57 -0800290
291 mListener = new ProCameraTestListener();
292 mCamera->setListener(mListener);
Igor Murashkin634a5152013-02-20 17:15:11 -0800293 }
294
295 virtual void TearDown() {
296 ASSERT_NE((void*)NULL, mCamera.get());
297 mCamera->disconnect();
298 }
299
300protected:
301 sp<ProCamera> mCamera;
Igor Murashkin53765732013-02-20 17:41:57 -0800302 sp<ProCameraTestListener> mListener;
303
Igor Murashkin39f79f72013-01-30 10:14:24 -0800304 static sp<Thread> mTestThread;
Igor Murashkin53765732013-02-20 17:41:57 -0800305
Igor Murashkin68506fd2013-02-20 17:57:31 -0800306 int mDisplaySecs;
Igor Murashkindcb07d52013-02-21 14:18:10 -0800307 int mDisplayFmt;
308 int mDisplayW;
309 int mDisplayH;
310
Igor Murashkin68506fd2013-02-20 17:57:31 -0800311 sp<SurfaceComposerClient> mComposerClient;
312 sp<SurfaceControl> mSurfaceControl;
313
Igor Murashkin5835cc42013-02-20 19:29:53 -0800314 sp<SurfaceComposerClient> mDepthComposerClient;
315 sp<SurfaceControl> mDepthSurfaceControl;
316
Igor Murashkin68506fd2013-02-20 17:57:31 -0800317 int getSurfaceWidth() {
318 return 512;
319 }
320 int getSurfaceHeight() {
321 return 512;
322 }
323
324 void createOnScreenSurface(sp<Surface>& surface) {
325 mComposerClient = new SurfaceComposerClient;
326 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
327
328 mSurfaceControl = mComposerClient->createSurface(
329 String8("ProCameraTest StreamingImage Surface"),
330 getSurfaceWidth(), getSurfaceHeight(),
331 PIXEL_FORMAT_RGB_888, 0);
332
Igor Murashkindcb07d52013-02-21 14:18:10 -0800333 mSurfaceControl->setPosition(0, 0);
Igor Murashkin5835cc42013-02-20 19:29:53 -0800334
Igor Murashkin68506fd2013-02-20 17:57:31 -0800335 ASSERT_TRUE(mSurfaceControl != NULL);
336 ASSERT_TRUE(mSurfaceControl->isValid());
337
338 SurfaceComposerClient::openGlobalTransaction();
339 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
340 ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
341 SurfaceComposerClient::closeGlobalTransaction();
342
343 sp<ANativeWindow> window = mSurfaceControl->getSurface();
344 surface = mSurfaceControl->getSurface();
345
346 ASSERT_NE((void*)NULL, surface.get());
347 }
348
Igor Murashkin5835cc42013-02-20 19:29:53 -0800349 void createDepthOnScreenSurface(sp<Surface>& surface) {
350 mDepthComposerClient = new SurfaceComposerClient;
351 ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
352
353 mDepthSurfaceControl = mDepthComposerClient->createSurface(
354 String8("ProCameraTest StreamingImage Surface"),
355 getSurfaceWidth(), getSurfaceHeight(),
356 PIXEL_FORMAT_RGB_888, 0);
357
358 mDepthSurfaceControl->setPosition(640, 0);
359
360 ASSERT_TRUE(mDepthSurfaceControl != NULL);
361 ASSERT_TRUE(mDepthSurfaceControl->isValid());
362
363 SurfaceComposerClient::openGlobalTransaction();
364 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
365 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
366 SurfaceComposerClient::closeGlobalTransaction();
367
368 sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
369 surface = mDepthSurfaceControl->getSurface();
370
371 ASSERT_NE((void*)NULL, surface.get());
372 }
373
Igor Murashkin7b33a742013-02-21 13:49:26 -0800374 template <typename T>
Igor Murashkindcb07d52013-02-21 14:18:10 -0800375 static bool ExistsItem(T needle, T* array, size_t count) {
376 if (!array) {
377 return false;
378 }
379
Igor Murashkina140a6e2013-02-21 14:45:03 -0800380 for (size_t i = 0; i < count; ++i) {
Igor Murashkin7b33a742013-02-21 13:49:26 -0800381 if (array[i] == needle) {
382 return true;
383 }
384 }
385 return false;
386 }
387
Igor Murashkindcb07d52013-02-21 14:18:10 -0800388
389 static int FormatFromString(const char* str) {
390 std::string s(str);
391
392#define CMP_STR(x, y) \
393 if (s == #x) return HAL_PIXEL_FORMAT_ ## y;
394#define CMP_STR_SAME(x) CMP_STR(x, x)
395
396 CMP_STR_SAME( Y16);
397 CMP_STR_SAME( Y8);
398 CMP_STR_SAME( YV12);
399 CMP_STR(NV16, YCbCr_422_SP);
400 CMP_STR(NV21, YCrCb_420_SP);
401 CMP_STR(YUY2, YCbCr_422_I);
402 CMP_STR(RAW, RAW_SENSOR);
403 CMP_STR(RGBA, RGBA_8888);
404
405 std::cerr << "Unknown format string " << str << std::endl;
406 return -1;
407
408 }
409
410 /**
411 * Creating a streaming request for these output streams from a template,
412 * and submit it
413 */
Igor Murashkina140a6e2013-02-21 14:45:03 -0800414 void createSubmitRequestForStreams(uint8_t* streamIds, size_t count, int requestCount=-1) {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800415
416 ASSERT_NE((void*)NULL, streamIds);
Igor Murashkina140a6e2013-02-21 14:45:03 -0800417 ASSERT_LT(0u, count);
Igor Murashkindcb07d52013-02-21 14:18:10 -0800418
419 camera_metadata_t *requestTmp = NULL;
420 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
421 /*out*/&requestTmp));
422 ASSERT_NE((void*)NULL, requestTmp);
423 CameraMetadata request(requestTmp);
424
425 // set the output streams. default is empty
426
427 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
428 request.update(tag, streamIds, count);
429
430 requestTmp = request.release();
Igor Murashkina140a6e2013-02-21 14:45:03 -0800431
432 if (requestCount < 0) {
433 EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true));
434 } else {
435 for (int i = 0; i < requestCount; ++i) {
436 EXPECT_OK(mCamera->submitRequest(requestTmp,
437 /*streaming*/false));
438 }
439 }
Igor Murashkindcb07d52013-02-21 14:18:10 -0800440 request.acquire(requestTmp);
441 }
442
Igor Murashkin634a5152013-02-20 17:15:11 -0800443};
444
Igor Murashkin39f79f72013-01-30 10:14:24 -0800445sp<Thread> ProCameraTest::mTestThread;
446
Igor Murashkin7b33a742013-02-21 13:49:26 -0800447TEST_F(ProCameraTest, AvailableFormats) {
448 if (HasFatalFailure()) {
449 return;
450 }
451
Igor Murashkindcb07d52013-02-21 14:18:10 -0800452 CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID);
453 ASSERT_FALSE(staticInfo.isEmpty());
Igor Murashkin7b33a742013-02-21 13:49:26 -0800454
Igor Murashkin7b33a742013-02-21 13:49:26 -0800455 uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
Igor Murashkindcb07d52013-02-21 14:18:10 -0800456 EXPECT_TRUE(staticInfo.exists(tag));
457 camera_metadata_entry_t entry = staticInfo.find(tag);
Igor Murashkin7b33a742013-02-21 13:49:26 -0800458
Igor Murashkindcb07d52013-02-21 14:18:10 -0800459 EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
Igor Murashkin7b33a742013-02-21 13:49:26 -0800460 entry.data.i32, entry.count));
Igor Murashkindcb07d52013-02-21 14:18:10 -0800461 EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
Igor Murashkin7b33a742013-02-21 13:49:26 -0800462 entry.data.i32, entry.count));
Igor Murashkin7b33a742013-02-21 13:49:26 -0800463}
464
Igor Murashkin39f79f72013-01-30 10:14:24 -0800465// test around exclusiveTryLock (immediate locking)
Igor Murashkin53765732013-02-20 17:41:57 -0800466TEST_F(ProCameraTest, LockingImmediate) {
Igor Murashkin634a5152013-02-20 17:15:11 -0800467
468 if (HasFatalFailure()) {
469 return;
470 }
471
Igor Murashkina91537e2013-02-21 12:02:29 -0800472 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
473 ProEvent_Mask(STOLEN) |
474 ProEvent_Mask(RELEASED));
475
Igor Murashkin53765732013-02-20 17:41:57 -0800476 EXPECT_FALSE(mCamera->hasExclusiveLock());
477 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
Igor Murashkin39f79f72013-01-30 10:14:24 -0800478 // at this point we definitely have the lock
479
480 EXPECT_EQ(OK, mListener->WaitForEvent());
481 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
482
483 EXPECT_TRUE(mCamera->hasExclusiveLock());
484 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
485
486 EXPECT_EQ(OK, mListener->WaitForEvent());
487 EXPECT_EQ(RELEASED, mListener->ReadEvent());
488
489 EXPECT_FALSE(mCamera->hasExclusiveLock());
490}
491
492// test around exclusiveLock (locking at some future point in time)
493TEST_F(ProCameraTest, LockingAsynchronous) {
494
495 if (HasFatalFailure()) {
496 return;
497 }
498
Igor Murashkina91537e2013-02-21 12:02:29 -0800499
500 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
501 ProEvent_Mask(STOLEN) |
502 ProEvent_Mask(RELEASED));
503
Igor Murashkin39f79f72013-01-30 10:14:24 -0800504 // TODO: Add another procamera that has a lock here.
505 // then we can be test that the lock wont immediately be acquired
506
507 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkina91537e2013-02-21 12:02:29 -0800508 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
509 // at this point we definitely have the lock
Igor Murashkin53765732013-02-20 17:41:57 -0800510
511 EXPECT_EQ(OK, mListener->WaitForEvent());
512 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
513
514 EXPECT_TRUE(mCamera->hasExclusiveLock());
515 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
516
517 EXPECT_EQ(OK, mListener->WaitForEvent());
518 EXPECT_EQ(RELEASED, mListener->ReadEvent());
519
520 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkin634a5152013-02-20 17:15:11 -0800521}
522
Igor Murashkin68506fd2013-02-20 17:57:31 -0800523// Stream directly to the screen.
Igor Murashkina91537e2013-02-21 12:02:29 -0800524TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
Igor Murashkin68506fd2013-02-20 17:57:31 -0800525 if (HasFatalFailure()) {
526 return;
527 }
Igor Murashkin68506fd2013-02-20 17:57:31 -0800528
Igor Murashkindcb07d52013-02-21 14:18:10 -0800529 sp<Surface> surface;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800530 if (mDisplaySecs > 0) {
Igor Murashkindcb07d52013-02-21 14:18:10 -0800531 createOnScreenSurface(/*out*/surface);
532 }
533 else {
534 dout << "Skipping, will not render to screen" << std::endl;
535 return;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800536 }
Igor Murashkin5835cc42013-02-20 19:29:53 -0800537
538 int depthStreamId = -1;
Igor Murashkindcb07d52013-02-21 14:18:10 -0800539 EXPECT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt, surface,
540 &depthStreamId));
Igor Murashkin5835cc42013-02-20 19:29:53 -0800541 EXPECT_NE(-1, depthStreamId);
Igor Murashkin68506fd2013-02-20 17:57:31 -0800542
543 EXPECT_OK(mCamera->exclusiveTryLock());
Igor Murashkin68506fd2013-02-20 17:57:31 -0800544
Igor Murashkindcb07d52013-02-21 14:18:10 -0800545 uint8_t streams[] = { depthStreamId };
546 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
Igor Murashkin68506fd2013-02-20 17:57:31 -0800547
Igor Murashkin985fd302013-02-20 18:24:43 -0800548 dout << "will sleep now for " << mDisplaySecs << std::endl;
Igor Murashkin68506fd2013-02-20 17:57:31 -0800549 sleep(mDisplaySecs);
Igor Murashkin68506fd2013-02-20 17:57:31 -0800550
Igor Murashkindcb07d52013-02-21 14:18:10 -0800551 EXPECT_OK(mCamera->deleteStream(depthStreamId));
Igor Murashkin5835cc42013-02-20 19:29:53 -0800552 EXPECT_OK(mCamera->exclusiveUnlock());
553}
554
Igor Murashkineb72e172013-02-21 11:43:14 -0800555// Stream directly to the screen.
Igor Murashkina91537e2013-02-21 12:02:29 -0800556TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
Igor Murashkineb72e172013-02-21 11:43:14 -0800557 if (HasFatalFailure()) {
558 return;
559 }
Igor Murashkineb72e172013-02-21 11:43:14 -0800560 sp<Surface> surface;
561 sp<Surface> depthSurface;
562 if (mDisplaySecs > 0) {
563 createOnScreenSurface(/*out*/surface);
564 createDepthOnScreenSurface(/*out*/depthSurface);
565 }
566
567 int streamId = -1;
568 EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
569 TEST_FORMAT_MAIN, surface, &streamId));
570 EXPECT_NE(-1, streamId);
571
572 int depthStreamId = -1;
573 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
574 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
575 EXPECT_NE(-1, depthStreamId);
576
577 EXPECT_OK(mCamera->exclusiveTryLock());
578 /*
579 */
580 /* iterate in a loop submitting requests every frame.
581 * what kind of requests doesnt really matter, just whatever.
582 */
583
584 // it would probably be better to use CameraMetadata from camera service.
585 camera_metadata_t *request = NULL;
586 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
587 /*out*/&request));
588 EXPECT_NE((void*)NULL, request);
589
590 /*FIXME: dont need this later, at which point the above should become an
591 ASSERT_NE*/
592 if(request == NULL) request = allocate_camera_metadata(10, 100);
593
594 // set the output streams to just this stream ID
595
596 // wow what a verbose API.
597 uint8_t allStreams[] = { streamId, depthStreamId };
598 // IMPORTANT. bad things will happen if its not a uint8.
599 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
600 camera_metadata_entry_t entry;
601 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
602 int find = find_camera_metadata_entry(request, tag, &entry);
603 if (find == -ENOENT) {
604 if (add_camera_metadata_entry(request, tag, &allStreams,
605 /*data_count*/streamCount) != OK) {
606 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
607 ASSERT_OK(append_camera_metadata(tmp, request));
608 free_camera_metadata(request);
609 request = tmp;
610
611 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
612 /*data_count*/streamCount));
613 }
614 } else {
615 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
616 &allStreams, /*data_count*/streamCount, &entry));
617 }
618
619 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
620
621 dout << "will sleep now for " << mDisplaySecs << std::endl;
622 sleep(mDisplaySecs);
623
624 free_camera_metadata(request);
625
626 for (int i = 0; i < streamCount; ++i) {
627 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
628 }
629 EXPECT_OK(mCamera->exclusiveUnlock());
630}
631
632TEST_F(ProCameraTest, CpuConsumerSingle) {
Igor Murashkin5835cc42013-02-20 19:29:53 -0800633 if (HasFatalFailure()) {
634 return;
635 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800636
637 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
638
Igor Murashkin5835cc42013-02-20 19:29:53 -0800639 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800640 sp<CpuConsumer> consumer;
Igor Murashkin5835cc42013-02-20 19:29:53 -0800641 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800642 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkin5835cc42013-02-20 19:29:53 -0800643 EXPECT_NE(-1, streamId);
644
645 EXPECT_OK(mCamera->exclusiveTryLock());
646 EXPECT_EQ(OK, mListener->WaitForEvent());
647 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
648 /* iterate in a loop submitting requests every frame.
649 * what kind of requests doesnt really matter, just whatever.
650 */
651
652 // it would probably be better to use CameraMetadata from camera service.
653 camera_metadata_t *request = NULL;
654 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
655 /*out*/&request));
656 EXPECT_NE((void*)NULL, request);
657
658 /*FIXME: dont need this later, at which point the above should become an
659 ASSERT_NE*/
660 if(request == NULL) request = allocate_camera_metadata(10, 100);
661
662 // set the output streams to just this stream ID
663
664 uint8_t allStreams[] = { streamId };
665 camera_metadata_entry_t entry;
666 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
667 int find = find_camera_metadata_entry(request, tag, &entry);
668 if (find == -ENOENT) {
669 if (add_camera_metadata_entry(request, tag, &allStreams,
670 /*data_count*/1) != OK) {
671 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
672 ASSERT_OK(append_camera_metadata(tmp, request));
673 free_camera_metadata(request);
674 request = tmp;
675
676 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
677 /*data_count*/1));
678 }
679 } else {
680 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
681 &allStreams, /*data_count*/1, &entry));
682 }
683
684 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
685
686 // Consume a couple of frames
687 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
688 EXPECT_EQ(OK, mListener->WaitForEvent());
689 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
690 }
691
692 // Done: clean up
693 free_camera_metadata(request);
694 EXPECT_OK(mCamera->deleteStream(streamId));
Igor Murashkin68506fd2013-02-20 17:57:31 -0800695 EXPECT_OK(mCamera->exclusiveUnlock());
696}
697
Igor Murashkineb72e172013-02-21 11:43:14 -0800698TEST_F(ProCameraTest, CpuConsumerDual) {
699 if (HasFatalFailure()) {
700 return;
701 }
Igor Murashkina91537e2013-02-21 12:02:29 -0800702
703 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
704
Igor Murashkineb72e172013-02-21 11:43:14 -0800705 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800706 sp<CpuConsumer> consumer;
Igor Murashkineb72e172013-02-21 11:43:14 -0800707 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800708 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkineb72e172013-02-21 11:43:14 -0800709 EXPECT_NE(-1, streamId);
710
711 int depthStreamId = -1;
712 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800713 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId));
Igor Murashkineb72e172013-02-21 11:43:14 -0800714 EXPECT_NE(-1, depthStreamId);
715
716 EXPECT_OK(mCamera->exclusiveTryLock());
Igor Murashkineb72e172013-02-21 11:43:14 -0800717 /*
718 */
719 /* iterate in a loop submitting requests every frame.
720 * what kind of requests doesnt really matter, just whatever.
721 */
722
723 // it would probably be better to use CameraMetadata from camera service.
724 camera_metadata_t *request = NULL;
725 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
726 /*out*/&request));
727 EXPECT_NE((void*)NULL, request);
728
729 if(request == NULL) request = allocate_camera_metadata(10, 100);
730
731 // set the output streams to just this stream ID
732
733 // wow what a verbose API.
734 uint8_t allStreams[] = { streamId, depthStreamId };
735 size_t streamCount = 2;
736 camera_metadata_entry_t entry;
737 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
738 int find = find_camera_metadata_entry(request, tag, &entry);
739 if (find == -ENOENT) {
740 if (add_camera_metadata_entry(request, tag, &allStreams,
741 /*data_count*/streamCount) != OK) {
742 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
743 ASSERT_OK(append_camera_metadata(tmp, request));
744 free_camera_metadata(request);
745 request = tmp;
746
747 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
748 /*data_count*/streamCount));
749 }
750 } else {
751 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
752 &allStreams, /*data_count*/streamCount, &entry));
753 }
754
755 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
756
757 // Consume a couple of frames
758 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
759 // stream id 1
760 EXPECT_EQ(OK, mListener->WaitForEvent());
761 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
762
763 // stream id 2
764 EXPECT_EQ(OK, mListener->WaitForEvent());
765 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
766
767 //TODO: events should be a struct with some data like the stream id
768 }
769
770 // Done: clean up
771 free_camera_metadata(request);
772 EXPECT_OK(mCamera->deleteStream(streamId));
773 EXPECT_OK(mCamera->exclusiveUnlock());
774}
775
Igor Murashkina91537e2013-02-21 12:02:29 -0800776TEST_F(ProCameraTest, ResultReceiver) {
777 if (HasFatalFailure()) {
778 return;
779 }
780
781 mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
782 //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED
783 // need to filter out events at read time
784
785 int streamId = -1;
Igor Murashkina140a6e2013-02-21 14:45:03 -0800786 sp<CpuConsumer> consumer;
Igor Murashkina91537e2013-02-21 12:02:29 -0800787 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
Igor Murashkina140a6e2013-02-21 14:45:03 -0800788 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
Igor Murashkina91537e2013-02-21 12:02:29 -0800789 EXPECT_NE(-1, streamId);
790
791 EXPECT_OK(mCamera->exclusiveTryLock());
792 /*
793 */
794 /* iterate in a loop submitting requests every frame.
795 * what kind of requests doesnt really matter, just whatever.
796 */
797
798 camera_metadata_t *request = NULL;
799 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
800 /*out*/&request));
801 EXPECT_NE((void*)NULL, request);
802
803 /*FIXME*/
804 if(request == NULL) request = allocate_camera_metadata(10, 100);
805
806 // set the output streams to just this stream ID
807
808 uint8_t allStreams[] = { streamId };
809 size_t streamCount = 1;
810 camera_metadata_entry_t entry;
811 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
812 int find = find_camera_metadata_entry(request, tag, &entry);
813 if (find == -ENOENT) {
814 if (add_camera_metadata_entry(request, tag, &allStreams,
815 /*data_count*/streamCount) != OK) {
816 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
817 ASSERT_OK(append_camera_metadata(tmp, request));
818 free_camera_metadata(request);
819 request = tmp;
820
821 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
822 /*data_count*/streamCount));
823 }
824 } else {
825 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
826 &allStreams, /*data_count*/streamCount, &entry));
827 }
828
829 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
830
831 // Consume a couple of results
832 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
833 EXPECT_EQ(OK, mListener->WaitForEvent());
834 EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
835 }
836
837 // Done: clean up
838 free_camera_metadata(request);
839 EXPECT_OK(mCamera->deleteStream(streamId));
840 EXPECT_OK(mCamera->exclusiveUnlock());
841}
842
Igor Murashkina140a6e2013-02-21 14:45:03 -0800843TEST_F(ProCameraTest, WaitForResult) {
844 if (HasFatalFailure()) {
845 return;
846 }
847
848 int streamId = -1;
849 sp<CpuConsumer> consumer;
850 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
851 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
852 EXPECT_NE(-1, streamId);
853
854 EXPECT_OK(mCamera->exclusiveTryLock());
855
856 uint8_t streams[] = { streamId };
857 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
858
859 // Consume a couple of results
860 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
861 EXPECT_OK(mCamera->waitForFrameMetadata());
862 CameraMetadata meta = mCamera->consumeFrameMetadata();
863 EXPECT_FALSE(meta.isEmpty());
864 }
865
866 // Done: clean up
867 consumer->abandon(); // since we didn't consume any of the buffers
868 EXPECT_OK(mCamera->deleteStream(streamId));
869 EXPECT_OK(mCamera->exclusiveUnlock());
870}
871
872TEST_F(ProCameraTest, WaitForSingleStreamBuffer) {
873 if (HasFatalFailure()) {
874 return;
875 }
876
877 int streamId = -1;
878 sp<CpuConsumer> consumer;
879 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
880 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
881 EXPECT_NE(-1, streamId);
882
883 EXPECT_OK(mCamera->exclusiveTryLock());
884
885 uint8_t streams[] = { streamId };
886 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
887 /*requests*/TEST_CPU_FRAME_COUNT));
888
889 // Consume a couple of results
890 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
891 EXPECT_OK(mCamera->waitForFrameBuffer(streamId));
892
893 CpuConsumer::LockedBuffer buf;
894 EXPECT_OK(consumer->lockNextBuffer(&buf));
895
896 dout << "Buffer synchronously received on streamId = " << streamId <<
897 ", dataPtr = " << (void*)buf.data <<
898 ", timestamp = " << buf.timestamp << std::endl;
899
900 EXPECT_OK(consumer->unlockBuffer(buf));
901 }
902
903 // Done: clean up
904 EXPECT_OK(mCamera->deleteStream(streamId));
905 EXPECT_OK(mCamera->exclusiveUnlock());
906}
907
908TEST_F(ProCameraTest, WaitForDualStreamBuffer) {
909 if (HasFatalFailure()) {
910 return;
911 }
912
913 const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10;
914
915 // 15 fps
916 int streamId = -1;
917 sp<CpuConsumer> consumer;
918 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
919 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
920 EXPECT_NE(-1, streamId);
921
922 // 30 fps
923 int depthStreamId = -1;
924 sp<CpuConsumer> depthConsumer;
925 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
926 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId));
927 EXPECT_NE(-1, depthStreamId);
928
929 EXPECT_OK(mCamera->exclusiveTryLock());
930
931 uint8_t streams[] = { streamId, depthStreamId };
932 ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2,
933 /*requests*/REQUEST_COUNT));
934
935 // Consume two frames simultaneously. Unsynchronized by timestamps.
936 for (int i = 0; i < REQUEST_COUNT; ++i) {
937
938 // Get the metadata
939 EXPECT_OK(mCamera->waitForFrameMetadata());
940 CameraMetadata meta = mCamera->consumeFrameMetadata();
941 EXPECT_FALSE(meta.isEmpty());
942
943 // Get the buffers
944
945 EXPECT_OK(mCamera->waitForFrameBuffer(depthStreamId));
946
947 /**
948 * Guaranteed to be able to consume the depth frame,
949 * since we waited on it.
950 */
951 CpuConsumer::LockedBuffer depthBuffer;
952 EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer));
953
954 dout << "Depth Buffer synchronously received on streamId = " <<
955 streamId <<
956 ", dataPtr = " << (void*)depthBuffer.data <<
957 ", timestamp = " << depthBuffer.timestamp << std::endl;
958
959 EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer));
960
961
962 /** Consume Greyscale frames if there are any.
963 * There may not be since it runs at half FPS */
964 CpuConsumer::LockedBuffer greyBuffer;
965 while (consumer->lockNextBuffer(&greyBuffer) == OK) {
966
967 dout << "GRAY Buffer synchronously received on streamId = " <<
968 streamId <<
969 ", dataPtr = " << (void*)greyBuffer.data <<
970 ", timestamp = " << greyBuffer.timestamp << std::endl;
971
972 EXPECT_OK(consumer->unlockBuffer(greyBuffer));
973 }
974 }
975
976 // Done: clean up
977 EXPECT_OK(mCamera->deleteStream(streamId));
978 EXPECT_OK(mCamera->exclusiveUnlock());
979}
980
981
982
983
984
Igor Murashkin634a5152013-02-20 17:15:11 -0800985}
986}
987}
988}
989