Jiyoung Shin | c15a6b0 | 2012-06-05 01:08:14 -0700 | [diff] [blame^] | 1 | /* |
| 2 | ** |
| 3 | ** Copyright 2008, The Android Open Source Project |
| 4 | ** Copyright 2012, Samsung Electronics Co. LTD |
| 5 | ** |
| 6 | ** Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 | ** you may not use this file except in compliance with the License. |
| 8 | ** You may obtain a copy of the License at |
| 9 | ** |
| 10 | ** http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | ** |
| 12 | ** Unless required by applicable law or agreed to in writing, software |
| 13 | ** distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | ** See the License for the specific language governing permissions and |
| 16 | ** limitations under the License. |
| 17 | */ |
| 18 | |
| 19 | /*! |
| 20 | * \file ExynosCameraHWInterface2.h |
| 21 | * \brief header file for Android Camera API 2.0 HAL |
| 22 | * \author Sungjoong Kang(sj3.kang@samsung.com) |
| 23 | * \date 2012/05/31 |
| 24 | * |
| 25 | * <b>Revision History: </b> |
| 26 | * - 2012/05/31 : Sungjoong Kang(sj3.kang@samsung.com) \n |
| 27 | * Initial Release |
| 28 | */ |
| 29 | |
| 30 | #ifndef EXYNOS_CAMERA_HW_INTERFACE_2_H |
| 31 | #define EXYNOS_CAMERA_HW_INTERFACE_2_H |
| 32 | |
| 33 | #include <hardware/camera2.h> |
| 34 | #include <camera/Camera.h> |
| 35 | #include <camera/CameraParameters.h> |
| 36 | #include "SignalDrivenThread.h" |
| 37 | #include "MetadataConverter.h" |
| 38 | #include "exynos_v4l2.h" |
| 39 | #include "videodev2_exynos_camera.h" |
| 40 | #include "gralloc_priv.h" |
| 41 | |
| 42 | #include <fcntl.h> |
| 43 | #include "fimc-is-metadata.h" |
| 44 | #include "ion.h" |
| 45 | |
| 46 | namespace android { |
| 47 | |
| 48 | |
| 49 | #define NODE_PREFIX "/dev/video" |
| 50 | |
| 51 | #define NUM_MAX_STREAM_THREAD (5) |
| 52 | #define NUM_MAX_DEQUEUED_REQUEST (4) |
| 53 | #define NUM_MAX_REQUEST_MGR_ENTRY NUM_MAX_DEQUEUED_REQUEST |
| 54 | #define NUM_OF_STREAM_BUF (15) |
| 55 | #define MAX_CAMERA_MEMORY_PLANE_NUM (4) |
| 56 | |
| 57 | #define SIGNAL_MAIN_REQ_Q_NOT_EMPTY (SIGNAL_THREAD_COMMON_LAST<<1) |
| 58 | #define SIGNAL_MAIN_REPROCESS_Q_NOT_EMPTY (SIGNAL_THREAD_COMMON_LAST<<2) |
| 59 | #define SIGNAL_MAIN_STREAM_OUTPUT_DONE (SIGNAL_THREAD_COMMON_LAST<<3) |
| 60 | #define SIGNAL_SENSOR_START_REQ_PROCESSING (SIGNAL_THREAD_COMMON_LAST<<4) |
| 61 | #define SIGNAL_STREAM_GET_BUFFER (SIGNAL_THREAD_COMMON_LAST<<5) |
| 62 | #define SIGNAL_STREAM_PUT_BUFFER (SIGNAL_THREAD_COMMON_LAST<<6) |
| 63 | #define SIGNAL_STREAM_CHANGE_PARAMETER (SIGNAL_THREAD_COMMON_LAST<<7) |
| 64 | |
| 65 | |
| 66 | #define SIGNAL_STREAM_DATA_COMING (SIGNAL_THREAD_COMMON_LAST<<15) |
| 67 | |
| 68 | |
| 69 | #define MAX_NUM_CAMERA_BUFFERS (16) |
| 70 | enum sensor_name { |
| 71 | SENSOR_NAME_S5K3H2 = 1, |
| 72 | SENSOR_NAME_S5K6A3 = 2, |
| 73 | SENSOR_NAME_S5K4E5 = 3, |
| 74 | SENSOR_NAME_S5K3H7 = 4, |
| 75 | SENSOR_NAME_CUSTOM = 5, |
| 76 | SENSOR_NAME_END |
| 77 | }; |
| 78 | |
| 79 | typedef struct exynos_camera_memory { |
| 80 | ion_buffer ionBuffer[MAX_CAMERA_MEMORY_PLANE_NUM]; |
| 81 | char *virBuffer[MAX_CAMERA_MEMORY_PLANE_NUM]; |
| 82 | int size[MAX_CAMERA_MEMORY_PLANE_NUM]; |
| 83 | } exynos_camera_memory_t; |
| 84 | |
| 85 | typedef struct node_info { |
| 86 | int fd; |
| 87 | int width; |
| 88 | int height; |
| 89 | int format; |
| 90 | int planes; |
| 91 | int buffers; |
| 92 | int currentBufferIndex; |
| 93 | enum v4l2_memory memory; |
| 94 | enum v4l2_buf_type type; |
| 95 | ion_client ionClient; |
| 96 | exynos_camera_memory_t buffer[MAX_NUM_CAMERA_BUFFERS]; |
| 97 | } node_info_t; |
| 98 | |
| 99 | |
| 100 | typedef struct camera_hw_info { |
| 101 | int sensor_id; |
| 102 | |
| 103 | node_info_t sensor; |
| 104 | node_info_t isp; |
| 105 | node_info_t capture; |
| 106 | node_info_t preview; |
| 107 | |
| 108 | |
| 109 | /*shot*/ |
| 110 | camera2_shot_t current_shot; |
| 111 | } camera_hw_info_t; |
| 112 | |
| 113 | typedef enum request_entry_status |
| 114 | { |
| 115 | EMPTY, |
| 116 | REGISTERED, |
| 117 | PROCESSING |
| 118 | } request_entry_status_t; |
| 119 | |
| 120 | typedef struct request_manager_entry { |
| 121 | request_entry_status_t status; |
| 122 | int id; |
| 123 | camera_metadata_t *original_request; |
| 124 | // TODO : allocate memory dynamically |
| 125 | // camera2_ctl_metadata_t *internal_request; |
| 126 | camera2_ctl_metadata_NEW_t internal_request; |
| 127 | int output_stream_count; |
| 128 | } request_manager_entry_t; |
| 129 | |
| 130 | class RequestManager { |
| 131 | public: |
| 132 | RequestManager(SignalDrivenThread* main_thread); |
| 133 | ~RequestManager(); |
| 134 | int GetNumEntries(); |
| 135 | bool IsRequestQueueFull(); |
| 136 | |
| 137 | void RegisterRequest(camera_metadata_t * new_request); |
| 138 | void DeregisterRequest(camera_metadata_t ** deregistered_request); |
| 139 | void PrepareFrame(size_t* num_entries, size_t* frame_size, |
| 140 | camera_metadata_t ** prepared_frame); |
| 141 | void MarkProcessingRequest(exynos_camera_memory_t* buf); |
| 142 | void NotifyStreamOutput(uint32_t stream_id); |
| 143 | |
| 144 | private: |
| 145 | |
| 146 | MetadataConverter *m_metadataConverter; |
| 147 | SignalDrivenThread *m_mainThread; |
| 148 | int m_numOfEntries; |
| 149 | int m_entryInsertionIndex; |
| 150 | int m_entryProcessingIndex; |
| 151 | int m_entryFrameOutputIndex; |
| 152 | request_manager_entry_t entries[NUM_MAX_REQUEST_MGR_ENTRY]; |
| 153 | |
| 154 | Mutex m_requestMutex; |
| 155 | |
| 156 | //TODO : alloc dynamically |
| 157 | char m_tempFrameMetadataBuf[2000]; |
| 158 | camera_metadata_t *m_tempFrameMetadata; |
| 159 | int32_t frame_seq_number; |
| 160 | }; |
| 161 | |
| 162 | typedef struct stream_parameters |
| 163 | { |
| 164 | uint32_t id; |
| 165 | uint32_t width; |
| 166 | uint32_t height; |
| 167 | int format; |
| 168 | const camera2_stream_ops_t* streamOps; |
| 169 | uint32_t usage; |
| 170 | uint32_t max_buffers; |
| 171 | int fd; |
| 172 | void *grallocVirtAddr[NUM_OF_STREAM_BUF]; |
| 173 | bool availableBufHandle[NUM_OF_STREAM_BUF]; |
| 174 | buffer_handle_t *bufHandle[NUM_OF_STREAM_BUF]; |
| 175 | node_info_t *node; |
| 176 | } stream_parameters_t; |
| 177 | |
| 178 | |
| 179 | class ExynosCameraHWInterface2 : public virtual RefBase { |
| 180 | public: |
| 181 | ExynosCameraHWInterface2(int cameraId, camera2_device_t *dev); |
| 182 | virtual ~ExynosCameraHWInterface2(); |
| 183 | |
| 184 | virtual void release(); |
| 185 | |
| 186 | inline int getCameraId() const; |
| 187 | |
| 188 | virtual int setRequestQueueSrcOps(const camera2_request_queue_src_ops_t *request_src_ops); |
| 189 | virtual int notifyRequestQueueNotEmpty(); |
| 190 | virtual int setFrameQueueDstOps(const camera2_frame_queue_dst_ops_t *frame_dst_ops); |
| 191 | virtual int getInProgressCount(); |
| 192 | virtual int flushCapturesInProgress(); |
| 193 | virtual int constructDefaultRequest(int request_template, camera_metadata_t **request); |
| 194 | virtual int allocateStream(uint32_t width, uint32_t height, |
| 195 | int format, const camera2_stream_ops_t *stream_ops, |
| 196 | uint32_t *stream_id, uint32_t *format_actual, uint32_t *usage, uint32_t *max_buffers); |
| 197 | virtual int registerStreamBuffers(uint32_t stream_id, int num_buffers, buffer_handle_t *buffers); |
| 198 | virtual int releaseStream(uint32_t stream_id); |
| 199 | virtual int allocateReprocessStream(uint32_t width, uint32_t height, |
| 200 | uint32_t format, const camera2_stream_in_ops_t *reprocess_stream_ops, |
| 201 | uint32_t *stream_id, uint32_t *consumer_usage, uint32_t *max_buffers); |
| 202 | virtual int releaseReprocessStream(uint32_t stream_id); |
| 203 | virtual int triggerAction(uint32_t trigger_id, int ext1, int ext2); |
| 204 | virtual int setNotifyCallback(camera2_notify_callback notify_cb, void *user); |
| 205 | virtual int getMetadataVendorTagOps(vendor_tag_query_ops_t **ops); |
| 206 | virtual int dump(int fd); |
| 207 | private: |
| 208 | |
| 209 | class MainThread : public SignalDrivenThread { |
| 210 | ExynosCameraHWInterface2 *mHardware; |
| 211 | public: |
| 212 | MainThread(ExynosCameraHWInterface2 *hw): |
| 213 | SignalDrivenThread("MainThread", PRIORITY_DEFAULT, 0), |
| 214 | mHardware(hw) { } |
| 215 | virtual void onFirstRef() { |
| 216 | } |
| 217 | status_t readyToRunInternal() { |
| 218 | return NO_ERROR; |
| 219 | } |
| 220 | void threadLoopInternal() { |
| 221 | mHardware->m_mainThreadFunc(this); |
| 222 | return; |
| 223 | } |
| 224 | }; |
| 225 | |
| 226 | class SensorThread : public SignalDrivenThread { |
| 227 | ExynosCameraHWInterface2 *mHardware; |
| 228 | public: |
| 229 | SensorThread(ExynosCameraHWInterface2 *hw): |
| 230 | SignalDrivenThread("SensorThread", PRIORITY_DEFAULT, 0), |
| 231 | mHardware(hw), |
| 232 | m_isBayerOutputEnabled(false) { } |
| 233 | virtual void onFirstRef() { |
| 234 | mHardware->m_sensorThreadInitialize(this); |
| 235 | } |
| 236 | status_t readyToRunInternal() { |
| 237 | mHardware->m_sensorThreadInitialize(this); |
| 238 | return NO_ERROR; |
| 239 | } |
| 240 | void threadLoopInternal() { |
| 241 | mHardware->m_sensorThreadFunc(this); |
| 242 | return; |
| 243 | } |
| 244 | //private: |
| 245 | bool m_isBayerOutputEnabled; |
| 246 | int m_sensorFd; |
| 247 | int m_ispFd; |
| 248 | }; |
| 249 | |
| 250 | class StreamThread : public SignalDrivenThread { |
| 251 | ExynosCameraHWInterface2 *mHardware; |
| 252 | public: |
| 253 | StreamThread(ExynosCameraHWInterface2 *hw, uint8_t new_index): |
| 254 | SignalDrivenThread("StreamThread", PRIORITY_DEFAULT, 0), |
| 255 | mHardware(hw), |
| 256 | m_index(new_index) { } |
| 257 | virtual void onFirstRef() { |
| 258 | mHardware->m_streamThreadInitialize(this); |
| 259 | } |
| 260 | status_t readyToRunInternal() { |
| 261 | mHardware->m_streamThreadInitialize(this); |
| 262 | return NO_ERROR; |
| 263 | } |
| 264 | void threadLoopInternal() { |
| 265 | mHardware->m_streamThreadFunc(this); |
| 266 | return; |
| 267 | } |
| 268 | void SetParameter(uint32_t id, uint32_t width, uint32_t height, int format, |
| 269 | const camera2_stream_ops_t* stream_ops, uint32_t usage, int fd, node_info_t * node); |
| 270 | void ApplyChange(void); |
| 271 | |
| 272 | uint8_t m_index; |
| 273 | //private: |
| 274 | stream_parameters_t m_parameters; |
| 275 | stream_parameters_t m_tempParameters; |
| 276 | |
| 277 | }; |
| 278 | |
| 279 | sp<MainThread> m_mainThread; |
| 280 | sp<SensorThread> m_sensorThread; |
| 281 | sp<StreamThread> m_streamThread; |
| 282 | |
| 283 | |
| 284 | |
| 285 | RequestManager *m_requestManager; |
| 286 | |
| 287 | void m_mainThreadFunc(SignalDrivenThread * self); |
| 288 | void m_sensorThreadFunc(SignalDrivenThread * self); |
| 289 | void m_sensorThreadInitialize(SignalDrivenThread * self); |
| 290 | void m_streamThreadFunc(SignalDrivenThread * self); |
| 291 | void m_streamThreadInitialize(SignalDrivenThread * self); |
| 292 | |
| 293 | int createIonClient(ion_client ionClient); |
| 294 | int deleteIonClient(ion_client ionClient); |
| 295 | int allocCameraMemory(ion_client ionClient, exynos_camera_memory_t *buf, int iMemoryNum); |
| 296 | void freeCameraMemory(exynos_camera_memory_t *buf, int iMemoryNum); |
| 297 | void initCameraMemory(exynos_camera_memory_t *buf, int iMemoryNum); |
| 298 | |
| 299 | camera2_request_queue_src_ops_t *m_requestQueueOps; |
| 300 | camera2_frame_queue_dst_ops_t *m_frameQueueOps; |
| 301 | camera2_notify_callback m_notifyCb; |
| 302 | void *m_callbackCookie; |
| 303 | |
| 304 | int m_numOfRemainingReqInSvc; |
| 305 | bool m_isRequestQueuePending; |
| 306 | |
| 307 | camera2_device_t *m_halDevice; |
| 308 | static gralloc_module_t const* m_grallocHal; |
| 309 | |
| 310 | |
| 311 | camera_hw_info_t m_camera_info; |
| 312 | |
| 313 | ion_client m_ionCameraClient; |
| 314 | |
| 315 | bool m_isSensorThreadOn; |
| 316 | bool m_isStreamStarted; |
| 317 | int matchBuffer(void * bufAddr); |
| 318 | bool m_isBufferInit; |
| 319 | }; |
| 320 | |
| 321 | }; // namespace android |
| 322 | |
| 323 | #endif |