1 /* 2 * Copyright (C) 2016 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 V4L2_CAMERA_HAL_V4L2_WRAPPER_H_ 18 #define V4L2_CAMERA_HAL_V4L2_WRAPPER_H_ 19 20 #include <array> 21 #include <memory> 22 #include <mutex> 23 #include <set> 24 #include <string> 25 #include <vector> 26 27 #include <android-base/unique_fd.h> 28 #include "arc/common_types.h" 29 #include "arc/frame_buffer.h" 30 #include "capture_request.h" 31 #include "common.h" 32 #include "stream_format.h" 33 34 namespace v4l2_camera_hal { 35 36 class V4L2Wrapper { 37 public: 38 // Use this method to create V4L2Wrapper objects. Functionally equivalent 39 // to "new V4L2Wrapper", except that it may return nullptr in case of failure. 40 static V4L2Wrapper* NewV4L2Wrapper(const std::string device_path); 41 virtual ~V4L2Wrapper(); 42 43 // Helper class to ensure all opened connections are closed. 44 class Connection { 45 public: Connection(std::shared_ptr<V4L2Wrapper> device)46 Connection(std::shared_ptr<V4L2Wrapper> device) 47 : device_(std::move(device)), connect_result_(device_->Connect()) {} ~Connection()48 ~Connection() { 49 if (connect_result_ == 0) { 50 device_->Disconnect(); 51 } 52 } 53 // Check whether the connection succeeded or not. status()54 inline int status() const { return connect_result_; } 55 56 private: 57 std::shared_ptr<V4L2Wrapper> device_; 58 const int connect_result_; 59 }; 60 61 // Turn the stream on or off. 62 virtual int StreamOn(); 63 virtual int StreamOff(); 64 // Manage controls. 65 virtual int QueryControl(uint32_t control_id, v4l2_query_ext_ctrl* result); 66 virtual int GetControl(uint32_t control_id, int32_t* value); 67 virtual int SetControl(uint32_t control_id, 68 int32_t desired, 69 int32_t* result = nullptr); 70 // Manage format. 71 virtual int GetFormats(std::set<uint32_t>* v4l2_formats); 72 virtual int GetQualifiedFormats(std::vector<uint32_t>* v4l2_formats); 73 virtual int GetFormatFrameSizes(uint32_t v4l2_format, 74 std::set<std::array<int32_t, 2>>* sizes); 75 76 // Durations are returned in ns. 77 virtual int GetFormatFrameDurationRange( 78 uint32_t v4l2_format, 79 const std::array<int32_t, 2>& size, 80 std::array<int64_t, 2>* duration_range); 81 virtual int SetFormat(const StreamFormat& desired_format, 82 uint32_t* result_max_buffers); 83 // Manage buffers. 84 virtual int EnqueueRequest( 85 std::shared_ptr<default_camera_hal::CaptureRequest> request); 86 virtual int DequeueRequest( 87 std::shared_ptr<default_camera_hal::CaptureRequest>* request); 88 virtual int GetInFlightBufferCount(); 89 90 private: 91 // Constructor is private to allow failing on bad input. 92 // Use NewV4L2Wrapper instead. 93 V4L2Wrapper(const std::string device_path); 94 95 // Connect or disconnect to the device. Access by creating/destroying 96 // a V4L2Wrapper::Connection object. 97 int Connect(); 98 void Disconnect(); 99 // Perform an ioctl call in a thread-safe fashion. 100 template <typename T> 101 int IoctlLocked(unsigned long request, T data); 102 // Request/release userspace buffer mode via VIDIOC_REQBUFS. 103 int RequestBuffers(uint32_t num_buffers); 104 connected()105 inline bool connected() { return device_fd_.get() >= 0; } 106 107 // Format management. 108 const arc::SupportedFormats GetSupportedFormats(); 109 110 // The camera device path. For example, /dev/video0. 111 const std::string device_path_; 112 // The opened device fd. 113 android::base::unique_fd device_fd_; 114 // The underlying gralloc module. 115 // std::unique_ptr<V4L2Gralloc> gralloc_; 116 // Whether or not the device supports the extended control query. 117 bool extended_query_supported_; 118 // The format this device is set up for. 119 std::unique_ptr<StreamFormat> format_; 120 // Lock protecting use of the buffer tracker. 121 std::mutex buffer_queue_lock_; 122 // Lock protecting use of the device. 123 std::mutex device_lock_; 124 // Lock protecting connecting/disconnecting the device. 125 std::mutex connection_lock_; 126 // Reference count connections. 127 int connection_count_; 128 // Supported formats. 129 arc::SupportedFormats supported_formats_; 130 // Qualified formats. 131 arc::SupportedFormats qualified_formats_; 132 133 class RequestContext { 134 public: RequestContext()135 RequestContext() 136 : active(false), 137 camera_buffer(std::make_shared<arc::AllocatedFrameBuffer>(0)){}; ~RequestContext()138 ~RequestContext(){}; 139 // Indicates whether this request context is in use. 140 bool active; 141 // Buffer handles of the context. 142 std::shared_ptr<arc::AllocatedFrameBuffer> camera_buffer; 143 std::shared_ptr<default_camera_hal::CaptureRequest> request; 144 }; 145 146 // Map of in flight requests. 147 // |buffers_.size()| will always be the maximum number of buffers this device 148 // can handle in its current format. 149 std::vector<RequestContext> buffers_; 150 151 friend class Connection; 152 friend class V4L2WrapperMock; 153 154 DISALLOW_COPY_AND_ASSIGN(V4L2Wrapper); 155 }; 156 157 } // namespace v4l2_camera_hal 158 159 #endif // V4L2_CAMERA_HAL_V4L2_WRAPPER_H_ 160