Home | History | Annotate | Download | only in 3_4
      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 
     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 
     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 
     74 V4L2Camera::~V4L2Camera() {
     75   HAL_LOG_ENTER();
     76 }
     77 
     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 
    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 
    113 int V4L2Camera::flushBuffers() {
    114   HAL_LOG_ENTER();
    115   return device_->StreamOff();
    116 }
    117 
    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 
    144 int V4L2Camera::initTemplate(int type, android::CameraMetadata* out) {
    145   HAL_LOG_ENTER();
    146 
    147   return metadata_->GetRequestTemplate(type, out);
    148 }
    149 
    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 
    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 
    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>
    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 
    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 
    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 
    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 
    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 
    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