blob: 021fbae19e4a166ff8e6355dca48931f8bb6f603 [file] [log] [blame]
Igor Murashkinbfb5d5e2013-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 Murashkin68c80662013-02-20 17:41:57 -080020#include <binder/IPCThreadState.h>
21#include <utils/Thread.h>
22
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -080023#include "Camera.h"
24#include "ProCamera.h"
Igor Murashkin68c80662013-02-20 17:41:57 -080025#include <utils/Vector.h>
26#include <utils/Mutex.h>
27#include <utils/Condition.h>
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -080028
Igor Murashkin94769262013-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
34
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -080035namespace android {
36namespace camera2 {
37namespace tests {
38namespace client {
39
40#define CAMERA_ID 0
41#define TEST_DEBUGGING 0
42
Igor Murashkin94769262013-02-20 17:57:31 -080043#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout
Igor Murashkinc0767f12013-02-20 19:29:53 -080044#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead
45
Igor Murashkin50761822013-02-21 11:43:14 -080046#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8
Igor Murashkinc0767f12013-02-20 19:29:53 -080047#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16
48
49#define TEST_CPU_FRAME_COUNT 2
50#define TEST_CPU_HEAP_COUNT 5
Igor Murashkin68c80662013-02-20 17:41:57 -080051
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -080052#if TEST_DEBUGGING
53#define dout std::cerr
54#else
55#define dout if (0) std::cerr
56#endif
57
Igor Murashkin90fce972013-01-30 10:14:24 -080058#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
59#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
60
61class ProCameraTest;
62
Igor Murashkinc0767f12013-02-20 19:29:53 -080063enum ProEvent {
Igor Murashkin68c80662013-02-20 17:41:57 -080064 UNKNOWN,
65 ACQUIRED,
66 RELEASED,
Igor Murashkinc0767f12013-02-20 19:29:53 -080067 STOLEN,
68 BUFFER_RECEIVED,
Igor Murashkin418e4932013-02-21 12:02:29 -080069 RESULT_RECEIVED,
Igor Murashkin68c80662013-02-20 17:41:57 -080070};
71
Igor Murashkin418e4932013-02-21 12:02:29 -080072inline int ProEvent_Mask(ProEvent e) {
73 return (1 << static_cast<int>(e));
74}
75
Igor Murashkinc0767f12013-02-20 19:29:53 -080076typedef Vector<ProEvent> EventList;
Igor Murashkin68c80662013-02-20 17:41:57 -080077
78class ProCameraTestThread : public Thread
79{
80public:
81 ProCameraTestThread() {
82 }
83
84 virtual bool threadLoop() {
85 mProc = ProcessState::self();
86 mProc->startThreadPool();
87
88 IPCThreadState *ptr = IPCThreadState::self();
89
Igor Murashkin68c80662013-02-20 17:41:57 -080090 ptr->joinThreadPool();
Igor Murashkin68c80662013-02-20 17:41:57 -080091
92 return false;
93 }
94
95 sp<ProcessState> mProc;
96};
97
98class ProCameraTestListener : public ProCameraListener {
99
100public:
Igor Murashkin418e4932013-02-21 12:02:29 -0800101 static const int EVENT_MASK_ALL = 0xFFFFFFFF;
102
103 ProCameraTestListener() {
104 mEventMask = EVENT_MASK_ALL;
105 }
106
Igor Murashkin68c80662013-02-20 17:41:57 -0800107 status_t WaitForEvent() {
108 Mutex::Autolock cal(mConditionMutex);
109
110 {
111 Mutex::Autolock al(mListenerMutex);
112
Igor Murashkinc0767f12013-02-20 19:29:53 -0800113 if (mProEventList.size() > 0) {
Igor Murashkin68c80662013-02-20 17:41:57 -0800114 return OK;
115 }
116 }
117
118 return mListenerCondition.waitRelative(mConditionMutex,
119 TEST_LISTENER_TIMEOUT);
120 }
121
122 /* Read events into out. Existing queue is flushed */
123 void ReadEvents(EventList& out) {
124 Mutex::Autolock al(mListenerMutex);
125
Igor Murashkinc0767f12013-02-20 19:29:53 -0800126 for (size_t i = 0; i < mProEventList.size(); ++i) {
127 out.push(mProEventList[i]);
Igor Murashkin68c80662013-02-20 17:41:57 -0800128 }
129
Igor Murashkinc0767f12013-02-20 19:29:53 -0800130 mProEventList.clear();
Igor Murashkin68c80662013-02-20 17:41:57 -0800131 }
132
133 /**
134 * Dequeue 1 event from the event queue.
135 * Returns UNKNOWN if queue is empty
136 */
Igor Murashkinc0767f12013-02-20 19:29:53 -0800137 ProEvent ReadEvent() {
Igor Murashkin68c80662013-02-20 17:41:57 -0800138 Mutex::Autolock al(mListenerMutex);
139
Igor Murashkinc0767f12013-02-20 19:29:53 -0800140 if (mProEventList.size() == 0) {
Igor Murashkin68c80662013-02-20 17:41:57 -0800141 return UNKNOWN;
142 }
143
Igor Murashkinc0767f12013-02-20 19:29:53 -0800144 ProEvent ev = mProEventList[0];
145 mProEventList.removeAt(0);
Igor Murashkin68c80662013-02-20 17:41:57 -0800146
147 return ev;
148 }
149
Igor Murashkin418e4932013-02-21 12:02:29 -0800150 void SetEventMask(int eventMask) {
151 Mutex::Autolock al(mListenerMutex);
152 mEventMask = eventMask;
153 }
154
Igor Murashkin68c80662013-02-20 17:41:57 -0800155private:
Igor Murashkinc0767f12013-02-20 19:29:53 -0800156 void QueueEvent(ProEvent ev) {
Igor Murashkin418e4932013-02-21 12:02:29 -0800157 bool eventAdded = false;
Igor Murashkin68c80662013-02-20 17:41:57 -0800158 {
159 Mutex::Autolock al(mListenerMutex);
Igor Murashkin418e4932013-02-21 12:02:29 -0800160
161 if (ProEvent_Mask(ev) & mEventMask) {
162 mProEventList.push(ev);
163 eventAdded = true;
164 }
Igor Murashkin68c80662013-02-20 17:41:57 -0800165 }
166
Igor Murashkin418e4932013-02-21 12:02:29 -0800167 if (eventAdded) {
168 mListenerCondition.broadcast();
169 }
Igor Murashkin68c80662013-02-20 17:41:57 -0800170 }
171
172protected:
173
174 //////////////////////////////////////////////////
175 ///////// ProCameraListener //////////////////////
176 //////////////////////////////////////////////////
177
178
179 // Lock has been acquired. Write operations now available.
180 virtual void onLockAcquired() {
181 QueueEvent(ACQUIRED);
182 }
183 // Lock has been released with exclusiveUnlock
184 virtual void onLockReleased() {
185 QueueEvent(RELEASED);
186 }
187
188 // Lock has been stolen by another client.
189 virtual void onLockStolen() {
190 QueueEvent(STOLEN);
191 }
192
193 // Lock free.
194 virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
195
196 dout << "Trigger notify: " << ext1 << " " << ext2
197 << " " << ext3 << std::endl;
198 }
199
Igor Murashkinc0767f12013-02-20 19:29:53 -0800200 virtual void onBufferReceived(int streamId,
201 const CpuConsumer::LockedBuffer& buf) {
202
203 dout << "Buffer received on streamId = " << streamId <<
204 ", dataPtr = " << (void*)buf.data << std::endl;
205
206 QueueEvent(BUFFER_RECEIVED);
207
208 }
Igor Murashkin418e4932013-02-21 12:02:29 -0800209 virtual void onResultReceived(int32_t frameId,
210 camera_metadata* request) {
211 dout << "Result received frameId = " << frameId
212 << ", requestPtr = " << (void*)request << std::endl;
213 QueueEvent(RESULT_RECEIVED);
Igor Murashkinc0767f12013-02-20 19:29:53 -0800214 free_camera_metadata(request);
215 }
216
Igor Murashkin68c80662013-02-20 17:41:57 -0800217 // TODO: remove
218
219 virtual void notify(int32_t , int32_t , int32_t ) {}
220 virtual void postData(int32_t , const sp<IMemory>& ,
221 camera_frame_metadata_t *) {}
222 virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {}
223
224
Igor Murashkinc0767f12013-02-20 19:29:53 -0800225 Vector<ProEvent> mProEventList;
Igor Murashkin68c80662013-02-20 17:41:57 -0800226 Mutex mListenerMutex;
227 Mutex mConditionMutex;
228 Condition mListenerCondition;
Igor Murashkin418e4932013-02-21 12:02:29 -0800229 int mEventMask;
Igor Murashkin68c80662013-02-20 17:41:57 -0800230};
231
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800232class ProCameraTest : public ::testing::Test {
233
Igor Murashkin68c80662013-02-20 17:41:57 -0800234public:
235 ProCameraTest() {
236 }
237
Igor Murashkin90fce972013-01-30 10:14:24 -0800238 static void SetUpTestCase() {
239 // Binder Thread Pool Initialization
Igor Murashkin68c80662013-02-20 17:41:57 -0800240 mTestThread = new ProCameraTestThread();
241 mTestThread->run("ProCameraTestThread");
Igor Murashkin90fce972013-01-30 10:14:24 -0800242 }
Igor Murashkin68c80662013-02-20 17:41:57 -0800243
Igor Murashkin90fce972013-01-30 10:14:24 -0800244 virtual void SetUp() {
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800245 mCamera = ProCamera::connect(CAMERA_ID);
246 ASSERT_NE((void*)NULL, mCamera.get());
Igor Murashkin68c80662013-02-20 17:41:57 -0800247
248 mListener = new ProCameraTestListener();
249 mCamera->setListener(mListener);
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800250 }
251
252 virtual void TearDown() {
253 ASSERT_NE((void*)NULL, mCamera.get());
254 mCamera->disconnect();
255 }
256
257protected:
258 sp<ProCamera> mCamera;
Igor Murashkin68c80662013-02-20 17:41:57 -0800259 sp<ProCameraTestListener> mListener;
260
Igor Murashkin90fce972013-01-30 10:14:24 -0800261 static sp<Thread> mTestThread;
Igor Murashkin68c80662013-02-20 17:41:57 -0800262
Igor Murashkin94769262013-02-20 17:57:31 -0800263 int mDisplaySecs;
264 sp<SurfaceComposerClient> mComposerClient;
265 sp<SurfaceControl> mSurfaceControl;
266
Igor Murashkinc0767f12013-02-20 19:29:53 -0800267 sp<SurfaceComposerClient> mDepthComposerClient;
268 sp<SurfaceControl> mDepthSurfaceControl;
269
Igor Murashkin94769262013-02-20 17:57:31 -0800270 int getSurfaceWidth() {
271 return 512;
272 }
273 int getSurfaceHeight() {
274 return 512;
275 }
276
277 void createOnScreenSurface(sp<Surface>& surface) {
278 mComposerClient = new SurfaceComposerClient;
279 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
280
281 mSurfaceControl = mComposerClient->createSurface(
282 String8("ProCameraTest StreamingImage Surface"),
283 getSurfaceWidth(), getSurfaceHeight(),
284 PIXEL_FORMAT_RGB_888, 0);
285
Igor Murashkinc0767f12013-02-20 19:29:53 -0800286 mSurfaceControl->setPosition(640, 0);
287
Igor Murashkin94769262013-02-20 17:57:31 -0800288 ASSERT_TRUE(mSurfaceControl != NULL);
289 ASSERT_TRUE(mSurfaceControl->isValid());
290
291 SurfaceComposerClient::openGlobalTransaction();
292 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
293 ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
294 SurfaceComposerClient::closeGlobalTransaction();
295
296 sp<ANativeWindow> window = mSurfaceControl->getSurface();
297 surface = mSurfaceControl->getSurface();
298
299 ASSERT_NE((void*)NULL, surface.get());
300 }
301
Igor Murashkinc0767f12013-02-20 19:29:53 -0800302 void createDepthOnScreenSurface(sp<Surface>& surface) {
303 mDepthComposerClient = new SurfaceComposerClient;
304 ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
305
306 mDepthSurfaceControl = mDepthComposerClient->createSurface(
307 String8("ProCameraTest StreamingImage Surface"),
308 getSurfaceWidth(), getSurfaceHeight(),
309 PIXEL_FORMAT_RGB_888, 0);
310
311 mDepthSurfaceControl->setPosition(640, 0);
312
313 ASSERT_TRUE(mDepthSurfaceControl != NULL);
314 ASSERT_TRUE(mDepthSurfaceControl->isValid());
315
316 SurfaceComposerClient::openGlobalTransaction();
317 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
318 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
319 SurfaceComposerClient::closeGlobalTransaction();
320
321 sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
322 surface = mDepthSurfaceControl->getSurface();
323
324 ASSERT_NE((void*)NULL, surface.get());
325 }
326
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800327};
328
Igor Murashkin90fce972013-01-30 10:14:24 -0800329sp<Thread> ProCameraTest::mTestThread;
330
331// test around exclusiveTryLock (immediate locking)
Igor Murashkin68c80662013-02-20 17:41:57 -0800332TEST_F(ProCameraTest, LockingImmediate) {
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800333
334 if (HasFatalFailure()) {
335 return;
336 }
337
Igor Murashkin418e4932013-02-21 12:02:29 -0800338 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
339 ProEvent_Mask(STOLEN) |
340 ProEvent_Mask(RELEASED));
341
Igor Murashkin68c80662013-02-20 17:41:57 -0800342 EXPECT_FALSE(mCamera->hasExclusiveLock());
343 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
Igor Murashkin90fce972013-01-30 10:14:24 -0800344 // at this point we definitely have the lock
345
346 EXPECT_EQ(OK, mListener->WaitForEvent());
347 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
348
349 EXPECT_TRUE(mCamera->hasExclusiveLock());
350 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
351
352 EXPECT_EQ(OK, mListener->WaitForEvent());
353 EXPECT_EQ(RELEASED, mListener->ReadEvent());
354
355 EXPECT_FALSE(mCamera->hasExclusiveLock());
356}
357
358// test around exclusiveLock (locking at some future point in time)
359TEST_F(ProCameraTest, LockingAsynchronous) {
360
361 if (HasFatalFailure()) {
362 return;
363 }
364
Igor Murashkin418e4932013-02-21 12:02:29 -0800365
366 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
367 ProEvent_Mask(STOLEN) |
368 ProEvent_Mask(RELEASED));
369
Igor Murashkin90fce972013-01-30 10:14:24 -0800370 // TODO: Add another procamera that has a lock here.
371 // then we can be test that the lock wont immediately be acquired
372
373 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkin418e4932013-02-21 12:02:29 -0800374 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
375 // at this point we definitely have the lock
Igor Murashkin68c80662013-02-20 17:41:57 -0800376
377 EXPECT_EQ(OK, mListener->WaitForEvent());
378 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
379
380 EXPECT_TRUE(mCamera->hasExclusiveLock());
381 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
382
383 EXPECT_EQ(OK, mListener->WaitForEvent());
384 EXPECT_EQ(RELEASED, mListener->ReadEvent());
385
386 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800387}
388
Igor Murashkin94769262013-02-20 17:57:31 -0800389// Stream directly to the screen.
Igor Murashkin418e4932013-02-21 12:02:29 -0800390TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
Igor Murashkin94769262013-02-20 17:57:31 -0800391 if (HasFatalFailure()) {
392 return;
393 }
394 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
395 if (displaySecsEnv != NULL) {
396 mDisplaySecs = atoi(displaySecsEnv);
397 if (mDisplaySecs < 0) {
398 mDisplaySecs = 0;
399 }
400 } else {
401 mDisplaySecs = 0;
402 }
403
Igor Murashkinc0767f12013-02-20 19:29:53 -0800404 sp<Surface> depthSurface;
Igor Murashkin94769262013-02-20 17:57:31 -0800405 if (mDisplaySecs > 0) {
Igor Murashkinc0767f12013-02-20 19:29:53 -0800406 createDepthOnScreenSurface(/*out*/depthSurface);
Igor Murashkin94769262013-02-20 17:57:31 -0800407 }
Igor Murashkinc0767f12013-02-20 19:29:53 -0800408
409 int depthStreamId = -1;
410 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
411 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
412 EXPECT_NE(-1, depthStreamId);
Igor Murashkin94769262013-02-20 17:57:31 -0800413
414 EXPECT_OK(mCamera->exclusiveTryLock());
415 /* iterate in a loop submitting requests every frame.
416 * what kind of requests doesnt really matter, just whatever.
417 */
418
419 // it would probably be better to use CameraMetadata from camera service.
420 camera_metadata_t *request = NULL;
421 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
422 /*out*/&request));
423 EXPECT_NE((void*)NULL, request);
424
425 /* FIXME: dont need this later, at which point the above should become an
426 ASSERT_NE*/
427 if(request == NULL) request = allocate_camera_metadata(10, 100);
428
429 // set the output streams to just this stream ID
430
431 // wow what a verbose API.
432 // i would give a loaf of bread for
433 // metadata->updateOrInsert(keys.request.output.streams, streamId);
Igor Murashkinc0767f12013-02-20 19:29:53 -0800434 uint8_t allStreams[] = { depthStreamId };
435 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
436
Igor Murashkin94769262013-02-20 17:57:31 -0800437 camera_metadata_entry_t entry;
438 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
439 int find = find_camera_metadata_entry(request, tag, &entry);
440 if (find == -ENOENT) {
Igor Murashkinc0767f12013-02-20 19:29:53 -0800441 if (add_camera_metadata_entry(request, tag, &allStreams,
442 /*data_count*/streamCount) != OK) {
Igor Murashkin69e22432013-02-20 18:24:43 -0800443 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
444 ASSERT_OK(append_camera_metadata(tmp, request));
445 free_camera_metadata(request);
446 request = tmp;
447
Igor Murashkinc0767f12013-02-20 19:29:53 -0800448 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
449 /*data_count*/streamCount));
Igor Murashkin69e22432013-02-20 18:24:43 -0800450 }
Igor Murashkin94769262013-02-20 17:57:31 -0800451 } else {
Igor Murashkinc0767f12013-02-20 19:29:53 -0800452 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
453 &allStreams, /*data_count*/streamCount, &entry));
Igor Murashkin94769262013-02-20 17:57:31 -0800454 }
455
456 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
457
Igor Murashkin69e22432013-02-20 18:24:43 -0800458 dout << "will sleep now for " << mDisplaySecs << std::endl;
Igor Murashkin94769262013-02-20 17:57:31 -0800459 sleep(mDisplaySecs);
Igor Murashkin94769262013-02-20 17:57:31 -0800460
461 free_camera_metadata(request);
Igor Murashkinc0767f12013-02-20 19:29:53 -0800462
463 for (int i = 0; i < streamCount; ++i) {
464 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
465 }
466 EXPECT_OK(mCamera->exclusiveUnlock());
467}
468
Igor Murashkin50761822013-02-21 11:43:14 -0800469// Stream directly to the screen.
Igor Murashkin418e4932013-02-21 12:02:29 -0800470TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
Igor Murashkin50761822013-02-21 11:43:14 -0800471 if (HasFatalFailure()) {
472 return;
473 }
474 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
475 if (displaySecsEnv != NULL) {
476 mDisplaySecs = atoi(displaySecsEnv);
477 if (mDisplaySecs < 0) {
478 mDisplaySecs = 0;
479 }
480 } else {
481 mDisplaySecs = 0;
482 }
483
484 sp<Surface> surface;
485 sp<Surface> depthSurface;
486 if (mDisplaySecs > 0) {
487 createOnScreenSurface(/*out*/surface);
488 createDepthOnScreenSurface(/*out*/depthSurface);
489 }
490
491 int streamId = -1;
492 EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
493 TEST_FORMAT_MAIN, surface, &streamId));
494 EXPECT_NE(-1, streamId);
495
496 int depthStreamId = -1;
497 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
498 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
499 EXPECT_NE(-1, depthStreamId);
500
501 EXPECT_OK(mCamera->exclusiveTryLock());
502 /*
503 */
504 /* iterate in a loop submitting requests every frame.
505 * what kind of requests doesnt really matter, just whatever.
506 */
507
508 // it would probably be better to use CameraMetadata from camera service.
509 camera_metadata_t *request = NULL;
510 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
511 /*out*/&request));
512 EXPECT_NE((void*)NULL, request);
513
514 /*FIXME: dont need this later, at which point the above should become an
515 ASSERT_NE*/
516 if(request == NULL) request = allocate_camera_metadata(10, 100);
517
518 // set the output streams to just this stream ID
519
520 // wow what a verbose API.
521 uint8_t allStreams[] = { streamId, depthStreamId };
522 // IMPORTANT. bad things will happen if its not a uint8.
523 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
524 camera_metadata_entry_t entry;
525 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
526 int find = find_camera_metadata_entry(request, tag, &entry);
527 if (find == -ENOENT) {
528 if (add_camera_metadata_entry(request, tag, &allStreams,
529 /*data_count*/streamCount) != OK) {
530 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
531 ASSERT_OK(append_camera_metadata(tmp, request));
532 free_camera_metadata(request);
533 request = tmp;
534
535 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
536 /*data_count*/streamCount));
537 }
538 } else {
539 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
540 &allStreams, /*data_count*/streamCount, &entry));
541 }
542
543 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
544
545 dout << "will sleep now for " << mDisplaySecs << std::endl;
546 sleep(mDisplaySecs);
547
548 free_camera_metadata(request);
549
550 for (int i = 0; i < streamCount; ++i) {
551 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
552 }
553 EXPECT_OK(mCamera->exclusiveUnlock());
554}
555
556TEST_F(ProCameraTest, CpuConsumerSingle) {
Igor Murashkinc0767f12013-02-20 19:29:53 -0800557 if (HasFatalFailure()) {
558 return;
559 }
Igor Murashkin418e4932013-02-21 12:02:29 -0800560
561 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
562
Igor Murashkinc0767f12013-02-20 19:29:53 -0800563 int streamId = -1;
564 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
565 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &streamId));
566 EXPECT_NE(-1, streamId);
567
568 EXPECT_OK(mCamera->exclusiveTryLock());
569 EXPECT_EQ(OK, mListener->WaitForEvent());
570 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
571 /* iterate in a loop submitting requests every frame.
572 * what kind of requests doesnt really matter, just whatever.
573 */
574
575 // it would probably be better to use CameraMetadata from camera service.
576 camera_metadata_t *request = NULL;
577 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
578 /*out*/&request));
579 EXPECT_NE((void*)NULL, request);
580
581 /*FIXME: dont need this later, at which point the above should become an
582 ASSERT_NE*/
583 if(request == NULL) request = allocate_camera_metadata(10, 100);
584
585 // set the output streams to just this stream ID
586
587 uint8_t allStreams[] = { streamId };
588 camera_metadata_entry_t entry;
589 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
590 int find = find_camera_metadata_entry(request, tag, &entry);
591 if (find == -ENOENT) {
592 if (add_camera_metadata_entry(request, tag, &allStreams,
593 /*data_count*/1) != OK) {
594 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
595 ASSERT_OK(append_camera_metadata(tmp, request));
596 free_camera_metadata(request);
597 request = tmp;
598
599 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
600 /*data_count*/1));
601 }
602 } else {
603 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
604 &allStreams, /*data_count*/1, &entry));
605 }
606
607 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
608
609 // Consume a couple of frames
610 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
611 EXPECT_EQ(OK, mListener->WaitForEvent());
612 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
613 }
614
615 // Done: clean up
616 free_camera_metadata(request);
617 EXPECT_OK(mCamera->deleteStream(streamId));
Igor Murashkin94769262013-02-20 17:57:31 -0800618 EXPECT_OK(mCamera->exclusiveUnlock());
619}
620
Igor Murashkin50761822013-02-21 11:43:14 -0800621TEST_F(ProCameraTest, CpuConsumerDual) {
622 if (HasFatalFailure()) {
623 return;
624 }
Igor Murashkin418e4932013-02-21 12:02:29 -0800625
626 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
627
Igor Murashkin50761822013-02-21 11:43:14 -0800628 int streamId = -1;
629 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
630 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &streamId));
631 EXPECT_NE(-1, streamId);
632
633 int depthStreamId = -1;
634 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
635 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthStreamId));
636 EXPECT_NE(-1, depthStreamId);
637
638 EXPECT_OK(mCamera->exclusiveTryLock());
Igor Murashkin50761822013-02-21 11:43:14 -0800639 /*
640 */
641 /* iterate in a loop submitting requests every frame.
642 * what kind of requests doesnt really matter, just whatever.
643 */
644
645 // it would probably be better to use CameraMetadata from camera service.
646 camera_metadata_t *request = NULL;
647 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
648 /*out*/&request));
649 EXPECT_NE((void*)NULL, request);
650
651 if(request == NULL) request = allocate_camera_metadata(10, 100);
652
653 // set the output streams to just this stream ID
654
655 // wow what a verbose API.
656 uint8_t allStreams[] = { streamId, depthStreamId };
657 size_t streamCount = 2;
658 camera_metadata_entry_t entry;
659 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
660 int find = find_camera_metadata_entry(request, tag, &entry);
661 if (find == -ENOENT) {
662 if (add_camera_metadata_entry(request, tag, &allStreams,
663 /*data_count*/streamCount) != OK) {
664 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
665 ASSERT_OK(append_camera_metadata(tmp, request));
666 free_camera_metadata(request);
667 request = tmp;
668
669 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
670 /*data_count*/streamCount));
671 }
672 } else {
673 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
674 &allStreams, /*data_count*/streamCount, &entry));
675 }
676
677 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
678
679 // Consume a couple of frames
680 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
681 // stream id 1
682 EXPECT_EQ(OK, mListener->WaitForEvent());
683 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
684
685 // stream id 2
686 EXPECT_EQ(OK, mListener->WaitForEvent());
687 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
688
689 //TODO: events should be a struct with some data like the stream id
690 }
691
692 // Done: clean up
693 free_camera_metadata(request);
694 EXPECT_OK(mCamera->deleteStream(streamId));
695 EXPECT_OK(mCamera->exclusiveUnlock());
696}
697
Igor Murashkin418e4932013-02-21 12:02:29 -0800698TEST_F(ProCameraTest, ResultReceiver) {
699 if (HasFatalFailure()) {
700 return;
701 }
702
703 mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
704 //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED
705 // need to filter out events at read time
706
707 int streamId = -1;
708 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
709 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &streamId));
710 EXPECT_NE(-1, streamId);
711
712 EXPECT_OK(mCamera->exclusiveTryLock());
713 /*
714 */
715 /* iterate in a loop submitting requests every frame.
716 * what kind of requests doesnt really matter, just whatever.
717 */
718
719 camera_metadata_t *request = NULL;
720 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
721 /*out*/&request));
722 EXPECT_NE((void*)NULL, request);
723
724 /*FIXME*/
725 if(request == NULL) request = allocate_camera_metadata(10, 100);
726
727 // set the output streams to just this stream ID
728
729 uint8_t allStreams[] = { streamId };
730 size_t streamCount = 1;
731 camera_metadata_entry_t entry;
732 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
733 int find = find_camera_metadata_entry(request, tag, &entry);
734 if (find == -ENOENT) {
735 if (add_camera_metadata_entry(request, tag, &allStreams,
736 /*data_count*/streamCount) != OK) {
737 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
738 ASSERT_OK(append_camera_metadata(tmp, request));
739 free_camera_metadata(request);
740 request = tmp;
741
742 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
743 /*data_count*/streamCount));
744 }
745 } else {
746 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
747 &allStreams, /*data_count*/streamCount, &entry));
748 }
749
750 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
751
752 // Consume a couple of results
753 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
754 EXPECT_EQ(OK, mListener->WaitForEvent());
755 EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
756 }
757
758 // Done: clean up
759 free_camera_metadata(request);
760 EXPECT_OK(mCamera->deleteStream(streamId));
761 EXPECT_OK(mCamera->exclusiveUnlock());
762}
763
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800764}
765}
766}
767}
768