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
NewV4L2Wrapper(const std::string device_path)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
V4L2Wrapper(const std::string device_path,std::unique_ptr<V4L2Gralloc> gralloc)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
~V4L2Wrapper()56 V4L2Wrapper::~V4L2Wrapper() {}
57
Connect()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
Disconnect()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>
IoctlLocked(int request,T data)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
StreamOn()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
StreamOff()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
QueryControl(uint32_t control_id,v4l2_query_ext_ctrl * result)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
GetControl(uint32_t control_id,int32_t * value)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
SetControl(uint32_t control_id,int32_t desired,int32_t * result)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
GetFormats(std::set<uint32_t> * v4l2_formats)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
GetFormatFrameSizes(uint32_t v4l2_format,std::set<std::array<int32_t,2>> * sizes)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.
FractToNs(const v4l2_fract & fract)395 inline int64_t FractToNs(const v4l2_fract& fract) {
396 return (1000000000LL * fract.numerator) / fract.denominator;
397 }
398
GetFormatFrameDurationRange(uint32_t v4l2_format,const std::array<int32_t,2> & size,std::array<int64_t,2> * duration_range)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
SetFormat(const StreamFormat & desired_format,uint32_t * result_max_buffers)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
RequestBuffers(uint32_t num_requested)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
EnqueueBuffer(const camera3_stream_buffer_t * camera_buffer,uint32_t * enqueued_index)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
DequeueBuffer(uint32_t * dequeued_index)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