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