ProCameraTests.cpp revision 687f26c7bd7ece88cad8d51fc47be7ab1600af9d
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#include <camera/CameraMetadata.h>
35
36namespace android {
37namespace camera2 {
38namespace tests {
39namespace client {
40
41#define CAMERA_ID 0
42#define TEST_DEBUGGING 0
43
44#define TEST_LISTENER_TIMEOUT 1000000000 // 1 second listener timeout
45#define TEST_FORMAT HAL_PIXEL_FORMAT_Y16 //TODO: YUY2 instead
46
47#define TEST_FORMAT_MAIN HAL_PIXEL_FORMAT_Y8
48#define TEST_FORMAT_DEPTH HAL_PIXEL_FORMAT_Y16
49
50// defaults for display "test"
51#define TEST_DISPLAY_FORMAT HAL_PIXEL_FORMAT_Y16
52#define TEST_DISPLAY_WIDTH 1280
53#define TEST_DISPLAY_HEIGHT 960
54
55#define TEST_CPU_FRAME_COUNT 2
56#define TEST_CPU_HEAP_COUNT 5
57
58#if TEST_DEBUGGING
59#define dout std::cerr
60#else
61#define dout if (0) std::cerr
62#endif
63
64#define EXPECT_OK(x) EXPECT_EQ(OK, (x))
65#define ASSERT_OK(x) ASSERT_EQ(OK, (x))
66
67class ProCameraTest;
68
69enum ProEvent {
70    UNKNOWN,
71    ACQUIRED,
72    RELEASED,
73    STOLEN,
74    BUFFER_RECEIVED,
75    RESULT_RECEIVED,
76};
77
78inline int ProEvent_Mask(ProEvent e) {
79    return (1 << static_cast<int>(e));
80}
81
82typedef Vector<ProEvent> EventList;
83
84class ProCameraTestThread : public Thread
85{
86public:
87    ProCameraTestThread() {
88    }
89
90    virtual bool threadLoop() {
91        mProc = ProcessState::self();
92        mProc->startThreadPool();
93
94        IPCThreadState *ptr = IPCThreadState::self();
95
96        ptr->joinThreadPool();
97
98        return false;
99    }
100
101    sp<ProcessState> mProc;
102};
103
104class ProCameraTestListener : public ProCameraListener {
105
106public:
107    static const int EVENT_MASK_ALL = 0xFFFFFFFF;
108
109    ProCameraTestListener() {
110        mEventMask = EVENT_MASK_ALL;
111    }
112
113    status_t WaitForEvent() {
114        Mutex::Autolock cal(mConditionMutex);
115
116        {
117            Mutex::Autolock al(mListenerMutex);
118
119            if (mProEventList.size() > 0) {
120                return OK;
121            }
122        }
123
124        return mListenerCondition.waitRelative(mConditionMutex,
125                                               TEST_LISTENER_TIMEOUT);
126    }
127
128    /* Read events into out. Existing queue is flushed */
129    void ReadEvents(EventList& out) {
130        Mutex::Autolock al(mListenerMutex);
131
132        for (size_t i = 0; i < mProEventList.size(); ++i) {
133            out.push(mProEventList[i]);
134        }
135
136        mProEventList.clear();
137    }
138
139    /**
140      * Dequeue 1 event from the event queue.
141      * Returns UNKNOWN if queue is empty
142      */
143    ProEvent ReadEvent() {
144        Mutex::Autolock al(mListenerMutex);
145
146        if (mProEventList.size() == 0) {
147            return UNKNOWN;
148        }
149
150        ProEvent ev = mProEventList[0];
151        mProEventList.removeAt(0);
152
153        return ev;
154    }
155
156    void SetEventMask(int eventMask) {
157        Mutex::Autolock al(mListenerMutex);
158        mEventMask = eventMask;
159    }
160
161private:
162    void QueueEvent(ProEvent ev) {
163        bool eventAdded = false;
164        {
165            Mutex::Autolock al(mListenerMutex);
166
167            if (ProEvent_Mask(ev) & mEventMask) {
168                mProEventList.push(ev);
169                eventAdded = true;
170            }
171        }
172
173        if (eventAdded) {
174            mListenerCondition.broadcast();
175        }
176    }
177
178protected:
179
180    //////////////////////////////////////////////////
181    ///////// ProCameraListener //////////////////////
182    //////////////////////////////////////////////////
183
184
185    // Lock has been acquired. Write operations now available.
186    virtual void onLockAcquired() {
187        QueueEvent(ACQUIRED);
188    }
189    // Lock has been released with exclusiveUnlock
190    virtual void onLockReleased() {
191        QueueEvent(RELEASED);
192    }
193
194    // Lock has been stolen by another client.
195    virtual void onLockStolen() {
196        QueueEvent(STOLEN);
197    }
198
199    // Lock free.
200    virtual void onTriggerNotify(int32_t ext1, int32_t ext2, int32_t ext3) {
201
202        dout << "Trigger notify: " << ext1 << " " << ext2
203             << " " << ext3 << std::endl;
204    }
205
206    virtual void onBufferReceived(int streamId,
207                                  const CpuConsumer::LockedBuffer& buf) {
208
209        dout << "Buffer received on streamId = " << streamId <<
210                ", dataPtr = " << (void*)buf.data <<
211                ", timestamp = " << buf.timestamp << std::endl;
212
213        QueueEvent(BUFFER_RECEIVED);
214
215    }
216    virtual void onResultReceived(int32_t frameId,
217                                  camera_metadata* request) {
218        dout << "Result received frameId = " << frameId
219             << ", requestPtr = " << (void*)request << std::endl;
220        QueueEvent(RESULT_RECEIVED);
221        free_camera_metadata(request);
222    }
223
224    // TODO: remove
225
226    virtual void notify(int32_t , int32_t , int32_t ) {}
227    virtual void postData(int32_t , const sp<IMemory>& ,
228                          camera_frame_metadata_t *) {}
229    virtual void postDataTimestamp(nsecs_t , int32_t , const sp<IMemory>& ) {}
230
231
232    Vector<ProEvent> mProEventList;
233    Mutex             mListenerMutex;
234    Mutex             mConditionMutex;
235    Condition         mListenerCondition;
236    int               mEventMask;
237};
238
239class ProCameraTest : public ::testing::Test {
240
241public:
242    ProCameraTest() {
243        char* displaySecsEnv = getenv("TEST_DISPLAY_SECS");
244        if (displaySecsEnv != NULL) {
245            mDisplaySecs = atoi(displaySecsEnv);
246            if (mDisplaySecs < 0) {
247                mDisplaySecs = 0;
248            }
249        } else {
250            mDisplaySecs = 0;
251        }
252
253        char* displayFmtEnv = getenv("TEST_DISPLAY_FORMAT");
254        if (displayFmtEnv != NULL) {
255            mDisplayFmt = FormatFromString(displayFmtEnv);
256        } else {
257            mDisplayFmt = TEST_DISPLAY_FORMAT;
258        }
259
260        char* displayWidthEnv = getenv("TEST_DISPLAY_WIDTH");
261        if (displayWidthEnv != NULL) {
262            mDisplayW = atoi(displayWidthEnv);
263            if (mDisplayW < 0) {
264                mDisplayW = 0;
265            }
266        } else {
267            mDisplayW = TEST_DISPLAY_WIDTH;
268        }
269
270        char* displayHeightEnv = getenv("TEST_DISPLAY_HEIGHT");
271        if (displayHeightEnv != NULL) {
272            mDisplayH = atoi(displayHeightEnv);
273            if (mDisplayH < 0) {
274                mDisplayH = 0;
275            }
276        } else {
277            mDisplayH = TEST_DISPLAY_HEIGHT;
278        }
279    }
280
281    static void SetUpTestCase() {
282        // Binder Thread Pool Initialization
283        mTestThread = new ProCameraTestThread();
284        mTestThread->run("ProCameraTestThread");
285    }
286
287    virtual void SetUp() {
288        mCamera = ProCamera::connect(CAMERA_ID);
289        ASSERT_NE((void*)NULL, mCamera.get());
290
291        mListener = new ProCameraTestListener();
292        mCamera->setListener(mListener);
293    }
294
295    virtual void TearDown() {
296        ASSERT_NE((void*)NULL, mCamera.get());
297        mCamera->disconnect();
298    }
299
300protected:
301    sp<ProCamera> mCamera;
302    sp<ProCameraTestListener> mListener;
303
304    static sp<Thread> mTestThread;
305
306    int mDisplaySecs;
307    int mDisplayFmt;
308    int mDisplayW;
309    int mDisplayH;
310
311    sp<SurfaceComposerClient> mComposerClient;
312    sp<SurfaceControl> mSurfaceControl;
313
314    sp<SurfaceComposerClient> mDepthComposerClient;
315    sp<SurfaceControl> mDepthSurfaceControl;
316
317    int getSurfaceWidth() {
318        return 512;
319    }
320    int getSurfaceHeight() {
321        return 512;
322    }
323
324    void createOnScreenSurface(sp<Surface>& surface) {
325        mComposerClient = new SurfaceComposerClient;
326        ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
327
328        mSurfaceControl = mComposerClient->createSurface(
329                String8("ProCameraTest StreamingImage Surface"),
330                getSurfaceWidth(), getSurfaceHeight(),
331                PIXEL_FORMAT_RGB_888, 0);
332
333        mSurfaceControl->setPosition(0, 0);
334
335        ASSERT_TRUE(mSurfaceControl != NULL);
336        ASSERT_TRUE(mSurfaceControl->isValid());
337
338        SurfaceComposerClient::openGlobalTransaction();
339        ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF));
340        ASSERT_EQ(NO_ERROR, mSurfaceControl->show());
341        SurfaceComposerClient::closeGlobalTransaction();
342
343        sp<ANativeWindow> window = mSurfaceControl->getSurface();
344        surface = mSurfaceControl->getSurface();
345
346        ASSERT_NE((void*)NULL, surface.get());
347    }
348
349    void createDepthOnScreenSurface(sp<Surface>& surface) {
350        mDepthComposerClient = new SurfaceComposerClient;
351        ASSERT_EQ(NO_ERROR, mDepthComposerClient->initCheck());
352
353        mDepthSurfaceControl = mDepthComposerClient->createSurface(
354                String8("ProCameraTest StreamingImage Surface"),
355                getSurfaceWidth(), getSurfaceHeight(),
356                PIXEL_FORMAT_RGB_888, 0);
357
358        mDepthSurfaceControl->setPosition(640, 0);
359
360        ASSERT_TRUE(mDepthSurfaceControl != NULL);
361        ASSERT_TRUE(mDepthSurfaceControl->isValid());
362
363        SurfaceComposerClient::openGlobalTransaction();
364        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->setLayer(0x7FFFFFFF));
365        ASSERT_EQ(NO_ERROR, mDepthSurfaceControl->show());
366        SurfaceComposerClient::closeGlobalTransaction();
367
368        sp<ANativeWindow> window = mDepthSurfaceControl->getSurface();
369        surface = mDepthSurfaceControl->getSurface();
370
371        ASSERT_NE((void*)NULL, surface.get());
372    }
373
374    template <typename T>
375    static bool ExistsItem(T needle, T* array, size_t count) {
376        if (!array) {
377            return false;
378        }
379
380        for (size_t i = 0; i < count; ++i) {
381            if (array[i] == needle) {
382                return true;
383            }
384        }
385        return false;
386    }
387
388
389    static int FormatFromString(const char* str) {
390        std::string s(str);
391
392#define CMP_STR(x, y)                               \
393        if (s == #x) return HAL_PIXEL_FORMAT_ ## y;
394#define CMP_STR_SAME(x) CMP_STR(x, x)
395
396        CMP_STR_SAME( Y16);
397        CMP_STR_SAME( Y8);
398        CMP_STR_SAME( YV12);
399        CMP_STR(NV16, YCbCr_422_SP);
400        CMP_STR(NV21, YCrCb_420_SP);
401        CMP_STR(YUY2, YCbCr_422_I);
402        CMP_STR(RAW,  RAW_SENSOR);
403        CMP_STR(RGBA, RGBA_8888);
404
405        std::cerr << "Unknown format string " << str << std::endl;
406        return -1;
407
408    }
409
410    /**
411     * Creating a streaming request for these output streams from a template,
412     *  and submit it
413     */
414    void createSubmitRequestForStreams(uint8_t* streamIds, size_t count, int requestCount=-1) {
415
416        ASSERT_NE((void*)NULL, streamIds);
417        ASSERT_LT(0u, count);
418
419        camera_metadata_t *requestTmp = NULL;
420        EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
421                                                /*out*/&requestTmp));
422        ASSERT_NE((void*)NULL, requestTmp);
423        CameraMetadata request(requestTmp);
424
425        // set the output streams. default is empty
426
427        uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
428        request.update(tag, streamIds, count);
429
430        requestTmp = request.release();
431
432        if (requestCount < 0) {
433            EXPECT_OK(mCamera->submitRequest(requestTmp, /*streaming*/true));
434        } else {
435            for (int i = 0; i < requestCount; ++i) {
436                EXPECT_OK(mCamera->submitRequest(requestTmp,
437                                                 /*streaming*/false));
438            }
439        }
440        request.acquire(requestTmp);
441    }
442
443};
444
445sp<Thread> ProCameraTest::mTestThread;
446
447TEST_F(ProCameraTest, AvailableFormats) {
448    if (HasFatalFailure()) {
449        return;
450    }
451
452    CameraMetadata staticInfo = mCamera->getCameraInfo(CAMERA_ID);
453    ASSERT_FALSE(staticInfo.isEmpty());
454
455    uint32_t tag = static_cast<uint32_t>(ANDROID_SCALER_AVAILABLE_FORMATS);
456    EXPECT_TRUE(staticInfo.exists(tag));
457    camera_metadata_entry_t entry = staticInfo.find(tag);
458
459    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YV12,
460                                                  entry.data.i32, entry.count));
461    EXPECT_TRUE(ExistsItem<int32_t>(HAL_PIXEL_FORMAT_YCrCb_420_SP,
462                                                  entry.data.i32, entry.count));
463}
464
465// test around exclusiveTryLock (immediate locking)
466TEST_F(ProCameraTest, LockingImmediate) {
467
468    if (HasFatalFailure()) {
469        return;
470    }
471
472    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
473                            ProEvent_Mask(STOLEN)   |
474                            ProEvent_Mask(RELEASED));
475
476    EXPECT_FALSE(mCamera->hasExclusiveLock());
477    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
478    // at this point we definitely have the lock
479
480    EXPECT_EQ(OK, mListener->WaitForEvent());
481    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
482
483    EXPECT_TRUE(mCamera->hasExclusiveLock());
484    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
485
486    EXPECT_EQ(OK, mListener->WaitForEvent());
487    EXPECT_EQ(RELEASED, mListener->ReadEvent());
488
489    EXPECT_FALSE(mCamera->hasExclusiveLock());
490}
491
492// test around exclusiveLock (locking at some future point in time)
493TEST_F(ProCameraTest, LockingAsynchronous) {
494
495    if (HasFatalFailure()) {
496        return;
497    }
498
499
500    mListener->SetEventMask(ProEvent_Mask(ACQUIRED) |
501                            ProEvent_Mask(STOLEN)   |
502                            ProEvent_Mask(RELEASED));
503
504    // TODO: Add another procamera that has a lock here.
505    // then we can be test that the lock wont immediately be acquired
506
507    EXPECT_FALSE(mCamera->hasExclusiveLock());
508    EXPECT_EQ(OK, mCamera->exclusiveTryLock());
509    // at this point we definitely have the lock
510
511    EXPECT_EQ(OK, mListener->WaitForEvent());
512    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
513
514    EXPECT_TRUE(mCamera->hasExclusiveLock());
515    EXPECT_EQ(OK, mCamera->exclusiveUnlock());
516
517    EXPECT_EQ(OK, mListener->WaitForEvent());
518    EXPECT_EQ(RELEASED, mListener->ReadEvent());
519
520    EXPECT_FALSE(mCamera->hasExclusiveLock());
521}
522
523// Stream directly to the screen.
524TEST_F(ProCameraTest, DISABLED_StreamingImageSingle) {
525    if (HasFatalFailure()) {
526        return;
527    }
528
529    sp<Surface> surface;
530    if (mDisplaySecs > 0) {
531        createOnScreenSurface(/*out*/surface);
532    }
533    else {
534        dout << "Skipping, will not render to screen" << std::endl;
535        return;
536    }
537
538    int depthStreamId = -1;
539    EXPECT_OK(mCamera->createStream(mDisplayW, mDisplayH, mDisplayFmt, surface,
540                                    &depthStreamId));
541    EXPECT_NE(-1, depthStreamId);
542
543    EXPECT_OK(mCamera->exclusiveTryLock());
544
545    uint8_t streams[] = { depthStreamId };
546    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
547
548    dout << "will sleep now for " << mDisplaySecs << std::endl;
549    sleep(mDisplaySecs);
550
551    EXPECT_OK(mCamera->deleteStream(depthStreamId));
552    EXPECT_OK(mCamera->exclusiveUnlock());
553}
554
555// Stream directly to the screen.
556TEST_F(ProCameraTest, DISABLED_StreamingImageDual) {
557    if (HasFatalFailure()) {
558        return;
559    }
560    sp<Surface> surface;
561    sp<Surface> depthSurface;
562    if (mDisplaySecs > 0) {
563        createOnScreenSurface(/*out*/surface);
564        createDepthOnScreenSurface(/*out*/depthSurface);
565    }
566
567    int streamId = -1;
568    EXPECT_OK(mCamera->createStream(/*width*/1280, /*height*/960,
569              TEST_FORMAT_MAIN, surface, &streamId));
570    EXPECT_NE(-1, streamId);
571
572    int depthStreamId = -1;
573    EXPECT_OK(mCamera->createStream(/*width*/320, /*height*/240,
574              TEST_FORMAT_DEPTH, depthSurface, &depthStreamId));
575    EXPECT_NE(-1, depthStreamId);
576
577    EXPECT_OK(mCamera->exclusiveTryLock());
578    /*
579    */
580    /* iterate in a loop submitting requests every frame.
581     *  what kind of requests doesnt really matter, just whatever.
582     */
583
584    // it would probably be better to use CameraMetadata from camera service.
585    camera_metadata_t *request = NULL;
586    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
587              /*out*/&request));
588    EXPECT_NE((void*)NULL, request);
589
590    /*FIXME: dont need this later, at which point the above should become an
591             ASSERT_NE*/
592    if(request == NULL) request = allocate_camera_metadata(10, 100);
593
594    // set the output streams to just this stream ID
595
596    // wow what a verbose API.
597    uint8_t allStreams[] = { streamId, depthStreamId };
598    // IMPORTANT. bad things will happen if its not a uint8.
599    size_t streamCount = sizeof(allStreams) / sizeof(allStreams[0]);
600    camera_metadata_entry_t entry;
601    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
602    int find = find_camera_metadata_entry(request, tag, &entry);
603    if (find == -ENOENT) {
604        if (add_camera_metadata_entry(request, tag, &allStreams,
605                                      /*data_count*/streamCount) != OK) {
606            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
607            ASSERT_OK(append_camera_metadata(tmp, request));
608            free_camera_metadata(request);
609            request = tmp;
610
611            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
612                                                /*data_count*/streamCount));
613        }
614    } else {
615        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
616                  &allStreams, /*data_count*/streamCount, &entry));
617    }
618
619    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
620
621    dout << "will sleep now for " << mDisplaySecs << std::endl;
622    sleep(mDisplaySecs);
623
624    free_camera_metadata(request);
625
626    for (int i = 0; i < streamCount; ++i) {
627        EXPECT_OK(mCamera->deleteStream(allStreams[i]));
628    }
629    EXPECT_OK(mCamera->exclusiveUnlock());
630}
631
632TEST_F(ProCameraTest, CpuConsumerSingle) {
633    if (HasFatalFailure()) {
634        return;
635    }
636
637    mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
638
639    int streamId = -1;
640    sp<CpuConsumer> consumer;
641    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
642                TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
643    EXPECT_NE(-1, streamId);
644
645    EXPECT_OK(mCamera->exclusiveTryLock());
646    EXPECT_EQ(OK, mListener->WaitForEvent());
647    EXPECT_EQ(ACQUIRED, mListener->ReadEvent());
648    /* iterate in a loop submitting requests every frame.
649     *  what kind of requests doesnt really matter, just whatever.
650     */
651
652    // it would probably be better to use CameraMetadata from camera service.
653    camera_metadata_t *request = NULL;
654    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
655        /*out*/&request));
656    EXPECT_NE((void*)NULL, request);
657
658    /*FIXME: dont need this later, at which point the above should become an
659      ASSERT_NE*/
660    if(request == NULL) request = allocate_camera_metadata(10, 100);
661
662    // set the output streams to just this stream ID
663
664    uint8_t allStreams[] = { streamId };
665    camera_metadata_entry_t entry;
666    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
667    int find = find_camera_metadata_entry(request, tag, &entry);
668    if (find == -ENOENT) {
669        if (add_camera_metadata_entry(request, tag, &allStreams,
670                /*data_count*/1) != OK) {
671            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
672            ASSERT_OK(append_camera_metadata(tmp, request));
673            free_camera_metadata(request);
674            request = tmp;
675
676            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
677                /*data_count*/1));
678        }
679    } else {
680        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
681            &allStreams, /*data_count*/1, &entry));
682    }
683
684    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
685
686    // Consume a couple of frames
687    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
688        EXPECT_EQ(OK, mListener->WaitForEvent());
689        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
690    }
691
692    // Done: clean up
693    free_camera_metadata(request);
694    EXPECT_OK(mCamera->deleteStream(streamId));
695    EXPECT_OK(mCamera->exclusiveUnlock());
696}
697
698TEST_F(ProCameraTest, CpuConsumerDual) {
699    if (HasFatalFailure()) {
700        return;
701    }
702
703    mListener->SetEventMask(ProEvent_Mask(BUFFER_RECEIVED));
704
705    int streamId = -1;
706    sp<CpuConsumer> consumer;
707    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
708                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
709    EXPECT_NE(-1, streamId);
710
711    int depthStreamId = -1;
712    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
713            TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &consumer, &depthStreamId));
714    EXPECT_NE(-1, depthStreamId);
715
716    EXPECT_OK(mCamera->exclusiveTryLock());
717    /*
718    */
719    /* iterate in a loop submitting requests every frame.
720     *  what kind of requests doesnt really matter, just whatever.
721     */
722
723    // it would probably be better to use CameraMetadata from camera service.
724    camera_metadata_t *request = NULL;
725    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
726                                            /*out*/&request));
727    EXPECT_NE((void*)NULL, request);
728
729    if(request == NULL) request = allocate_camera_metadata(10, 100);
730
731    // set the output streams to just this stream ID
732
733    // wow what a verbose API.
734    uint8_t allStreams[] = { streamId, depthStreamId };
735    size_t streamCount = 2;
736    camera_metadata_entry_t entry;
737    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
738    int find = find_camera_metadata_entry(request, tag, &entry);
739    if (find == -ENOENT) {
740        if (add_camera_metadata_entry(request, tag, &allStreams,
741                                      /*data_count*/streamCount) != OK) {
742            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
743            ASSERT_OK(append_camera_metadata(tmp, request));
744            free_camera_metadata(request);
745            request = tmp;
746
747            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
748                                                   /*data_count*/streamCount));
749        }
750    } else {
751        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
752                              &allStreams, /*data_count*/streamCount, &entry));
753    }
754
755    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
756
757    // Consume a couple of frames
758    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
759        // stream id 1
760        EXPECT_EQ(OK, mListener->WaitForEvent());
761        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
762
763        // stream id 2
764        EXPECT_EQ(OK, mListener->WaitForEvent());
765        EXPECT_EQ(BUFFER_RECEIVED, mListener->ReadEvent());
766
767        //TODO: events should be a struct with some data like the stream id
768    }
769
770    // Done: clean up
771    free_camera_metadata(request);
772    EXPECT_OK(mCamera->deleteStream(streamId));
773    EXPECT_OK(mCamera->exclusiveUnlock());
774}
775
776TEST_F(ProCameraTest, ResultReceiver) {
777    if (HasFatalFailure()) {
778        return;
779    }
780
781    mListener->SetEventMask(ProEvent_Mask(RESULT_RECEIVED));
782    //FIXME: if this is run right after the previous test we get BUFFER_RECEIVED
783    // need to filter out events at read time
784
785    int streamId = -1;
786    sp<CpuConsumer> consumer;
787    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
788                TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
789    EXPECT_NE(-1, streamId);
790
791    EXPECT_OK(mCamera->exclusiveTryLock());
792    /*
793    */
794    /* iterate in a loop submitting requests every frame.
795     *  what kind of requests doesnt really matter, just whatever.
796     */
797
798    camera_metadata_t *request = NULL;
799    EXPECT_OK(mCamera->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
800                                            /*out*/&request));
801    EXPECT_NE((void*)NULL, request);
802
803    /*FIXME*/
804    if(request == NULL) request = allocate_camera_metadata(10, 100);
805
806    // set the output streams to just this stream ID
807
808    uint8_t allStreams[] = { streamId };
809    size_t streamCount = 1;
810    camera_metadata_entry_t entry;
811    uint32_t tag = static_cast<uint32_t>(ANDROID_REQUEST_OUTPUT_STREAMS);
812    int find = find_camera_metadata_entry(request, tag, &entry);
813    if (find == -ENOENT) {
814        if (add_camera_metadata_entry(request, tag, &allStreams,
815                                      /*data_count*/streamCount) != OK) {
816            camera_metadata_t *tmp = allocate_camera_metadata(1000, 10000);
817            ASSERT_OK(append_camera_metadata(tmp, request));
818            free_camera_metadata(request);
819            request = tmp;
820
821            ASSERT_OK(add_camera_metadata_entry(request, tag, &allStreams,
822                                                /*data_count*/streamCount));
823        }
824    } else {
825        ASSERT_OK(update_camera_metadata_entry(request, entry.index,
826                               &allStreams, /*data_count*/streamCount, &entry));
827    }
828
829    EXPECT_OK(mCamera->submitRequest(request, /*streaming*/true));
830
831    // Consume a couple of results
832    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
833        EXPECT_EQ(OK, mListener->WaitForEvent());
834        EXPECT_EQ(RESULT_RECEIVED, mListener->ReadEvent());
835    }
836
837    // Done: clean up
838    free_camera_metadata(request);
839    EXPECT_OK(mCamera->deleteStream(streamId));
840    EXPECT_OK(mCamera->exclusiveUnlock());
841}
842
843TEST_F(ProCameraTest, WaitForResult) {
844    if (HasFatalFailure()) {
845        return;
846    }
847
848    int streamId = -1;
849    sp<CpuConsumer> consumer;
850    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
851                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
852    EXPECT_NE(-1, streamId);
853
854    EXPECT_OK(mCamera->exclusiveTryLock());
855
856    uint8_t streams[] = { streamId };
857    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1));
858
859    // Consume a couple of results
860    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
861        EXPECT_OK(mCamera->waitForFrameMetadata());
862        CameraMetadata meta = mCamera->consumeFrameMetadata();
863        EXPECT_FALSE(meta.isEmpty());
864    }
865
866    // Done: clean up
867    consumer->abandon(); // since we didn't consume any of the buffers
868    EXPECT_OK(mCamera->deleteStream(streamId));
869    EXPECT_OK(mCamera->exclusiveUnlock());
870}
871
872TEST_F(ProCameraTest, WaitForSingleStreamBuffer) {
873    if (HasFatalFailure()) {
874        return;
875    }
876
877    int streamId = -1;
878    sp<CpuConsumer> consumer;
879    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
880                  TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
881    EXPECT_NE(-1, streamId);
882
883    EXPECT_OK(mCamera->exclusiveTryLock());
884
885    uint8_t streams[] = { streamId };
886    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/1,
887                                            /*requests*/TEST_CPU_FRAME_COUNT));
888
889    // Consume a couple of results
890    for (int i = 0; i < TEST_CPU_FRAME_COUNT; ++i) {
891        EXPECT_OK(mCamera->waitForFrameBuffer(streamId));
892
893        CpuConsumer::LockedBuffer buf;
894        EXPECT_OK(consumer->lockNextBuffer(&buf));
895
896        dout << "Buffer synchronously received on streamId = " << streamId <<
897                ", dataPtr = " << (void*)buf.data <<
898                ", timestamp = " << buf.timestamp << std::endl;
899
900        EXPECT_OK(consumer->unlockBuffer(buf));
901    }
902
903    // Done: clean up
904    EXPECT_OK(mCamera->deleteStream(streamId));
905    EXPECT_OK(mCamera->exclusiveUnlock());
906}
907
908TEST_F(ProCameraTest, WaitForDualStreamBuffer) {
909    if (HasFatalFailure()) {
910        return;
911    }
912
913    const int REQUEST_COUNT = TEST_CPU_FRAME_COUNT * 10;
914
915    // 15 fps
916    int streamId = -1;
917    sp<CpuConsumer> consumer;
918    EXPECT_OK(mCamera->createStreamCpu(/*width*/1280, /*height*/960,
919                 TEST_FORMAT_MAIN, TEST_CPU_HEAP_COUNT, &consumer, &streamId));
920    EXPECT_NE(-1, streamId);
921
922    // 30 fps
923    int depthStreamId = -1;
924    sp<CpuConsumer> depthConsumer;
925    EXPECT_OK(mCamera->createStreamCpu(/*width*/320, /*height*/240,
926       TEST_FORMAT_DEPTH, TEST_CPU_HEAP_COUNT, &depthConsumer, &depthStreamId));
927    EXPECT_NE(-1, depthStreamId);
928
929    EXPECT_OK(mCamera->exclusiveTryLock());
930
931    uint8_t streams[] = { streamId, depthStreamId };
932    ASSERT_NO_FATAL_FAILURE(createSubmitRequestForStreams(streams, /*count*/2,
933                                                    /*requests*/REQUEST_COUNT));
934
935    // Consume two frames simultaneously. Unsynchronized by timestamps.
936    for (int i = 0; i < REQUEST_COUNT; ++i) {
937
938        // Get the metadata
939        EXPECT_OK(mCamera->waitForFrameMetadata());
940        CameraMetadata meta = mCamera->consumeFrameMetadata();
941        EXPECT_FALSE(meta.isEmpty());
942
943        // Get the buffers
944
945        EXPECT_OK(mCamera->waitForFrameBuffer(depthStreamId));
946
947        /**
948          * Guaranteed to be able to consume the depth frame,
949          * since we waited on it.
950          */
951        CpuConsumer::LockedBuffer depthBuffer;
952        EXPECT_OK(depthConsumer->lockNextBuffer(&depthBuffer));
953
954        dout << "Depth Buffer synchronously received on streamId = " <<
955                streamId <<
956                ", dataPtr = " << (void*)depthBuffer.data <<
957                ", timestamp = " << depthBuffer.timestamp << std::endl;
958
959        EXPECT_OK(depthConsumer->unlockBuffer(depthBuffer));
960
961
962        /** Consume Greyscale frames if there are any.
963          * There may not be since it runs at half FPS */
964        CpuConsumer::LockedBuffer greyBuffer;
965        while (consumer->lockNextBuffer(&greyBuffer) == OK) {
966
967            dout << "GRAY Buffer synchronously received on streamId = " <<
968                streamId <<
969                ", dataPtr = " << (void*)greyBuffer.data <<
970                ", timestamp = " << greyBuffer.timestamp << std::endl;
971
972            EXPECT_OK(consumer->unlockBuffer(greyBuffer));
973        }
974    }
975
976    // Done: clean up
977    EXPECT_OK(mCamera->deleteStream(streamId));
978    EXPECT_OK(mCamera->exclusiveUnlock());
979}
980
981
982
983
984
985}
986}
987}
988}
989
990