1 /* 2 * Copyright 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 //#define LOG_NDEBUG 0 18 #define LOG_TAG "V4L2Camera" 19 20 #include "v4l2_camera.h" 21 22 #include <cstdlib> 23 #include <fcntl.h> 24 25 #include <camera/CameraMetadata.h> 26 #include <hardware/camera3.h> 27 #include <linux/videodev2.h> 28 #include <sys/stat.h> 29 #include <sys/types.h> 30 #include "common.h" 31 #include "function_thread.h" 32 #include "metadata/metadata_common.h" 33 #include "stream_format.h" 34 #include "v4l2_metadata_factory.h" 35 36 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a))) 37 38 namespace v4l2_camera_hal { 39 40 V4L2Camera* V4L2Camera::NewV4L2Camera(int id, const std::string path) { 41 HAL_LOG_ENTER(); 42 43 std::shared_ptr<V4L2Wrapper> v4l2_wrapper(V4L2Wrapper::NewV4L2Wrapper(path)); 44 if (!v4l2_wrapper) { 45 HAL_LOGE("Failed to initialize V4L2 wrapper."); 46 return nullptr; 47 } 48 49 std::unique_ptr<Metadata> metadata; 50 int res = GetV4L2Metadata(v4l2_wrapper, &metadata); 51 if (res) { 52 HAL_LOGE("Failed to initialize V4L2 metadata: %d", res); 53 return nullptr; 54 } 55 56 return new V4L2Camera(id, std::move(v4l2_wrapper), std::move(metadata)); 57 } 58 59 V4L2Camera::V4L2Camera(int id, 60 std::shared_ptr<V4L2Wrapper> v4l2_wrapper, 61 std::unique_ptr<Metadata> metadata) 62 : default_camera_hal::Camera(id), 63 device_(std::move(v4l2_wrapper)), 64 metadata_(std::move(metadata)), 65 buffer_enqueuer_(new FunctionThread( 66 std::bind(&V4L2Camera::enqueueRequestBuffers, this))), 67 buffer_dequeuer_(new FunctionThread( 68 std::bind(&V4L2Camera::dequeueRequestBuffers, this))), 69 max_input_streams_(0), 70 max_output_streams_({{0, 0, 0}}) { 71 HAL_LOG_ENTER(); 72 } 73 74 V4L2Camera::~V4L2Camera() { 75 HAL_LOG_ENTER(); 76 } 77 78 int V4L2Camera::connect() { 79 HAL_LOG_ENTER(); 80 81 if (connection_) { 82 HAL_LOGE("Already connected. Please disconnect and try again."); 83 return -EIO; 84 } 85 86 connection_.reset(new V4L2Wrapper::Connection(device_)); 87 if (connection_->status()) { 88 HAL_LOGE("Failed to connect to device."); 89 return connection_->status(); 90 } 91 92 // TODO(b/29185945): confirm this is a supported device. 93 // This is checked by the HAL, but the device at |device_|'s path may 94 // not be the same one that was there when the HAL was loaded. 95 // (Alternatively, better hotplugging support may make this unecessary 96 // by disabling cameras that get disconnected and checking newly connected 97 // cameras, so connect() is never called on an unsupported camera) 98 99 // TODO(b/29158098): Inform service of any flashes that are no longer 100 // available because this camera is in use. 101 return 0; 102 } 103 104 void V4L2Camera::disconnect() { 105 HAL_LOG_ENTER(); 106 107 connection_.reset(); 108 109 // TODO(b/29158098): Inform service of any flashes that are available again 110 // because this camera is no longer in use. 111 } 112 113 int V4L2Camera::flushBuffers() { 114 HAL_LOG_ENTER(); 115 return device_->StreamOff(); 116 } 117 118 int V4L2Camera::initStaticInfo(android::CameraMetadata* out) { 119 HAL_LOG_ENTER(); 120 121 int res = metadata_->FillStaticMetadata(out); 122 if (res) { 123 HAL_LOGE("Failed to get static metadata."); 124 return res; 125 } 126 127 // Extract max streams for use in verifying stream configs. 128 res = SingleTagValue( 129 *out, ANDROID_REQUEST_MAX_NUM_INPUT_STREAMS, &max_input_streams_); 130 if (res) { 131 HAL_LOGE("Failed to get max num input streams from static metadata."); 132 return res; 133 } 134 res = SingleTagValue( 135 *out, ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS, &max_output_streams_); 136 if (res) { 137 HAL_LOGE("Failed to get max num output streams from static metadata."); 138 return res; 139 } 140 141 return 0; 142 } 143 144 int V4L2Camera::initTemplate(int type, android::CameraMetadata* out) { 145 HAL_LOG_ENTER(); 146 147 return metadata_->GetRequestTemplate(type, out); 148 } 149 150 void V4L2Camera::initDeviceInfo(camera_info_t* info) { 151 HAL_LOG_ENTER(); 152 153 // TODO(b/31044975): move this into device interface. 154 // For now, just constants. 155 info->resource_cost = 100; 156 info->conflicting_devices = nullptr; 157 info->conflicting_devices_length = 0; 158 } 159 160 int V4L2Camera::initDevice() { 161 HAL_LOG_ENTER(); 162 163 // Start the buffer enqueue/dequeue threads if they're not already running. 164 if (!buffer_enqueuer_->isRunning()) { 165 android::status_t res = buffer_enqueuer_->run("Enqueue buffers"); 166 if (res != android::OK) { 167 HAL_LOGE("Failed to start buffer enqueue thread: %d", res); 168 return -ENODEV; 169 } 170 } 171 if (!buffer_dequeuer_->isRunning()) { 172 android::status_t res = buffer_dequeuer_->run("Dequeue buffers"); 173 if (res != android::OK) { 174 HAL_LOGE("Failed to start buffer dequeue thread: %d", res); 175 return -ENODEV; 176 } 177 } 178 179 return 0; 180 } 181 182 int V4L2Camera::enqueueRequest( 183 std::shared_ptr<default_camera_hal::CaptureRequest> request) { 184 HAL_LOG_ENTER(); 185 186 // Assume request validated before calling this function. 187 // (For now, always exactly 1 output buffer, no inputs). 188 { 189 std::lock_guard<std::mutex> guard(request_queue_lock_); 190 request_queue_.push(request); 191 requests_available_.notify_one(); 192 } 193 194 return 0; 195 } 196 197 std::shared_ptr<default_camera_hal::CaptureRequest> 198 V4L2Camera::dequeueRequest() { 199 std::unique_lock<std::mutex> lock(request_queue_lock_); 200 while (request_queue_.empty()) { 201 requests_available_.wait(lock); 202 } 203 204 std::shared_ptr<default_camera_hal::CaptureRequest> request = 205 request_queue_.front(); 206 request_queue_.pop(); 207 return request; 208 } 209 210 bool V4L2Camera::enqueueRequestBuffers() { 211 // Get a request from the queue (blocks this thread until one is available). 212 std::shared_ptr<default_camera_hal::CaptureRequest> request = 213 dequeueRequest(); 214 215 // Assume request validated before being added to the queue 216 // (For now, always exactly 1 output buffer, no inputs). 217 218 // Setting and getting settings are best effort here, 219 // since there's no way to know through V4L2 exactly what 220 // settings are used for a buffer unless we were to enqueue them 221 // one at a time, which would be too slow. 222 223 // Set the requested settings 224 int res = metadata_->SetRequestSettings(request->settings); 225 if (res) { 226 HAL_LOGE("Failed to set settings."); 227 completeRequest(request, res); 228 return true; 229 } 230 231 // Replace the requested settings with a snapshot of 232 // the used settings/state immediately before enqueue. 233 res = metadata_->FillResultMetadata(&request->settings); 234 if (res) { 235 // Note: since request is a shared pointer, this may happen if another 236 // thread has already decided to complete the request (e.g. via flushing), 237 // since that locks the metadata (in that case, this failing is fine, 238 // and completeRequest will simply do nothing). 239 HAL_LOGE("Failed to fill result metadata."); 240 completeRequest(request, res); 241 return true; 242 } 243 244 // Actually enqueue the buffer for capture. 245 res = device_->EnqueueRequest(request); 246 if (res) { 247 HAL_LOGE("Device failed to enqueue buffer."); 248 completeRequest(request, res); 249 return true; 250 } 251 252 // Make sure the stream is on (no effect if already on). 253 res = device_->StreamOn(); 254 if (res) { 255 HAL_LOGE("Device failed to turn on stream."); 256 // Don't really want to send an error for only the request here, 257 // since this is a full device error. 258 // TODO: Should trigger full flush. 259 return true; 260 } 261 262 std::unique_lock<std::mutex> lock(in_flight_lock_); 263 in_flight_buffer_count_++; 264 buffers_in_flight_.notify_one(); 265 return true; 266 } 267 268 bool V4L2Camera::dequeueRequestBuffers() { 269 // Dequeue a buffer. 270 std::shared_ptr<default_camera_hal::CaptureRequest> request; 271 int res; 272 273 { 274 std::unique_lock<std::mutex> lock(in_flight_lock_); 275 res = device_->DequeueRequest(&request); 276 if (!res) { 277 if (request) { 278 completeRequest(request, res); 279 in_flight_buffer_count_--; 280 } 281 return true; 282 } 283 } 284 285 if (res == -EAGAIN) { 286 // EAGAIN just means nothing to dequeue right now. 287 // Wait until something is available before looping again. 288 std::unique_lock<std::mutex> lock(in_flight_lock_); 289 while (in_flight_buffer_count_ == 0) { 290 buffers_in_flight_.wait(lock); 291 } 292 } else { 293 HAL_LOGW("Device failed to dequeue buffer: %d", res); 294 } 295 return true; 296 } 297 298 bool V4L2Camera::validateDataspacesAndRotations( 299 const camera3_stream_configuration_t* stream_config) { 300 HAL_LOG_ENTER(); 301 302 for (uint32_t i = 0; i < stream_config->num_streams; ++i) { 303 if (stream_config->streams[i]->rotation != CAMERA3_STREAM_ROTATION_0) { 304 HAL_LOGV("Rotation %d for stream %d not supported", 305 stream_config->streams[i]->rotation, 306 i); 307 return false; 308 } 309 // Accept all dataspaces, as it will just be overwritten below anyways. 310 } 311 return true; 312 } 313 314 int V4L2Camera::setupStreams(camera3_stream_configuration_t* stream_config) { 315 HAL_LOG_ENTER(); 316 317 std::lock_guard<std::mutex> guard(in_flight_lock_); 318 // The framework should be enforcing this, but doesn't hurt to be safe. 319 if (device_->GetInFlightBufferCount() != 0) { 320 HAL_LOGE("Can't set device format while frames are in flight."); 321 return -EINVAL; 322 } 323 in_flight_buffer_count_ = 0; 324 325 // stream_config should have been validated; assume at least 1 stream. 326 camera3_stream_t* stream = stream_config->streams[0]; 327 int format = stream->format; 328 uint32_t width = stream->width; 329 uint32_t height = stream->height; 330 331 if (stream_config->num_streams > 1) { 332 // TODO(b/29939583): V4L2 doesn't actually support more than 1 333 // stream at a time. If not all streams are the same format 334 // and size, error. Note that this means the HAL is not spec-compliant. 335 // Technically, this error should be thrown during validation, but 336 // since it isn't a spec-valid error validation isn't set up to check it. 337 for (uint32_t i = 1; i < stream_config->num_streams; ++i) { 338 stream = stream_config->streams[i]; 339 if (stream->format != format || stream->width != width || 340 stream->height != height) { 341 HAL_LOGE( 342 "V4L2 only supports 1 stream configuration at a time " 343 "(stream 0 is format %d, width %u, height %u, " 344 "stream %d is format %d, width %u, height %u).", 345 format, 346 width, 347 height, 348 i, 349 stream->format, 350 stream->width, 351 stream->height); 352 return -EINVAL; 353 } 354 } 355 } 356 357 // Ensure the stream is off. 358 int res = device_->StreamOff(); 359 if (res) { 360 HAL_LOGE("Device failed to turn off stream for reconfiguration: %d.", res); 361 return -ENODEV; 362 } 363 364 StreamFormat stream_format(format, width, height); 365 uint32_t max_buffers = 0; 366 res = device_->SetFormat(stream_format, &max_buffers); 367 if (res) { 368 HAL_LOGE("Failed to set device to correct format for stream: %d.", res); 369 return -ENODEV; 370 } 371 372 // Sanity check. 373 if (max_buffers < 1) { 374 HAL_LOGE("Setting format resulted in an invalid maximum of %u buffers.", 375 max_buffers); 376 return -ENODEV; 377 } 378 379 // Set all the streams dataspaces, usages, and max buffers. 380 for (uint32_t i = 0; i < stream_config->num_streams; ++i) { 381 stream = stream_config->streams[i]; 382 383 // Override HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED format. 384 if (stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { 385 stream->format = HAL_PIXEL_FORMAT_RGBA_8888; 386 } 387 388 // Max buffers as reported by the device. 389 stream->max_buffers = max_buffers; 390 391 // Usage: currently using sw graphics. 392 switch (stream->stream_type) { 393 case CAMERA3_STREAM_INPUT: 394 stream->usage = GRALLOC_USAGE_SW_READ_OFTEN; 395 break; 396 case CAMERA3_STREAM_OUTPUT: 397 stream->usage = GRALLOC_USAGE_SW_WRITE_OFTEN; 398 break; 399 case CAMERA3_STREAM_BIDIRECTIONAL: 400 stream->usage = 401 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; 402 break; 403 default: 404 // nothing to do. 405 break; 406 } 407 408 // Doesn't matter what was requested, we always use dataspace V0_JFIF. 409 // Note: according to camera3.h, this isn't allowed, but the camera 410 // framework team claims it's underdocumented; the implementation lets the 411 // HAL overwrite it. If this is changed, change the validation above. 412 stream->data_space = HAL_DATASPACE_V0_JFIF; 413 } 414 415 return 0; 416 } 417 418 bool V4L2Camera::isValidRequestSettings( 419 const android::CameraMetadata& settings) { 420 if (!metadata_->IsValidRequest(settings)) { 421 HAL_LOGE("Invalid request settings."); 422 return false; 423 } 424 return true; 425 } 426 427 } // namespace v4l2_camera_hal 428