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_UTILS__ 18 #define __ANDROID_HAL_CAMERA2_TESTS_UTILS__ 19 20 // Utility classes for camera2 HAL testing 21 22 #include <system/camera_metadata.h> 23 #include <hardware/camera2.h> 24 25 #include <gui/Surface.h> 26 #include <gui/CpuConsumer.h> 27 28 #include <utils/List.h> 29 #include <utils/Mutex.h> 30 #include <utils/Condition.h> 31 32 namespace android { 33 namespace camera2 { 34 namespace tests { 35 36 /** 37 * Queue class for both sending requests to a camera2 device, and for receiving 38 * frames from a camera2 device. 39 */ 40 class MetadataQueue: public camera2_request_queue_src_ops_t, 41 public camera2_frame_queue_dst_ops_t { 42 public: 43 MetadataQueue(); 44 ~MetadataQueue(); 45 46 // Interface to camera2 HAL device, either for requests (device is consumer) 47 // or for frames (device is producer) 48 const camera2_request_queue_src_ops_t* getToConsumerInterface(); 49 void setFromConsumerInterface(camera2_device_t *d); 50 51 const camera2_frame_queue_dst_ops_t* getToProducerInterface(); 52 53 // Real interfaces. On enqueue, queue takes ownership of buffer pointer 54 // On dequeue, user takes ownership of buffer pointer. 55 status_t enqueue(camera_metadata_t *buf); 56 status_t dequeue(camera_metadata_t **buf, bool incrementCount = true); 57 int getBufferCount(); 58 status_t waitForBuffer(nsecs_t timeout); 59 60 // Set repeating buffer(s); if the queue is empty on a dequeue call, the 61 // queue copies the contents of the stream slot into the queue, and then 62 // dequeues the first new entry. 63 status_t setStreamSlot(camera_metadata_t *buf); 64 status_t setStreamSlot(const List<camera_metadata_t*> &bufs); 65 66 private: 67 status_t freeBuffers(List<camera_metadata_t*>::iterator start, 68 List<camera_metadata_t*>::iterator end); 69 70 camera2_device_t *mDevice; 71 72 Mutex mMutex; 73 Condition notEmpty; 74 75 int mFrameCount; 76 77 int mCount; 78 List<camera_metadata_t*> mEntries; 79 int mStreamSlotCount; 80 List<camera_metadata_t*> mStreamSlot; 81 82 bool mSignalConsumer; 83 84 static MetadataQueue* getInstance(const camera2_frame_queue_dst_ops_t *q); 85 static MetadataQueue* getInstance(const camera2_request_queue_src_ops_t *q); 86 87 static int consumer_buffer_count(const camera2_request_queue_src_ops_t *q); 88 89 static int consumer_dequeue(const camera2_request_queue_src_ops_t *q, 90 camera_metadata_t **buffer); 91 92 static int consumer_free(const camera2_request_queue_src_ops_t *q, 93 camera_metadata_t *old_buffer); 94 95 static int producer_dequeue(const camera2_frame_queue_dst_ops_t *q, 96 size_t entries, size_t bytes, 97 camera_metadata_t **buffer); 98 99 static int producer_cancel(const camera2_frame_queue_dst_ops_t *q, 100 camera_metadata_t *old_buffer); 101 102 static int producer_enqueue(const camera2_frame_queue_dst_ops_t *q, 103 camera_metadata_t *filled_buffer); 104 105 }; 106 107 /** 108 * Basic class to receive and queue up notifications from the camera device 109 */ 110 111 class NotifierListener { 112 public: 113 114 NotifierListener(); 115 116 status_t getNotificationsFrom(camera2_device *dev); 117 118 status_t getNextNotification(int32_t *msg_type, int32_t *ext1, 119 int32_t *ext2, int32_t *ext3); 120 121 status_t waitForNotification(int32_t *msg_type, int32_t *ext1, 122 int32_t *ext2, int32_t *ext3); 123 124 int numNotifications(); 125 126 private: 127 128 status_t getNextNotificationLocked(int32_t *msg_type, 129 int32_t *ext1, int32_t *ext2, int32_t *ext3); 130 131 struct Notification { 132 Notification(int32_t type, int32_t e1, int32_t e2, int32_t e3): 133 msg_type(type), 134 ext1(e1), 135 ext2(e2), 136 ext3(e3) 137 {} 138 139 int32_t msg_type; 140 int32_t ext1; 141 int32_t ext2; 142 int32_t ext3; 143 }; 144 145 List<Notification> mNotifications; 146 147 Mutex mMutex; 148 Condition mNewNotification; 149 150 void onNotify(int32_t msg_type, 151 int32_t ext1, 152 int32_t ext2, 153 int32_t ext3); 154 155 static void notify_callback_dispatch(int32_t msg_type, 156 int32_t ext1, 157 int32_t ext2, 158 int32_t ext3, 159 void *user); 160 161 }; 162 163 /** 164 * Adapter from an IGraphicBufferProducer interface to camera2 device stream ops. 165 * Also takes care of allocating/deallocating stream in device interface 166 */ 167 class StreamAdapter: public camera2_stream_ops { 168 public: 169 StreamAdapter(sp<IGraphicBufferProducer> consumer); 170 171 ~StreamAdapter(); 172 173 status_t connectToDevice(camera2_device_t *d, 174 uint32_t width, uint32_t height, int format); 175 176 status_t disconnect(); 177 178 // Get stream ID. Only valid after a successful connectToDevice call. 179 int getId(); 180 181 private: 182 enum { 183 ERROR = -1, 184 DISCONNECTED = 0, 185 UNINITIALIZED, 186 ALLOCATED, 187 CONNECTED, 188 ACTIVE 189 } mState; 190 191 sp<ANativeWindow> mConsumerInterface; 192 camera2_device_t *mDevice; 193 194 uint32_t mId; 195 uint32_t mWidth; 196 uint32_t mHeight; 197 uint32_t mFormat; 198 uint32_t mUsage; 199 uint32_t mMaxProducerBuffers; 200 uint32_t mMaxConsumerBuffers; 201 202 const camera2_stream_ops *getStreamOps(); 203 204 static ANativeWindow* toANW(const camera2_stream_ops_t *w); 205 206 static int dequeue_buffer(const camera2_stream_ops_t *w, 207 buffer_handle_t** buffer); 208 209 static int enqueue_buffer(const camera2_stream_ops_t* w, 210 int64_t timestamp, 211 buffer_handle_t* buffer); 212 213 static int cancel_buffer(const camera2_stream_ops_t* w, 214 buffer_handle_t* buffer); 215 216 static int set_crop(const camera2_stream_ops_t* w, 217 int left, int top, int right, int bottom); 218 219 }; 220 221 /** 222 * Simple class to wait on the CpuConsumer to have a frame available 223 */ 224 class FrameWaiter : public CpuConsumer::FrameAvailableListener { 225 public: 226 FrameWaiter(); 227 228 /** 229 * Wait for max timeout nanoseconds for a new frame. Returns 230 * OK if a frame is available, TIMED_OUT if the timeout was reached. 231 */ 232 status_t waitForFrame(nsecs_t timeout); 233 234 virtual void onFrameAvailable(const BufferItem& item); 235 236 int mPendingFrames; 237 Mutex mMutex; 238 Condition mCondition; 239 }; 240 241 struct HWModuleHelpers { 242 /* attempt to unload the library with dlclose */ 243 static int closeModule(hw_module_t* module); 244 }; 245 246 } 247 } 248 } 249 250 #endif 251