Home | History | Annotate | Download | only in camera2
      1 /*
      2  * Copyright (C) 2012 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 #ifndef __ANDROID_HAL_CAMERA2_TESTS_STREAM_FIXTURE__
     18 #define __ANDROID_HAL_CAMERA2_TESTS_STREAM_FIXTURE__
     19 
     20 #include <gtest/gtest.h>
     21 #include <iostream>
     22 
     23 #include <gui/CpuConsumer.h>
     24 #include <gui/Surface.h>
     25 #include <utils/Condition.h>
     26 #include <utils/Mutex.h>
     27 #include <system/camera_metadata.h>
     28 
     29 #include "CameraModuleFixture.h"
     30 #include "TestExtensions.h"
     31 
     32 namespace android {
     33 namespace camera2 {
     34 namespace tests {
     35 
     36 // Format specifier for picking the best format for CPU reading the given device
     37 // version
     38 #define CAMERA_STREAM_AUTO_CPU_FORMAT (-1)
     39 
     40 struct CameraStreamParams;
     41 
     42 void PrintTo(const CameraStreamParams& p, ::std::ostream* os);
     43 
     44 struct CameraStreamParams {
     45     int mFormat;
     46     int mHeapCount;
     47 
     48 };
     49 
     50 inline ::std::ostream& operator<<(::std::ostream& os, const CameraStreamParams &p) {
     51     PrintTo(p, &os);
     52     return os;
     53 }
     54 
     55 inline void PrintTo(const CameraStreamParams& p, ::std::ostream* os) {
     56     char fmt[100];
     57     camera_metadata_enum_snprint(
     58         ANDROID_SCALER_AVAILABLE_FORMATS, p.mFormat, fmt, sizeof(fmt));
     59 
     60     *os <<  "{ ";
     61     *os <<  "Format: 0x"  << std::hex << p.mFormat    << ", ";
     62     *os <<  "Format name: " << fmt << ", ";
     63     *os <<  "HeapCount: " <<             p.mHeapCount;
     64     *os << " }";
     65 }
     66 
     67 class CameraStreamFixture
     68     : public CameraModuleFixture</*InfoQuirk*/true> {
     69 
     70 public:
     71     CameraStreamFixture(CameraStreamParams p)
     72     : CameraModuleFixture(TestSettings::DeviceId()) {
     73         TEST_EXTENSION_FORKING_CONSTRUCTOR;
     74 
     75         mParam = p;
     76 
     77         SetUp();
     78     }
     79 
     80     ~CameraStreamFixture() {
     81         TEST_EXTENSION_FORKING_DESTRUCTOR;
     82 
     83         TearDown();
     84     }
     85 
     86 private:
     87 
     88     void SetUp() {
     89         TEST_EXTENSION_FORKING_SET_UP;
     90 
     91         CameraModuleFixture::SetUp();
     92 
     93         CameraStreamParams p = mParam;
     94         sp<CameraDeviceBase> device = mDevice;
     95 
     96         /* use an arbitrary w,h */
     97         {
     98             const int tag = ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES;
     99 
    100             const CameraMetadata& staticInfo = device->info();
    101             camera_metadata_ro_entry entry = staticInfo.find(tag);
    102             ASSERT_NE(0u, entry.count)
    103                 << "Missing tag android.scaler.availableProcessedSizes";
    104 
    105             ASSERT_LE(2u, entry.count);
    106             /* this seems like it would always be the smallest w,h
    107                but we actually make no contract that it's sorted asc */;
    108             mWidth = entry.data.i32[0];
    109             mHeight = entry.data.i32[1];
    110         }
    111     }
    112     void TearDown() {
    113         TEST_EXTENSION_FORKING_TEAR_DOWN;
    114 
    115         // important: shut down HAL before releasing streams
    116         CameraModuleFixture::TearDown();
    117 
    118         mNativeWindow.clear();
    119         mCpuConsumer.clear();
    120         mFrameListener.clear();
    121     }
    122 
    123 protected:
    124     struct FrameListener : public ConsumerBase::FrameAvailableListener {
    125 
    126         FrameListener() {
    127             mPendingFrames = 0;
    128         }
    129 
    130         // CpuConsumer::FrameAvailableListener implementation
    131         virtual void onFrameAvailable() {
    132             ALOGV("Frame now available (start)");
    133 
    134             Mutex::Autolock lock(mMutex);
    135             mPendingFrames++;
    136             mCondition.signal();
    137 
    138             ALOGV("Frame now available (end)");
    139         }
    140 
    141         status_t waitForFrame(nsecs_t timeout) {
    142             status_t res;
    143             Mutex::Autolock lock(mMutex);
    144             while (mPendingFrames == 0) {
    145                 res = mCondition.waitRelative(mMutex, timeout);
    146                 if (res != OK) return res;
    147             }
    148             mPendingFrames--;
    149             return OK;
    150         }
    151 
    152     private:
    153         Mutex mMutex;
    154         Condition mCondition;
    155         int mPendingFrames;
    156     };
    157 
    158     void CreateStream() {
    159         sp<CameraDeviceBase> device = mDevice;
    160         CameraStreamParams p = mParam;
    161 
    162         mCpuConsumer = new CpuConsumer(p.mHeapCount);
    163         mCpuConsumer->setName(String8("CameraStreamTest::mCpuConsumer"));
    164 
    165         mNativeWindow = new Surface(
    166             mCpuConsumer->getProducerInterface());
    167 
    168         int format = MapAutoFormat(p.mFormat);
    169 
    170         ASSERT_EQ(OK,
    171             device->createStream(mNativeWindow,
    172                 mWidth, mHeight, format, /*size (for jpegs)*/0,
    173                 &mStreamId));
    174 
    175         ASSERT_NE(-1, mStreamId);
    176 
    177         // do not make 'this' a FrameListener or the lifetime policy will clash
    178         mFrameListener = new FrameListener();
    179         mCpuConsumer->setFrameAvailableListener(mFrameListener);
    180     }
    181 
    182     void DeleteStream() {
    183         ASSERT_EQ(OK, mDevice->deleteStream(mStreamId));
    184     }
    185 
    186     int MapAutoFormat(int format) {
    187         if (format == CAMERA_STREAM_AUTO_CPU_FORMAT) {
    188             if (getDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
    189                 format = HAL_PIXEL_FORMAT_YCbCr_420_888;
    190             } else {
    191                 format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
    192             }
    193         }
    194         return format;
    195     }
    196 
    197     int mWidth;
    198     int mHeight;
    199 
    200     int mStreamId;
    201 
    202     android::sp<FrameListener>       mFrameListener;
    203     android::sp<CpuConsumer>         mCpuConsumer;
    204     android::sp<ANativeWindow>       mNativeWindow;
    205 
    206 
    207 private:
    208     CameraStreamParams mParam;
    209 };
    210 
    211 }
    212 }
    213 }
    214 
    215 #endif
    216