ProCameraTests.cpp revision a91537e268f2b35f9f0dfdc0c4f84655c93285ae
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}; 328 329sp<Thread> ProCameraTest::mTestThread; 330 331// test around exclusiveTryLock (immediate locking) 332TEST_F(ProCameraTest, LockingImmediate) { 333 334 if (HasFatalFailure()) { 335 return; 336 } 337 338 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) | 339 ProEvent_Mask(STOLEN) | 340 ProEvent_Mask(RELEASED)); 341 342 EXPECT_FALSE(mCamera->hasExclusiveLock()); 343 EXPECT_EQ(OK, mCamera->exclusiveTryLock()); 344 // 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 365 366 mListener->SetEventMask(ProEvent_Mask(ACQUIRED) | 367 ProEvent_Mask(STOLEN) | 368 ProEvent_Mask(RELEASED)); 369 370 // 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()); 374 EXPECT_EQ(OK, mCamera->exclusiveTryLock()); 375 // at this point we definitely have the lock 376 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()); 387} 388 389// Stream directly to the screen. 390TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) { 391 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 404 sp<Surface> depthSurface; 405 if (mDisplaySecs > 0) { 406 createDepthOnScreenSurface(/*out*/depthSurface); 407 } 408 409 int depthStreamId = -1; 410 EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240, 411 TEST_FORMAT_DEPTH, depthSurface, &depthStreamId)); 412 EXPECT_NE(-1, depthStreamId); 413 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); 434 uint8_t allStreams[] = { depthStreamId }; 435 size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]); 436 437 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) { 441 if (add_camera_metadata_entry(request, tag, &allStreams, 442 /*data_count*/streamCount) != OK) { 443 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 448 ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams, 449 /*data_count*/streamCount)); 450 } 451 } else { 452 ASSERT_OK(update_camera_metadata_entry(request, entry.index, 453 &allStreams, /*data_count*/streamCount, &entry)); 454 } 455 456 EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true)); 457 458 dout << "will sleep now for " << mDisplaySecs << std::endl; 459 sleep(mDisplaySecs); 460 461 free_camera_metadata(request); 462 463 for (int i = 0; i < streamCount; ++i) { 464 EXPECT_OK(mCamera->deleteStream(allStreams[i])); 465 } 466 EXPECT_OK(mCamera->exclusiveUnlock()); 467} 468 469// Stream directly to the screen. 470TEST_F(ProCameraTest, DISABLED_StreamingImageDual) { 471 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) { 557 if (HasFatalFailure()) { 558 return; 559 } 560 561 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED)); 562 563 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)); 618 EXPECT_OK(mCamera->exclusiveUnlock()); 619} 620 621TEST_F(ProCameraTest, CpuConsumerDual) { 622 if (HasFatalFailure()) { 623 return; 624 } 625 626 mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED)); 627 628 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()); 639 /* 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 698TEST_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 764} 765} 766} 767} 768 769