ProCameraTests.cpp revision 7b33a74bbc514b99c16be7fff9a34e892bc19264
1/* 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 20#include <binder/IPCThreadState.h> 21#include <utils/Thread.h> 22 23#include "Camera.h" 24#include "ProCamera.h" 25#include <utils/Vector.h> 26#include <utils/Mutex.h> 27#include <utils/Condition.h> 28 29#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 35namespace android { 36namespace camera2 { 37namespace tests { 38namespace client { 39 40#define CAMERA_ID 0 41#define TEST_DEBUGGING 0 42 43#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout 44#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead 45 46#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8 47#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16 48 49#define TEST_CPU_FRAME_COUNT 2 50#define TEST_CPU_HEAP_COUNT 5 51 52#if TEST_DEBUGGING 53#define dout std::cerr 54#else 55#define dout if (0) std::cerr 56#endif 57 58#define EXPECT_OK(x) EXPECT_EQ(OK, (x)) 59#define ASSERT_OK(x) ASSERT_EQ(OK, (x)) 60 61class ProCameraTest; 62 63enum ProEvent { 64 UNKNOWN, 65 ACQUIRED, 66 RELEASED, 67 STOLEN, 68 BUFFER_RECEIVED, 69 RESULT_RECEIVED, 70}; 71 72inline int ProEvent_Mask(ProEvent e) { 73 return (1 << static_cast<int>(e)); 74} 75 76typedef Vector<ProEvent> EventList; 77 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 90 ptr->joinThreadPool(); 91 92 return false; 93 } 94 95 sp<ProcessState> mProc; 96}; 97 98class ProCameraTestListener : public ProCameraListener { 99 100public: 101 static const int EVENT_MASK_ALL = 0xFFFFFFFF; 102 103 ProCameraTestListener() { 104 mEventMask = EVENT_MASK_ALL; 105 } 106 107 status_t WaitForEvent() { 108 Mutex::Autolock cal(mConditionMutex); 109 110 { 111 Mutex::Autolock al(mListenerMutex); 112 113 if (mProEventList.size() > 0) { 114 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 126 for (size_t i = 0; i < mProEventList.size(); ++i) { 127 out.push(mProEventList[i]); 128 } 129 130 mProEventList.clear(); 131 } 132 133 /** 134 * Dequeue 1 event from the event queue. 135 * Returns UNKNOWN if queue is empty 136 */ 137 ProEvent ReadEvent() { 138 Mutex::Autolock al(mListenerMutex); 139 140 if (mProEventList.size() == 0) { 141 return UNKNOWN; 142 } 143 144 ProEvent ev = mProEventList[0]; 145 mProEventList.removeAt(0); 146 147 return ev; 148 } 149 150 void SetEventMask(int eventMask) { 151 Mutex::Autolock al(mListenerMutex); 152 mEventMask = eventMask; 153 } 154 155private: 156 void QueueEvent(ProEvent ev) { 157 bool eventAdded = false; 158 { 159 Mutex::Autolock al(mListenerMutex); 160 161 if (ProEvent_Mask(ev) & mEventMask) { 162 mProEventList.push(ev); 163 eventAdded = true; 164 } 165 } 166 167 if (eventAdded) { 168 mListenerCondition.broadcast(); 169 } 170 } 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 200 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 } 209 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); 214 free_camera_metadata(request); 215 } 216 217 // 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 225 Vector<ProEvent> mProEventList; 226 Mutex mListenerMutex; 227 Mutex mConditionMutex; 228 Condition mListenerCondition; 229 int mEventMask; 230}; 231 232class ProCameraTest : public ::testing::Test { 233 234public: 235 ProCameraTest() { 236 } 237 238 static void SetUpTestCase() { 239 // Binder Thread Pool Initialization 240 mTestThread = new ProCameraTestThread(); 241 mTestThread->run("ProCameraTestThread"); 242 } 243 244 virtual void SetUp() { 245 mCamera = ProCamera::connect(CAMERA_ID); 246 ASSERT_NE((void*)NULL, mCamera.get()); 247 248 mListener = new ProCameraTestListener(); 249 mCamera->setListener(mListener); 250 } 251 252 virtual void TearDown() { 253 ASSERT_NE((void*)NULL, mCamera.get()); 254 mCamera->disconnect(); 255 } 256 257protected: 258 sp<ProCamera> mCamera; 259 sp<ProCameraTestListener> mListener; 260 261 static sp<Thread> mTestThread; 262 263 int mDisplaySecs; 264 sp<SurfaceComposerClient> mComposerClient; 265 sp<SurfaceControl> mSurfaceControl; 266 267 sp<SurfaceComposerClient> mDepthComposerClient; 268 sp<SurfaceControl> mDepthSurfaceControl; 269 270 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 286 mSurfaceControl->setPosition(640, 0); 287 288 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 302 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 327 template <typename T> 328 static bool FindItem(T needle, T* array, size_t count) { 329 for (int i = 0; i < count; ++i) { 330 if (array[i] == needle) { 331 return true; 332 } 333 } 334 return false; 335 } 336 337}; 338 339sp<Thread> ProCameraTest::mTestThread; 340 341TEST_F(ProCameraTest, AvailableFormats) { 342 if (HasFatalFailure()) { 343 return; 344 } 345 346 camera_metadata_t* info = mCamera->getCameraInfo(CAMERA_ID); 347 ASSERT_NE((void*)NULL, info); 348 349 camera_metadata_entry_t entry; 350 uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS); 351 EXPECT_EQ(OK, find_camera_metadata_entry(info, tag, &entry)); 352 353 EXPECT_TRUE(FindItem<int32_t>(HAL_PIXEL_FORMAT_YV12, 354 entry.data.i32, entry.count)); 355 EXPECT_TRUE(FindItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP, 356 entry.data.i32, entry.count)); 357 358 free_camera_metadata(info); 359} 360 361// test around exclusiveTryLock (immediate locking) 362TEST_F(ProCameraTest, LockingImmediate) { 363 364 if (HasFatalFailure()) { 365 return; 366 } 367 368 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) | 369 ProEvent_Mask(STOLEN) | 370 ProEvent_Mask(RELEASED)); 371 372 EXPECT_FALSE(mCamera->hasExclusiveLock()); 373 EXPECT_EQ(OK, mCamera->exclusiveTryLock()); 374 // at this point we definitely have the lock 375 376 EXPECT_EQ(OK, mListener->WaitForEvent()); 377 EXPECT_EQ(ACQUIRED, mListener->ReadEvent()); 378 379 EXPECT_TRUE(mCamera->hasExclusiveLock()); 380 EXPECT_EQ(OK, mCamera->exclusiveUnlock()); 381 382 EXPECT_EQ(OK, mListener->WaitForEvent()); 383 EXPECT_EQ(RELEASED, mListener->ReadEvent()); 384 385 EXPECT_FALSE(mCamera->hasExclusiveLock()); 386} 387 388// test around exclusiveLock (locking at some future point in time) 389TEST_F(ProCameraTest, LockingAsynchronous) { 390 391 if (HasFatalFailure()) { 392 return; 393 } 394 395 396 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) | 397 ProEvent_Mask(STOLEN) | 398 ProEvent_Mask(RELEASED)); 399 400 // TODO: Add another procamera that has a lock here. 401 // then we can be test that the lock wont immediately be acquired 402 403 EXPECT_FALSE(mCamera->hasExclusiveLock()); 404 EXPECT_EQ(OK, mCamera->exclusiveTryLock()); 405 // at this point we definitely have the lock 406 407 EXPECT_EQ(OK, mListener->WaitForEvent()); 408 EXPECT_EQ(ACQUIRED, mListener->ReadEvent()); 409 410 EXPECT_TRUE(mCamera->hasExclusiveLock()); 411 EXPECT_EQ(OK, mCamera->exclusiveUnlock()); 412 413 EXPECT_EQ(OK, mListener->WaitForEvent()); 414 EXPECT_EQ(RELEASED, mListener->ReadEvent()); 415 416 EXPECT_FALSE(mCamera->hasExclusiveLock()); 417} 418 419// Stream directly to the screen. 420TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) { 421 if (HasFatalFailure()) { 422 return; 423 } 424 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS"); 425 if (displaySecsEnv != NULL) { 426 mDisplaySecs = atoi(displaySecsEnv); 427 if (mDisplaySecs < 0) { 428 mDisplaySecs = 0; 429 } 430 } else { 431 mDisplaySecs = 0; 432 } 433 434 sp<Surface> depthSurface; 435 if (mDisplaySecs > 0) { 436 createDepthOnScreenSurface(/*out*/depthSurface); 437 } 438 439 int depthStreamId = -1; 440 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240, 441 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId)); 442 EXPECT_NE(-1, depthStreamId); 443 444 EXPECT_OK(mCamera->exclusiveTryLock()); 445 /* iterate in a loop submitting requests every frame. 446 * what kind of requests doesnt really matter, just whatever. 447 */ 448 449 // it would probably be better to use CameraMetadata from camera service. 450 camera_metadata_t *request = NULL; 451 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 452 /*out*/&request)); 453 EXPECT_NE((void*)NULL, request); 454 455 /* FIXME: dont need this later, at which point the above should become an 456 ASSERT_NE*/ 457 if(request == NULL) request = allocate_camera_metadata(10, 100); 458 459 // set the output streams to just this stream ID 460 461 // wow what a verbose API. 462 // i would give a loaf of bread for 463 // metadata->updateOrInsert(keys.request.output.streams, streamId); 464 uint8_t allStreams[] = { depthStreamId }; 465 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]); 466 467 camera_metadata_entry_t entry; 468 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 469 int find = find_camera_metadata_entry(request, tag, &entry); 470 if (find == -ENOENT) { 471 if (add_camera_metadata_entry(request, tag, &allStreams, 472 /*data_count*/streamCount) != OK) { 473 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 474 ASSERT_OK(append_camera_metadata(tmp, request)); 475 free_camera_metadata(request); 476 request = tmp; 477 478 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 479 /*data_count*/streamCount)); 480 } 481 } else { 482 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 483 &allStreams, /*data_count*/streamCount, &entry)); 484 } 485 486 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 487 488 dout << "will sleep now for " << mDisplaySecs << std::endl; 489 sleep(mDisplaySecs); 490 491 free_camera_metadata(request); 492 493 for (int i = 0; i < streamCount; ++i) { 494 EXPECT_OK(mCamera->deleteStream(allStreams[i])); 495 } 496 EXPECT_OK(mCamera->exclusiveUnlock()); 497} 498 499// Stream directly to the screen. 500TEST_F(ProCameraTest, DISABLED_StreamingImageDual) { 501 if (HasFatalFailure()) { 502 return; 503 } 504 char* displaySecsEnv = getenv("TEST_DISPLAY_SECS"); 505 if (displaySecsEnv != NULL) { 506 mDisplaySecs = atoi(displaySecsEnv); 507 if (mDisplaySecs < 0) { 508 mDisplaySecs = 0; 509 } 510 } else { 511 mDisplaySecs = 0; 512 } 513 514 sp<Surface> surface; 515 sp<Surface> depthSurface; 516 if (mDisplaySecs > 0) { 517 createOnScreenSurface(/*out*/surface); 518 createDepthOnScreenSurface(/*out*/depthSurface); 519 } 520 521 int streamId = -1; 522 EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960, 523 TEST_FORMAT_MAIN, surface, &streamId)); 524 EXPECT_NE(-1, streamId); 525 526 int depthStreamId = -1; 527 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240, 528 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId)); 529 EXPECT_NE(-1, depthStreamId); 530 531 EXPECT_OK(mCamera->exclusiveTryLock()); 532 /* 533 */ 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 // wow what a verbose API. 551 uint8_t allStreams[] = { streamId, depthStreamId }; 552 // IMPORTANT. bad things will happen if its not a uint8. 553 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]); 554 camera_metadata_entry_t entry; 555 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 556 int find = find_camera_metadata_entry(request, tag, &entry); 557 if (find == -ENOENT) { 558 if (add_camera_metadata_entry(request, tag, &allStreams, 559 /*data_count*/streamCount) != OK) { 560 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 561 ASSERT_OK(append_camera_metadata(tmp, request)); 562 free_camera_metadata(request); 563 request = tmp; 564 565 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 566 /*data_count*/streamCount)); 567 } 568 } else { 569 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 570 &allStreams, /*data_count*/streamCount, &entry)); 571 } 572 573 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 574 575 dout << "will sleep now for " << mDisplaySecs << std::endl; 576 sleep(mDisplaySecs); 577 578 free_camera_metadata(request); 579 580 for (int i = 0; i < streamCount; ++i) { 581 EXPECT_OK(mCamera->deleteStream(allStreams[i])); 582 } 583 EXPECT_OK(mCamera->exclusiveUnlock()); 584} 585 586TEST_F(ProCameraTest, CpuConsumerSingle) { 587 if (HasFatalFailure()) { 588 return; 589 } 590 591 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED)); 592 593 int streamId = -1; 594 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240, 595 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &streamId)); 596 EXPECT_NE(-1, streamId); 597 598 EXPECT_OK(mCamera->exclusiveTryLock()); 599 EXPECT_EQ(OK, mListener->WaitForEvent()); 600 EXPECT_EQ(ACQUIRED, mListener->ReadEvent()); 601 /* iterate in a loop submitting requests every frame. 602 * what kind of requests doesnt really matter, just whatever. 603 */ 604 605 // it would probably be better to use CameraMetadata from camera service. 606 camera_metadata_t *request = NULL; 607 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 608 /*out*/&request)); 609 EXPECT_NE((void*)NULL, request); 610 611 /*FIXME: dont need this later, at which point the above should become an 612 ASSERT_NE*/ 613 if(request == NULL) request = allocate_camera_metadata(10, 100); 614 615 // set the output streams to just this stream ID 616 617 uint8_t allStreams[] = { streamId }; 618 camera_metadata_entry_t entry; 619 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 620 int find = find_camera_metadata_entry(request, tag, &entry); 621 if (find == -ENOENT) { 622 if (add_camera_metadata_entry(request, tag, &allStreams, 623 /*data_count*/1) != OK) { 624 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 625 ASSERT_OK(append_camera_metadata(tmp, request)); 626 free_camera_metadata(request); 627 request = tmp; 628 629 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 630 /*data_count*/1)); 631 } 632 } else { 633 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 634 &allStreams, /*data_count*/1, &entry)); 635 } 636 637 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 638 639 // Consume a couple of frames 640 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) { 641 EXPECT_EQ(OK, mListener->WaitForEvent()); 642 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent()); 643 } 644 645 // Done: clean up 646 free_camera_metadata(request); 647 EXPECT_OK(mCamera->deleteStream(streamId)); 648 EXPECT_OK(mCamera->exclusiveUnlock()); 649} 650 651TEST_F(ProCameraTest, CpuConsumerDual) { 652 if (HasFatalFailure()) { 653 return; 654 } 655 656 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED)); 657 658 int streamId = -1; 659 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, 660 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &streamId)); 661 EXPECT_NE(-1, streamId); 662 663 int depthStreamId = -1; 664 EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240, 665 TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthStreamId)); 666 EXPECT_NE(-1, depthStreamId); 667 668 EXPECT_OK(mCamera->exclusiveTryLock()); 669 /* 670 */ 671 /* iterate in a loop submitting requests every frame. 672 * what kind of requests doesnt really matter, just whatever. 673 */ 674 675 // it would probably be better to use CameraMetadata from camera service. 676 camera_metadata_t *request = NULL; 677 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 678 /*out*/&request)); 679 EXPECT_NE((void*)NULL, request); 680 681 if(request == NULL) request = allocate_camera_metadata(10, 100); 682 683 // set the output streams to just this stream ID 684 685 // wow what a verbose API. 686 uint8_t allStreams[] = { streamId, depthStreamId }; 687 size_t streamCount = 2; 688 camera_metadata_entry_t entry; 689 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 690 int find = find_camera_metadata_entry(request, tag, &entry); 691 if (find == -ENOENT) { 692 if (add_camera_metadata_entry(request, tag, &allStreams, 693 /*data_count*/streamCount) != OK) { 694 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 695 ASSERT_OK(append_camera_metadata(tmp, request)); 696 free_camera_metadata(request); 697 request = tmp; 698 699 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 700 /*data_count*/streamCount)); 701 } 702 } else { 703 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 704 &allStreams, /*data_count*/streamCount, &entry)); 705 } 706 707 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 708 709 // Consume a couple of frames 710 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) { 711 // stream id 1 712 EXPECT_EQ(OK, mListener->WaitForEvent()); 713 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent()); 714 715 // stream id 2 716 EXPECT_EQ(OK, mListener->WaitForEvent()); 717 EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent()); 718 719 //TODO: events should be a struct with some data like the stream id 720 } 721 722 // Done: clean up 723 free_camera_metadata(request); 724 EXPECT_OK(mCamera->deleteStream(streamId)); 725 EXPECT_OK(mCamera->exclusiveUnlock()); 726} 727 728TEST_F(ProCameraTest, ResultReceiver) { 729 if (HasFatalFailure()) { 730 return; 731 } 732 733 mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED)); 734 //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED 735 // need to filter out events at read time 736 737 int streamId = -1; 738 EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960, 739 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &streamId)); 740 EXPECT_NE(-1, streamId); 741 742 EXPECT_OK(mCamera->exclusiveTryLock()); 743 /* 744 */ 745 /* iterate in a loop submitting requests every frame. 746 * what kind of requests doesnt really matter, just whatever. 747 */ 748 749 camera_metadata_t *request = NULL; 750 EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW, 751 /*out*/&request)); 752 EXPECT_NE((void*)NULL, request); 753 754 /*FIXME*/ 755 if(request == NULL) request = allocate_camera_metadata(10, 100); 756 757 // set the output streams to just this stream ID 758 759 uint8_t allStreams[] = { streamId }; 760 size_t streamCount = 1; 761 camera_metadata_entry_t entry; 762 uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS); 763 int find = find_camera_metadata_entry(request, tag, &entry); 764 if (find == -ENOENT) { 765 if (add_camera_metadata_entry(request, tag, &allStreams, 766 /*data_count*/streamCount) != OK) { 767 camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000); 768 ASSERT_OK(append_camera_metadata(tmp, request)); 769 free_camera_metadata(request); 770 request = tmp; 771 772 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 773 /*data_count*/streamCount)); 774 } 775 } else { 776 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 777 &allStreams, /*data_count*/streamCount, &entry)); 778 } 779 780 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 781 782 // Consume a couple of results 783 for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) { 784 EXPECT_EQ(OK, mListener->WaitForEvent()); 785 EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent()); 786 } 787 788 // Done: clean up 789 free_camera_metadata(request); 790 EXPECT_OK(mCamera->deleteStream(streamId)); 791 EXPECT_OK(mCamera->exclusiveUnlock()); 792} 793 794} 795} 796} 797} 798 799