• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
NewV4L2Camera(int id,const std::string path)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 
V4L2Camera(int id,std::shared_ptr<V4L2Wrapper> v4l2_wrapper,std::unique_ptr<Metadata> metadata)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 
~V4L2Camera()74 V4L2Camera::~V4L2Camera() {
75   HAL_LOG_ENTER();
76 }
77 
connect()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 
disconnect()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 
flushBuffers()113 int V4L2Camera::flushBuffers() {
114   HAL_LOG_ENTER();
115   return device_->StreamOff();
116 }
117 
initStaticInfo(android::CameraMetadata * out)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 
initTemplate(int type,android::CameraMetadata * out)144 int V4L2Camera::initTemplate(int type, android::CameraMetadata* out) {
145   HAL_LOG_ENTER();
146 
147   return metadata_->GetRequestTemplate(type, out);
148 }
149 
initDeviceInfo(camera_info_t * info)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 
initDevice()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 
enqueueRequest(std::shared_ptr<default_camera_hal::CaptureRequest> request)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>
dequeueRequest()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 
enqueueRequestBuffers()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 
dequeueRequestBuffers()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 
validateDataspacesAndRotations(const camera3_stream_configuration_t * stream_config)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 
setupStreams(camera3_stream_configuration_t * stream_config)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 
isValidRequestSettings(const android::CameraMetadata & settings)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