blob: dafa995ab55d43bb70730eac036f08e38c636662 [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 Murashkin68c80662013-02-20 17:41:57 -080069};
70
Igor Murashkinc0767f12013-02-20 19:29:53 -080071typedef Vector<ProEvent> EventList;
Igor Murashkin68c80662013-02-20 17:41:57 -080072
73class ProCameraTestThread : public Thread
74{
75public:
76 ProCameraTestThread() {
77 }
78
79 virtual bool threadLoop() {
80 mProc = ProcessState::self();
81 mProc->startThreadPool();
82
83 IPCThreadState *ptr = IPCThreadState::self();
84
Igor Murashkin68c80662013-02-20 17:41:57 -080085 ptr->joinThreadPool();
Igor Murashkin68c80662013-02-20 17:41:57 -080086
87 return false;
88 }
89
90 sp<ProcessState> mProc;
91};
92
93class ProCameraTestListener : public ProCameraListener {
94
95public:
96 status_t WaitForEvent() {
97 Mutex::Autolock cal(mConditionMutex);
98
99 {
100 Mutex::Autolock al(mListenerMutex);
101
Igor Murashkinc0767f12013-02-20 19:29:53 -0800102 if (mProEventList.size() > 0) {
Igor Murashkin68c80662013-02-20 17:41:57 -0800103 return OK;
104 }
105 }
106
107 return mListenerCondition.waitRelative(mConditionMutex,
108 TEST_LISTENER_TIMEOUT);
109 }
110
111 /* Read events into out. Existing queue is flushed */
112 void ReadEvents(EventList& out) {
113 Mutex::Autolock al(mListenerMutex);
114
Igor Murashkinc0767f12013-02-20 19:29:53 -0800115 for (size_t i = 0; i < mProEventList.size(); ++i) {
116 out.push(mProEventList[i]);
Igor Murashkin68c80662013-02-20 17:41:57 -0800117 }
118
Igor Murashkinc0767f12013-02-20 19:29:53 -0800119 mProEventList.clear();
Igor Murashkin68c80662013-02-20 17:41:57 -0800120 }
121
122 /**
123 * Dequeue 1 event from the event queue.
124 * Returns UNKNOWN if queue is empty
125 */
Igor Murashkinc0767f12013-02-20 19:29:53 -0800126 ProEvent ReadEvent() {
Igor Murashkin68c80662013-02-20 17:41:57 -0800127 Mutex::Autolock al(mListenerMutex);
128
Igor Murashkinc0767f12013-02-20 19:29:53 -0800129 if (mProEventList.size() == 0) {
Igor Murashkin68c80662013-02-20 17:41:57 -0800130 return UNKNOWN;
131 }
132
Igor Murashkinc0767f12013-02-20 19:29:53 -0800133 ProEvent ev = mProEventList[0];
134 mProEventList.removeAt(0);
Igor Murashkin68c80662013-02-20 17:41:57 -0800135
136 return ev;
137 }
138
139private:
Igor Murashkinc0767f12013-02-20 19:29:53 -0800140 void QueueEvent(ProEvent ev) {
Igor Murashkin68c80662013-02-20 17:41:57 -0800141 {
142 Mutex::Autolock al(mListenerMutex);
Igor Murashkinc0767f12013-02-20 19:29:53 -0800143 mProEventList.push(ev);
Igor Murashkin68c80662013-02-20 17:41:57 -0800144 }
145
146
147 mListenerCondition.broadcast();
148 }
149
150protected:
151
152 //////////////////////////////////////////////////
153 ///////// ProCameraListener //////////////////////
154 //////////////////////////////////////////////////
155
156
157 // Lock has been acquired. Write operations now available.
158 virtual void onLockAcquired() {
159 QueueEvent(ACQUIRED);
160 }
161 // Lock has been released with exclusiveUnlock
162 virtual void onLockReleased() {
163 QueueEvent(RELEASED);
164 }
165
166 // Lock has been stolen by another client.
167 virtual void onLockStolen() {
168 QueueEvent(STOLEN);
169 }
170
171 // Lock free.
172 virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
173
174 dout << "Trigger notify: " << ext1 << " " << ext2
175 << " " << ext3 << std::endl;
176 }
177
Igor Murashkinc0767f12013-02-20 19:29:53 -0800178 virtual void onBufferReceived(int streamId,
179 const CpuConsumer::LockedBuffer& buf) {
180
181 dout << "Buffer received on streamId = " << streamId <<
182 ", dataPtr = " << (void*)buf.data << std::endl;
183
184 QueueEvent(BUFFER_RECEIVED);
185
186 }
187 virtual void onRequestReceived(
188 camera_metadata* request) {
189 free_camera_metadata(request);
190 }
191
Igor Murashkin68c80662013-02-20 17:41:57 -0800192 // TODO: remove
193
194 virtual void notify(int32_t , int32_t , int32_t ) {}
195 virtual void postData(int32_t , const sp<IMemory>& ,
196 camera_frame_metadata_t *) {}
197 virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {}
198
199
Igor Murashkinc0767f12013-02-20 19:29:53 -0800200 Vector<ProEvent> mProEventList;
Igor Murashkin68c80662013-02-20 17:41:57 -0800201 Mutex mListenerMutex;
202 Mutex mConditionMutex;
203 Condition mListenerCondition;
204};
205
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800206class ProCameraTest : public ::testing::Test {
207
Igor Murashkin68c80662013-02-20 17:41:57 -0800208public:
209 ProCameraTest() {
210 }
211
Igor Murashkin90fce972013-01-30 10:14:24 -0800212 static void SetUpTestCase() {
213 // Binder Thread Pool Initialization
Igor Murashkin68c80662013-02-20 17:41:57 -0800214 mTestThread = new ProCameraTestThread();
215 mTestThread->run("ProCameraTestThread");
Igor Murashkin90fce972013-01-30 10:14:24 -0800216 }
Igor Murashkin68c80662013-02-20 17:41:57 -0800217
Igor Murashkin90fce972013-01-30 10:14:24 -0800218 virtual void SetUp() {
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800219 mCamera = ProCamera::connect(CAMERA_ID);
220 ASSERT_NE((void*)NULL, mCamera.get());
Igor Murashkin68c80662013-02-20 17:41:57 -0800221
222 mListener = new ProCameraTestListener();
223 mCamera->setListener(mListener);
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800224 }
225
226 virtual void TearDown() {
227 ASSERT_NE((void*)NULL, mCamera.get());
228 mCamera->disconnect();
229 }
230
231protected:
232 sp<ProCamera> mCamera;
Igor Murashkin68c80662013-02-20 17:41:57 -0800233 sp<ProCameraTestListener> mListener;
234
Igor Murashkin90fce972013-01-30 10:14:24 -0800235 static sp<Thread> mTestThread;
Igor Murashkin68c80662013-02-20 17:41:57 -0800236
Igor Murashkin94769262013-02-20 17:57:31 -0800237 int mDisplaySecs;
238 sp<SurfaceComposerClient> mComposerClient;
239 sp<SurfaceControl> mSurfaceControl;
240
Igor Murashkinc0767f12013-02-20 19:29:53 -0800241 sp<SurfaceComposerClient> mDepthComposerClient;
242 sp<SurfaceControl> mDepthSurfaceControl;
243
Igor Murashkin94769262013-02-20 17:57:31 -0800244 int getSurfaceWidth() {
245 return 512;
246 }
247 int getSurfaceHeight() {
248 return 512;
249 }
250
251 void createOnScreenSurface(sp<Surface>& surface) {
252 mComposerClient = new SurfaceComposerClient;
253 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
254
255 mSurfaceControl = mComposerClient->createSurface(
256 String8("ProCameraTest StreamingImage Surface"),
257 getSurfaceWidth(), getSurfaceHeight(),
258 PIXEL_FORMAT_RGB_888, 0);
259
Igor Murashkinc0767f12013-02-20 19:29:53 -0800260 mSurfaceControl->setPosition(640, 0);
261
Igor Murashkin94769262013-02-20 17:57:31 -0800262 ASSERT_TRUE(mSurfaceControl != NULL);
263 ASSERT_TRUE(mSurfaceControl->isValid());
264
265 SurfaceComposerClient::openGlobalTransaction();
266 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
267 ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
268 SurfaceComposerClient::closeGlobalTransaction();
269
270 sp<ANativeWindow> window = mSurfaceControl->getSurface();
271 surface = mSurfaceControl->getSurface();
272
273 ASSERT_NE((void*)NULL, surface.get());
274 }
275
Igor Murashkinc0767f12013-02-20 19:29:53 -0800276 void createDepthOnScreenSurface(sp<Surface>& surface) {
277 mDepthComposerClient = new SurfaceComposerClient;
278 ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
279
280 mDepthSurfaceControl = mDepthComposerClient->createSurface(
281 String8("ProCameraTest StreamingImage Surface"),
282 getSurfaceWidth(), getSurfaceHeight(),
283 PIXEL_FORMAT_RGB_888, 0);
284
285 mDepthSurfaceControl->setPosition(640, 0);
286
287 ASSERT_TRUE(mDepthSurfaceControl != NULL);
288 ASSERT_TRUE(mDepthSurfaceControl->isValid());
289
290 SurfaceComposerClient::openGlobalTransaction();
291 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
292 ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
293 SurfaceComposerClient::closeGlobalTransaction();
294
295 sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
296 surface = mDepthSurfaceControl->getSurface();
297
298 ASSERT_NE((void*)NULL, surface.get());
299 }
300
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800301};
302
Igor Murashkin90fce972013-01-30 10:14:24 -0800303sp<Thread> ProCameraTest::mTestThread;
304
305// test around exclusiveTryLock (immediate locking)
Igor Murashkin68c80662013-02-20 17:41:57 -0800306TEST_F(ProCameraTest, LockingImmediate) {
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800307
308 if (HasFatalFailure()) {
309 return;
310 }
311
Igor Murashkin68c80662013-02-20 17:41:57 -0800312 EXPECT_FALSE(mCamera->hasExclusiveLock());
313 EXPECT_EQ(OK, mCamera->exclusiveTryLock());
Igor Murashkin90fce972013-01-30 10:14:24 -0800314 // at this point we definitely have the lock
315
316 EXPECT_EQ(OK, mListener->WaitForEvent());
317 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
318
319 EXPECT_TRUE(mCamera->hasExclusiveLock());
320 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
321
322 EXPECT_EQ(OK, mListener->WaitForEvent());
323 EXPECT_EQ(RELEASED, mListener->ReadEvent());
324
325 EXPECT_FALSE(mCamera->hasExclusiveLock());
326}
327
328// test around exclusiveLock (locking at some future point in time)
329TEST_F(ProCameraTest, LockingAsynchronous) {
330
331 if (HasFatalFailure()) {
332 return;
333 }
334
335 // TODO: Add another procamera that has a lock here.
336 // then we can be test that the lock wont immediately be acquired
337
338 EXPECT_FALSE(mCamera->hasExclusiveLock());
339 EXPECT_EQ(OK, mCamera->exclusiveLock());
340 // at this point we may or may not have the lock
341 // we cant be sure until we get an ACQUIRED event
Igor Murashkin68c80662013-02-20 17:41:57 -0800342
343 EXPECT_EQ(OK, mListener->WaitForEvent());
344 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
345
346 EXPECT_TRUE(mCamera->hasExclusiveLock());
347 EXPECT_EQ(OK, mCamera->exclusiveUnlock());
348
349 EXPECT_EQ(OK, mListener->WaitForEvent());
350 EXPECT_EQ(RELEASED, mListener->ReadEvent());
351
352 EXPECT_FALSE(mCamera->hasExclusiveLock());
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800353}
354
Igor Murashkin94769262013-02-20 17:57:31 -0800355// Stream directly to the screen.
Igor Murashkin50761822013-02-21 11:43:14 -0800356TEST_F(ProCameraTest, StreamingImageSingle) {
Igor Murashkin94769262013-02-20 17:57:31 -0800357 if (HasFatalFailure()) {
358 return;
359 }
360 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
361 if (displaySecsEnv != NULL) {
362 mDisplaySecs = atoi(displaySecsEnv);
363 if (mDisplaySecs < 0) {
364 mDisplaySecs = 0;
365 }
366 } else {
367 mDisplaySecs = 0;
368 }
369
Igor Murashkinc0767f12013-02-20 19:29:53 -0800370 sp<Surface> depthSurface;
Igor Murashkin94769262013-02-20 17:57:31 -0800371 if (mDisplaySecs > 0) {
Igor Murashkinc0767f12013-02-20 19:29:53 -0800372 createDepthOnScreenSurface(/*out*/depthSurface);
Igor Murashkin94769262013-02-20 17:57:31 -0800373 }
Igor Murashkinc0767f12013-02-20 19:29:53 -0800374
375 int depthStreamId = -1;
376 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
377 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
378 EXPECT_NE(-1, depthStreamId);
Igor Murashkin94769262013-02-20 17:57:31 -0800379
380 EXPECT_OK(mCamera->exclusiveTryLock());
381 /* iterate in a loop submitting requests every frame.
382 * what kind of requests doesnt really matter, just whatever.
383 */
384
385 // it would probably be better to use CameraMetadata from camera service.
386 camera_metadata_t *request = NULL;
387 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
388 /*out*/&request));
389 EXPECT_NE((void*)NULL, request);
390
391 /* FIXME: dont need this later, at which point the above should become an
392 ASSERT_NE*/
393 if(request == NULL) request = allocate_camera_metadata(10, 100);
394
395 // set the output streams to just this stream ID
396
397 // wow what a verbose API.
398 // i would give a loaf of bread for
399 // metadata->updateOrInsert(keys.request.output.streams, streamId);
Igor Murashkinc0767f12013-02-20 19:29:53 -0800400 uint8_t allStreams[] = { depthStreamId };
401 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
402
Igor Murashkin94769262013-02-20 17:57:31 -0800403 camera_metadata_entry_t entry;
404 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
405 int find = find_camera_metadata_entry(request, tag, &entry);
406 if (find == -ENOENT) {
Igor Murashkinc0767f12013-02-20 19:29:53 -0800407 if (add_camera_metadata_entry(request, tag, &allStreams,
408 /*data_count*/streamCount) != OK) {
Igor Murashkin69e22432013-02-20 18:24:43 -0800409 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
410 ASSERT_OK(append_camera_metadata(tmp, request));
411 free_camera_metadata(request);
412 request = tmp;
413
Igor Murashkinc0767f12013-02-20 19:29:53 -0800414 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
415 /*data_count*/streamCount));
Igor Murashkin69e22432013-02-20 18:24:43 -0800416 }
Igor Murashkin94769262013-02-20 17:57:31 -0800417 } else {
Igor Murashkinc0767f12013-02-20 19:29:53 -0800418 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
419 &allStreams, /*data_count*/streamCount, &entry));
Igor Murashkin94769262013-02-20 17:57:31 -0800420 }
421
422 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
423
Igor Murashkin69e22432013-02-20 18:24:43 -0800424 dout << "will sleep now for " << mDisplaySecs << std::endl;
Igor Murashkin94769262013-02-20 17:57:31 -0800425 sleep(mDisplaySecs);
Igor Murashkin94769262013-02-20 17:57:31 -0800426
427 free_camera_metadata(request);
Igor Murashkinc0767f12013-02-20 19:29:53 -0800428
429 for (int i = 0; i < streamCount; ++i) {
430 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
431 }
432 EXPECT_OK(mCamera->exclusiveUnlock());
433}
434
Igor Murashkin50761822013-02-21 11:43:14 -0800435// Stream directly to the screen.
436TEST_F(ProCameraTest, StreamingImageDual) {
437 if (HasFatalFailure()) {
438 return;
439 }
440 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
441 if (displaySecsEnv != NULL) {
442 mDisplaySecs = atoi(displaySecsEnv);
443 if (mDisplaySecs < 0) {
444 mDisplaySecs = 0;
445 }
446 } else {
447 mDisplaySecs = 0;
448 }
449
450 sp<Surface> surface;
451 sp<Surface> depthSurface;
452 if (mDisplaySecs > 0) {
453 createOnScreenSurface(/*out*/surface);
454 createDepthOnScreenSurface(/*out*/depthSurface);
455 }
456
457 int streamId = -1;
458 EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
459 TEST_FORMAT_MAIN, surface, &streamId));
460 EXPECT_NE(-1, streamId);
461
462 int depthStreamId = -1;
463 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
464 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
465 EXPECT_NE(-1, depthStreamId);
466
467 EXPECT_OK(mCamera->exclusiveTryLock());
468 /*
469 */
470 /* iterate in a loop submitting requests every frame.
471 * what kind of requests doesnt really matter, just whatever.
472 */
473
474 // it would probably be better to use CameraMetadata from camera service.
475 camera_metadata_t *request = NULL;
476 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
477 /*out*/&request));
478 EXPECT_NE((void*)NULL, request);
479
480 /*FIXME: dont need this later, at which point the above should become an
481 ASSERT_NE*/
482 if(request == NULL) request = allocate_camera_metadata(10, 100);
483
484 // set the output streams to just this stream ID
485
486 // wow what a verbose API.
487 uint8_t allStreams[] = { streamId, depthStreamId };
488 // IMPORTANT. bad things will happen if its not a uint8.
489 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
490 camera_metadata_entry_t entry;
491 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
492 int find = find_camera_metadata_entry(request, tag, &entry);
493 if (find == -ENOENT) {
494 if (add_camera_metadata_entry(request, tag, &allStreams,
495 /*data_count*/streamCount) != OK) {
496 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
497 ASSERT_OK(append_camera_metadata(tmp, request));
498 free_camera_metadata(request);
499 request = tmp;
500
501 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
502 /*data_count*/streamCount));
503 }
504 } else {
505 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
506 &allStreams, /*data_count*/streamCount, &entry));
507 }
508
509 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
510
511 dout << "will sleep now for " << mDisplaySecs << std::endl;
512 sleep(mDisplaySecs);
513
514 free_camera_metadata(request);
515
516 for (int i = 0; i < streamCount; ++i) {
517 EXPECT_OK(mCamera->deleteStream(allStreams[i]));
518 }
519 EXPECT_OK(mCamera->exclusiveUnlock());
520}
521
522TEST_F(ProCameraTest, CpuConsumerSingle) {
Igor Murashkinc0767f12013-02-20 19:29:53 -0800523 if (HasFatalFailure()) {
524 return;
525 }
526 int streamId = -1;
527 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
528 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &streamId));
529 EXPECT_NE(-1, streamId);
530
531 EXPECT_OK(mCamera->exclusiveTryLock());
532 EXPECT_EQ(OK, mListener->WaitForEvent());
533 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
534 /* iterate in a loop submitting requests every frame.
535 * what kind of requests doesnt really matter, just whatever.
536 */
537
538 // it would probably be better to use CameraMetadata from camera service.
539 camera_metadata_t *request = NULL;
540 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
541 /*out*/&request));
542 EXPECT_NE((void*)NULL, request);
543
544 /*FIXME: dont need this later, at which point the above should become an
545 ASSERT_NE*/
546 if(request == NULL) request = allocate_camera_metadata(10, 100);
547
548 // set the output streams to just this stream ID
549
550 uint8_t allStreams[] = { streamId };
551 camera_metadata_entry_t entry;
552 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
553 int find = find_camera_metadata_entry(request, tag, &entry);
554 if (find == -ENOENT) {
555 if (add_camera_metadata_entry(request, tag, &allStreams,
556 /*data_count*/1) != OK) {
557 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
558 ASSERT_OK(append_camera_metadata(tmp, request));
559 free_camera_metadata(request);
560 request = tmp;
561
562 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
563 /*data_count*/1));
564 }
565 } else {
566 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
567 &allStreams, /*data_count*/1, &entry));
568 }
569
570 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
571
572 // Consume a couple of frames
573 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
574 EXPECT_EQ(OK, mListener->WaitForEvent());
575 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
576 }
577
578 // Done: clean up
579 free_camera_metadata(request);
580 EXPECT_OK(mCamera->deleteStream(streamId));
Igor Murashkin94769262013-02-20 17:57:31 -0800581 EXPECT_OK(mCamera->exclusiveUnlock());
582}
583
Igor Murashkin50761822013-02-21 11:43:14 -0800584TEST_F(ProCameraTest, CpuConsumerDual) {
585 if (HasFatalFailure()) {
586 return;
587 }
588 int streamId = -1;
589 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
590 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &streamId));
591 EXPECT_NE(-1, streamId);
592
593 int depthStreamId = -1;
594 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
595 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthStreamId));
596 EXPECT_NE(-1, depthStreamId);
597
598 EXPECT_OK(mCamera->exclusiveTryLock());
599 EXPECT_EQ(OK, mListener->WaitForEvent());
600 EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
601 /*
602 */
603 /* iterate in a loop submitting requests every frame.
604 * what kind of requests doesnt really matter, just whatever.
605 */
606
607 // it would probably be better to use CameraMetadata from camera service.
608 camera_metadata_t *request = NULL;
609 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
610 /*out*/&request));
611 EXPECT_NE((void*)NULL, request);
612
613 if(request == NULL) request = allocate_camera_metadata(10, 100);
614
615 // set the output streams to just this stream ID
616
617 // wow what a verbose API.
618 uint8_t allStreams[] = { streamId, depthStreamId };
619 size_t streamCount = 2;
620 camera_metadata_entry_t entry;
621 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
622 int find = find_camera_metadata_entry(request, tag, &entry);
623 if (find == -ENOENT) {
624 if (add_camera_metadata_entry(request, tag, &allStreams,
625 /*data_count*/streamCount) != OK) {
626 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
627 ASSERT_OK(append_camera_metadata(tmp, request));
628 free_camera_metadata(request);
629 request = tmp;
630
631 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
632 /*data_count*/streamCount));
633 }
634 } else {
635 ASSERT_OK(update_camera_metadata_entry(request, entry.index,
636 &allStreams, /*data_count*/streamCount, &entry));
637 }
638
639 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
640
641 // Consume a couple of frames
642 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
643 // stream id 1
644 EXPECT_EQ(OK, mListener->WaitForEvent());
645 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
646
647 // stream id 2
648 EXPECT_EQ(OK, mListener->WaitForEvent());
649 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
650
651 //TODO: events should be a struct with some data like the stream id
652 }
653
654 // Done: clean up
655 free_camera_metadata(request);
656 EXPECT_OK(mCamera->deleteStream(streamId));
657 EXPECT_OK(mCamera->exclusiveUnlock());
658}
659
Igor Murashkinbfb5d5e2013-02-20 17:15:11 -0800660}
661}
662}
663}
664