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