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