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 #include "v4l2_wrapper.h" 18 19 #include <algorithm> 20 #include <array> 21 #include <limits> 22 #include <mutex> 23 #include <vector> 24 25 #include <fcntl.h> 26 #include <linux/videodev2.h> 27 #include <sys/stat.h> 28 #include <sys/types.h> 29 30 #include <android-base/unique_fd.h> 31 32 #include "common.h" 33 #include "stream_format.h" 34 #include "v4l2_gralloc.h" 35 36 namespace v4l2_camera_hal { 37 38 const int32_t kStandardSizes[][2] = {{640, 480}, {320, 240}}; 39 40 V4L2Wrapper* V4L2Wrapper::NewV4L2Wrapper(const std::string device_path) { 41 std::unique_ptr<V4L2Gralloc> gralloc(V4L2Gralloc::NewV4L2Gralloc()); 42 if (!gralloc) { 43 HAL_LOGE("Failed to initialize gralloc helper."); 44 return nullptr; 45 } 46 47 return new V4L2Wrapper(device_path, std::move(gralloc)); 48 } 49 50 V4L2Wrapper::V4L2Wrapper(const std::string device_path, 51 std::unique_ptr<V4L2Gralloc> gralloc) 52 : device_path_(std::move(device_path)), 53 gralloc_(std::move(gralloc)), 54 connection_count_(0) {} 55 56 V4L2Wrapper::~V4L2Wrapper() {} 57 58 int V4L2Wrapper::Connect() { 59 HAL_LOG_ENTER(); 60 std::lock_guard<std::mutex> lock(connection_lock_); 61 62 if (connected()) { 63 HAL_LOGV("Camera device %s is already connected.", device_path_.c_str()); 64 ++connection_count_; 65 return 0; 66 } 67 68 // Open in nonblocking mode (DQBUF may return EAGAIN). 69 int fd = TEMP_FAILURE_RETRY(open(device_path_.c_str(), O_RDWR | O_NONBLOCK)); 70 if (fd < 0) { 71 HAL_LOGE("failed to open %s (%s)", device_path_.c_str(), strerror(errno)); 72 return -ENODEV; 73 } 74 device_fd_.reset(fd); 75 ++connection_count_; 76 77 // Check if this connection has the extended control query capability. 78 v4l2_query_ext_ctrl query; 79 query.id = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND; 80 extended_query_supported_ = (IoctlLocked(VIDIOC_QUERY_EXT_CTRL, &query) == 0); 81 82 // TODO(b/29185945): confirm this is a supported device. 83 // This is checked by the HAL, but the device at device_path_ may 84 // not be the same one that was there when the HAL was loaded. 85 // (Alternatively, better hotplugging support may make this unecessary 86 // by disabling cameras that get disconnected and checking newly connected 87 // cameras, so Connect() is never called on an unsupported camera) 88 return 0; 89 } 90 91 void V4L2Wrapper::Disconnect() { 92 HAL_LOG_ENTER(); 93 std::lock_guard<std::mutex> lock(connection_lock_); 94 95 if (connection_count_ == 0) { 96 // Not connected. 97 HAL_LOGE("Camera device %s is not connected, cannot disconnect.", 98 device_path_.c_str()); 99 return; 100 } 101 102 --connection_count_; 103 if (connection_count_ > 0) { 104 HAL_LOGV("Disconnected from camera device %s. %d connections remain.", 105 device_path_.c_str()); 106 return; 107 } 108 109 device_fd_.reset(-1); // Includes close(). 110 format_.reset(); 111 buffers_.clear(); 112 // Closing the device releases all queued buffers back to the user. 113 gralloc_->unlockAllBuffers(); 114 } 115 116 // Helper function. Should be used instead of ioctl throughout this class. 117 template <typename T> 118 int V4L2Wrapper::IoctlLocked(int request, T data) { 119 // Potentially called so many times logging entry is a bad idea. 120 std::lock_guard<std::mutex> lock(device_lock_); 121 122 if (!connected()) { 123 HAL_LOGE("Device %s not connected.", device_path_.c_str()); 124 return -ENODEV; 125 } 126 return TEMP_FAILURE_RETRY(ioctl(device_fd_.get(), request, data)); 127 } 128 129 int V4L2Wrapper::StreamOn() { 130 if (!format_) { 131 HAL_LOGE("Stream format must be set before turning on stream."); 132 return -EINVAL; 133 } 134 135 int32_t type = format_->type(); 136 if (IoctlLocked(VIDIOC_STREAMON, &type) < 0) { 137 HAL_LOGE("STREAMON fails: %s", strerror(errno)); 138 return -ENODEV; 139 } 140 141 HAL_LOGV("Stream turned on."); 142 return 0; 143 } 144 145 int V4L2Wrapper::StreamOff() { 146 if (!format_) { 147 // Can't have turned on the stream without format being set, 148 // so nothing to turn off here. 149 return 0; 150 } 151 152 int32_t type = format_->type(); 153 int res = IoctlLocked(VIDIOC_STREAMOFF, &type); 154 // Calling STREAMOFF releases all queued buffers back to the user. 155 int gralloc_res = gralloc_->unlockAllBuffers(); 156 // No buffers in flight. 157 for (size_t i = 0; i < buffers_.size(); ++i) { 158 buffers_[i] = false; 159 } 160 if (res < 0) { 161 HAL_LOGE("STREAMOFF fails: %s", strerror(errno)); 162 return -ENODEV; 163 } 164 if (gralloc_res < 0) { 165 HAL_LOGE("Failed to unlock all buffers after turning stream off."); 166 return gralloc_res; 167 } 168 169 HAL_LOGV("Stream turned off."); 170 return 0; 171 } 172 173 int V4L2Wrapper::QueryControl(uint32_t control_id, 174 v4l2_query_ext_ctrl* result) { 175 int res; 176 177 memset(result, 0, sizeof(*result)); 178 179 if (extended_query_supported_) { 180 result->id = control_id; 181 res = IoctlLocked(VIDIOC_QUERY_EXT_CTRL, result); 182 // Assuming the operation was supported (not ENOTTY), no more to do. 183 if (errno != ENOTTY) { 184 if (res) { 185 HAL_LOGE("QUERY_EXT_CTRL fails: %s", strerror(errno)); 186 return -ENODEV; 187 } 188 return 0; 189 } 190 } 191 192 // Extended control querying not supported, fall back to basic control query. 193 v4l2_queryctrl query; 194 query.id = control_id; 195 if (IoctlLocked(VIDIOC_QUERYCTRL, &query)) { 196 HAL_LOGE("QUERYCTRL fails: %s", strerror(errno)); 197 return -ENODEV; 198 } 199 200 // Convert the basic result to the extended result. 201 result->id = query.id; 202 result->type = query.type; 203 memcpy(result->name, query.name, sizeof(query.name)); 204 result->minimum = query.minimum; 205 if (query.type == V4L2_CTRL_TYPE_BITMASK) { 206 // According to the V4L2 documentation, when type is BITMASK, 207 // max and default should be interpreted as __u32. Practically, 208 // this means the conversion from 32 bit to 64 will pad with 0s not 1s. 209 result->maximum = static_cast<uint32_t>(query.maximum); 210 result->default_value = static_cast<uint32_t>(query.default_value); 211 } else { 212 result->maximum = query.maximum; 213 result->default_value = query.default_value; 214 } 215 result->step = static_cast<uint32_t>(query.step); 216 result->flags = query.flags; 217 result->elems = 1; 218 switch (result->type) { 219 case V4L2_CTRL_TYPE_INTEGER64: 220 result->elem_size = sizeof(int64_t); 221 break; 222 case V4L2_CTRL_TYPE_STRING: 223 result->elem_size = result->maximum + 1; 224 break; 225 default: 226 result->elem_size = sizeof(int32_t); 227 break; 228 } 229 230 return 0; 231 } 232 233 int V4L2Wrapper::GetControl(uint32_t control_id, int32_t* value) { 234 // For extended controls (any control class other than "user"), 235 // G_EXT_CTRL must be used instead of G_CTRL. 236 if (V4L2_CTRL_ID2CLASS(control_id) != V4L2_CTRL_CLASS_USER) { 237 v4l2_ext_control control; 238 v4l2_ext_controls controls; 239 memset(&control, 0, sizeof(control)); 240 memset(&controls, 0, sizeof(controls)); 241 242 control.id = control_id; 243 controls.ctrl_class = V4L2_CTRL_ID2CLASS(control_id); 244 controls.count = 1; 245 controls.controls = &control; 246 247 if (IoctlLocked(VIDIOC_G_EXT_CTRLS, &controls) < 0) { 248 HAL_LOGE("G_EXT_CTRLS fails: %s", strerror(errno)); 249 return -ENODEV; 250 } 251 *value = control.value; 252 } else { 253 v4l2_control control{control_id, 0}; 254 if (IoctlLocked(VIDIOC_G_CTRL, &control) < 0) { 255 HAL_LOGE("G_CTRL fails: %s", strerror(errno)); 256 return -ENODEV; 257 } 258 *value = control.value; 259 } 260 return 0; 261 } 262 263 int V4L2Wrapper::SetControl(uint32_t control_id, 264 int32_t desired, 265 int32_t* result) { 266 int32_t result_value = 0; 267 268 // TODO(b/29334616): When async, this may need to check if the stream 269 // is on, and if so, lock it off while setting format. Need to look 270 // into if V4L2 supports adjusting controls while the stream is on. 271 272 // For extended controls (any control class other than "user"), 273 // S_EXT_CTRL must be used instead of S_CTRL. 274 if (V4L2_CTRL_ID2CLASS(control_id) != V4L2_CTRL_CLASS_USER) { 275 v4l2_ext_control control; 276 v4l2_ext_controls controls; 277 memset(&control, 0, sizeof(control)); 278 memset(&controls, 0, sizeof(controls)); 279 280 control.id = control_id; 281 control.value = desired; 282 controls.ctrl_class = V4L2_CTRL_ID2CLASS(control_id); 283 controls.count = 1; 284 controls.controls = &control; 285 286 if (IoctlLocked(VIDIOC_S_EXT_CTRLS, &controls) < 0) { 287 HAL_LOGE("S_EXT_CTRLS fails: %s", strerror(errno)); 288 return -ENODEV; 289 } 290 result_value = control.value; 291 } else { 292 v4l2_control control{control_id, desired}; 293 if (IoctlLocked(VIDIOC_S_CTRL, &control) < 0) { 294 HAL_LOGE("S_CTRL fails: %s", strerror(errno)); 295 return -ENODEV; 296 } 297 result_value = control.value; 298 } 299 300 // If the caller wants to know the result, pass it back. 301 if (result != nullptr) { 302 *result = result_value; 303 } 304 return 0; 305 } 306 307 int V4L2Wrapper::GetFormats(std::set<uint32_t>* v4l2_formats) { 308 HAL_LOG_ENTER(); 309 310 v4l2_fmtdesc format_query; 311 memset(&format_query, 0, sizeof(format_query)); 312 // TODO(b/30000211): multiplanar support. 313 format_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 314 while (IoctlLocked(VIDIOC_ENUM_FMT, &format_query) >= 0) { 315 v4l2_formats->insert(format_query.pixelformat); 316 ++format_query.index; 317 } 318 319 if (errno != EINVAL) { 320 HAL_LOGE( 321 "ENUM_FMT fails at index %d: %s", format_query.index, strerror(errno)); 322 return -ENODEV; 323 } 324 return 0; 325 } 326 327 int V4L2Wrapper::GetFormatFrameSizes(uint32_t v4l2_format, 328 std::set<std::array<int32_t, 2>>* sizes) { 329 v4l2_frmsizeenum size_query; 330 memset(&size_query, 0, sizeof(size_query)); 331 size_query.pixel_format = v4l2_format; 332 if (IoctlLocked(VIDIOC_ENUM_FRAMESIZES, &size_query) < 0) { 333 HAL_LOGE("ENUM_FRAMESIZES failed: %s", strerror(errno)); 334 return -ENODEV; 335 } 336 if (size_query.type == V4L2_FRMSIZE_TYPE_DISCRETE) { 337 // Discrete: enumerate all sizes using VIDIOC_ENUM_FRAMESIZES. 338 // Assuming that a driver with discrete frame sizes has a reasonable number 339 // of them. 340 do { 341 sizes->insert({{{static_cast<int32_t>(size_query.discrete.width), 342 static_cast<int32_t>(size_query.discrete.height)}}}); 343 ++size_query.index; 344 } while (IoctlLocked(VIDIOC_ENUM_FRAMESIZES, &size_query) >= 0); 345 if (errno != EINVAL) { 346 HAL_LOGE("ENUM_FRAMESIZES fails at index %d: %s", 347 size_query.index, 348 strerror(errno)); 349 return -ENODEV; 350 } 351 } else { 352 // Continuous/Step-wise: based on the stepwise struct returned by the query. 353 // Fully listing all possible sizes, with large enough range/small enough 354 // step size, may produce far too many potential sizes. Instead, find the 355 // closest to a set of standard sizes. 356 for (const auto size : kStandardSizes) { 357 // Find the closest size, rounding up. 358 uint32_t desired_width = size[0]; 359 uint32_t desired_height = size[1]; 360 if (desired_width < size_query.stepwise.min_width || 361 desired_height < size_query.stepwise.min_height) { 362 HAL_LOGV("Standard size %u x %u is too small for format %d", 363 desired_width, 364 desired_height, 365 v4l2_format); 366 continue; 367 } else if (desired_width > size_query.stepwise.max_width && 368 desired_height > size_query.stepwise.max_height) { 369 HAL_LOGV("Standard size %u x %u is too big for format %d", 370 desired_width, 371 desired_height, 372 v4l2_format); 373 continue; 374 } 375 376 // Round up. 377 uint32_t width_steps = (desired_width - size_query.stepwise.min_width + 378 size_query.stepwise.step_width - 1) / 379 size_query.stepwise.step_width; 380 uint32_t height_steps = (desired_height - size_query.stepwise.min_height + 381 size_query.stepwise.step_height - 1) / 382 size_query.stepwise.step_height; 383 sizes->insert( 384 {{{static_cast<int32_t>(size_query.stepwise.min_width + 385 width_steps * size_query.stepwise.step_width), 386 static_cast<int32_t>(size_query.stepwise.min_height + 387 height_steps * 388 size_query.stepwise.step_height)}}}); 389 } 390 } 391 return 0; 392 } 393 394 // Converts a v4l2_fract with units of seconds to an int64_t with units of ns. 395 inline int64_t FractToNs(const v4l2_fract& fract) { 396 return (1000000000LL * fract.numerator) / fract.denominator; 397 } 398 399 int V4L2Wrapper::GetFormatFrameDurationRange( 400 uint32_t v4l2_format, 401 const std::array<int32_t, 2>& size, 402 std::array<int64_t, 2>* duration_range) { 403 // Potentially called so many times logging entry is a bad idea. 404 405 v4l2_frmivalenum duration_query; 406 memset(&duration_query, 0, sizeof(duration_query)); 407 duration_query.pixel_format = v4l2_format; 408 duration_query.width = size[0]; 409 duration_query.height = size[1]; 410 if (IoctlLocked(VIDIOC_ENUM_FRAMEINTERVALS, &duration_query) < 0) { 411 HAL_LOGE("ENUM_FRAMEINTERVALS failed: %s", strerror(errno)); 412 return -ENODEV; 413 } 414 415 int64_t min = std::numeric_limits<int64_t>::max(); 416 int64_t max = std::numeric_limits<int64_t>::min(); 417 if (duration_query.type == V4L2_FRMSIZE_TYPE_DISCRETE) { 418 // Discrete: enumerate all durations using VIDIOC_ENUM_FRAMEINTERVALS. 419 do { 420 min = std::min(min, FractToNs(duration_query.discrete)); 421 max = std::max(max, FractToNs(duration_query.discrete)); 422 ++duration_query.index; 423 } while (IoctlLocked(VIDIOC_ENUM_FRAMEINTERVALS, &duration_query) >= 0); 424 if (errno != EINVAL) { 425 HAL_LOGE("ENUM_FRAMEINTERVALS fails at index %d: %s", 426 duration_query.index, 427 strerror(errno)); 428 return -ENODEV; 429 } 430 } else { 431 // Continuous/Step-wise: simply convert the given min and max. 432 min = FractToNs(duration_query.stepwise.min); 433 max = FractToNs(duration_query.stepwise.max); 434 } 435 (*duration_range)[0] = min; 436 (*duration_range)[1] = max; 437 return 0; 438 } 439 440 int V4L2Wrapper::SetFormat(const StreamFormat& desired_format, 441 uint32_t* result_max_buffers) { 442 HAL_LOG_ENTER(); 443 444 if (format_ && desired_format == *format_) { 445 HAL_LOGV("Already in correct format, skipping format setting."); 446 *result_max_buffers = buffers_.size(); 447 return 0; 448 } 449 450 // Not in the correct format, set the new one. 451 452 if (format_) { 453 // If we had an old format, first request 0 buffers to inform the device 454 // we're no longer using any previously "allocated" buffers from the old 455 // format. This seems like it shouldn't be necessary for USERPTR memory, 456 // and/or should happen from turning the stream off, but the driver 457 // complained. May be a driver issue, or may be intended behavior. 458 int res = RequestBuffers(0); 459 if (res) { 460 return res; 461 } 462 } 463 464 // Set the camera to the new format. 465 v4l2_format new_format; 466 desired_format.FillFormatRequest(&new_format); 467 // TODO(b/29334616): When async, this will need to check if the stream 468 // is on, and if so, lock it off while setting format. 469 470 if (IoctlLocked(VIDIOC_S_FMT, &new_format) < 0) { 471 HAL_LOGE("S_FMT failed: %s", strerror(errno)); 472 return -ENODEV; 473 } 474 475 // Check that the driver actually set to the requested values. 476 if (desired_format != new_format) { 477 HAL_LOGE("Device doesn't support desired stream configuration."); 478 return -EINVAL; 479 } 480 481 // Keep track of our new format. 482 format_.reset(new StreamFormat(new_format)); 483 484 // Format changed, request new buffers. 485 int res = RequestBuffers(1); 486 if (res) { 487 HAL_LOGE("Requesting buffers for new format failed."); 488 return res; 489 } 490 *result_max_buffers = buffers_.size(); 491 return 0; 492 } 493 494 int V4L2Wrapper::RequestBuffers(uint32_t num_requested) { 495 v4l2_requestbuffers req_buffers; 496 memset(&req_buffers, 0, sizeof(req_buffers)); 497 req_buffers.type = format_->type(); 498 req_buffers.memory = V4L2_MEMORY_USERPTR; 499 req_buffers.count = num_requested; 500 501 int res = IoctlLocked(VIDIOC_REQBUFS, &req_buffers); 502 // Calling REQBUFS releases all queued buffers back to the user. 503 int gralloc_res = gralloc_->unlockAllBuffers(); 504 if (res < 0) { 505 HAL_LOGE("REQBUFS failed: %s", strerror(errno)); 506 return -ENODEV; 507 } 508 if (gralloc_res < 0) { 509 HAL_LOGE("Failed to unlock all buffers when setting up new buffers."); 510 return gralloc_res; 511 } 512 513 // V4L2 will set req_buffers.count to a number of buffers it can handle. 514 if (num_requested > 0 && req_buffers.count < 1) { 515 HAL_LOGE("REQBUFS claims it can't handle any buffers."); 516 return -ENODEV; 517 } 518 buffers_.resize(req_buffers.count, false); 519 520 return 0; 521 } 522 523 int V4L2Wrapper::EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer, 524 uint32_t* enqueued_index) { 525 if (!format_) { 526 HAL_LOGE("Stream format must be set before enqueuing buffers."); 527 return -ENODEV; 528 } 529 530 // Find a free buffer index. Could use some sort of persistent hinting 531 // here to improve expected efficiency, but buffers_.size() is expected 532 // to be low enough (<10 experimentally) that it's not worth it. 533 int index = -1; 534 { 535 std::lock_guard<std::mutex> guard(buffer_queue_lock_); 536 for (int i = 0; i < buffers_.size(); ++i) { 537 if (!buffers_[i]) { 538 index = i; 539 break; 540 } 541 } 542 } 543 if (index < 0) { 544 // Note: The HAL should be tracking the number of buffers in flight 545 // for each stream, and should never overflow the device. 546 HAL_LOGE("Cannot enqueue buffer: stream is already full."); 547 return -ENODEV; 548 } 549 550 // Set up a v4l2 buffer struct. 551 v4l2_buffer device_buffer; 552 memset(&device_buffer, 0, sizeof(device_buffer)); 553 device_buffer.type = format_->type(); 554 device_buffer.index = index; 555 556 // Use QUERYBUF to ensure our buffer/device is in good shape, 557 // and fill out remaining fields. 558 if (IoctlLocked(VIDIOC_QUERYBUF, &device_buffer) < 0) { 559 HAL_LOGE("QUERYBUF fails: %s", strerror(errno)); 560 return -ENODEV; 561 } 562 563 // Lock the buffer for writing (fills in the user pointer field). 564 int res = 565 gralloc_->lock(camera_buffer, format_->bytes_per_line(), &device_buffer); 566 if (res) { 567 HAL_LOGE("Gralloc failed to lock buffer."); 568 return res; 569 } 570 if (IoctlLocked(VIDIOC_QBUF, &device_buffer) < 0) { 571 HAL_LOGE("QBUF fails: %s", strerror(errno)); 572 gralloc_->unlock(&device_buffer); 573 return -ENODEV; 574 } 575 576 // Mark the buffer as in flight. 577 std::lock_guard<std::mutex> guard(buffer_queue_lock_); 578 buffers_[index] = true; 579 580 if (enqueued_index) { 581 *enqueued_index = index; 582 } 583 return 0; 584 } 585 586 int V4L2Wrapper::DequeueBuffer(uint32_t* dequeued_index) { 587 if (!format_) { 588 HAL_LOGV( 589 "Format not set, so stream can't be on, " 590 "so no buffers available for dequeueing"); 591 return -EAGAIN; 592 } 593 594 v4l2_buffer buffer; 595 memset(&buffer, 0, sizeof(buffer)); 596 buffer.type = format_->type(); 597 buffer.memory = V4L2_MEMORY_USERPTR; 598 int res = IoctlLocked(VIDIOC_DQBUF, &buffer); 599 if (res) { 600 if (errno == EAGAIN) { 601 // Expected failure. 602 return -EAGAIN; 603 } else { 604 // Unexpected failure. 605 HAL_LOGE("DQBUF fails: %s", strerror(errno)); 606 return -ENODEV; 607 } 608 } 609 610 // Mark the buffer as no longer in flight. 611 { 612 std::lock_guard<std::mutex> guard(buffer_queue_lock_); 613 buffers_[buffer.index] = false; 614 } 615 616 // Now that we're done painting the buffer, we can unlock it. 617 res = gralloc_->unlock(&buffer); 618 if (res) { 619 HAL_LOGE("Gralloc failed to unlock buffer after dequeueing."); 620 return res; 621 } 622 623 if (dequeued_index) { 624 *dequeued_index = buffer.index; 625 } 626 return 0; 627 } 628 629 } // namespace v4l2_camera_hal 630