Home | History | Annotate | Download | only in 3_4
      1 /*
      2  * Copyright (C) 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 // Modified from hardware/libhardware/modules/camera/Camera.cpp
     18 
     19 #include <cstdlib>
     20 #include <memory>
     21 #include <vector>
     22 #include <stdio.h>
     23 #include <hardware/camera3.h>
     24 #include <sync/sync.h>
     25 #include <system/camera_metadata.h>
     26 #include <system/graphics.h>
     27 #include <utils/Mutex.h>
     28 
     29 #include "metadata/metadata_common.h"
     30 
     31 //#define LOG_NDEBUG 0
     32 #define LOG_TAG "Camera"
     33 #include <cutils/log.h>
     34 
     35 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
     36 #include <utils/Trace.h>
     37 
     38 #include "camera.h"
     39 
     40 #define CAMERA_SYNC_TIMEOUT 5000 // in msecs
     41 
     42 namespace default_camera_hal {
     43 
     44 extern "C" {
     45 // Shim passed to the framework to close an opened device.
     46 static int close_device(hw_device_t* dev)
     47 {
     48     camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
     49     Camera* cam = static_cast<Camera*>(cam_dev->priv);
     50     return cam->close();
     51 }
     52 } // extern "C"
     53 
     54 Camera::Camera(int id)
     55   : mId(id),
     56     mSettingsSet(false),
     57     mBusy(false),
     58     mCallbackOps(NULL),
     59     mInFlightTracker(new RequestTracker)
     60 {
     61     memset(&mTemplates, 0, sizeof(mTemplates));
     62     memset(&mDevice, 0, sizeof(mDevice));
     63     mDevice.common.tag    = HARDWARE_DEVICE_TAG;
     64     mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_4;
     65     mDevice.common.close  = close_device;
     66     mDevice.ops           = const_cast<camera3_device_ops_t*>(&sOps);
     67     mDevice.priv          = this;
     68 }
     69 
     70 Camera::~Camera()
     71 {
     72 }
     73 
     74 int Camera::openDevice(const hw_module_t *module, hw_device_t **device)
     75 {
     76     ALOGI("%s:%d: Opening camera device", __func__, mId);
     77     ATRACE_CALL();
     78     android::Mutex::Autolock al(mDeviceLock);
     79 
     80     if (mBusy) {
     81         ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
     82         return -EBUSY;
     83     }
     84 
     85     int connectResult = connect();
     86     if (connectResult != 0) {
     87       return connectResult;
     88     }
     89     mBusy = true;
     90     mDevice.common.module = const_cast<hw_module_t*>(module);
     91     *device = &mDevice.common;
     92     return 0;
     93 }
     94 
     95 int Camera::getInfo(struct camera_info *info)
     96 {
     97     info->device_version = mDevice.common.version;
     98     initDeviceInfo(info);
     99     if (!mStaticInfo) {
    100         int res = loadStaticInfo();
    101         if (res) {
    102             return res;
    103         }
    104     }
    105     info->static_camera_characteristics = mStaticInfo->raw_metadata();
    106     info->facing = mStaticInfo->facing();
    107     info->orientation = mStaticInfo->orientation();
    108 
    109     return 0;
    110 }
    111 
    112 int Camera::loadStaticInfo() {
    113   // Using a lock here ensures |mStaticInfo| will only ever be set once,
    114   // even in concurrent situations.
    115   android::Mutex::Autolock al(mStaticInfoLock);
    116 
    117   if (mStaticInfo) {
    118     return 0;
    119   }
    120 
    121   std::unique_ptr<android::CameraMetadata> static_metadata =
    122       std::make_unique<android::CameraMetadata>();
    123   int res = initStaticInfo(static_metadata.get());
    124   if (res) {
    125     ALOGE("%s:%d: Failed to get static info from device.",
    126           __func__, mId);
    127     return res;
    128   }
    129 
    130   mStaticInfo.reset(StaticProperties::NewStaticProperties(
    131       std::move(static_metadata)));
    132   if (!mStaticInfo) {
    133     ALOGE("%s:%d: Failed to initialize static properties from device metadata.",
    134           __func__, mId);
    135     return -ENODEV;
    136   }
    137 
    138   return 0;
    139 }
    140 
    141 int Camera::close()
    142 {
    143     ALOGI("%s:%d: Closing camera device", __func__, mId);
    144     ATRACE_CALL();
    145     android::Mutex::Autolock al(mDeviceLock);
    146 
    147     if (!mBusy) {
    148         ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
    149         return -EINVAL;
    150     }
    151 
    152     flush();
    153     disconnect();
    154     mBusy = false;
    155     return 0;
    156 }
    157 
    158 int Camera::initialize(const camera3_callback_ops_t *callback_ops)
    159 {
    160     int res;
    161 
    162     ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
    163     mCallbackOps = callback_ops;
    164     // per-device specific initialization
    165     res = initDevice();
    166     if (res != 0) {
    167         ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
    168         return res;
    169     }
    170     return 0;
    171 }
    172 
    173 int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
    174 {
    175     android::Mutex::Autolock al(mDeviceLock);
    176 
    177     ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
    178     ATRACE_CALL();
    179 
    180     // Check that there are no in-flight requests.
    181     if (!mInFlightTracker->Empty()) {
    182         ALOGE("%s:%d: Can't configure streams while frames are in flight.",
    183               __func__, mId);
    184         return -EINVAL;
    185     }
    186 
    187     // Verify the set of streams in aggregate, and perform configuration if valid.
    188     int res = validateStreamConfiguration(stream_config);
    189     if (res) {
    190         ALOGE("%s:%d: Failed to validate stream set", __func__, mId);
    191     } else {
    192         // Set up all streams. Since they've been validated,
    193         // this should only result in fatal (-ENODEV) errors.
    194         // This occurs after validation to ensure that if there
    195         // is a non-fatal error, the stream configuration doesn't change states.
    196         res = setupStreams(stream_config);
    197         if (res) {
    198             ALOGE("%s:%d: Failed to setup stream set", __func__, mId);
    199         }
    200     }
    201 
    202     // Set trackers based on result.
    203     if (!res) {
    204         // Success, set up the in-flight trackers for the new streams.
    205         mInFlightTracker->SetStreamConfiguration(*stream_config);
    206         // Must provide new settings for the new configuration.
    207         mSettingsSet = false;
    208     } else if (res != -EINVAL) {
    209         // Fatal error, the old configuration is invalid.
    210         mInFlightTracker->ClearStreamConfiguration();
    211     }
    212     // On a non-fatal error the old configuration, if any, remains valid.
    213     return res;
    214 }
    215 
    216 int Camera::validateStreamConfiguration(
    217     const camera3_stream_configuration_t* stream_config)
    218 {
    219     // Check that the configuration is well-formed.
    220     if (stream_config == nullptr) {
    221         ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
    222         return -EINVAL;
    223     } else if (stream_config->num_streams == 0) {
    224         ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
    225         return -EINVAL;
    226     } else if (stream_config->streams == nullptr) {
    227         ALOGE("%s:%d: NULL stream configuration streams", __func__, mId);
    228         return -EINVAL;
    229     }
    230 
    231     // Check that the configuration is supported.
    232     // Make sure static info has been initialized before trying to use it.
    233     if (!mStaticInfo) {
    234         int res = loadStaticInfo();
    235         if (res) {
    236             return res;
    237         }
    238     }
    239     if (!mStaticInfo->StreamConfigurationSupported(stream_config)) {
    240         ALOGE("%s:%d: Stream configuration does not match static "
    241               "metadata restrictions.", __func__, mId);
    242         return -EINVAL;
    243     }
    244 
    245     // Dataspace support is poorly documented - unclear if the expectation
    246     // is that a device supports ALL dataspaces that could match a given
    247     // format. For now, defer to child class implementation.
    248     // Rotation support isn't described by metadata, so must defer to device.
    249     if (!validateDataspacesAndRotations(stream_config)) {
    250         ALOGE("%s:%d: Device can not handle configuration "
    251               "dataspaces or rotations.", __func__, mId);
    252         return -EINVAL;
    253     }
    254 
    255     return 0;
    256 }
    257 
    258 bool Camera::isValidTemplateType(int type)
    259 {
    260     return type > 0 && type < CAMERA3_TEMPLATE_COUNT;
    261 }
    262 
    263 const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
    264 {
    265     ALOGV("%s:%d: type=%d", __func__, mId, type);
    266 
    267     if (!isValidTemplateType(type)) {
    268         ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
    269         return NULL;
    270     }
    271 
    272     if (!mTemplates[type]) {
    273         // Check if the device has the necessary features
    274         // for the requested template. If not, don't bother.
    275         if (!mStaticInfo->TemplateSupported(type)) {
    276             ALOGW("%s:%d: Camera does not support template type %d",
    277                   __func__, mId, type);
    278             return NULL;
    279         }
    280 
    281         // Initialize this template if it hasn't been initialized yet.
    282         std::unique_ptr<android::CameraMetadata> new_template =
    283             std::make_unique<android::CameraMetadata>();
    284         int res = initTemplate(type, new_template.get());
    285         if (res || !new_template) {
    286             ALOGE("%s:%d: Failed to generate template of type: %d",
    287                   __func__, mId, type);
    288             return NULL;
    289         }
    290         mTemplates[type] = std::move(new_template);
    291     }
    292 
    293     // The "locking" here only causes non-const methods to fail,
    294     // which is not a problem since the CameraMetadata being locked
    295     // is already const. Destructing automatically "unlocks".
    296     return mTemplates[type]->getAndLock();
    297 }
    298 
    299 int Camera::processCaptureRequest(camera3_capture_request_t *temp_request)
    300 {
    301     int res;
    302     // TODO(b/32917568): A capture request submitted or ongoing during a flush
    303     // should be returned with an error; for now they are mutually exclusive.
    304     android::Mutex::Autolock al(mFlushLock);
    305 
    306     ATRACE_CALL();
    307 
    308     if (temp_request == NULL) {
    309         ALOGE("%s:%d: NULL request recieved", __func__, mId);
    310         return -EINVAL;
    311     }
    312 
    313     // Make a persistent copy of request, since otherwise it won't live
    314     // past the end of this method.
    315     std::shared_ptr<CaptureRequest> request = std::make_shared<CaptureRequest>(temp_request);
    316 
    317     ALOGV("%s:%d: frame: %d", __func__, mId, request->frame_number);
    318 
    319     if (!mInFlightTracker->CanAddRequest(*request)) {
    320         // Streams are full or frame number is not unique.
    321         ALOGE("%s:%d: Can not add request.", __func__, mId);
    322         return -EINVAL;
    323     }
    324 
    325     // Null/Empty indicates use last settings
    326     if (request->settings.isEmpty() && !mSettingsSet) {
    327         ALOGE("%s:%d: NULL settings without previous set Frame:%d",
    328               __func__, mId, request->frame_number);
    329         return -EINVAL;
    330     }
    331 
    332     if (request->input_buffer != NULL) {
    333         ALOGV("%s:%d: Reprocessing input buffer %p", __func__, mId,
    334               request->input_buffer.get());
    335     } else {
    336         ALOGV("%s:%d: Capturing new frame.", __func__, mId);
    337     }
    338 
    339     if (!isValidRequestSettings(request->settings)) {
    340         ALOGE("%s:%d: Invalid request settings.", __func__, mId);
    341         return -EINVAL;
    342     }
    343 
    344     // Pre-process output buffers.
    345     if (request->output_buffers.size() <= 0) {
    346         ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
    347               request->output_buffers.size());
    348         return -EINVAL;
    349     }
    350     for (auto& output_buffer : request->output_buffers) {
    351         res = preprocessCaptureBuffer(&output_buffer);
    352         if (res)
    353             return -ENODEV;
    354     }
    355 
    356     // Add the request to tracking.
    357     if (!mInFlightTracker->Add(request)) {
    358         ALOGE("%s:%d: Failed to track request for frame %d.",
    359               __func__, mId, request->frame_number);
    360         return -ENODEV;
    361     }
    362 
    363     // Valid settings have been provided (mSettingsSet is a misnomer;
    364     // all that matters is that a previous request with valid settings
    365     // has been passed to the device, not that they've been set).
    366     mSettingsSet = true;
    367 
    368     // Send the request off to the device for completion.
    369     enqueueRequest(request);
    370 
    371     // Request is now in flight. The device will call completeRequest
    372     // asynchronously when it is done filling buffers and metadata.
    373     return 0;
    374 }
    375 
    376 void Camera::completeRequest(std::shared_ptr<CaptureRequest> request, int err)
    377 {
    378     if (!mInFlightTracker->Remove(request)) {
    379         ALOGE("%s:%d: Completed request %p is not being tracked. "
    380               "It may have been cleared out during a flush.",
    381               __func__, mId, request.get());
    382         return;
    383     }
    384 
    385     // Since |request| has been removed from the tracking, this method
    386     // MUST call sendResult (can still return a result in an error state, e.g.
    387     // through completeRequestWithError) so the frame doesn't get lost.
    388 
    389     if (err) {
    390       ALOGE("%s:%d: Error completing request for frame %d.",
    391             __func__, mId, request->frame_number);
    392       completeRequestWithError(request);
    393       return;
    394     }
    395 
    396     // Notify the framework with the shutter time (extracted from the result).
    397     int64_t timestamp = 0;
    398     // TODO(b/31360070): The general metadata methods should be part of the
    399     // default_camera_hal namespace, not the v4l2_camera_hal namespace.
    400     int res = v4l2_camera_hal::SingleTagValue(
    401         request->settings, ANDROID_SENSOR_TIMESTAMP, &timestamp);
    402     if (res) {
    403         ALOGE("%s:%d: Request for frame %d is missing required metadata.",
    404               __func__, mId, request->frame_number);
    405         // TODO(b/31653322): Send RESULT error.
    406         // For now sending REQUEST error instead.
    407         completeRequestWithError(request);
    408         return;
    409     }
    410     notifyShutter(request->frame_number, timestamp);
    411 
    412     // TODO(b/31653322): Check all returned buffers for errors
    413     // (if any, send BUFFER error).
    414 
    415     sendResult(request);
    416 }
    417 
    418 int Camera::flush()
    419 {
    420     ALOGV("%s:%d: Flushing.", __func__, mId);
    421     // TODO(b/32917568): Synchronization. Behave "appropriately"
    422     // (i.e. according to camera3.h) if process_capture_request()
    423     // is called concurrently with this (in either order).
    424     // Since the callback to completeRequest also may happen on a separate
    425     // thread, this function should behave nicely concurrently with that too.
    426     android::Mutex::Autolock al(mFlushLock);
    427 
    428     std::set<std::shared_ptr<CaptureRequest>> requests;
    429     mInFlightTracker->Clear(&requests);
    430     for (auto& request : requests) {
    431         // TODO(b/31653322): See camera3.h. Should return different error
    432         // depending on status of the request.
    433         completeRequestWithError(request);
    434     }
    435 
    436     ALOGV("%s:%d: Flushed %u requests.", __func__, mId, requests.size());
    437 
    438     // Call down into the device flushing.
    439     return flushBuffers();
    440 }
    441 
    442 int Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer)
    443 {
    444     int res;
    445     // TODO(b/29334616): This probably should be non-blocking; part
    446     // of the asynchronous request processing.
    447     if (buffer->acquire_fence != -1) {
    448         res = sync_wait(buffer->acquire_fence, CAMERA_SYNC_TIMEOUT);
    449         if (res == -ETIME) {
    450             ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
    451                     __func__, mId);
    452             return res;
    453         } else if (res) {
    454             ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
    455                     __func__, mId, strerror(-res), res);
    456             return res;
    457         }
    458         ::close(buffer->acquire_fence);
    459     }
    460 
    461     // Acquire fence has been waited upon.
    462     buffer->acquire_fence = -1;
    463     // No release fence waiting unless the device sets it.
    464     buffer->release_fence = -1;
    465 
    466     buffer->status = CAMERA3_BUFFER_STATUS_OK;
    467     return 0;
    468 }
    469 
    470 void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp)
    471 {
    472     camera3_notify_msg_t message;
    473     memset(&message, 0, sizeof(message));
    474     message.type = CAMERA3_MSG_SHUTTER;
    475     message.message.shutter.frame_number = frame_number;
    476     message.message.shutter.timestamp = timestamp;
    477     mCallbackOps->notify(mCallbackOps, &message);
    478 }
    479 
    480 void Camera::completeRequestWithError(std::shared_ptr<CaptureRequest> request)
    481 {
    482     // Send an error notification.
    483     camera3_notify_msg_t message;
    484     memset(&message, 0, sizeof(message));
    485     message.type = CAMERA3_MSG_ERROR;
    486     message.message.error.frame_number = request->frame_number;
    487     message.message.error.error_stream = nullptr;
    488     message.message.error.error_code = CAMERA3_MSG_ERROR_REQUEST;
    489     mCallbackOps->notify(mCallbackOps, &message);
    490 
    491     // TODO(b/31856611): Ensure all the buffers indicate their error status.
    492 
    493     // Send the errored out result.
    494     sendResult(request);
    495 }
    496 
    497 void Camera::sendResult(std::shared_ptr<CaptureRequest> request) {
    498     // Fill in the result struct
    499     // (it only needs to live until the end of the framework callback).
    500     camera3_capture_result_t result {
    501         request->frame_number,
    502         request->settings.getAndLock(),
    503         static_cast<uint32_t>(request->output_buffers.size()),
    504         request->output_buffers.data(),
    505         request->input_buffer.get(),
    506         1  // Total result; only 1 part.
    507     };
    508     // Make the framework callback.
    509     mCallbackOps->process_capture_result(mCallbackOps, &result);
    510 }
    511 
    512 void Camera::dump(int fd)
    513 {
    514     ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
    515     ATRACE_CALL();
    516     android::Mutex::Autolock al(mDeviceLock);
    517 
    518     dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
    519 
    520     // TODO: dump all settings
    521 }
    522 
    523 const char* Camera::templateToString(int type)
    524 {
    525     switch (type) {
    526     case CAMERA3_TEMPLATE_PREVIEW:
    527         return "CAMERA3_TEMPLATE_PREVIEW";
    528     case CAMERA3_TEMPLATE_STILL_CAPTURE:
    529         return "CAMERA3_TEMPLATE_STILL_CAPTURE";
    530     case CAMERA3_TEMPLATE_VIDEO_RECORD:
    531         return "CAMERA3_TEMPLATE_VIDEO_RECORD";
    532     case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
    533         return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
    534     case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
    535         return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
    536     }
    537     // TODO: support vendor templates
    538     return "Invalid template type!";
    539 }
    540 
    541 extern "C" {
    542 // Get handle to camera from device priv data
    543 static Camera *camdev_to_camera(const camera3_device_t *dev)
    544 {
    545     return reinterpret_cast<Camera*>(dev->priv);
    546 }
    547 
    548 static int initialize(const camera3_device_t *dev,
    549         const camera3_callback_ops_t *callback_ops)
    550 {
    551     return camdev_to_camera(dev)->initialize(callback_ops);
    552 }
    553 
    554 static int configure_streams(const camera3_device_t *dev,
    555         camera3_stream_configuration_t *stream_list)
    556 {
    557     return camdev_to_camera(dev)->configureStreams(stream_list);
    558 }
    559 
    560 static const camera_metadata_t *construct_default_request_settings(
    561         const camera3_device_t *dev, int type)
    562 {
    563     return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
    564 }
    565 
    566 static int process_capture_request(const camera3_device_t *dev,
    567         camera3_capture_request_t *request)
    568 {
    569     return camdev_to_camera(dev)->processCaptureRequest(request);
    570 }
    571 
    572 static void dump(const camera3_device_t *dev, int fd)
    573 {
    574     camdev_to_camera(dev)->dump(fd);
    575 }
    576 
    577 static int flush(const camera3_device_t *dev)
    578 {
    579     return camdev_to_camera(dev)->flush();
    580 }
    581 
    582 } // extern "C"
    583 
    584 const camera3_device_ops_t Camera::sOps = {
    585     .initialize = default_camera_hal::initialize,
    586     .configure_streams = default_camera_hal::configure_streams,
    587     .register_stream_buffers = nullptr,
    588     .construct_default_request_settings
    589         = default_camera_hal::construct_default_request_settings,
    590     .process_capture_request = default_camera_hal::process_capture_request,
    591     .get_metadata_vendor_tag_ops = nullptr,
    592     .dump = default_camera_hal::dump,
    593     .flush = default_camera_hal::flush,
    594     .reserved = {0},
    595 };
    596 
    597 }  // namespace default_camera_hal
    598