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